diff --git a/idd/LGIddHelper/CConfigWindow.cpp b/idd/LGIddHelper/CConfigWindow.cpp new file mode 100644 index 00000000..9d3f169d --- /dev/null +++ b/idd/LGIddHelper/CConfigWindow.cpp @@ -0,0 +1,48 @@ +#include "CConfigWindow.h" +#include +#include +#include + +ATOM CConfigWindow::s_atom = 0; + +bool CConfigWindow::registerClass() +{ + WNDCLASSEX wx = {}; + populateWindowClass(wx); + wx.hIconSm = wx.hIcon = LoadIcon(hInstance, IDI_APPLICATION); + wx.lpszClassName = L"LookingGlassIddConfig"; + + s_atom = RegisterClassEx(&wx); + return s_atom; +} + +CConfigWindow::CConfigWindow() +{ + if (!CreateWindowEx(0, MAKEINTATOM(s_atom), L"Looking Glass IDD Configuration", + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, 300, 200, + NULL, NULL, hInstance, this)) + { + DEBUG_ERROR_HR(GetLastError(), "Failed to create window"); + } +} + +LRESULT CConfigWindow::handleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + default: + return CWindow::handleMessage(uMsg, wParam, lParam); + } +} + +LRESULT CConfigWindow::onCreate() +{ + return 0; +} + +LRESULT CConfigWindow::onFinal() +{ + if (m_onDestroy) + m_onDestroy(); + return CWindow::onFinal(); +} diff --git a/idd/LGIddHelper/CConfigWindow.h b/idd/LGIddHelper/CConfigWindow.h new file mode 100644 index 00000000..0be77066 --- /dev/null +++ b/idd/LGIddHelper/CConfigWindow.h @@ -0,0 +1,20 @@ +#pragma once +#include "CWindow.h" +#include + +class CConfigWindow : public CWindow +{ + static ATOM s_atom; + + std::function m_onDestroy; + + virtual LRESULT handleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override; + virtual LRESULT onCreate() override; + virtual LRESULT onFinal() override; + +public: + CConfigWindow(); + static bool registerClass(); + + void onDestroy(std::function func) { m_onDestroy = std::move(func); } +}; diff --git a/idd/LGIddHelper/CNotifyWindow.cpp b/idd/LGIddHelper/CNotifyWindow.cpp index 77373df6..edc2f1e2 100644 --- a/idd/LGIddHelper/CNotifyWindow.cpp +++ b/idd/LGIddHelper/CNotifyWindow.cpp @@ -1,9 +1,14 @@ #include "CNotifyWindow.h" +#include "CConfigWindow.h" #include #include #include +#define WM_NOTIFY_ICON (WM_USER) +#define WM_CLEAN_UP_CONFIG (WM_USER+1) + #define ID_MENU_SHOW_LOG 3000 +#define ID_MENU_SHOW_CONFIG 3001 ATOM CNotifyWindow::s_atom = 0; UINT CNotifyWindow::s_taskbarCreated = 0; @@ -31,6 +36,7 @@ CNotifyWindow::CNotifyWindow() : m_iconData({ 0 }), m_menu(CreatePopupMenu()), if (m_menu) { AppendMenu(m_menu, MF_STRING, ID_MENU_SHOW_LOG, L"Open log directory"); + AppendMenu(m_menu, MF_STRING, ID_MENU_SHOW_CONFIG, L"Open configuration"); } } @@ -43,11 +49,15 @@ LRESULT CNotifyWindow::handleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { - case WM_NCDESTROY: - PostQuitMessage(0); - return 0; case WM_NOTIFY_ICON: return onNotifyIcon(LOWORD(lParam), HIWORD(lParam), GET_X_LPARAM(wParam), GET_Y_LPARAM(wParam)); + case WM_CLEAN_UP_CONFIG: + if (m_config && !m_config->hwnd()) + { + DEBUG_INFO("Config window closed"); + m_config.reset(); + } + return 0; default: if (s_taskbarCreated && uMsg == s_taskbarCreated) { @@ -71,6 +81,12 @@ LRESULT CNotifyWindow::onClose() return 0; } +LRESULT CNotifyWindow::onFinal() +{ + PostQuitMessage(0); + return CWindow::onFinal(); +} + LRESULT CNotifyWindow::onNotifyIcon(UINT uEvent, WORD wIconId, int x, int y) { switch (uEvent) @@ -81,6 +97,14 @@ LRESULT CNotifyWindow::onNotifyIcon(UINT uEvent, WORD wIconId, int x, int y) case ID_MENU_SHOW_LOG: ShellExecute(m_hwnd, L"open", g_debug.logDir(), NULL, NULL, SW_NORMAL); break; + case ID_MENU_SHOW_CONFIG: + DEBUG_INFO("Config window opened"); + m_config.reset(new CConfigWindow()); + m_config->onDestroy([this]() { + PostMessage(m_hwnd, WM_CLEAN_UP_CONFIG, 0, 0); + }); + ShowWindow(*m_config, SW_NORMAL); + break; } break; } diff --git a/idd/LGIddHelper/CNotifyWindow.h b/idd/LGIddHelper/CNotifyWindow.h index 690cb93a..f0606eb0 100644 --- a/idd/LGIddHelper/CNotifyWindow.h +++ b/idd/LGIddHelper/CNotifyWindow.h @@ -1,7 +1,8 @@ #pragma once #include "CWindow.h" +#include -#define WM_NOTIFY_ICON (WM_USER) +class CConfigWindow; class CNotifyWindow : public CWindow { @@ -11,6 +12,7 @@ class CNotifyWindow : public CWindow NOTIFYICONDATA m_iconData; HMENU m_menu; bool closeRequested; + std::unique_ptr m_config; LRESULT onNotifyIcon(UINT uEvent, WORD wIconId, int x, int y); void registerIcon(); @@ -18,6 +20,7 @@ class CNotifyWindow : public CWindow virtual LRESULT handleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override; virtual LRESULT onCreate() override; virtual LRESULT onClose() override; + virtual LRESULT onFinal() override; public: CNotifyWindow(); diff --git a/idd/LGIddHelper/CWindow.cpp b/idd/LGIddHelper/CWindow.cpp index ee9d1772..e9d4eede 100644 --- a/idd/LGIddHelper/CWindow.cpp +++ b/idd/LGIddHelper/CWindow.cpp @@ -47,6 +47,8 @@ LRESULT CWindow::handleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) return onClose(); case WM_DESTROY: return onDestroy(); + case WM_NCDESTROY: + return onFinal(); default: return DefWindowProc(m_hwnd, uMsg, wParam, lParam); } @@ -67,13 +69,16 @@ LRESULT CWindow::onDestroy() return 0; } +LRESULT CWindow::onFinal() +{ + m_hwnd = 0; + return 0; +} + void CWindow::destroy() { if (m_hwnd) - { DestroyWindow(m_hwnd); - m_hwnd = NULL; - } } CWindow::~CWindow() diff --git a/idd/LGIddHelper/CWindow.h b/idd/LGIddHelper/CWindow.h index 074c9e30..8a23d95d 100644 --- a/idd/LGIddHelper/CWindow.h +++ b/idd/LGIddHelper/CWindow.h @@ -7,11 +7,12 @@ class CWindow { static LRESULT CALLBACK wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +protected: virtual LRESULT onCreate(); virtual LRESULT onClose(); virtual LRESULT onDestroy(); + virtual LRESULT onFinal(); -protected: static HINSTANCE hInstance; static void populateWindowClass(WNDCLASSEX &wx); @@ -24,4 +25,5 @@ public: void destroy(); HWND hwnd() { return m_hwnd; } + operator HWND() { return m_hwnd; } }; diff --git a/idd/LGIddHelper/LGIddHelper.vcxproj b/idd/LGIddHelper/LGIddHelper.vcxproj index 78c52ffa..e34120ad 100644 --- a/idd/LGIddHelper/LGIddHelper.vcxproj +++ b/idd/LGIddHelper/LGIddHelper.vcxproj @@ -177,6 +177,7 @@ copy /Y "$(ProjectDir)VERSION" "$(SolutionDir)$(Platform)\$(Configuration)\LGIdd + @@ -184,6 +185,7 @@ copy /Y "$(ProjectDir)VERSION" "$(SolutionDir)$(Platform)\$(Configuration)\LGIdd + diff --git a/idd/LGIddHelper/main.cpp b/idd/LGIddHelper/main.cpp index c772c67c..3f7bb135 100644 --- a/idd/LGIddHelper/main.cpp +++ b/idd/LGIddHelper/main.cpp @@ -13,6 +13,7 @@ using namespace Microsoft::WRL::Wrappers::HandleTraits; #include "VersionInfo.h" #include "CPipeClient.h" #include "CNotifyWindow.h" +#include "CConfigWindow.h" #define ARRAY_SIZE(x) (sizeof(x) / sizeof*(x)) #define SVCNAME L"Looking Glass (IDD Helper)" @@ -86,6 +87,12 @@ int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ return EXIT_FAILURE; } + if (!CConfigWindow::registerClass()) + { + DEBUG_ERROR("Failed to register config window class"); + return EXIT_FAILURE; + } + if (!g_pipe.Init()) return EXIT_FAILURE;