OSDN Git Service

add entry to escape NLS keys
[yamy/yamy.git] / windowstool.cpp
index c96e4c7..09221ce 100644 (file)
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// 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