mirror of
https://github.com/etlegacy/Update-Installer.git
synced 2025-01-22 23:41:10 +00:00
Add Windows implementation of updater dialog
The Windows implementation uses Win++, a thin header-only wrapper around the Windows API
This commit is contained in:
parent
214f2273b9
commit
5cd7d22192
4 changed files with 256 additions and 5 deletions
|
@ -32,6 +32,9 @@ endif()
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(SOURCES ${SOURCES} UpdateDialogCocoa.mm)
|
set(SOURCES ${SOURCES} UpdateDialogCocoa.mm)
|
||||||
endif()
|
endif()
|
||||||
|
if (WIN32)
|
||||||
|
set(SOURCES ${SOURCES} UpdateDialogWin32.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
set (HEADERS
|
set (HEADERS
|
||||||
Dir.h
|
Dir.h
|
||||||
|
@ -47,7 +50,10 @@ if (ENABLE_GTK)
|
||||||
set(HEADERS ${HEADERS} UpdateDialogGtk.h)
|
set(HEADERS ${HEADERS} UpdateDialogGtk.h)
|
||||||
endif()
|
endif()
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(SOURCES ${SOURCES} UpdateDialogCocoa.h)
|
set(HEADERS ${HEADERS} UpdateDialogCocoa.h)
|
||||||
|
endif()
|
||||||
|
if (WIN32)
|
||||||
|
set(HEADERS ${HEADERS} UpdateDialogWin32.h)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(updatershared
|
add_library(updatershared
|
||||||
|
|
187
src/UpdateDialogWin32.cpp
Normal file
187
src/UpdateDialogWin32.cpp
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
#include "UpdateDialogWin32.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 = 0;
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
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 width = 300;
|
||||||
|
int height = 130;
|
||||||
|
|
||||||
|
DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
|
||||||
|
m_window.CreateEx(0 /* dwExStyle */,
|
||||||
|
updateDialogClassName /* class name */,
|
||||||
|
"Mendeley Updater",
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UpdateDialogWin32::updateRetryCancel(const std::string& message)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateDialogWin32::updateProgress(int percentage)
|
||||||
|
{
|
||||||
|
Message* message = new Message(Message::UpdateProgress);
|
||||||
|
message->progress = percentage;
|
||||||
|
SendNotifyMessage(m_window.GetHwnd(),WM_USER,reinterpret_cast<WPARAM>(message),0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateDialogWin32::updateFinished()
|
||||||
|
{
|
||||||
|
Message* message = new Message(Message::UpdateFinished);
|
||||||
|
SendNotifyMessage(m_window.GetHwnd(),WM_USER,reinterpret_cast<WPARAM>(message),0);
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT WINAPI UpdateDialogWin32::windowProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case WM_COMMAND:
|
||||||
|
{
|
||||||
|
if (reinterpret_cast<HWND>(lParam) == m_finishButton.GetHwnd())
|
||||||
|
{
|
||||||
|
PostQuitMessage(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_USER:
|
||||||
|
{
|
||||||
|
if (window == m_window.GetHwnd())
|
||||||
|
{
|
||||||
|
Message* message = reinterpret_cast<Message*>(wParam);
|
||||||
|
switch (message->type)
|
||||||
|
{
|
||||||
|
case Message::UpdateFailed:
|
||||||
|
break;
|
||||||
|
case Message::UpdateProgress:
|
||||||
|
m_progressBar.SetPos(message->progress);
|
||||||
|
break;
|
||||||
|
case Message::UpdateFinished:
|
||||||
|
m_finishButton.EnableWindow(true);
|
||||||
|
m_progressLabel.SetWindowText("Updates installed. Click 'Finish' to restart the application.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
delete message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return DefWindowProc(window,message,wParam,lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateDialogWin32::installWindowProc(CWnd* window)
|
||||||
|
{
|
||||||
|
windowDialogMap[window->GetHwnd()] = this;
|
||||||
|
}
|
|
@ -1,7 +1,56 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class UpdateDialogWin32
|
#include "Platform.h"
|
||||||
|
#include "UpdateObserver.h"
|
||||||
|
|
||||||
|
#include "wincore.h"
|
||||||
|
#include "controls.h"
|
||||||
|
#include "stdcontrols.h"
|
||||||
|
|
||||||
|
class UpdateDialogWin32 : public UpdateObserver
|
||||||
{
|
{
|
||||||
// TODO - UI for update dialog on Windows
|
public:
|
||||||
|
UpdateDialogWin32();
|
||||||
|
~UpdateDialogWin32();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void exec();
|
||||||
|
|
||||||
|
// implements UpdateObserver
|
||||||
|
virtual void updateError(const std::string& errorMessage);
|
||||||
|
virtual bool updateRetryCancel(const std::string& message);
|
||||||
|
virtual void updateProgress(int percentage);
|
||||||
|
virtual void updateFinished();
|
||||||
|
|
||||||
|
LRESULT WINAPI windowProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Message
|
||||||
|
{
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
UpdateFailed,
|
||||||
|
UpdateProgress,
|
||||||
|
UpdateFinished
|
||||||
|
};
|
||||||
|
|
||||||
|
Message(Type _type)
|
||||||
|
: type(_type)
|
||||||
|
, progress(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Type type;
|
||||||
|
std::string message;
|
||||||
|
int progress;
|
||||||
|
};
|
||||||
|
|
||||||
|
void installWindowProc(CWnd* window);
|
||||||
|
|
||||||
|
CWinApp m_app;
|
||||||
|
CWnd m_window;
|
||||||
|
CStatic m_progressLabel;
|
||||||
|
CProgressBar m_progressBar;
|
||||||
|
CButton m_finishButton;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
13
src/main.cpp
13
src/main.cpp
|
@ -14,6 +14,10 @@
|
||||||
#include "UpdateDialogCocoa.h"
|
#include "UpdateDialogCocoa.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(PLATFORM_WINDOWS)
|
||||||
|
#include "UpdateDialogWin32.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
void runWithUi(int argc, char** argv, UpdateInstaller* installer);
|
void runWithUi(int argc, char** argv, UpdateInstaller* installer);
|
||||||
|
@ -118,7 +122,12 @@ void runWithUi(int argc, char** argv, UpdateInstaller* installer)
|
||||||
#ifdef PLATFORM_WINDOWS
|
#ifdef PLATFORM_WINDOWS
|
||||||
void runWithUi(int argc, char** argv, UpdateInstaller* installer)
|
void runWithUi(int argc, char** argv, UpdateInstaller* installer)
|
||||||
{
|
{
|
||||||
// TODO - Windows UI
|
UpdateDialogWin32 dialog;
|
||||||
installer->run();
|
installer->setObserver(&dialog);
|
||||||
|
dialog.init();
|
||||||
|
tthread::thread updaterThread(runUpdaterThread,installer);
|
||||||
|
dialog.exec();
|
||||||
|
updaterThread.join();
|
||||||
|
installer->restartMainApp();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue