summaryrefslogtreecommitdiffstats
path: root/mmc_updater/src/UpdateDialogWin32.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mmc_updater/src/UpdateDialogWin32.cpp')
-rw-r--r--mmc_updater/src/UpdateDialogWin32.cpp215
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;
+}