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 }