| 2318 | |
| 2319 | |
| 2320 | ResultType GuiType::Create(LPTSTR aTitle) |
| 2321 | { |
| 2322 | if (mHwnd) // It already exists |
| 2323 | return FAIL; // Should be impossible since mHwnd is checked by caller. |
| 2324 | |
| 2325 | // Use a separate class for GUI, which gives it a separate WindowProc and allows it to be more |
| 2326 | // distinct when used with the ahk_class method of addressing windows. |
| 2327 | if (!sGuiWinClass) |
| 2328 | { |
| 2329 | WNDCLASSEX wc = {0}; |
| 2330 | wc.cbSize = sizeof(wc); |
| 2331 | wc.lpszClassName = WINDOW_CLASS_GUI; |
| 2332 | wc.hInstance = g_hInstance; |
| 2333 | wc.lpfnWndProc = GuiWindowProc; |
| 2334 | wc.hIcon = g_IconLarge; |
| 2335 | wc.hIconSm = g_IconSmall; |
| 2336 | wc.style = CS_DBLCLKS; // v1.0.44.12: CS_DBLCLKS is accepted as a good default by nearly everyone. It causes the window to receive WM_LBUTTONDBLCLK, WM_RBUTTONDBLCLK, and WM_MBUTTONDBLCLK (even without this, all windows receive WM_NCLBUTTONDBLCLK, WM_NCMBUTTONDBLCLK, and WM_NCRBUTTONDBLCLK). |
| 2337 | // CS_HREDRAW and CS_VREDRAW are not included above because they cause extra flickering. It's generally better for a window to manage its own redrawing when it's resized. |
| 2338 | wc.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW); |
| 2339 | wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); |
| 2340 | wc.cbWndExtra = DLGWINDOWEXTRA; // So that it will be the type that uses DefDlgProc() vs. DefWindowProc(). |
| 2341 | sGuiWinClass = RegisterClassEx(&wc); |
| 2342 | if (!sGuiWinClass) |
| 2343 | return g_script.Win32Error(); |
| 2344 | } |
| 2345 | |
| 2346 | if ( !(mHwnd = CreateWindowEx(mExStyle, WINDOW_CLASS_GUI, aTitle |
| 2347 | , mStyle, 0, 0, 0, 0, mOwner, NULL, g_hInstance, NULL)) ) |
| 2348 | return g_script.Win32Error(); |
| 2349 | |
| 2350 | // Set the user pointer in the window to this GuiType object, so that it is possible to retrieve it back from the window handle. |
| 2351 | SetWindowLongPtr(mHwnd, GWLP_USERDATA, (LONG_PTR)this); |
| 2352 | |
| 2353 | // L17: Use separate big/small icons for best results. |
| 2354 | HICON big_icon, small_icon; |
| 2355 | if (g_script.mCustomIcon) |
| 2356 | { |
| 2357 | mIconEligibleForDestruction = big_icon = g_script.mCustomIcon; |
| 2358 | mIconEligibleForDestructionSmall = small_icon = g_script.mCustomIconSmall; // Should always be non-NULL if mCustomIcon is non-NULL. |
| 2359 | } |
| 2360 | else |
| 2361 | { |
| 2362 | big_icon = g_IconLarge; |
| 2363 | small_icon = g_IconSmall; |
| 2364 | // Unlike mCustomIcon, leave mIconEligibleForDestruction NULL because these |
| 2365 | // icons are used for various other purposes and should never be destroyed. |
| 2366 | } |
| 2367 | // Setting the small icon puts it in the upper left corner of the dialog window. |
| 2368 | // Setting the big icon makes the dialog show up correctly in the Alt-Tab menu (but big seems to |
| 2369 | // have no effect unless the window is unowned, i.e. it has a button on the task bar). |
| 2370 | // Change for v1.0.37.07: Set both icons unconditionally for code simplicity, and also in case |
| 2371 | // it's possible for the window to change after creation in a way that would make a custom icon |
| 2372 | // become relevant. Set the big icon even if it's owned because there might be ways |
| 2373 | // an owned window can have an entry in the alt-tab menu. The following ways come close |
| 2374 | // but don't actually succeed: |
| 2375 | // 1) It's owned by the main window but the main window isn't visible: It acquires the main window's icon |
| 2376 | // in the alt-tab menu regardless of whether it was given a big icon of its own. |
| 2377 | // 2) It's owned by another GUI window but it has the WS_EX_APPWINDOW style (might force a taskbar button): |
nothing calls this directly
no test coverage detected