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 <ae@cy.md> 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 /// `FindWindowExW` wrapper as a D range interface. 29 struct WindowIterator 30 { 31 private: 32 LPCWSTR szClassName, szWindowName; 33 HWND hParent, h; 34 35 public: 36 @property 37 bool empty() const { return h is null; } /// 38 39 @property 40 HWND front() const { return cast(HWND)h; } /// 41 42 void popFront() 43 { 44 h = FindWindowExW(hParent, h, szClassName, szWindowName); 45 } /// 46 } 47 48 WindowIterator windowIterator(string szClassName, string szWindowName, HWND hParent=null) 49 { 50 auto iterator = WindowIterator(toWStringz(szClassName), toWStringz(szWindowName), hParent); 51 iterator.popFront(); // initiate search 52 return iterator; 53 } /// ditto 54 55 private static wchar[0xFFFF] textBuf = void; 56 57 string _windowStringQuery(alias FUNC)(HWND h) 58 { 59 SetLastError(0); 60 auto result = FUNC(h, textBuf.ptr, textBuf.length); 61 if (result) 62 return textBuf[0..result].toUTF8(); 63 else 64 { 65 auto code = GetLastError(); 66 if (code) 67 throw new WindowsException(code, __traits(identifier, FUNC)); 68 else 69 return null; 70 } 71 } 72 73 alias _windowStringQuery!GetClassNameW getClassName ; /// `GetClassNameW` wrapper. 74 alias _windowStringQuery!GetWindowTextW getWindowText; /// `GetWIndowTextW` wrapper. 75 76 /// Create an utility hidden window. 77 HWND createHiddenWindow(string name, WNDPROC proc) 78 { 79 auto szName = toWStringz(name); 80 81 HINSTANCE hInstance = GetModuleHandle(null); 82 83 WNDCLASSEXW wcx; 84 85 wcx.cbSize = wcx.sizeof; 86 wcx.lpfnWndProc = proc; 87 wcx.hInstance = hInstance; 88 wcx.lpszClassName = szName; 89 wenforce(RegisterClassExW(&wcx), "RegisterClassEx failed"); 90 91 HWND hWnd = CreateWindowW( 92 szName, // name of window class 93 szName, // title-bar string 94 WS_OVERLAPPEDWINDOW, // top-level window 95 CW_USEDEFAULT, // default horizontal position 96 CW_USEDEFAULT, // default vertical position 97 CW_USEDEFAULT, // default width 98 CW_USEDEFAULT, // default height 99 null, // no owner window 100 null, // use class menu 101 hInstance, // handle to application instance 102 null); // no window-creation data 103 wenforce(hWnd, "CreateWindow failed"); 104 105 return hWnd; 106 }