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
133 LONG_PTR style = GetWindowLongPtr(i_hwnd, GWL_STYLE);
\r
135 LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
\r
137 if ((style & WS_CHILD) == 0)
\r
139 if (io_isMDI && *io_isMDI)
\r
142 LONG_PTR exStyle = GetWindowLongPtr(i_hwnd, GWL_EXSTYLE);
\r
144 LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);
\r
146 if (exStyle & WS_EX_MDICHILD)
\r
149 i_hwnd = GetParent(i_hwnd);
\r
157 // move window asynchronously
\r
158 void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y)
\r
160 SetWindowPos(i_hwnd, NULL, i_x, i_y, 0, 0,
\r
161 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
\r
162 SWP_NOSIZE | SWP_NOZORDER);
\r
166 // move window asynchronously
\r
167 void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y, int i_w, int i_h)
\r
169 SetWindowPos(i_hwnd, NULL, i_x, i_y, i_w, i_h,
\r
170 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
\r
175 // resize asynchronously
\r
176 void asyncResize(HWND i_hwnd, int i_w, int i_h)
\r
178 SetWindowPos(i_hwnd, NULL, 0, 0, i_w, i_h,
\r
179 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
\r
180 SWP_NOMOVE | SWP_NOZORDER);
\r
185 DWORD getDllVersion(const _TCHAR *i_dllname)
\r
187 DWORD dwVersion = 0;
\r
189 if (HINSTANCE hinstDll = LoadLibrary(i_dllname))
\r
191 DLLGETVERSIONPROC pDllGetVersion
\r
192 = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");
\r
193 /* Because some DLLs may not implement this function, you
\r
194 * must test for it explicitly. Depending on the particular
\r
195 * DLL, the lack of a DllGetVersion function may
\r
196 * be a useful indicator of the version.
\r
198 if (pDllGetVersion)
\r
200 DLLVERSIONINFO dvi;
\r
201 ZeroMemory(&dvi, sizeof(dvi));
\r
202 dvi.cbSize = sizeof(dvi);
\r
204 HRESULT hr = (*pDllGetVersion)(&dvi);
\r
206 dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
\r
209 FreeLibrary(hinstDll);
\r
215 // workaround of SetForegroundWindow
\r
216 bool setForegroundWindow(HWND i_hwnd)
\r
218 int nForegroundID = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
\r
219 int nTargetID = GetWindowThreadProcessId(i_hwnd, NULL);
\r
221 //if (!AttachThreadInput(nTargetID, nForegroundID, TRUE))
\r
223 AttachThreadInput(nTargetID, nForegroundID, TRUE);
\r
226 SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &sp_time, 0);
\r
227 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (void *)0, 0);
\r
229 SetForegroundWindow(i_hwnd);
\r
231 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (void *)sp_time, 0);
\r
233 AttachThreadInput(nTargetID, nForegroundID, FALSE);
\r
239 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
243 // get edit control's text size
\r
244 // @return bytes of text
\r
245 size_t editGetTextBytes(HWND i_hwnd)
\r
247 return Edit_GetTextLength(i_hwnd);
\r
252 void editDeleteLine(HWND i_hwnd, size_t i_n)
\r
254 int len = Edit_LineLength(i_hwnd, i_n);
\r
258 int index = Edit_LineIndex(i_hwnd, i_n);
\r
259 Edit_SetSel(i_hwnd, index, index + len);
\r
260 Edit_ReplaceSel(i_hwnd, _T(""));
\r
264 // insert text at last
\r
265 void editInsertTextAtLast(HWND i_hwnd, const tstring &i_text,
\r
266 size_t i_threshold)
\r
268 if (i_text.empty())
\r
271 size_t len = editGetTextBytes(i_hwnd);
\r
273 if (i_threshold < len)
\r
275 Edit_SetSel(i_hwnd, 0, len / 3 * 2);
\r
276 Edit_ReplaceSel(i_hwnd, _T(""));
\r
277 editDeleteLine(i_hwnd, 0);
\r
278 len = editGetTextBytes(i_hwnd);
\r
281 Edit_SetSel(i_hwnd, len, len);
\r
284 Array<_TCHAR> buf(i_text.size() * 2 + 1);
\r
285 _TCHAR *d = buf.get();
\r
286 const _TCHAR *str = i_text.c_str();
\r
287 for (const _TCHAR *s = str; s < str + i_text.size(); ++ s)
\r
289 if (*s == _T('\n'))
\r
295 Edit_ReplaceSel(i_hwnd, buf.get());
\r
299 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
300 // Windows2000/XP specific API
\r
303 // initialize layerd window
\r
304 static BOOL WINAPI initalizeLayerdWindow(
\r
305 HWND i_hwnd, COLORREF i_crKey, BYTE i_bAlpha, DWORD i_dwFlags)
\r
307 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
\r
311 SetLayeredWindowAttributes_t proc =
\r
312 reinterpret_cast<SetLayeredWindowAttributes_t>(
\r
313 GetProcAddress(hModule, "SetLayeredWindowAttributes"));
\r
314 if (setLayeredWindowAttributes) {
\r
315 setLayeredWindowAttributes = proc;
\r
316 return setLayeredWindowAttributes(i_hwnd, i_crKey, i_bAlpha, i_dwFlags);
\r
323 // SetLayeredWindowAttributes API
\r
324 SetLayeredWindowAttributes_t setLayeredWindowAttributes
\r
325 = initalizeLayerdWindow;
\r
328 // emulate MonitorFromWindow API
\r
329 static HMONITOR WINAPI emulateMonitorFromWindow(HWND hwnd, DWORD dwFlags)
\r
331 return reinterpret_cast<HMONITOR>(1); // dummy HMONITOR
\r
334 // initialize MonitorFromWindow API
\r
335 static HMONITOR WINAPI initializeMonitorFromWindow(HWND hwnd, DWORD dwFlags)
\r
337 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
\r
341 FARPROC proc = GetProcAddress(hModule, "MonitorFromWindow");
\r
343 monitorFromWindow =
\r
344 reinterpret_cast<HMONITOR (WINAPI *)(HWND, DWORD)>(proc);
\r
346 monitorFromWindow = emulateMonitorFromWindow;
\r
348 return monitorFromWindow(hwnd, dwFlags);
\r
351 // MonitorFromWindow API
\r
352 HMONITOR (WINAPI *monitorFromWindow)(HWND hwnd, DWORD dwFlags)
\r
353 = initializeMonitorFromWindow;
\r
356 // emulate GetMonitorInfo API
\r
357 static BOOL WINAPI emulateGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)
\r
359 if(lpmi->cbSize != sizeof(MONITORINFO))
\r
362 lpmi->rcMonitor.left = 0;
\r
363 lpmi->rcMonitor.top = 0;
\r
364 lpmi->rcMonitor.right = GetSystemMetrics(SM_CXFULLSCREEN);
\r
365 lpmi->rcMonitor.bottom = GetSystemMetrics(SM_CYFULLSCREEN);
\r
366 SystemParametersInfo(SPI_GETWORKAREA, 0,
\r
367 reinterpret_cast<PVOID>(&lpmi->rcWork), FALSE);
\r
368 lpmi->dwFlags = MONITORINFOF_PRIMARY;
\r
373 // initialize GetMonitorInfo API
\r
375 BOOL WINAPI initializeGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)
\r
377 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
\r
381 FARPROC proc = GetProcAddress(hModule, "GetMonitorInfoA");
\r
384 reinterpret_cast<BOOL (WINAPI *)(HMONITOR, LPMONITORINFO)>(proc);
\r
386 getMonitorInfo = emulateGetMonitorInfo;
\r
388 return getMonitorInfo(hMonitor, lpmi);
\r
391 // GetMonitorInfo API
\r
392 BOOL (WINAPI *getMonitorInfo)(HMONITOR hMonitor, LPMONITORINFO lpmi)
\r
393 = initializeGetMonitorInfo;
\r
396 // enumalte EnumDisplayMonitors API
\r
397 static BOOL WINAPI emulateEnumDisplayMonitors(
\r
398 HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
\r
400 lpfnEnum(reinterpret_cast<HMONITOR>(1), hdc, lprcClip, dwData);
\r
404 // initialize EnumDisplayMonitors API
\r
405 static BOOL WINAPI initializeEnumDisplayMonitors(
\r
406 HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
\r
408 HMODULE hModule = GetModuleHandle(_T("user32.dll"));
\r
412 FARPROC proc = GetProcAddress(hModule, "EnumDisplayMonitors");
\r
414 enumDisplayMonitors =
\r
415 reinterpret_cast<BOOL (WINAPI *)(HDC, LPRECT, MONITORENUMPROC, LPARAM)>
\r
418 enumDisplayMonitors = emulateEnumDisplayMonitors;
\r
420 return enumDisplayMonitors(hdc, lprcClip, lpfnEnum, dwData);
\r
423 // EnumDisplayMonitors API
\r
424 BOOL (WINAPI *enumDisplayMonitors)
\r
425 (HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
\r
426 = initializeEnumDisplayMonitors;
\r
429 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
430 // Windows2000/XP specific API
\r
434 initializeWTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags)
\r
436 LoadLibrary(_T("wtsapi32.dll"));
\r
437 HMODULE hModule = GetModuleHandle(_T("wtsapi32.dll"));
\r
441 WTSRegisterSessionNotification_t proc =
\r
442 reinterpret_cast<WTSRegisterSessionNotification_t>(
\r
443 GetProcAddress(hModule, "WTSRegisterSessionNotification"));
\r
445 wtsRegisterSessionNotification = proc;
\r
446 return wtsRegisterSessionNotification(hWnd, dwFlags);
\r
452 // WTSRegisterSessionNotification API
\r
453 WTSRegisterSessionNotification_t wtsRegisterSessionNotification
\r
454 = initializeWTSRegisterSessionNotification;
\r
457 static BOOL WINAPI initializeWTSUnRegisterSessionNotification(HWND hWnd)
\r
459 HMODULE hModule = GetModuleHandle(_T("wtsapi32.dll"));
\r
463 WTSUnRegisterSessionNotification_t proc =
\r
464 reinterpret_cast<WTSUnRegisterSessionNotification_t>(
\r
465 GetProcAddress(hModule, "WTSUnRegisterSessionNotification"));
\r
467 wtsUnRegisterSessionNotification = proc;
\r
468 return wtsUnRegisterSessionNotification(hWnd);
\r
474 // WTSUnRegisterSessionNotification API
\r
475 WTSUnRegisterSessionNotification_t wtsUnRegisterSessionNotification
\r
476 = initializeWTSUnRegisterSessionNotification;
\r
479 static DWORD WINAPI initializeWTSGetActiveConsoleSessionId(void)
\r
481 HMODULE hModule = GetModuleHandle(_T("kernel32.dll"));
\r
485 WTSGetActiveConsoleSessionId_t proc =
\r
486 reinterpret_cast<WTSGetActiveConsoleSessionId_t>(
\r
487 GetProcAddress(hModule, "WTSGetActiveConsoleSessionId"));
\r
489 wtsGetActiveConsoleSessionId = proc;
\r
490 return wtsGetActiveConsoleSessionId();
\r
496 // WTSGetActiveConsoleSessionId API
\r
497 WTSGetActiveConsoleSessionId_t wtsGetActiveConsoleSessionId
\r
498 = initializeWTSGetActiveConsoleSessionId;
\r
501 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
504 // PathRemoveFileSpec()
\r
505 tstring pathRemoveFileSpec(const tstring &i_path)
\r
507 const _TCHAR *str = i_path.c_str();
\r
508 const _TCHAR *b = _tcsrchr(str, _T('\\'));
\r
509 const _TCHAR *s = _tcsrchr(str, _T('/'));
\r
511 return tstring(str, MIN(b, s));
\r
513 return tstring(str, b);
\r
515 return tstring(str, s);
\r
516 if (const _TCHAR *c = _tcsrchr(str, _T(':')))
\r
517 return tstring(str, c + 1);
\r