diff options
Diffstat (limited to 'mmc_updater/src/UpdateDialogWin32.cpp')
-rw-r--r-- | mmc_updater/src/UpdateDialogWin32.cpp | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/mmc_updater/src/UpdateDialogWin32.cpp b/mmc_updater/src/UpdateDialogWin32.cpp new file mode 100644 index 00000000..bdc25437 --- /dev/null +++ b/mmc_updater/src/UpdateDialogWin32.cpp @@ -0,0 +1,215 @@ +#include "UpdateDialogWin32.h" + +#include "AppInfo.h" +#include "Log.h" + +// enable themed controls +// see http://msdn.microsoft.com/en-us/library/bb773175%28v=vs.85%29.aspx +// for details +#pragma comment(linker,"\"/manifestdependency:type='win32' \ +name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ +processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") + +static const char* updateDialogClassName = "UPDATEDIALOG"; + +static std::map<HWND,UpdateDialogWin32*> windowDialogMap; + +// enable the standard Windows font for a widget +// (typically Tahoma or Segoe UI) +void setDefaultFont(HWND window) +{ + SendMessage(window, WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(TRUE, 0)); +} + +LRESULT WINAPI updateDialogWindowProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) +{ + std::map<HWND,UpdateDialogWin32*>::const_iterator iter = windowDialogMap.find(window); + if (iter != windowDialogMap.end()) + { + return iter->second->windowProc(window,message,wParam,lParam); + } + else + { + return DefWindowProc(window,message,wParam,lParam); + } +}; + +void registerWindowClass() +{ + WNDCLASSEX wcex; + ZeroMemory(&wcex,sizeof(WNDCLASSEX)); + + wcex.cbSize = sizeof(WNDCLASSEX); + + HBRUSH background = CreateSolidBrush(GetSysColor(COLOR_3DFACE)); + + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = updateDialogWindowProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hIcon = LoadIcon(GetModuleHandle(0),"IDI_APPICON"); + wcex.hCursor = LoadCursor(0,IDC_ARROW); + wcex.hbrBackground = (HBRUSH)background; + wcex.lpszMenuName = (LPCTSTR)0; + wcex.lpszClassName = updateDialogClassName; + wcex.hIconSm = 0; + wcex.hInstance = GetModuleHandle(0); + + RegisterClassEx(&wcex); +} + +UpdateDialogWin32::UpdateDialogWin32() +: m_hadError(false) +{ + registerWindowClass(); +} + +UpdateDialogWin32::~UpdateDialogWin32() +{ + for (std::map<HWND,UpdateDialogWin32*>::iterator iter = windowDialogMap.begin(); + iter != windowDialogMap.end(); + iter++) + { + if (iter->second == this) + { + std::map<HWND,UpdateDialogWin32*>::iterator oldIter = iter; + ++iter; + windowDialogMap.erase(oldIter); + } + else + { + ++iter; + } + } +} + +void UpdateDialogWin32::init(int /* argc */, char** /* argv */) +{ + int width = 300; + int height = 130; + + DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + m_window.CreateEx(0 /* dwExStyle */, + updateDialogClassName /* class name */, + AppInfo::name().c_str(), + style, + 0, 0, width, height, + 0 /* parent */, 0 /* menu */, 0 /* reserved */); + m_progressBar.Create(&m_window); + m_finishButton.Create(&m_window); + m_progressLabel.Create(&m_window); + + installWindowProc(&m_window); + installWindowProc(&m_finishButton); + + setDefaultFont(m_progressLabel); + setDefaultFont(m_finishButton); + + m_progressBar.SetRange(0,100); + m_finishButton.SetWindowText("Finish"); + m_finishButton.EnableWindow(false); + m_progressLabel.SetWindowText("Installing Updates"); + + m_window.SetWindowPos(0,0,0,width,height,0); + m_progressBar.SetWindowPos(0,10,40,width - 30,20,0); + m_progressLabel.SetWindowPos(0,10,15,width - 30,20,0); + m_finishButton.SetWindowPos(0,width-100,70,80,25,0); + m_window.CenterWindow(); + m_window.ShowWindow(); +} + +void UpdateDialogWin32::exec() +{ + m_app.Run(); +} + +void UpdateDialogWin32::updateError(const std::string& errorMessage) +{ + UpdateMessage* message = new UpdateMessage(UpdateMessage::UpdateFailed); + message->message = errorMessage; + SendNotifyMessage(m_window.GetHwnd(),WM_USER,reinterpret_cast<WPARAM>(message),0); +} + +void UpdateDialogWin32::updateProgress(int percentage) +{ + UpdateMessage* message = new UpdateMessage(UpdateMessage::UpdateProgress); + message->progress = percentage; + SendNotifyMessage(m_window.GetHwnd(),WM_USER,reinterpret_cast<WPARAM>(message),0); +} + +void UpdateDialogWin32::updateFinished() +{ + UpdateMessage* message = new UpdateMessage(UpdateMessage::UpdateFinished); + SendNotifyMessage(m_window.GetHwnd(),WM_USER,reinterpret_cast<WPARAM>(message),0); + UpdateDialog::updateFinished(); +} + +void UpdateDialogWin32::quit() +{ + PostThreadMessage(GetWindowThreadProcessId(m_window.GetHwnd(), 0 /* process ID */), WM_QUIT, 0, 0); +} + +LRESULT WINAPI UpdateDialogWin32::windowProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_CLOSE: + if (window == m_window.GetHwnd()) + { + return 0; + } + break; + case WM_COMMAND: + { + if (reinterpret_cast<HWND>(lParam) == m_finishButton.GetHwnd()) + { + quit(); + } + } + break; + case WM_USER: + { + if (window == m_window.GetHwnd()) + { + UpdateMessage* message = reinterpret_cast<UpdateMessage*>(wParam); + switch (message->type) + { + case UpdateMessage::UpdateFailed: + { + m_hadError = true; + std::string text = AppInfo::updateErrorMessage(message->message); + MessageBox(m_window.GetHwnd(),text.c_str(),"Update Problem",MB_OK); + } + break; + case UpdateMessage::UpdateProgress: + m_progressBar.SetPos(message->progress); + break; + case UpdateMessage::UpdateFinished: + { + std::string message; + m_finishButton.EnableWindow(true); + if (m_hadError) + { + message = "Update failed."; + } + else + { + message = "Updates installed."; + } + message += " Click 'Finish' to restart the application."; + m_progressLabel.SetWindowText(message.c_str()); + } + break; + } + delete message; + } + } + break; + } + return DefWindowProc(window,message,wParam,lParam); +} + +void UpdateDialogWin32::installWindowProc(CWnd* window) +{ + windowDialogMap[window->GetHwnd()] = this; +} |