-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// windowstool.cpp
-
-
-#include "misc.h"
-
-#include "windowstool.h"
-#include "array.h"
-
-#include <windowsx.h>
-#include <malloc.h>
-#include <shlwapi.h>
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Global variables
-
-
-// instance handle of this application
-HINSTANCE g_hInst = NULL;
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Functions
-
-
-// load resource string
-tstring loadString(UINT i_id)
-{
- _TCHAR buf[1024];
- if (LoadString(g_hInst, i_id, buf, NUMBER_OF(buf)))
- return tstring(buf);
- else
- return _T("");
-}
-
-
-// load small icon resource
-HICON loadSmallIcon(UINT i_id)
-{
- return reinterpret_cast<HICON>(
- LoadImage(g_hInst, MAKEINTRESOURCE(i_id), IMAGE_ICON, 16, 16, 0));
-}
-
-
-// load big icon resource
-HICON loadBigIcon(UINT i_id)
-{
- return reinterpret_cast<HICON>(
- LoadImage(g_hInst, MAKEINTRESOURCE(i_id), IMAGE_ICON, 32, 32, 0));
-}
-
-
-// set small icon to the specified window.
-// @return handle of previous icon or NULL
-HICON setSmallIcon(HWND i_hwnd, UINT i_id)
-{
- HICON hicon = (i_id == static_cast<UINT>(-1)) ? NULL : loadSmallIcon(i_id);
- return reinterpret_cast<HICON>(
- SendMessage(i_hwnd, WM_SETICON, static_cast<WPARAM>(ICON_SMALL),
- reinterpret_cast<LPARAM>(hicon)));
-}
-
-
-// set big icon to the specified window.
-// @return handle of previous icon or NULL
-HICON setBigIcon(HWND i_hwnd, UINT i_id)
-{
- HICON hicon = (i_id == static_cast<UINT>(-1)) ? NULL : loadBigIcon(i_id);
- return reinterpret_cast<HICON>(
- SendMessage(i_hwnd, WM_SETICON, static_cast<WPARAM>(ICON_BIG),
- reinterpret_cast<LPARAM>(hicon)));
-}
-
-
-// remove icon from a window that is set by setSmallIcon
-void unsetSmallIcon(HWND i_hwnd)
-{
- HICON hicon = setSmallIcon(i_hwnd, -1);
- if (hicon)
- CHECK_TRUE( DestroyIcon(hicon) );
-}
-
-
-// remove icon from a window that is set by setBigIcon
-void unsetBigIcon(HWND i_hwnd)
-{
- HICON hicon = setBigIcon(i_hwnd, -1);
- if (hicon)
- CHECK_TRUE( DestroyIcon(hicon) );
-}
-
-
-// resize the window (it does not move the window)
-bool resizeWindow(HWND i_hwnd, int i_w, int i_h, bool i_doRepaint)
-{
- UINT flag = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
- if (!i_doRepaint)
- flag |= SWP_NOREDRAW;
- return !!SetWindowPos(i_hwnd, NULL, 0, 0, i_w, i_h, flag);
-}
-
-
-// get rect of the window in client coordinates
-// @return rect of the window in client coordinates
-bool getChildWindowRect(HWND i_hwnd, RECT *o_rc)
-{
- if (!GetWindowRect(i_hwnd, o_rc))
- return false;
- POINT p = { o_rc->left, o_rc->top };
- HWND phwnd = GetParent(i_hwnd);
- if (!phwnd)
- return false;
- if (!ScreenToClient(phwnd, &p))
- return false;
- o_rc->left = p.x;
- o_rc->top = p.y;
- p.x = o_rc->right;
- p.y = o_rc->bottom;
- ScreenToClient(phwnd, &p);
- o_rc->right = p.x;
- o_rc->bottom = p.y;
- return true;
-}
-
-
-// get toplevel (non-child) window
-HWND getToplevelWindow(HWND i_hwnd, bool *io_isMDI)
-{
- while (i_hwnd)
- {
- LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
- if ((style & WS_CHILD) == 0)
- break;
- if (io_isMDI && *io_isMDI)
- {
- LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);
- if (exStyle & WS_EX_MDICHILD)
- return i_hwnd;
- }
- i_hwnd = GetParent(i_hwnd);
- }
- if (io_isMDI)
- *io_isMDI = false;
- return i_hwnd;
-}
-
-
-// move window asynchronously
-void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y)
-{
- SetWindowPos(i_hwnd, NULL, i_x, i_y, 0, 0,
- SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOSIZE | SWP_NOZORDER);
-}
-
-
-// move window asynchronously
-void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y, int i_w, int i_h)
-{
- SetWindowPos(i_hwnd, NULL, i_x, i_y, i_w, i_h,
- SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOZORDER);
-}
-
-
-// resize asynchronously
-void asyncResize(HWND i_hwnd, int i_w, int i_h)
-{
- SetWindowPos(i_hwnd, NULL, 0, 0, i_w, i_h,
- SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOMOVE | SWP_NOZORDER);
-}
-
-
-// get dll version
-DWORD getDllVersion(const _TCHAR *i_dllname)
-{
- DWORD dwVersion = 0;
-
- if (HINSTANCE hinstDll = LoadLibrary(i_dllname))
- {
- DLLGETVERSIONPROC pDllGetVersion
- = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");
- /* Because some DLLs may not implement this function, you
- * must test for it explicitly. Depending on the particular
- * DLL, the lack of a DllGetVersion function may
- * be a useful indicator of the version.
- */
- if (pDllGetVersion)
- {
- DLLVERSIONINFO dvi;
- ZeroMemory(&dvi, sizeof(dvi));
- dvi.cbSize = sizeof(dvi);
-
- HRESULT hr = (*pDllGetVersion)(&dvi);
- if (SUCCEEDED(hr))
- dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
- }
-
- FreeLibrary(hinstDll);
- }
- return dwVersion;
-}
-
-
-// workaround of SetForegroundWindow
-bool setForegroundWindow(HWND i_hwnd)
-{
- int nForegroundID = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
- int nTargetID = GetWindowThreadProcessId(i_hwnd, NULL);
-
- //if (!AttachThreadInput(nTargetID, nForegroundID, TRUE))
- //return false;
- AttachThreadInput(nTargetID, nForegroundID, TRUE);
-
- DWORD sp_time;
- SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &sp_time, 0);
- SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (void *)0, 0);
-
- SetForegroundWindow(i_hwnd);
-
- SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (void *)sp_time, 0);
-
- AttachThreadInput(nTargetID, nForegroundID, FALSE);
- return true;
-}
-
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// edit control
-
-
-// get edit control's text size
-// @return bytes of text
-size_t editGetTextBytes(HWND i_hwnd)
-{
- return Edit_GetTextLength(i_hwnd);
-}
-
-
-// delete a line
-void editDeleteLine(HWND i_hwnd, size_t i_n)
-{
- int len = Edit_LineLength(i_hwnd, i_n);
- if (len < 0)
- return;
- len += 2;
- int index = Edit_LineIndex(i_hwnd, i_n);
- Edit_SetSel(i_hwnd, index, index + len);
- Edit_ReplaceSel(i_hwnd, _T(""));
-}
-
-
-// insert text at last
-void editInsertTextAtLast(HWND i_hwnd, const tstring &i_text,
- size_t i_threshold)
-{
- if (i_text.empty())
- return;
-
- size_t len = editGetTextBytes(i_hwnd);
-
- if (i_threshold < len)
- {
- Edit_SetSel(i_hwnd, 0, len / 3 * 2);
- Edit_ReplaceSel(i_hwnd, _T(""));
- editDeleteLine(i_hwnd, 0);
- len = editGetTextBytes(i_hwnd);
- }
-
- Edit_SetSel(i_hwnd, len, len);
-
- // \n -> \r\n
- Array<_TCHAR> buf(i_text.size() * 2 + 1);
- _TCHAR *d = buf.get();
- const _TCHAR *str = i_text.c_str();
- for (const _TCHAR *s = str; s < str + i_text.size(); ++ s)
- {
- if (*s == _T('\n'))
- *d++ = _T('\r');
- *d++ = *s;
- }
- *d = _T('\0');
-
- Edit_ReplaceSel(i_hwnd, buf.get());
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Windows2000/XP specific API
-
-
-// initialize layerd window
-static BOOL WINAPI initalizeLayerdWindow(
- HWND i_hwnd, COLORREF i_crKey, BYTE i_bAlpha, DWORD i_dwFlags)
-{
- HMODULE hModule = GetModuleHandle(_T("user32.dll"));
- if (!hModule) {
- return FALSE;
- }
- SetLayeredWindowAttributes_t proc =
- reinterpret_cast<SetLayeredWindowAttributes_t>(
- GetProcAddress(hModule, "SetLayeredWindowAttributes"));
- if (setLayeredWindowAttributes) {
- setLayeredWindowAttributes = proc;
- return setLayeredWindowAttributes(i_hwnd, i_crKey, i_bAlpha, i_dwFlags);
- } else {
- return FALSE;
- }
-}
-
-
-// SetLayeredWindowAttributes API
-SetLayeredWindowAttributes_t setLayeredWindowAttributes
- = initalizeLayerdWindow;
-
-
-// emulate MonitorFromWindow API
-static HMONITOR WINAPI emulateMonitorFromWindow(HWND hwnd, DWORD dwFlags)
-{
- return reinterpret_cast<HMONITOR>(1); // dummy HMONITOR
-}
-
-// initialize MonitorFromWindow API
-static HMONITOR WINAPI initializeMonitorFromWindow(HWND hwnd, DWORD dwFlags)
-{
- HMODULE hModule = GetModuleHandle(_T("user32.dll"));
- if (!hModule)
- return FALSE;
-
- FARPROC proc = GetProcAddress(hModule, "MonitorFromWindow");
- if(proc)
- monitorFromWindow =
- reinterpret_cast<HMONITOR (WINAPI *)(HWND, DWORD)>(proc);
- else
- monitorFromWindow = emulateMonitorFromWindow;
-
- return monitorFromWindow(hwnd, dwFlags);
-}
-
-// MonitorFromWindow API
-HMONITOR (WINAPI *monitorFromWindow)(HWND hwnd, DWORD dwFlags)
- = initializeMonitorFromWindow;
-
-
-// emulate GetMonitorInfo API
-static BOOL WINAPI emulateGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)
-{
- if(lpmi->cbSize != sizeof(MONITORINFO))
- return FALSE;
-
- lpmi->rcMonitor.left = 0;
- lpmi->rcMonitor.top = 0;
- lpmi->rcMonitor.right = GetSystemMetrics(SM_CXFULLSCREEN);
- lpmi->rcMonitor.bottom = GetSystemMetrics(SM_CYFULLSCREEN);
- SystemParametersInfo(SPI_GETWORKAREA, 0,
- reinterpret_cast<PVOID>(&lpmi->rcWork), FALSE);
- lpmi->dwFlags = MONITORINFOF_PRIMARY;
-
- return TRUE;
-}
-
-// initialize GetMonitorInfo API
-static
-BOOL WINAPI initializeGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)
-{
- HMODULE hModule = GetModuleHandle(_T("user32.dll"));
- if (!hModule)
- return FALSE;
-
- FARPROC proc = GetProcAddress(hModule, "GetMonitorInfoA");
- if(proc)
- getMonitorInfo =
- reinterpret_cast<BOOL (WINAPI *)(HMONITOR, LPMONITORINFO)>(proc);
- else
- getMonitorInfo = emulateGetMonitorInfo;
-
- return getMonitorInfo(hMonitor, lpmi);
-}
-
-// GetMonitorInfo API
-BOOL (WINAPI *getMonitorInfo)(HMONITOR hMonitor, LPMONITORINFO lpmi)
- = initializeGetMonitorInfo;
-
-
-// enumalte EnumDisplayMonitors API
-static BOOL WINAPI emulateEnumDisplayMonitors(
- HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
-{
- lpfnEnum(reinterpret_cast<HMONITOR>(1), hdc, lprcClip, dwData);
- return TRUE;
-}
-
-// initialize EnumDisplayMonitors API
-static BOOL WINAPI initializeEnumDisplayMonitors(
- HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
-{
- HMODULE hModule = GetModuleHandle(_T("user32.dll"));
- if (!hModule)
- return FALSE;
-
- FARPROC proc = GetProcAddress(hModule, "EnumDisplayMonitors");
- if(proc)
- enumDisplayMonitors =
- reinterpret_cast<BOOL (WINAPI *)(HDC, LPRECT, MONITORENUMPROC, LPARAM)>
- (proc);
- else
- enumDisplayMonitors = emulateEnumDisplayMonitors;
-
- return enumDisplayMonitors(hdc, lprcClip, lpfnEnum, dwData);
-}
-
-// EnumDisplayMonitors API
-BOOL (WINAPI *enumDisplayMonitors)
- (HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
- = initializeEnumDisplayMonitors;
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Windows2000/XP specific API
-
-
-static BOOL WINAPI
-initializeWTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags)
-{
- LoadLibrary(_T("wtsapi32.dll"));
- HMODULE hModule = GetModuleHandle(_T("wtsapi32.dll"));
- if (!hModule) {
- return FALSE;
- }
- WTSRegisterSessionNotification_t proc =
- reinterpret_cast<WTSRegisterSessionNotification_t>(
- GetProcAddress(hModule, "WTSRegisterSessionNotification"));
- if (proc) {
- wtsRegisterSessionNotification = proc;
- return wtsRegisterSessionNotification(hWnd, dwFlags);
- } else {
- return 0;
- }
-}
-
-// WTSRegisterSessionNotification API
-WTSRegisterSessionNotification_t wtsRegisterSessionNotification
- = initializeWTSRegisterSessionNotification;
-
-
-static BOOL WINAPI initializeWTSUnRegisterSessionNotification(HWND hWnd)
-{
- HMODULE hModule = GetModuleHandle(_T("wtsapi32.dll"));
- if (!hModule) {
- return FALSE;
- }
- WTSUnRegisterSessionNotification_t proc =
- reinterpret_cast<WTSUnRegisterSessionNotification_t>(
- GetProcAddress(hModule, "WTSUnRegisterSessionNotification"));
- if (proc) {
- wtsUnRegisterSessionNotification = proc;
- return wtsUnRegisterSessionNotification(hWnd);
- } else {
- return 0;
- }
-}
-
-// WTSUnRegisterSessionNotification API
-WTSUnRegisterSessionNotification_t wtsUnRegisterSessionNotification
- = initializeWTSUnRegisterSessionNotification;
-
-
-static DWORD WINAPI initializeWTSGetActiveConsoleSessionId(void)
-{
- HMODULE hModule = GetModuleHandle(_T("kernel32.dll"));
- if (!hModule) {
- return FALSE;
- }
- WTSGetActiveConsoleSessionId_t proc =
- reinterpret_cast<WTSGetActiveConsoleSessionId_t>(
- GetProcAddress(hModule, "WTSGetActiveConsoleSessionId"));
- if (proc) {
- wtsGetActiveConsoleSessionId = proc;
- return wtsGetActiveConsoleSessionId();
- } else {
- return 0;
- }
-}
-
-// WTSGetActiveConsoleSessionId API
-WTSGetActiveConsoleSessionId_t wtsGetActiveConsoleSessionId
- = initializeWTSGetActiveConsoleSessionId;
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Utility
-
-// PathRemoveFileSpec()
-tstring pathRemoveFileSpec(const tstring &i_path)
-{
- const _TCHAR *str = i_path.c_str();
- const _TCHAR *b = _tcsrchr(str, _T('\\'));
- const _TCHAR *s = _tcsrchr(str, _T('/'));
- if (b && s)
- return tstring(str, MIN(b, s));
- if (b)
- return tstring(str, b);
- if (s)
- return tstring(str, s);
- if (const _TCHAR *c = _tcsrchr(str, _T(':')))
- return tstring(str, c + 1);
- return i_path;
-}
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// windowstool.cpp\r
+\r
+\r
+#include "misc.h"\r
+\r
+#include "windowstool.h"\r
+#include "array.h"\r
+\r
+#include <windowsx.h>\r
+#include <malloc.h>\r
+#include <shlwapi.h>\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// Global variables\r
+\r
+\r
+// instance handle of this application\r
+HINSTANCE g_hInst = NULL;\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// Functions\r
+\r
+\r
+// load resource string\r
+tstring loadString(UINT i_id)\r
+{\r
+ _TCHAR buf[1024];\r
+ if (LoadString(g_hInst, i_id, buf, NUMBER_OF(buf)))\r
+ return tstring(buf);\r
+ else\r
+ return _T("");\r
+}\r
+\r
+\r
+// load small icon resource\r
+HICON loadSmallIcon(UINT i_id)\r
+{\r
+ return reinterpret_cast<HICON>(\r
+ LoadImage(g_hInst, MAKEINTRESOURCE(i_id), IMAGE_ICON, 16, 16, 0));\r
+}\r
+\r
+\r
+// load big icon resource\r
+HICON loadBigIcon(UINT i_id)\r
+{\r
+ return reinterpret_cast<HICON>(\r
+ LoadImage(g_hInst, MAKEINTRESOURCE(i_id), IMAGE_ICON, 32, 32, 0));\r
+}\r
+\r
+\r
+// set small icon to the specified window.\r
+// @return handle of previous icon or NULL\r
+HICON setSmallIcon(HWND i_hwnd, UINT i_id)\r
+{\r
+ HICON hicon = (i_id == static_cast<UINT>(-1)) ? NULL : loadSmallIcon(i_id);\r
+ return reinterpret_cast<HICON>(\r
+ SendMessage(i_hwnd, WM_SETICON, static_cast<WPARAM>(ICON_SMALL),\r
+ reinterpret_cast<LPARAM>(hicon)));\r
+}\r
+\r
+\r
+// set big icon to the specified window.\r
+// @return handle of previous icon or NULL\r
+HICON setBigIcon(HWND i_hwnd, UINT i_id)\r
+{\r
+ HICON hicon = (i_id == static_cast<UINT>(-1)) ? NULL : loadBigIcon(i_id);\r
+ return reinterpret_cast<HICON>(\r
+ SendMessage(i_hwnd, WM_SETICON, static_cast<WPARAM>(ICON_BIG),\r
+ reinterpret_cast<LPARAM>(hicon)));\r
+}\r
+\r
+\r
+// remove icon from a window that is set by setSmallIcon\r
+void unsetSmallIcon(HWND i_hwnd)\r
+{\r
+ HICON hicon = setSmallIcon(i_hwnd, -1);\r
+ if (hicon)\r
+ CHECK_TRUE( DestroyIcon(hicon) );\r
+}\r
+\r
+\r
+// remove icon from a window that is set by setBigIcon\r
+void unsetBigIcon(HWND i_hwnd)\r
+{\r
+ HICON hicon = setBigIcon(i_hwnd, -1);\r
+ if (hicon)\r
+ CHECK_TRUE( DestroyIcon(hicon) );\r
+}\r
+\r
+\r
+// resize the window (it does not move the window)\r
+bool resizeWindow(HWND i_hwnd, int i_w, int i_h, bool i_doRepaint)\r
+{\r
+ UINT flag = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;\r
+ if (!i_doRepaint)\r
+ flag |= SWP_NOREDRAW;\r
+ return !!SetWindowPos(i_hwnd, NULL, 0, 0, i_w, i_h, flag);\r
+}\r
+\r
+\r
+// get rect of the window in client coordinates\r
+// @return rect of the window in client coordinates\r
+bool getChildWindowRect(HWND i_hwnd, RECT *o_rc)\r
+{\r
+ if (!GetWindowRect(i_hwnd, o_rc))\r
+ return false;\r
+ POINT p = { o_rc->left, o_rc->top };\r
+ HWND phwnd = GetParent(i_hwnd);\r
+ if (!phwnd)\r
+ return false;\r
+ if (!ScreenToClient(phwnd, &p))\r
+ return false;\r
+ o_rc->left = p.x;\r
+ o_rc->top = p.y;\r
+ p.x = o_rc->right;\r
+ p.y = o_rc->bottom;\r
+ ScreenToClient(phwnd, &p);\r
+ o_rc->right = p.x;\r
+ o_rc->bottom = p.y;\r
+ return true;\r
+}\r
+\r
+\r
+// get toplevel (non-child) window\r
+HWND getToplevelWindow(HWND i_hwnd, bool *io_isMDI)\r
+{\r
+ while (i_hwnd) {\r
+#ifdef MAYU64\r
+ LONG_PTR style = GetWindowLongPtr(i_hwnd, GWL_STYLE);\r
+#else\r
+ LONG style = GetWindowLong(i_hwnd, GWL_STYLE);\r
+#endif\r
+ if ((style & WS_CHILD) == 0)\r
+ break;\r
+ if (io_isMDI && *io_isMDI) {\r
+#ifdef MAYU64\r
+ LONG_PTR exStyle = GetWindowLongPtr(i_hwnd, GWL_EXSTYLE);\r
+#else\r
+ LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);\r
+#endif\r
+ if (exStyle & WS_EX_MDICHILD)\r
+ return i_hwnd;\r
+ }\r
+ i_hwnd = GetParent(i_hwnd);\r
+ }\r
+ if (io_isMDI)\r
+ *io_isMDI = false;\r
+ return i_hwnd;\r
+}\r
+\r
+\r
+// move window asynchronously\r
+void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y)\r
+{\r
+ SetWindowPos(i_hwnd, NULL, i_x, i_y, 0, 0,\r
+ SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |\r
+ SWP_NOSIZE | SWP_NOZORDER);\r
+}\r
+\r
+\r
+// move window asynchronously\r
+void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y, int i_w, int i_h)\r
+{\r
+ SetWindowPos(i_hwnd, NULL, i_x, i_y, i_w, i_h,\r
+ SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |\r
+ SWP_NOZORDER);\r
+}\r
+\r
+\r
+// resize asynchronously\r
+void asyncResize(HWND i_hwnd, int i_w, int i_h)\r
+{\r
+ SetWindowPos(i_hwnd, NULL, 0, 0, i_w, i_h,\r
+ SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |\r
+ SWP_NOMOVE | SWP_NOZORDER);\r
+}\r
+\r
+\r
+// get dll version\r
+DWORD getDllVersion(const _TCHAR *i_dllname)\r
+{\r
+ DWORD dwVersion = 0;\r
+\r
+ if (HINSTANCE hinstDll = LoadLibrary(i_dllname)) {\r
+ DLLGETVERSIONPROC pDllGetVersion\r
+ = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");\r
+ /* Because some DLLs may not implement this function, you\r
+ * must test for it explicitly. Depending on the particular\r
+ * DLL, the lack of a DllGetVersion function may\r
+ * be a useful indicator of the version.\r
+ */\r
+ if (pDllGetVersion) {\r
+ DLLVERSIONINFO dvi;\r
+ ZeroMemory(&dvi, sizeof(dvi));\r
+ dvi.cbSize = sizeof(dvi);\r
+\r
+ HRESULT hr = (*pDllGetVersion)(&dvi);\r
+ if (SUCCEEDED(hr))\r
+ dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);\r
+ }\r
+\r
+ FreeLibrary(hinstDll);\r
+ }\r
+ return dwVersion;\r
+}\r
+\r
+\r
+// workaround of SetForegroundWindow\r
+bool setForegroundWindow(HWND i_hwnd)\r
+{\r
+ int nForegroundID = GetWindowThreadProcessId(GetForegroundWindow(), NULL);\r
+ int nTargetID = GetWindowThreadProcessId(i_hwnd, NULL);\r
+\r
+ //if (!AttachThreadInput(nTargetID, nForegroundID, TRUE))\r
+ //return false;\r
+ AttachThreadInput(nTargetID, nForegroundID, TRUE);\r
+\r
+ DWORD sp_time;\r
+ SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &sp_time, 0);\r
+ SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (void *)0, 0);\r
+\r
+ SetForegroundWindow(i_hwnd);\r
+\r
+ SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (void *)sp_time, 0);\r
+\r
+ AttachThreadInput(nTargetID, nForegroundID, FALSE);\r
+ return true;\r
+}\r
+\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// edit control\r
+\r
+\r
+// get edit control's text size\r
+// @return bytes of text\r
+size_t editGetTextBytes(HWND i_hwnd)\r
+{\r
+ return Edit_GetTextLength(i_hwnd);\r
+}\r
+\r
+\r
+// delete a line\r
+void editDeleteLine(HWND i_hwnd, size_t i_n)\r
+{\r
+ int len = Edit_LineLength(i_hwnd, i_n);\r
+ if (len < 0)\r
+ return;\r
+ len += 2;\r
+ int index = Edit_LineIndex(i_hwnd, i_n);\r
+ Edit_SetSel(i_hwnd, index, index + len);\r
+ Edit_ReplaceSel(i_hwnd, _T(""));\r
+}\r
+\r
+\r
+// insert text at last\r
+void editInsertTextAtLast(HWND i_hwnd, const tstring &i_text,\r
+ size_t i_threshold)\r
+{\r
+ if (i_text.empty())\r
+ return;\r
+\r
+ size_t len = editGetTextBytes(i_hwnd);\r
+\r
+ if (i_threshold < len) {\r
+ Edit_SetSel(i_hwnd, 0, len / 3 * 2);\r
+ Edit_ReplaceSel(i_hwnd, _T(""));\r
+ editDeleteLine(i_hwnd, 0);\r
+ len = editGetTextBytes(i_hwnd);\r
+ }\r
+\r
+ Edit_SetSel(i_hwnd, len, len);\r
+\r
+ // \n -> \r\n\r
+ Array<_TCHAR> buf(i_text.size() * 2 + 1);\r
+ _TCHAR *d = buf.get();\r
+ const _TCHAR *str = i_text.c_str();\r
+ for (const _TCHAR *s = str; s < str + i_text.size(); ++ s) {\r
+ if (*s == _T('\n'))\r
+ *d++ = _T('\r');\r
+ *d++ = *s;\r
+ }\r
+ *d = _T('\0');\r
+\r
+ Edit_ReplaceSel(i_hwnd, buf.get());\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// Windows2000/XP specific API\r
+\r
+\r
+// initialize layerd window\r
+static BOOL WINAPI initalizeLayerdWindow(\r
+ HWND i_hwnd, COLORREF i_crKey, BYTE i_bAlpha, DWORD i_dwFlags)\r
+{\r
+ HMODULE hModule = GetModuleHandle(_T("user32.dll"));\r
+ if (!hModule) {\r
+ return FALSE;\r
+ }\r
+ SetLayeredWindowAttributes_t proc =\r
+ reinterpret_cast<SetLayeredWindowAttributes_t>(\r
+ GetProcAddress(hModule, "SetLayeredWindowAttributes"));\r
+ if (setLayeredWindowAttributes) {\r
+ setLayeredWindowAttributes = proc;\r
+ return setLayeredWindowAttributes(i_hwnd, i_crKey, i_bAlpha, i_dwFlags);\r
+ } else {\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+\r
+// SetLayeredWindowAttributes API\r
+SetLayeredWindowAttributes_t setLayeredWindowAttributes\r
+= initalizeLayerdWindow;\r
+\r
+\r
+// emulate MonitorFromWindow API\r
+static HMONITOR WINAPI emulateMonitorFromWindow(HWND hwnd, DWORD dwFlags)\r
+{\r
+ return reinterpret_cast<HMONITOR>(1); // dummy HMONITOR\r
+}\r
+\r
+// initialize MonitorFromWindow API\r
+static HMONITOR WINAPI initializeMonitorFromWindow(HWND hwnd, DWORD dwFlags)\r
+{\r
+ HMODULE hModule = GetModuleHandle(_T("user32.dll"));\r
+ if (!hModule)\r
+ return FALSE;\r
+\r
+ FARPROC proc = GetProcAddress(hModule, "MonitorFromWindow");\r
+ if (proc)\r
+ monitorFromWindow =\r
+ reinterpret_cast<HMONITOR (WINAPI *)(HWND, DWORD)>(proc);\r
+ else\r
+ monitorFromWindow = emulateMonitorFromWindow;\r
+\r
+ return monitorFromWindow(hwnd, dwFlags);\r
+}\r
+\r
+// MonitorFromWindow API\r
+HMONITOR (WINAPI *monitorFromWindow)(HWND hwnd, DWORD dwFlags)\r
+= initializeMonitorFromWindow;\r
+\r
+\r
+// emulate GetMonitorInfo API\r
+static BOOL WINAPI emulateGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)\r
+{\r
+ if (lpmi->cbSize != sizeof(MONITORINFO))\r
+ return FALSE;\r
+\r
+ lpmi->rcMonitor.left = 0;\r
+ lpmi->rcMonitor.top = 0;\r
+ lpmi->rcMonitor.right = GetSystemMetrics(SM_CXFULLSCREEN);\r
+ lpmi->rcMonitor.bottom = GetSystemMetrics(SM_CYFULLSCREEN);\r
+ SystemParametersInfo(SPI_GETWORKAREA, 0,\r
+ reinterpret_cast<PVOID>(&lpmi->rcWork), FALSE);\r
+ lpmi->dwFlags = MONITORINFOF_PRIMARY;\r
+\r
+ return TRUE;\r
+}\r
+\r
+// initialize GetMonitorInfo API\r
+static\r
+BOOL WINAPI initializeGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)\r
+{\r
+ HMODULE hModule = GetModuleHandle(_T("user32.dll"));\r
+ if (!hModule)\r
+ return FALSE;\r
+\r
+ FARPROC proc = GetProcAddress(hModule, "GetMonitorInfoA");\r
+ if (proc)\r
+ getMonitorInfo =\r
+ reinterpret_cast<BOOL (WINAPI *)(HMONITOR, LPMONITORINFO)>(proc);\r
+ else\r
+ getMonitorInfo = emulateGetMonitorInfo;\r
+\r
+ return getMonitorInfo(hMonitor, lpmi);\r
+}\r
+\r
+// GetMonitorInfo API\r
+BOOL (WINAPI *getMonitorInfo)(HMONITOR hMonitor, LPMONITORINFO lpmi)\r
+= initializeGetMonitorInfo;\r
+\r
+\r
+// enumalte EnumDisplayMonitors API\r
+static BOOL WINAPI emulateEnumDisplayMonitors(\r
+ HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)\r
+{\r
+ lpfnEnum(reinterpret_cast<HMONITOR>(1), hdc, lprcClip, dwData);\r
+ return TRUE;\r
+}\r
+\r
+// initialize EnumDisplayMonitors API\r
+static BOOL WINAPI initializeEnumDisplayMonitors(\r
+ HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)\r
+{\r
+ HMODULE hModule = GetModuleHandle(_T("user32.dll"));\r
+ if (!hModule)\r
+ return FALSE;\r
+\r
+ FARPROC proc = GetProcAddress(hModule, "EnumDisplayMonitors");\r
+ if (proc)\r
+ enumDisplayMonitors =\r
+ reinterpret_cast<BOOL (WINAPI *)(HDC, LPRECT, MONITORENUMPROC, LPARAM)>\r
+ (proc);\r
+ else\r
+ enumDisplayMonitors = emulateEnumDisplayMonitors;\r
+\r
+ return enumDisplayMonitors(hdc, lprcClip, lpfnEnum, dwData);\r
+}\r
+\r
+// EnumDisplayMonitors API\r
+BOOL (WINAPI *enumDisplayMonitors)\r
+(HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)\r
+= initializeEnumDisplayMonitors;\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// Windows2000/XP specific API\r
+\r
+\r
+static BOOL WINAPI\r
+initializeWTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags)\r
+{\r
+ LoadLibrary(_T("wtsapi32.dll"));\r
+ HMODULE hModule = GetModuleHandle(_T("wtsapi32.dll"));\r
+ if (!hModule) {\r
+ return FALSE;\r
+ }\r
+ WTSRegisterSessionNotification_t proc =\r
+ reinterpret_cast<WTSRegisterSessionNotification_t>(\r
+ GetProcAddress(hModule, "WTSRegisterSessionNotification"));\r
+ if (proc) {\r
+ wtsRegisterSessionNotification = proc;\r
+ return wtsRegisterSessionNotification(hWnd, dwFlags);\r
+ } else {\r
+ return 0;\r
+ }\r
+}\r
+\r
+// WTSRegisterSessionNotification API\r
+WTSRegisterSessionNotification_t wtsRegisterSessionNotification\r
+= initializeWTSRegisterSessionNotification;\r
+\r
+\r
+static BOOL WINAPI initializeWTSUnRegisterSessionNotification(HWND hWnd)\r
+{\r
+ HMODULE hModule = GetModuleHandle(_T("wtsapi32.dll"));\r
+ if (!hModule) {\r
+ return FALSE;\r
+ }\r
+ WTSUnRegisterSessionNotification_t proc =\r
+ reinterpret_cast<WTSUnRegisterSessionNotification_t>(\r
+ GetProcAddress(hModule, "WTSUnRegisterSessionNotification"));\r
+ if (proc) {\r
+ wtsUnRegisterSessionNotification = proc;\r
+ return wtsUnRegisterSessionNotification(hWnd);\r
+ } else {\r
+ return 0;\r
+ }\r
+}\r
+\r
+// WTSUnRegisterSessionNotification API\r
+WTSUnRegisterSessionNotification_t wtsUnRegisterSessionNotification\r
+= initializeWTSUnRegisterSessionNotification;\r
+\r
+\r
+static DWORD WINAPI initializeWTSGetActiveConsoleSessionId(void)\r
+{\r
+ HMODULE hModule = GetModuleHandle(_T("kernel32.dll"));\r
+ if (!hModule) {\r
+ return FALSE;\r
+ }\r
+ WTSGetActiveConsoleSessionId_t proc =\r
+ reinterpret_cast<WTSGetActiveConsoleSessionId_t>(\r
+ GetProcAddress(hModule, "WTSGetActiveConsoleSessionId"));\r
+ if (proc) {\r
+ wtsGetActiveConsoleSessionId = proc;\r
+ return wtsGetActiveConsoleSessionId();\r
+ } else {\r
+ return 0;\r
+ }\r
+}\r
+\r
+// WTSGetActiveConsoleSessionId API\r
+WTSGetActiveConsoleSessionId_t wtsGetActiveConsoleSessionId\r
+= initializeWTSGetActiveConsoleSessionId;\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// Utility\r
+\r
+// PathRemoveFileSpec()\r
+tstring pathRemoveFileSpec(const tstring &i_path)\r
+{\r
+ const _TCHAR *str = i_path.c_str();\r
+ const _TCHAR *b = _tcsrchr(str, _T('\\'));\r
+ const _TCHAR *s = _tcsrchr(str, _T('/'));\r
+ if (b && s)\r
+ return tstring(str, MIN(b, s));\r
+ if (b)\r
+ return tstring(str, b);\r
+ if (s)\r
+ return tstring(str, s);\r
+ if (const _TCHAR *c = _tcsrchr(str, _T(':')))\r
+ return tstring(str, c + 1);\r
+ return i_path;\r
+}\r
+\r
+BOOL checkWindowsVersion(DWORD i_major, DWORD i_minor)\r
+{\r
+ DWORDLONG conditionMask = 0;\r
+ OSVERSIONINFOEX osvi;\r
+ memset(&osvi, 0, sizeof(OSVERSIONINFOEX));\r
+\r
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);\r
+ osvi.dwMajorVersion = i_major;\r
+ osvi.dwMinorVersion = i_minor;\r
+\r
+ VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);\r
+ VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);\r
+\r
+ // Perform the test.\r
+ return VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, conditionMask);\r
+}\r