1 /** 2 * Windows GUI window utility code. 3 * 4 * License: 5 * This Source Code Form is subject to the terms of 6 * the Mozilla Public License, v. 2.0. If a copy of 7 * the MPL was not distributed with this file, You 8 * can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * Authors: 11 * Vladimir Panteleev <vladimir@thecybershadow.net> 12 */ 13 14 module ae.sys.windows.window; 15 version (Windows): 16 17 import std.range; 18 import std.utf; 19 20 import ae.sys.windows.imports; 21 mixin(importWin32!q{winbase}); 22 mixin(importWin32!q{winnt}); 23 mixin(importWin32!q{winuser}); 24 25 import ae.sys.windows.exception; 26 import ae.sys.windows.text; 27 28 struct WindowIterator 29 { 30 private: 31 LPCWSTR szClassName, szWindowName; 32 HWND hParent, h; 33 34 public: 35 @property 36 bool empty() const { return h is null; } 37 38 @property 39 HWND front() const { return cast(HWND)h; } 40 41 void popFront() 42 { 43 h = FindWindowExW(hParent, h, szClassName, szWindowName); 44 } 45 } 46 47 WindowIterator windowIterator(string szClassName, string szWindowName, HWND hParent=null) 48 { 49 auto iterator = WindowIterator(toWStringz(szClassName), toWStringz(szWindowName), hParent); 50 iterator.popFront(); // initiate search 51 return iterator; 52 } 53 54 private static wchar[0xFFFF] textBuf = void; 55 56 string windowStringQuery(alias FUNC)(HWND h) 57 { 58 SetLastError(0); 59 auto result = FUNC(h, textBuf.ptr, textBuf.length); 60 if (result) 61 return textBuf[0..result].toUTF8(); 62 else 63 { 64 auto code = GetLastError(); 65 if (code) 66 throw new WindowsException(code, __traits(identifier, FUNC)); 67 else 68 return null; 69 } 70 } 71 72 alias windowStringQuery!GetClassNameW getClassName; 73 alias windowStringQuery!GetWindowTextW getWindowText; 74 75 /// Create an utility hidden window. 76 HWND createHiddenWindow(string name, WNDPROC proc) 77 { 78 auto szName = toWStringz(name); 79 80 HINSTANCE hInstance = GetModuleHandle(null); 81 82 WNDCLASSEXW wcx; 83 84 wcx.cbSize = wcx.sizeof; 85 wcx.lpfnWndProc = proc; 86 wcx.hInstance = hInstance; 87 wcx.lpszClassName = szName; 88 wenforce(RegisterClassExW(&wcx), "RegisterClassEx failed"); 89 90 HWND hWnd = CreateWindowW( 91 szName, // name of window class 92 szName, // title-bar string 93 WS_OVERLAPPEDWINDOW, // top-level window 94 CW_USEDEFAULT, // default horizontal position 95 CW_USEDEFAULT, // default vertical position 96 CW_USEDEFAULT, // default width 97 CW_USEDEFAULT, // default height 98 null, // no owner window 99 null, // use class menu 100 hInstance, // handle to application instance 101 null); // no window-creation data 102 wenforce(hWnd, "CreateWindow failed"); 103 104 return hWnd; 105 }