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 }