A simple, small calculator placed discreetly near the Windows Taskbar or anywhere on the screen
0

Configure Feed

Select the types of activity you want to include in your feed.

feat: persist window position, anchor above tray on first run, survive Explorer restart

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Marco Maroni (Jul 14, 2026, 3:23 PM +0200) 81d7bc17 1fa8e05f

+37 -2
+4 -2
App.cpp
··· 83 83 wc.lpszClassName = L"TaskbarCalculatorOwner"; 84 84 RegisterClassW(&wc); 85 85 86 - HWND owner = CreateWindowW(wc.lpszClassName, L"", 0, 0, 0, 0, 0, 87 - HWND_MESSAGE, nullptr, hInst, nullptr); 86 + // Hidden top-level tool window (no taskbar button) so it still receives 87 + // the broadcast "TaskbarCreated" message when Explorer restarts. 88 + HWND owner = CreateWindowExW(WS_EX_TOOLWINDOW, wc.lpszClassName, L"", 89 + WS_POPUP, 0, 0, 0, 0, nullptr, nullptr, hInst, nullptr); 88 90 89 91 g_tray.Add(owner, WM_TRAY_CALLBACK, TRAY_ICON_ID, L"Taskbar Calculator"); 90 92
+30
CalculatorWindow.cpp
··· 4 4 #include "VisualStyle.h" 5 5 #include "Utils.h" 6 6 #include "Calculator.h" 7 + #include "Settings.h" 7 8 8 9 //////////////////////////////////////////////////////////////////////////////// 9 10 // ··· 146 147 147 148 POINTL ideal = CalcIdealSize(); 148 149 SetWindowPos(NULL, 0, 0, ideal.x + 24, ideal.y + 16, SWP_NOMOVE | SWP_NOZORDER); 150 + PlaceInitial(); 149 151 return TRUE; 152 + } 153 + 154 + void CCalculatorWindow::PlaceInitial() 155 + { 156 + RECT wr; GetWindowRect(&wr); 157 + int w = wr.right - wr.left, h = wr.bottom - wr.top; 158 + 159 + POINT pt; 160 + if (Settings::LoadWindowPos(pt)) { 161 + SetWindowPos(NULL, pt.x, pt.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); 162 + return; 163 + } 164 + // First run: anchor bottom-right, just above the notification area. 165 + APPBARDATA abd{}; abd.cbSize = sizeof(abd); 166 + RECT work; SystemParametersInfo(SPI_GETWORKAREA, 0, &work, 0); 167 + int x = work.right - w - 8; 168 + int y = work.bottom - h - 8; 169 + if (SHAppBarMessage(ABM_GETTASKBARPOS, &abd)) { 170 + if (abd.rc.top > work.top) y = abd.rc.top - h - 8; 171 + } 172 + SetWindowPos(NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); 150 173 } 151 174 152 175 void CCalculatorWindow::ToggleVisible() ··· 324 347 // Allow dragging the window by its body. 325 348 ReleaseCapture(); 326 349 SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, 0); 350 + return 0; 351 + } 352 + 353 + LRESULT CCalculatorWindow::OnExitSizeMove(UINT, WPARAM, LPARAM, BOOL&) 354 + { 355 + RECT wr; GetWindowRect(&wr); 356 + Settings::SaveWindowPos(POINT{ wr.left, wr.top }); 327 357 return 0; 328 358 } 329 359
+3
CalculatorWindow.h
··· 16 16 BOOL CreateStandalone(); 17 17 void ToggleVisible(); 18 18 bool IsShown() const { return m_shown; } 19 + void PlaceInitial(); 19 20 20 21 POINTL CalcMinimalSize() const; 21 22 POINTL CalcIdealSize() const; ··· 40 41 MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged) 41 42 MESSAGE_HANDLER(WM_CLOSE, OnClose) 42 43 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) 44 + MESSAGE_HANDLER(WM_EXITSIZEMOVE, OnExitSizeMove) 43 45 END_MSG_MAP() 44 46 45 47 // Handler prototypes: ··· 56 58 LRESULT OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); 57 59 LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); 58 60 LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); 61 + LRESULT OnExitSizeMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); 59 62 60 63 void Paint(HDC hdc, const RECT& rcPaint) const; 61 64 // UINT_PTR SetUpdateTimer();