1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 #include "windowstool.h"
15 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19 // instance handle of this application
20 HINSTANCE g_hInst = NULL;
23 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 // load resource string
28 tstring loadString(UINT i_id)
31 if (LoadString(g_hInst, i_id, buf, NUMBER_OF(buf)))
38 // load small icon resource
39 HICON loadSmallIcon(UINT i_id)
41 return reinterpret_cast<HICON>(
42 LoadImage(g_hInst, MAKEINTRESOURCE(i_id), IMAGE_ICON, 16, 16, 0));
46 // load big icon resource
47 HICON loadBigIcon(UINT i_id)
49 return reinterpret_cast<HICON>(
50 LoadImage(g_hInst, MAKEINTRESOURCE(i_id), IMAGE_ICON, 32, 32, 0));
54 // set small icon to the specified window.
55 // @return handle of previous icon or NULL
56 HICON setSmallIcon(HWND i_hwnd, UINT i_id)
58 HICON hicon = (i_id == static_cast<UINT>(-1)) ? NULL : loadSmallIcon(i_id);
59 return reinterpret_cast<HICON>(
60 SendMessage(i_hwnd, WM_SETICON, static_cast<WPARAM>(ICON_SMALL),
61 reinterpret_cast<LPARAM>(hicon)));
65 // set big icon to the specified window.
66 // @return handle of previous icon or NULL
67 HICON setBigIcon(HWND i_hwnd, UINT i_id)
69 HICON hicon = (i_id == static_cast<UINT>(-1)) ? NULL : loadBigIcon(i_id);
70 return reinterpret_cast<HICON>(
71 SendMessage(i_hwnd, WM_SETICON, static_cast<WPARAM>(ICON_BIG),
72 reinterpret_cast<LPARAM>(hicon)));
76 // remove icon from a window that is set by setSmallIcon
77 void unsetSmallIcon(HWND i_hwnd)
79 HICON hicon = setSmallIcon(i_hwnd, -1);
81 CHECK_TRUE( DestroyIcon(hicon) );
85 // remove icon from a window that is set by setBigIcon
86 void unsetBigIcon(HWND i_hwnd)
88 HICON hicon = setBigIcon(i_hwnd, -1);
90 CHECK_TRUE( DestroyIcon(hicon) );
94 // resize the window (it does not move the window)
95 bool resizeWindow(HWND i_hwnd, int i_w, int i_h, bool i_doRepaint)
97 UINT flag = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
100 return !!SetWindowPos(i_hwnd, NULL, 0, 0, i_w, i_h, flag);
104 // get rect of the window in client coordinates
105 // @return rect of the window in client coordinates
106 bool getChildWindowRect(HWND i_hwnd, RECT *o_rc)
108 if (!GetWindowRect(i_hwnd, o_rc))
110 POINT p = { o_rc->left, o_rc->top };
111 HWND phwnd = GetParent(i_hwnd);
114 if (!ScreenToClient(phwnd, &p))
120 ScreenToClient(phwnd, &p);
127 // get toplevel (non-child) window
128 HWND getToplevelWindow(HWND i_hwnd, bool *io_isMDI)
133 LONG_PTR style = GetWindowLongPtr(i_hwnd, GWL_STYLE);
135 LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
137 if ((style & WS_CHILD) == 0)
139 if (io_isMDI && *io_isMDI)
142 LONG_PTR exStyle = GetWindowLongPtr(i_hwnd, GWL_EXSTYLE);
144 LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);
146 if (exStyle & WS_EX_MDICHILD)
149 i_hwnd = GetParent(i_hwnd);
157 // move window asynchronously
158 void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y)
160 SetWindowPos(i_hwnd, NULL, i_x, i_y, 0, 0,
161 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
162 SWP_NOSIZE | SWP_NOZORDER);
166 // move window asynchronously
167 void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y, int i_w, int i_h)
169 SetWindowPos(i_hwnd, NULL, i_x, i_y, i_w, i_h,
170 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
175 // resize asynchronously
176 void asyncResize(HWND i_hwnd, int i_w, int i_h)
178 SetWindowPos(i_hwnd, NULL, 0, 0, i_w, i_h,
179 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
180 SWP_NOMOVE | SWP_NOZORDER);
185 DWORD getDllVersion(const _TCHAR *i_dllname)
189 if (HINSTANCE hinstDll = LoadLibrary(i_dllname))
191 DLLGETVERSIONPROC pDllGetVersion
192 = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");
193 /* Because some DLLs may not implement this function, you
194 * must test for it explicitly. Depending on the particular
195 * DLL, the lack of a DllGetVersion function may
196 * be a useful indicator of the version.
201 ZeroMemory(&dvi, sizeof(dvi));
202 dvi.cbSize = sizeof(dvi);
204 HRESULT hr = (*pDllGetVersion)(&dvi);
206 dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
209 FreeLibrary(hinstDll);
215 // workaround of SetForegroundWindow
216 bool setForegroundWindow(HWND i_hwnd)
218 int nForegroundID = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
219 int nTargetID = GetWindowThreadProcessId(i_hwnd, NULL);
221 //if (!AttachThreadInput(nTargetID, nForegroundID, TRUE))
223 AttachThreadInput(nTargetID, nForegroundID, TRUE);
226 SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &sp_time, 0);
227 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (void *)0, 0);
229 SetForegroundWindow(i_hwnd);
231 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (void *)sp_time, 0);
233 AttachThreadInput(nTargetID, nForegroundID, FALSE);
239 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
243 // get edit control's text size
244 // @return bytes of text
245 size_t editGetTextBytes(HWND i_hwnd)
247 return Edit_GetTextLength(i_hwnd);
252 void editDeleteLine(HWND i_hwnd, size_t i_n)
254 int len = Edit_LineLength(i_hwnd, i_n);
258 int index = Edit_LineIndex(i_hwnd, i_n);
259 Edit_SetSel(i_hwnd, index, index + len);
260 Edit_ReplaceSel(i_hwnd, _T(""));
264 // insert text at last
265 void editInsertTextAtLast(HWND i_hwnd, const tstring &i_text,
271 size_t len = editGetTextBytes(i_hwnd);
273 if (i_threshold < len)
275 Edit_SetSel(i_hwnd, 0, len / 3 * 2);
276 Edit_ReplaceSel(i_hwnd, _T(""));
277 editDeleteLine(i_hwnd, 0);
278 len = editGetTextBytes(i_hwnd);
281 Edit_SetSel(i_hwnd, len, len);
284 Array<_TCHAR> buf(i_text.size() * 2 + 1);
285 _TCHAR *d = buf.get();
286 const _TCHAR *str = i_text.c_str();
287 for (const _TCHAR *s = str; s < str + i_text.size(); ++ s)
295 Edit_ReplaceSel(i_hwnd, buf.get());
299 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
300 // Windows2000/XP specific API
303 // initialize layerd window
304 static BOOL WINAPI initalizeLayerdWindow(
305 HWND i_hwnd, COLORREF i_crKey, BYTE i_bAlpha, DWORD i_dwFlags)
307 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
311 SetLayeredWindowAttributes_t proc =
312 reinterpret_cast<SetLayeredWindowAttributes_t>(
313 GetProcAddress(hModule, "SetLayeredWindowAttributes"));
314 if (setLayeredWindowAttributes) {
315 setLayeredWindowAttributes = proc;
316 return setLayeredWindowAttributes(i_hwnd, i_crKey, i_bAlpha, i_dwFlags);
323 // SetLayeredWindowAttributes API
324 SetLayeredWindowAttributes_t setLayeredWindowAttributes
325 = initalizeLayerdWindow;
328 // emulate MonitorFromWindow API
329 static HMONITOR WINAPI emulateMonitorFromWindow(HWND hwnd, DWORD dwFlags)
331 return reinterpret_cast<HMONITOR>(1); // dummy HMONITOR
334 // initialize MonitorFromWindow API
335 static HMONITOR WINAPI initializeMonitorFromWindow(HWND hwnd, DWORD dwFlags)
337 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
341 FARPROC proc = GetProcAddress(hModule, "MonitorFromWindow");
344 reinterpret_cast<HMONITOR (WINAPI *)(HWND, DWORD)>(proc);
346 monitorFromWindow = emulateMonitorFromWindow;
348 return monitorFromWindow(hwnd, dwFlags);
351 // MonitorFromWindow API
352 HMONITOR (WINAPI *monitorFromWindow)(HWND hwnd, DWORD dwFlags)
353 = initializeMonitorFromWindow;
356 // emulate GetMonitorInfo API
357 static BOOL WINAPI emulateGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)
359 if(lpmi->cbSize != sizeof(MONITORINFO))
362 lpmi->rcMonitor.left = 0;
363 lpmi->rcMonitor.top = 0;
364 lpmi->rcMonitor.right = GetSystemMetrics(SM_CXFULLSCREEN);
365 lpmi->rcMonitor.bottom = GetSystemMetrics(SM_CYFULLSCREEN);
366 SystemParametersInfo(SPI_GETWORKAREA, 0,
367 reinterpret_cast<PVOID>(&lpmi->rcWork), FALSE);
368 lpmi->dwFlags = MONITORINFOF_PRIMARY;
373 // initialize GetMonitorInfo API
375 BOOL WINAPI initializeGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)
377 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
381 FARPROC proc = GetProcAddress(hModule, "GetMonitorInfoA");
384 reinterpret_cast<BOOL (WINAPI *)(HMONITOR, LPMONITORINFO)>(proc);
386 getMonitorInfo = emulateGetMonitorInfo;
388 return getMonitorInfo(hMonitor, lpmi);
391 // GetMonitorInfo API
392 BOOL (WINAPI *getMonitorInfo)(HMONITOR hMonitor, LPMONITORINFO lpmi)
393 = initializeGetMonitorInfo;
396 // enumalte EnumDisplayMonitors API
397 static BOOL WINAPI emulateEnumDisplayMonitors(
398 HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
400 lpfnEnum(reinterpret_cast<HMONITOR>(1), hdc, lprcClip, dwData);
404 // initialize EnumDisplayMonitors API
405 static BOOL WINAPI initializeEnumDisplayMonitors(
406 HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
408 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
412 FARPROC proc = GetProcAddress(hModule, "EnumDisplayMonitors");
414 enumDisplayMonitors =
415 reinterpret_cast<BOOL (WINAPI *)(HDC, LPRECT, MONITORENUMPROC, LPARAM)>
418 enumDisplayMonitors = emulateEnumDisplayMonitors;
420 return enumDisplayMonitors(hdc, lprcClip, lpfnEnum, dwData);
423 // EnumDisplayMonitors API
424 BOOL (WINAPI *enumDisplayMonitors)
425 (HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
426 = initializeEnumDisplayMonitors;
429 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
430 // Windows2000/XP specific API
434 initializeWTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags)
436 LoadLibrary(_T("wtsapi32.dll"));
437 HMODULE hModule = GetModuleHandle(_T("wtsapi32.dll"));
441 WTSRegisterSessionNotification_t proc =
442 reinterpret_cast<WTSRegisterSessionNotification_t>(
443 GetProcAddress(hModule, "WTSRegisterSessionNotification"));
445 wtsRegisterSessionNotification = proc;
446 return wtsRegisterSessionNotification(hWnd, dwFlags);
452 // WTSRegisterSessionNotification API
453 WTSRegisterSessionNotification_t wtsRegisterSessionNotification
454 = initializeWTSRegisterSessionNotification;
457 static BOOL WINAPI initializeWTSUnRegisterSessionNotification(HWND hWnd)
459 HMODULE hModule = GetModuleHandle(_T("wtsapi32.dll"));
463 WTSUnRegisterSessionNotification_t proc =
464 reinterpret_cast<WTSUnRegisterSessionNotification_t>(
465 GetProcAddress(hModule, "WTSUnRegisterSessionNotification"));
467 wtsUnRegisterSessionNotification = proc;
468 return wtsUnRegisterSessionNotification(hWnd);
474 // WTSUnRegisterSessionNotification API
475 WTSUnRegisterSessionNotification_t wtsUnRegisterSessionNotification
476 = initializeWTSUnRegisterSessionNotification;
479 static DWORD WINAPI initializeWTSGetActiveConsoleSessionId(void)
481 HMODULE hModule = GetModuleHandle(_T("kernel32.dll"));
485 WTSGetActiveConsoleSessionId_t proc =
486 reinterpret_cast<WTSGetActiveConsoleSessionId_t>(
487 GetProcAddress(hModule, "WTSGetActiveConsoleSessionId"));
489 wtsGetActiveConsoleSessionId = proc;
490 return wtsGetActiveConsoleSessionId();
496 // WTSGetActiveConsoleSessionId API
497 WTSGetActiveConsoleSessionId_t wtsGetActiveConsoleSessionId
498 = initializeWTSGetActiveConsoleSessionId;
501 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
504 // PathRemoveFileSpec()
505 tstring pathRemoveFileSpec(const tstring &i_path)
507 const _TCHAR *str = i_path.c_str();
508 const _TCHAR *b = _tcsrchr(str, _T('\\'));
509 const _TCHAR *s = _tcsrchr(str, _T('/'));
511 return tstring(str, MIN(b, s));
513 return tstring(str, b);
515 return tstring(str, s);
516 if (const _TCHAR *c = _tcsrchr(str, _T(':')))
517 return tstring(str, c + 1);