From 94b4883cd218722b569b0a6106d989adba65ac97 Mon Sep 17 00:00:00 2001 From: Mike Crowe Date: Tue, 30 May 2006 16:47:12 +0000 Subject: [PATCH] Make the configuration dialog appear near the mouse pointer if launched from the shell notification icon as requested by Roku's Anthony Wood. --- win32/FireflyShell/FireflyShell.cpp | 6 ++-- win32/FireflyShell/FireflyShell.h | 5 +-- win32/FireflyShell/MainDlg.cpp | 53 ++++++++++++++++++++++++++++- win32/FireflyShell/MainDlg.h | 9 ++++- win32/FireflyShell/NotifyIcon.cpp | 6 ++-- 5 files changed, 69 insertions(+), 10 deletions(-) diff --git a/win32/FireflyShell/FireflyShell.cpp b/win32/FireflyShell/FireflyShell.cpp index 716252d4..f68caef2 100644 --- a/win32/FireflyShell/FireflyShell.cpp +++ b/win32/FireflyShell/FireflyShell.cpp @@ -77,7 +77,7 @@ int Application::Run(LPCTSTR lpstrCmdLine, int nCmdShow) EnableServerEvents(true); if (ShowDialogAtStart(lpstrCmdLine, nCmdShow)) - Configure(); + Configure(false); int nRet = theLoop.Run(); @@ -100,7 +100,7 @@ void Application::Exit() ::PostQuitMessage(0); } -void Application::Configure() +void Application::Configure(bool move_window) { if (m_dlg) { @@ -112,7 +112,7 @@ void Application::Configure() CheckCanConfigure(); // Other people may need to talk to the dialog while it exists. - CMainDlg dlg; + CMainDlg dlg(move_window); m_dlg = &dlg; dlg.DoModal(); m_dlg = NULL; diff --git a/win32/FireflyShell/FireflyShell.h b/win32/FireflyShell/FireflyShell.h index f43190cf..f5e5d186 100644 --- a/win32/FireflyShell/FireflyShell.h +++ b/win32/FireflyShell/FireflyShell.h @@ -74,8 +74,9 @@ public: return m_registered_activation_message; } - // User actions - void Configure(); + // Pass true to move the window so it is near the mouse + // cursor. + void Configure(bool move_window); void Exit(); // Service control diff --git a/win32/FireflyShell/MainDlg.cpp b/win32/FireflyShell/MainDlg.cpp index ce904581..79b3813a 100644 --- a/win32/FireflyShell/MainDlg.cpp +++ b/win32/FireflyShell/MainDlg.cpp @@ -20,7 +20,8 @@ #include "MainDlg.h" #include "FireflyShell.h" -CMainDlg::CMainDlg() +CMainDlg::CMainDlg(bool move_window) + : m_window_move_required(move_window) { this->AddPage(m_pageConfig); this->AddPage(m_pageAdvanced); @@ -57,3 +58,53 @@ LRESULT CMainDlg::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHand return result; } + +void CMainDlg::PositionWindow() +{ + POINT cursor_pt; + GetCursorPos(&cursor_pt); + + CRect desktop_rect; + if (SystemParametersInfo(SPI_GETWORKAREA, 0, &desktop_rect, 0)) + { + // Don't put it hard against the edge of the screen or task bar. + desktop_rect.DeflateRect(CSize(4, 4)); + + CRect window_rect; + GetWindowRect(&window_rect); + + // First move the window so that it's middle is at the cursor position. + CPoint pos; + + pos.x = cursor_pt.x - window_rect.Width()/2; + pos.y = cursor_pt.y - window_rect.Height()/2; + + // Now make that window appear on the work area but in case it doesn't fit prefer to fit the + // top left. + if (pos.x + window_rect.Width() > desktop_rect.right) + pos.x = desktop_rect.right - window_rect.Width(); + if (pos.y + window_rect.Height() > desktop_rect.bottom) + pos.y = desktop_rect.bottom - window_rect.Height(); + + if (pos.x < desktop_rect.left) + pos.x = desktop_rect.left; + if (pos.y < desktop_rect.top) + pos.y = desktop_rect.top; + + SetWindowPos(NULL, pos.x, pos.y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER); + } +} + +void CMainDlg::OnMove(CPoint pt) +{ + if (m_window_move_required) + { + // We don't want to recurse. + m_window_move_required = false; + PositionWindow(); + } + else + { + SetMsgHandled(false); + } +} \ No newline at end of file diff --git a/win32/FireflyShell/MainDlg.h b/win32/FireflyShell/MainDlg.h index 14f28923..cdb211e9 100644 --- a/win32/FireflyShell/MainDlg.h +++ b/win32/FireflyShell/MainDlg.h @@ -32,16 +32,23 @@ class CMainDlg : public CPropertySheetImpl CAdvancedPage m_pageAdvanced; CLogPage m_pageLog; CAboutPage m_pageAbout; + bool m_window_move_required; BEGIN_MSG_MAP(CMainDlg) MESSAGE_HANDLER(WM_COMMAND, OnCommand) + MSG_WM_MOVE(OnMove) CHAIN_MSG_MAP(base) END_MSG_MAP() LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + void OnMove(CPoint); + void PositionWindow(); public: - CMainDlg(); + // Pass true if you want the window to be moved to near the mouse pointer. + // This is usually only the case if the window is displayed as a result of + // clicking on the shell notification icon. + CMainDlg(bool move_window); }; #endif // MAINDLG_H \ No newline at end of file diff --git a/win32/FireflyShell/NotifyIcon.cpp b/win32/FireflyShell/NotifyIcon.cpp index 3aea1b5a..d71432db 100644 --- a/win32/FireflyShell/NotifyIcon.cpp +++ b/win32/FireflyShell/NotifyIcon.cpp @@ -139,7 +139,7 @@ LRESULT CNotifyIcon::OnNotifyIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam switch (lParam) { case WM_LBUTTONDBLCLK: - GetApplication()->Configure(); + GetApplication()->Configure(true); bHandled = true; return 0L; case WM_RBUTTONDOWN: @@ -175,7 +175,7 @@ void CNotifyIcon::OnContextMenu() LRESULT CNotifyIcon::OnConfigure(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { - GetApplication()->Configure(); + GetApplication()->Configure(true); return 0; } @@ -190,7 +190,7 @@ LRESULT CNotifyIcon::OnRegisteredActivation(UINT, WPARAM, LPARAM, BOOL &bHandled { ATLTRACE(_T("Activate\n")); bHandled = true; - GetApplication()->Configure(); + GetApplication()->Configure(false); // We return a magic number so that the caller knows we've been found // and can give up.