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)
132 LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
133 if ((style & WS_CHILD) == 0)
135 if (io_isMDI && *io_isMDI)
137 LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);
138 if (exStyle & WS_EX_MDICHILD)
141 i_hwnd = GetParent(i_hwnd);
149 // move window asynchronously
150 void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y)
152 SetWindowPos(i_hwnd, NULL, i_x, i_y, 0, 0,
153 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
154 SWP_NOSIZE | SWP_NOZORDER);
158 // move window asynchronously
159 void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y, int i_w, int i_h)
161 SetWindowPos(i_hwnd, NULL, i_x, i_y, i_w, i_h,
162 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
167 // resize asynchronously
168 void asyncResize(HWND i_hwnd, int i_w, int i_h)
170 SetWindowPos(i_hwnd, NULL, 0, 0, i_w, i_h,
171 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
172 SWP_NOMOVE | SWP_NOZORDER);
177 DWORD getDllVersion(const _TCHAR *i_dllname)
181 if (HINSTANCE hinstDll = LoadLibrary(i_dllname))
183 DLLGETVERSIONPROC pDllGetVersion
184 = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");
185 /* Because some DLLs may not implement this function, you
186 * must test for it explicitly. Depending on the particular
187 * DLL, the lack of a DllGetVersion function may
188 * be a useful indicator of the version.
193 ZeroMemory(&dvi, sizeof(dvi));
194 dvi.cbSize = sizeof(dvi);
196 HRESULT hr = (*pDllGetVersion)(&dvi);
198 dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
201 FreeLibrary(hinstDll);
207 // workaround of SetForegroundWindow
208 bool setForegroundWindow(HWND i_hwnd)
210 int nForegroundID = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
211 int nTargetID = GetWindowThreadProcessId(i_hwnd, NULL);
213 //if (!AttachThreadInput(nTargetID, nForegroundID, TRUE))
215 AttachThreadInput(nTargetID, nForegroundID, TRUE);
218 SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &sp_time, 0);
219 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (void *)0, 0);
221 SetForegroundWindow(i_hwnd);
223 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (void *)sp_time, 0);
225 AttachThreadInput(nTargetID, nForegroundID, FALSE);
231 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
235 // get edit control's text size
236 // @return bytes of text
237 size_t editGetTextBytes(HWND i_hwnd)
239 return Edit_GetTextLength(i_hwnd);
244 void editDeleteLine(HWND i_hwnd, size_t i_n)
246 int len = Edit_LineLength(i_hwnd, i_n);
250 int index = Edit_LineIndex(i_hwnd, i_n);
251 Edit_SetSel(i_hwnd, index, index + len);
252 Edit_ReplaceSel(i_hwnd, _T(""));
256 // insert text at last
257 void editInsertTextAtLast(HWND i_hwnd, const tstring &i_text,
263 size_t len = editGetTextBytes(i_hwnd);
265 if (i_threshold < len)
267 Edit_SetSel(i_hwnd, 0, len / 3 * 2);
268 Edit_ReplaceSel(i_hwnd, _T(""));
269 editDeleteLine(i_hwnd, 0);
270 len = editGetTextBytes(i_hwnd);
273 Edit_SetSel(i_hwnd, len, len);
276 Array<_TCHAR> buf(i_text.size() * 2 + 1);
277 _TCHAR *d = buf.get();
278 const _TCHAR *str = i_text.c_str();
279 for (const _TCHAR *s = str; s < str + i_text.size(); ++ s)
287 Edit_ReplaceSel(i_hwnd, buf.get());
291 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
292 // Windows2000/XP specific API
295 // initialize layerd window
296 static BOOL WINAPI initalizeLayerdWindow(
297 HWND i_hwnd, COLORREF i_crKey, BYTE i_bAlpha, DWORD i_dwFlags)
299 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
303 SetLayeredWindowAttributes_t proc =
304 reinterpret_cast<SetLayeredWindowAttributes_t>(
305 GetProcAddress(hModule, "SetLayeredWindowAttributes"));
306 if (setLayeredWindowAttributes) {
307 setLayeredWindowAttributes = proc;
308 return setLayeredWindowAttributes(i_hwnd, i_crKey, i_bAlpha, i_dwFlags);
315 // SetLayeredWindowAttributes API
316 SetLayeredWindowAttributes_t setLayeredWindowAttributes
317 = initalizeLayerdWindow;
320 // emulate MonitorFromWindow API
321 static HMONITOR WINAPI emulateMonitorFromWindow(HWND hwnd, DWORD dwFlags)
323 return reinterpret_cast<HMONITOR>(1); // dummy HMONITOR
326 // initialize MonitorFromWindow API
327 static HMONITOR WINAPI initializeMonitorFromWindow(HWND hwnd, DWORD dwFlags)
329 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
333 FARPROC proc = GetProcAddress(hModule, "MonitorFromWindow");
336 reinterpret_cast<HMONITOR (WINAPI *)(HWND, DWORD)>(proc);
338 monitorFromWindow = emulateMonitorFromWindow;
340 return monitorFromWindow(hwnd, dwFlags);
343 // MonitorFromWindow API
344 HMONITOR (WINAPI *monitorFromWindow)(HWND hwnd, DWORD dwFlags)
345 = initializeMonitorFromWindow;
348 // emulate GetMonitorInfo API
349 static BOOL WINAPI emulateGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)
351 if(lpmi->cbSize != sizeof(MONITORINFO))
354 lpmi->rcMonitor.left = 0;
355 lpmi->rcMonitor.top = 0;
356 lpmi->rcMonitor.right = GetSystemMetrics(SM_CXFULLSCREEN);
357 lpmi->rcMonitor.bottom = GetSystemMetrics(SM_CYFULLSCREEN);
358 SystemParametersInfo(SPI_GETWORKAREA, 0,
359 reinterpret_cast<PVOID>(&lpmi->rcWork), FALSE);
360 lpmi->dwFlags = MONITORINFOF_PRIMARY;
365 // initialize GetMonitorInfo API
367 BOOL WINAPI initializeGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)
369 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
373 FARPROC proc = GetProcAddress(hModule, "GetMonitorInfoA");
376 reinterpret_cast<BOOL (WINAPI *)(HMONITOR, LPMONITORINFO)>(proc);
378 getMonitorInfo = emulateGetMonitorInfo;
380 return getMonitorInfo(hMonitor, lpmi);
383 // GetMonitorInfo API
384 BOOL (WINAPI *getMonitorInfo)(HMONITOR hMonitor, LPMONITORINFO lpmi)
385 = initializeGetMonitorInfo;
388 // enumalte EnumDisplayMonitors API
389 static BOOL WINAPI emulateEnumDisplayMonitors(
390 HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
392 lpfnEnum(reinterpret_cast<HMONITOR>(1), hdc, lprcClip, dwData);
396 // initialize EnumDisplayMonitors API
397 static BOOL WINAPI initializeEnumDisplayMonitors(
398 HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
400 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
404 FARPROC proc = GetProcAddress(hModule, "EnumDisplayMonitors");
406 enumDisplayMonitors =
407 reinterpret_cast<BOOL (WINAPI *)(HDC, LPRECT, MONITORENUMPROC, LPARAM)>
410 enumDisplayMonitors = emulateEnumDisplayMonitors;
412 return enumDisplayMonitors(hdc, lprcClip, lpfnEnum, dwData);
415 // EnumDisplayMonitors API
416 BOOL (WINAPI *enumDisplayMonitors)
417 (HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
418 = initializeEnumDisplayMonitors;
421 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
422 // Windows2000/XP specific API
426 initializeWTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags)
428 LoadLibrary(_T("wtsapi32.dll"));
429 HMODULE hModule = GetModuleHandle(_T("wtsapi32.dll"));
433 WTSRegisterSessionNotification_t proc =
434 reinterpret_cast<WTSRegisterSessionNotification_t>(
435 GetProcAddress(hModule, "WTSRegisterSessionNotification"));
437 wtsRegisterSessionNotification = proc;
438 return wtsRegisterSessionNotification(hWnd, dwFlags);
444 // WTSRegisterSessionNotification API
445 WTSRegisterSessionNotification_t wtsRegisterSessionNotification
446 = initializeWTSRegisterSessionNotification;
449 static BOOL WINAPI initializeWTSUnRegisterSessionNotification(HWND hWnd)
451 HMODULE hModule = GetModuleHandle(_T("wtsapi32.dll"));
455 WTSUnRegisterSessionNotification_t proc =
456 reinterpret_cast<WTSUnRegisterSessionNotification_t>(
457 GetProcAddress(hModule, "WTSUnRegisterSessionNotification"));
459 wtsUnRegisterSessionNotification = proc;
460 return wtsUnRegisterSessionNotification(hWnd);
466 // WTSUnRegisterSessionNotification API
467 WTSUnRegisterSessionNotification_t wtsUnRegisterSessionNotification
468 = initializeWTSUnRegisterSessionNotification;
471 static DWORD WINAPI initializeWTSGetActiveConsoleSessionId(void)
473 HMODULE hModule = GetModuleHandle(_T("kernel32.dll"));
477 WTSGetActiveConsoleSessionId_t proc =
478 reinterpret_cast<WTSGetActiveConsoleSessionId_t>(
479 GetProcAddress(hModule, "WTSGetActiveConsoleSessionId"));
481 wtsGetActiveConsoleSessionId = proc;
482 return wtsGetActiveConsoleSessionId();
488 // WTSGetActiveConsoleSessionId API
489 WTSGetActiveConsoleSessionId_t wtsGetActiveConsoleSessionId
490 = initializeWTSGetActiveConsoleSessionId;
493 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
496 // PathRemoveFileSpec()
497 tstring pathRemoveFileSpec(const tstring &i_path)
499 const _TCHAR *str = i_path.c_str();
500 const _TCHAR *b = _tcsrchr(str, _T('\\'));
501 const _TCHAR *s = _tcsrchr(str, _T('/'));
503 return tstring(str, MIN(b, s));
505 return tstring(str, b);
507 return tstring(str, s);
508 if (const _TCHAR *c = _tcsrchr(str, _T(':')))
509 return tstring(str, c + 1);