1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
7 #include "windowstool.h"
\r
10 #include <windowsx.h>
\r
12 #include <shlwapi.h>
\r
15 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
19 // instance handle of this application
\r
20 HINSTANCE g_hInst = NULL;
\r
23 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
27 // load resource string
\r
28 tstring loadString(UINT i_id)
\r
31 if (LoadString(g_hInst, i_id, buf, NUMBER_OF(buf)))
\r
32 return tstring(buf);
\r
38 // load small icon resource
\r
39 HICON loadSmallIcon(UINT i_id)
\r
41 return reinterpret_cast<HICON>(
\r
42 LoadImage(g_hInst, MAKEINTRESOURCE(i_id), IMAGE_ICON, 16, 16, 0));
\r
46 // load big icon resource
\r
47 HICON loadBigIcon(UINT i_id)
\r
49 return reinterpret_cast<HICON>(
\r
50 LoadImage(g_hInst, MAKEINTRESOURCE(i_id), IMAGE_ICON, 32, 32, 0));
\r
54 // set small icon to the specified window.
\r
55 // @return handle of previous icon or NULL
\r
56 HICON setSmallIcon(HWND i_hwnd, UINT i_id)
\r
58 HICON hicon = (i_id == static_cast<UINT>(-1)) ? NULL : loadSmallIcon(i_id);
\r
59 return reinterpret_cast<HICON>(
\r
60 SendMessage(i_hwnd, WM_SETICON, static_cast<WPARAM>(ICON_SMALL),
\r
61 reinterpret_cast<LPARAM>(hicon)));
\r
65 // set big icon to the specified window.
\r
66 // @return handle of previous icon or NULL
\r
67 HICON setBigIcon(HWND i_hwnd, UINT i_id)
\r
69 HICON hicon = (i_id == static_cast<UINT>(-1)) ? NULL : loadBigIcon(i_id);
\r
70 return reinterpret_cast<HICON>(
\r
71 SendMessage(i_hwnd, WM_SETICON, static_cast<WPARAM>(ICON_BIG),
\r
72 reinterpret_cast<LPARAM>(hicon)));
\r
76 // remove icon from a window that is set by setSmallIcon
\r
77 void unsetSmallIcon(HWND i_hwnd)
\r
79 HICON hicon = setSmallIcon(i_hwnd, -1);
\r
81 CHECK_TRUE( DestroyIcon(hicon) );
\r
85 // remove icon from a window that is set by setBigIcon
\r
86 void unsetBigIcon(HWND i_hwnd)
\r
88 HICON hicon = setBigIcon(i_hwnd, -1);
\r
90 CHECK_TRUE( DestroyIcon(hicon) );
\r
94 // resize the window (it does not move the window)
\r
95 bool resizeWindow(HWND i_hwnd, int i_w, int i_h, bool i_doRepaint)
\r
97 UINT flag = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
\r
99 flag |= SWP_NOREDRAW;
\r
100 return !!SetWindowPos(i_hwnd, NULL, 0, 0, i_w, i_h, flag);
\r
104 // get rect of the window in client coordinates
\r
105 // @return rect of the window in client coordinates
\r
106 bool getChildWindowRect(HWND i_hwnd, RECT *o_rc)
\r
108 if (!GetWindowRect(i_hwnd, o_rc))
\r
110 POINT p = { o_rc->left, o_rc->top };
\r
111 HWND phwnd = GetParent(i_hwnd);
\r
114 if (!ScreenToClient(phwnd, &p))
\r
119 p.y = o_rc->bottom;
\r
120 ScreenToClient(phwnd, &p);
\r
122 o_rc->bottom = p.y;
\r
127 // get toplevel (non-child) window
\r
128 HWND getToplevelWindow(HWND i_hwnd, bool *io_isMDI)
\r
132 LONG_PTR style = GetWindowLongPtr(i_hwnd, GWL_STYLE);
\r
134 LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
\r
136 if ((style & WS_CHILD) == 0)
\r
138 if (io_isMDI && *io_isMDI) {
\r
140 LONG_PTR exStyle = GetWindowLongPtr(i_hwnd, GWL_EXSTYLE);
\r
142 LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);
\r
144 if (exStyle & WS_EX_MDICHILD)
\r
147 i_hwnd = GetParent(i_hwnd);
\r
155 // move window asynchronously
\r
156 void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y)
\r
158 SetWindowPos(i_hwnd, NULL, i_x, i_y, 0, 0,
\r
159 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
\r
160 SWP_NOSIZE | SWP_NOZORDER);
\r
164 // move window asynchronously
\r
165 void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y, int i_w, int i_h)
\r
167 SetWindowPos(i_hwnd, NULL, i_x, i_y, i_w, i_h,
\r
168 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
\r
173 // resize asynchronously
\r
174 void asyncResize(HWND i_hwnd, int i_w, int i_h)
\r
176 SetWindowPos(i_hwnd, NULL, 0, 0, i_w, i_h,
\r
177 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
\r
178 SWP_NOMOVE | SWP_NOZORDER);
\r
183 DWORD getDllVersion(const _TCHAR *i_dllname)
\r
185 DWORD dwVersion = 0;
\r
187 if (HINSTANCE hinstDll = LoadLibrary(i_dllname)) {
\r
188 DLLGETVERSIONPROC pDllGetVersion
\r
189 = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");
\r
190 /* Because some DLLs may not implement this function, you
\r
191 * must test for it explicitly. Depending on the particular
\r
192 * DLL, the lack of a DllGetVersion function may
\r
193 * be a useful indicator of the version.
\r
195 if (pDllGetVersion) {
\r
196 DLLVERSIONINFO dvi;
\r
197 ZeroMemory(&dvi, sizeof(dvi));
\r
198 dvi.cbSize = sizeof(dvi);
\r
200 HRESULT hr = (*pDllGetVersion)(&dvi);
\r
202 dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
\r
205 FreeLibrary(hinstDll);
\r
211 // workaround of SetForegroundWindow
\r
212 bool setForegroundWindow(HWND i_hwnd)
\r
214 int nForegroundID = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
\r
215 int nTargetID = GetWindowThreadProcessId(i_hwnd, NULL);
\r
217 //if (!AttachThreadInput(nTargetID, nForegroundID, TRUE))
\r
219 AttachThreadInput(nTargetID, nForegroundID, TRUE);
\r
222 SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &sp_time, 0);
\r
223 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (void *)0, 0);
\r
225 SetForegroundWindow(i_hwnd);
\r
227 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (void *)sp_time, 0);
\r
229 AttachThreadInput(nTargetID, nForegroundID, FALSE);
\r
235 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
239 // get edit control's text size
\r
240 // @return bytes of text
\r
241 size_t editGetTextBytes(HWND i_hwnd)
\r
243 return Edit_GetTextLength(i_hwnd);
\r
248 void editDeleteLine(HWND i_hwnd, size_t i_n)
\r
250 int len = Edit_LineLength(i_hwnd, i_n);
\r
254 int index = Edit_LineIndex(i_hwnd, i_n);
\r
255 Edit_SetSel(i_hwnd, index, index + len);
\r
256 Edit_ReplaceSel(i_hwnd, _T(""));
\r
260 // insert text at last
\r
261 void editInsertTextAtLast(HWND i_hwnd, const tstring &i_text,
\r
262 size_t i_threshold)
\r
264 if (i_text.empty())
\r
267 size_t len = editGetTextBytes(i_hwnd);
\r
269 if (i_threshold < len) {
\r
270 Edit_SetSel(i_hwnd, 0, len / 3 * 2);
\r
271 Edit_ReplaceSel(i_hwnd, _T(""));
\r
272 editDeleteLine(i_hwnd, 0);
\r
273 len = editGetTextBytes(i_hwnd);
\r
276 Edit_SetSel(i_hwnd, len, len);
\r
279 Array<_TCHAR> buf(i_text.size() * 2 + 1);
\r
280 _TCHAR *d = buf.get();
\r
281 const _TCHAR *str = i_text.c_str();
\r
282 for (const _TCHAR *s = str; s < str + i_text.size(); ++ s) {
\r
283 if (*s == _T('\n'))
\r
289 Edit_ReplaceSel(i_hwnd, buf.get());
\r
293 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
294 // Windows2000/XP specific API
\r
297 // initialize layerd window
\r
298 static BOOL WINAPI initalizeLayerdWindow(
\r
299 HWND i_hwnd, COLORREF i_crKey, BYTE i_bAlpha, DWORD i_dwFlags)
\r
301 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
\r
305 SetLayeredWindowAttributes_t proc =
\r
306 reinterpret_cast<SetLayeredWindowAttributes_t>(
\r
307 GetProcAddress(hModule, "SetLayeredWindowAttributes"));
\r
308 if (setLayeredWindowAttributes) {
\r
309 setLayeredWindowAttributes = proc;
\r
310 return setLayeredWindowAttributes(i_hwnd, i_crKey, i_bAlpha, i_dwFlags);
\r
317 // SetLayeredWindowAttributes API
\r
318 SetLayeredWindowAttributes_t setLayeredWindowAttributes
\r
319 = initalizeLayerdWindow;
\r
322 // emulate MonitorFromWindow API
\r
323 static HMONITOR WINAPI emulateMonitorFromWindow(HWND hwnd, DWORD dwFlags)
\r
325 return reinterpret_cast<HMONITOR>(1); // dummy HMONITOR
\r
328 // initialize MonitorFromWindow API
\r
329 static HMONITOR WINAPI initializeMonitorFromWindow(HWND hwnd, DWORD dwFlags)
\r
331 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
\r
335 FARPROC proc = GetProcAddress(hModule, "MonitorFromWindow");
\r
337 monitorFromWindow =
\r
338 reinterpret_cast<HMONITOR (WINAPI *)(HWND, DWORD)>(proc);
\r
340 monitorFromWindow = emulateMonitorFromWindow;
\r
342 return monitorFromWindow(hwnd, dwFlags);
\r
345 // MonitorFromWindow API
\r
346 HMONITOR (WINAPI *monitorFromWindow)(HWND hwnd, DWORD dwFlags)
\r
347 = initializeMonitorFromWindow;
\r
350 // emulate GetMonitorInfo API
\r
351 static BOOL WINAPI emulateGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)
\r
353 if (lpmi->cbSize != sizeof(MONITORINFO))
\r
356 lpmi->rcMonitor.left = 0;
\r
357 lpmi->rcMonitor.top = 0;
\r
358 lpmi->rcMonitor.right = GetSystemMetrics(SM_CXFULLSCREEN);
\r
359 lpmi->rcMonitor.bottom = GetSystemMetrics(SM_CYFULLSCREEN);
\r
360 SystemParametersInfo(SPI_GETWORKAREA, 0,
\r
361 reinterpret_cast<PVOID>(&lpmi->rcWork), FALSE);
\r
362 lpmi->dwFlags = MONITORINFOF_PRIMARY;
\r
367 // initialize GetMonitorInfo API
\r
369 BOOL WINAPI initializeGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)
\r
371 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
\r
375 FARPROC proc = GetProcAddress(hModule, "GetMonitorInfoA");
\r
378 reinterpret_cast<BOOL (WINAPI *)(HMONITOR, LPMONITORINFO)>(proc);
\r
380 getMonitorInfo = emulateGetMonitorInfo;
\r
382 return getMonitorInfo(hMonitor, lpmi);
\r
385 // GetMonitorInfo API
\r
386 BOOL (WINAPI *getMonitorInfo)(HMONITOR hMonitor, LPMONITORINFO lpmi)
\r
387 = initializeGetMonitorInfo;
\r
390 // enumalte EnumDisplayMonitors API
\r
391 static BOOL WINAPI emulateEnumDisplayMonitors(
\r
392 HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
\r
394 lpfnEnum(reinterpret_cast<HMONITOR>(1), hdc, lprcClip, dwData);
\r
398 // initialize EnumDisplayMonitors API
\r
399 static BOOL WINAPI initializeEnumDisplayMonitors(
\r
400 HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
\r
402 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
\r
406 FARPROC proc = GetProcAddress(hModule, "EnumDisplayMonitors");
\r
408 enumDisplayMonitors =
\r
409 reinterpret_cast<BOOL (WINAPI *)(HDC, LPRECT, MONITORENUMPROC, LPARAM)>
\r
412 enumDisplayMonitors = emulateEnumDisplayMonitors;
\r
414 return enumDisplayMonitors(hdc, lprcClip, lpfnEnum, dwData);
\r
417 // EnumDisplayMonitors API
\r
418 BOOL (WINAPI *enumDisplayMonitors)
\r
419 (HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
\r
420 = initializeEnumDisplayMonitors;
\r
423 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
424 // Windows2000/XP specific API
\r
428 initializeWTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags)
\r
430 LoadLibrary(_T("wtsapi32.dll"));
\r
431 HMODULE hModule = GetModuleHandle(_T("wtsapi32.dll"));
\r
435 WTSRegisterSessionNotification_t proc =
\r
436 reinterpret_cast<WTSRegisterSessionNotification_t>(
\r
437 GetProcAddress(hModule, "WTSRegisterSessionNotification"));
\r
439 wtsRegisterSessionNotification = proc;
\r
440 return wtsRegisterSessionNotification(hWnd, dwFlags);
\r
446 // WTSRegisterSessionNotification API
\r
447 WTSRegisterSessionNotification_t wtsRegisterSessionNotification
\r
448 = initializeWTSRegisterSessionNotification;
\r
451 static BOOL WINAPI initializeWTSUnRegisterSessionNotification(HWND hWnd)
\r
453 HMODULE hModule = GetModuleHandle(_T("wtsapi32.dll"));
\r
457 WTSUnRegisterSessionNotification_t proc =
\r
458 reinterpret_cast<WTSUnRegisterSessionNotification_t>(
\r
459 GetProcAddress(hModule, "WTSUnRegisterSessionNotification"));
\r
461 wtsUnRegisterSessionNotification = proc;
\r
462 return wtsUnRegisterSessionNotification(hWnd);
\r
468 // WTSUnRegisterSessionNotification API
\r
469 WTSUnRegisterSessionNotification_t wtsUnRegisterSessionNotification
\r
470 = initializeWTSUnRegisterSessionNotification;
\r
473 static DWORD WINAPI initializeWTSGetActiveConsoleSessionId(void)
\r
475 HMODULE hModule = GetModuleHandle(_T("kernel32.dll"));
\r
479 WTSGetActiveConsoleSessionId_t proc =
\r
480 reinterpret_cast<WTSGetActiveConsoleSessionId_t>(
\r
481 GetProcAddress(hModule, "WTSGetActiveConsoleSessionId"));
\r
483 wtsGetActiveConsoleSessionId = proc;
\r
484 return wtsGetActiveConsoleSessionId();
\r
490 // WTSGetActiveConsoleSessionId API
\r
491 WTSGetActiveConsoleSessionId_t wtsGetActiveConsoleSessionId
\r
492 = initializeWTSGetActiveConsoleSessionId;
\r
495 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
498 // PathRemoveFileSpec()
\r
499 tstring pathRemoveFileSpec(const tstring &i_path)
\r
501 const _TCHAR *str = i_path.c_str();
\r
502 const _TCHAR *b = _tcsrchr(str, _T('\\'));
\r
503 const _TCHAR *s = _tcsrchr(str, _T('/'));
\r
505 return tstring(str, MIN(b, s));
\r
507 return tstring(str, b);
\r
509 return tstring(str, s);
\r
510 if (const _TCHAR *c = _tcsrchr(str, _T(':')))
\r
511 return tstring(str, c + 1);
\r
515 BOOL checkWindowsVersion(DWORD i_major, DWORD i_minor)
\r
517 DWORDLONG conditionMask = 0;
\r
518 OSVERSIONINFOEX osvi;
\r
519 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
\r
521 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
\r
522 osvi.dwMajorVersion = i_major;
\r
523 osvi.dwMinorVersion = i_minor;
\r
525 VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
\r
526 VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
\r
528 // Perform the test.
\r
529 return VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, conditionMask);
\r