ImGUI 它是与平台无关的C++轻量级跨平台图形界面库,没有任何第三方依赖,可以将ImGUI的源码直接加到项目中使用,该框架通常会配合特定的D3Dx9等图形开发工具包一起使用,ImGUI常用来实现进程内的菜单功能,而有些辅助开发作者也会使用该框架开发菜单页面,总体来说这是一个很不错的绘图库,如下将公开新版ImGUI如何实现绘制外部菜单的功能。
在使用ImGUI页面之前需要先来实现一个简单的附着功能,即如何将一个窗体附着到另一个窗体之上,其实代码很简单,如下所示当用户输入进程PID时,会自动跟随窗体并附着在窗体顶部。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
struct handle_data
{
unsigned
long
process_id;
HWND best_handle;
};
/
/
By: LyShark
BOOL
IsMainWindow(HWND handle)
{
return
GetWindow(handle, GW_OWNER)
=
=
(HWND)
0
&& IsWindowVisible(handle);
}
BOOL
CALLBACK EnumWindowsCallback(HWND handle, LPARAM lParam)
{
/
/
By: LyShark
handle_data& data
=
*
(handle_data
*
)lParam;
unsigned
long
process_id
=
0
;
GetWindowThreadProcessId(handle, &process_id);
if
(data.process_id !
=
process_id || !IsMainWindow(handle)) {
return
TRUE;
}
data.best_handle
=
handle;
return
FALSE;
}
/
/
By: LyShark
HWND FindMainWindow(unsigned
long
process_id)
{
handle_data data;
data.process_id
=
process_id;
data.best_handle
=
0
;
EnumWindows(EnumWindowsCallback, (LPARAM)&data);
return
data.best_handle;
}
int
main(
int
argc, char
*
argv[])
{
DWORD pid
=
28396
;
std::cout <<
"输入进程PID: "
<< std::endl;
std::cin >> pid;
/
/
获取屏幕宽和高
int
iWidth
=
::GetSystemMetrics(SM_CXSCREEN);
int
iHeight
=
::GetSystemMetrics(SM_CYSCREEN);
/
/
根据PID寻找游戏窗口
HWND hwnd
=
FindMainWindow(pid);
while
(
1
)
{
SetTimer(hwnd,
1
,
150
, NULL);
/
/
实现透明必须设置WS_EX_LAYERED标志
LONG
lWinStyleEx
=
GetWindowLong(hwnd, GWL_EXSTYLE);
lWinStyleEx
=
lWinStyleEx | WS_EX_LAYERED;
SetWindowLong(hwnd, GWL_EXSTYLE, lWinStyleEx);
SetLayeredWindowAttributes(hwnd,
0
, RGB(
40
,
40
,
40
), LWA_ALPHA);
/
/
去掉标题栏及边框
LONG_PTR Style
=
GetWindowLongPtr(hwnd, GWL_STYLE);
Style
=
Style & ~WS_CAPTION & ~WS_SYSMENU & ~WS_SIZEBOX;
SetWindowLongPtr(hwnd, GWL_STYLE, Style);
/
/
至顶层窗口 最大化
SetWindowPos(hwnd, HWND_TOPMOST,
0
,
0
, iWidth, iHeight, SWP_SHOWWINDOW);
/
/
设置窗体可穿透鼠标
SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_TRANSPARENT | WS_EX_LAYERED);
/
/
绘图
HDC hdc
=
::GetDC(hwnd);
HDC mdc
=
::CreateCompatibleDC(hdc);
/
/
创建画笔
HPEN hpen
=
CreatePen(PS_SOLID,
10
, RGB(
0
,
255
,
0
));
/
/
DC 选择画笔
SelectObject(hdc, hpen);
/
/
(画笔)从初始点移动到
50
,
50
MoveToEx(hdc,
100
,
100
, NULL);
/
/
(画笔)从初始点画线到
100
,
100
LineTo(hdc,
1000
,
1000
);
RECT rect
=
{
0
};
rect.bottom
=
10
;
rect.left
=
20
;
rect.right
=
20
;
rect.top
=
15
;
DrawText(hdc, L
"hello lyshark.com"
, strlen(
"hello lyshark.com"
), &rect, DT_CALCRECT | DT_CENTER | DT_SINGLELINE);
}
return
0
;
}
接着我们使用Imgui绘制一个动态菜单,首先下载imgui并打开项目中的examples
目录,找到example_win32_directx9
打开后自己配置好dx9SDK
开发工具包。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
/
/
全局变量
/
/
lyshark.com
static HWND hwnd;
static HWND GameHwnd;
static RECT WindowRectangle;
static
int
WindowWide, WindowHeight;
static LPDIRECT3D9 g_pD3D
=
NULL;
static LPDIRECT3DDEVICE9 g_pd3dDevice
=
NULL;
static D3DPRESENT_PARAMETERS g_d3dpp
=
{};
/
/
单选框设置状态
bool
show_another_window
=
false;
/
/
imgui 回调函数
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
/
/
By: LyShark
bool
CreateDeviceD3D(HWND hWnd)
{
if
((g_pD3D
=
Direct3DCreate9(D3D_SDK_VERSION))
=
=
NULL)
{
return
false;
}
ZeroMemory(&g_d3dpp, sizeof(g_d3dpp));
g_d3dpp.Windowed
=
TRUE;
g_d3dpp.SwapEffect
=
D3DSWAPEFFECT_DISCARD;
g_d3dpp.BackBufferFormat
=
D3DFMT_UNKNOWN;
g_d3dpp.EnableAutoDepthStencil
=
TRUE;
g_d3dpp.AutoDepthStencilFormat
=
D3DFMT_D16;
g_d3dpp.PresentationInterval
=
D3DPRESENT_INTERVAL_ONE;
if
(g_pD3D
-
>CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) <
0
)
{
return
false;
}
return
true;
}
void CleanupDeviceD3D()
{
if
(g_pd3dDevice)
{
g_pd3dDevice
-
>Release();
g_pd3dDevice
=
NULL;
}
if
(g_pD3D)
{
g_pD3D
-
>Release();
g_pD3D
=
NULL;
}
}
void ResetDevice()
{
ImGui_ImplDX9_InvalidateDeviceObjects();
HRESULT hr
=
g_pd3dDevice
-
>Reset(&g_d3dpp);
if
(hr
=
=
D3DERR_INVALIDCALL)
{
IM_ASSERT(
0
);
}
ImGui_ImplDX9_CreateDeviceObjects();
}
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if
(ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
{
return
true;
}
switch (msg)
{
case WM_SIZE:
if
(g_pd3dDevice !
=
NULL && wParam !
=
SIZE_MINIMIZED)
{
g_d3dpp.BackBufferWidth
=
LOWORD(lParam);
g_d3dpp.BackBufferHeight
=
HIWORD(lParam);
ResetDevice();
}
return
0
;
case WM_SYSCOMMAND:
if
((wParam &
0xfff0
)
=
=
SC_KEYMENU)
{
return
0
;
}
break
;
case WM_DESTROY:
PostQuitMessage(
0
);
return
0
;
}
return
DefWindowProc(hWnd, msg, wParam, lParam);
}
/
/
绘制主方法
/
/
www.cnblogs.com
/
lyshark
void DrawImGUI()
{
/
/
启动IMGUI自绘
ImGui_ImplDX9_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
static
float
f
=
0.0f
;
static
int
counter
=
0
;
static char sz[
256
]
=
{
0
};
ImGui::Begin(
"LyShark 辅助GUI主菜单"
);
ImGui::Text(
"这是一段测试字符串"
);
ImGui::Checkbox(
"弹出子窗口"
, &show_another_window);
ImGui::SliderFloat(
"浮点条"
, &f,
0.0f
,
1.0f
);
ImGui::InputText(
"输入内容"
, sz,
256
,
0
,
0
,
0
);
if
(ImGui::Button(
"点我触发"
))
counter
+
+
;
ImGui::SameLine();
ImGui::Text(
"触发次数 = %d"
, counter);
ImGui::Text(
"当前FPS: %.3f ms/frame (%.1f FPS)"
,
1000.0f
/
ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
ImGui::End();
if
(show_another_window)
{
ImGui::Begin(
"我是子窗体"
, &show_another_window);
ImGui::Text(
" 您好,LyShark !"
);
if
(ImGui::Button(
"关闭窗体"
))
show_another_window
=
false;
ImGui::End();
}
ImGui::EndFrame();
}
/
/
自身窗口循环事件
void WindowMessageLoop()
{
bool
done
=
false;
while
(!done)
{
/
/
每次都将窗体置顶并跟随游戏窗体移动
GetWindowRect(GameHwnd, &WindowRectangle);
WindowWide
=
(WindowRectangle.right)
-
(WindowRectangle.left);
WindowHeight
=
(WindowRectangle.bottom)
-
(WindowRectangle.top);
DWORD dwStyle
=
GetWindowLong(GameHwnd, GWL_STYLE);
if
(dwStyle & WS_BORDER)
{
WindowRectangle.top
+
=
23
;
WindowHeight
-
=
23
;
}
/
/
跟随窗口移动
MoveWindow(hwnd, WindowRectangle.left
+
8
, WindowRectangle.top
+
8
, WindowWide
-
11
, WindowHeight
-
11
, true);
/
/
开始消息循环
MSG msg;
while
(PeekMessage(&msg, NULL,
0U
,
0U
, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if
(msg.message
=
=
WM_QUIT)
{
done
=
true;
}
}
if
(done)
{
break
;
}
/
/
开始绘制
DrawImGUI();
g_pd3dDevice
-
>SetRenderState(D3DRS_ZENABLE, FALSE);
g_pd3dDevice
-
>SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
g_pd3dDevice
-
>SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
g_pd3dDevice
-
>Clear(
0
, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
0
,
1.0f
,
0
);
if
(g_pd3dDevice
-
>BeginScene() >
=
0
)
{
ImGui::Render();
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
g_pd3dDevice
-
>EndScene();
}
HRESULT result
=
g_pd3dDevice
-
>Present(NULL, NULL, NULL, NULL);
if
(result
=
=
D3DERR_DEVICELOST && g_pd3dDevice
-
>TestCooperativeLevel()
=
=
D3DERR_DEVICENOTRESET)
{
ResetDevice();
}
}
}
int
main(
int
argc, char
*
argv[])
{
/
/
注册窗体类
WNDCLASSEX wc;
/
/
附加到指定窗体上
wc.cbClsExtra
=
NULL;
wc.cbSize
=
sizeof(WNDCLASSEX);
wc.cbWndExtra
=
NULL;
wc.hbrBackground
=
(HBRUSH)CreateSolidBrush(RGB(
0
,
0
,
0
));
wc.hCursor
=
LoadCursor(
0
, IDC_ARROW);
wc.hIcon
=
LoadIcon(
0
, IDI_APPLICATION);
wc.hIconSm
=
LoadIcon(
0
, IDI_APPLICATION);
wc.hInstance
=
GetModuleHandle(NULL);
wc.lpfnWndProc
=
(WNDPROC)WndProc;
wc.lpszClassName
=
L
" "
;
wc.lpszMenuName
=
L
" "
;
wc.style
=
CS_VREDRAW | CS_HREDRAW;
RegisterClassEx(&wc);
/
/
得到窗口句柄
GameHwnd
=
FindWindowA(NULL,
"Counter-Strike Source"
);
GetWindowRect(GameHwnd, &WindowRectangle);
WindowWide
=
WindowRectangle.right
-
WindowRectangle.left;
WindowHeight
=
WindowRectangle.bottom
-
WindowRectangle.top;
/
/
创建窗体
hwnd
=
CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TOOLWINDOW, L
" "
, L
" "
, WS_POPUP,
1
,
1
, WindowWide, WindowHeight,
0
,
0
, wc.hInstance,
0
);
/
/
显示窗口
SetLayeredWindowAttributes(hwnd,
0
, RGB(
0
,
0
,
0
), LWA_ALPHA);
SetLayeredWindowAttributes(hwnd,
0
, RGB(
0
,
0
,
0
), LWA_COLORKEY);
ShowWindow(hwnd, SW_SHOW);
/
/
初始化D3D
if
(!CreateDeviceD3D(hwnd))
{
CleanupDeviceD3D();
UnregisterClass(wc.lpszClassName, wc.hInstance);
return
0
;
}
/
/
更新窗体
UpdateWindow(hwnd);
/
/
初始化ImGUI
ImGui::CreateContext();
ImGuiIO& io
=
ImGui::GetIO(); (void)io;
io.Fonts
-
>AddFontFromFileTTF(
"c:/windows/fonts/simhei.ttf"
,
13.0f
, NULL, io.Fonts
-
>GetGlyphRangesChineseSimplifiedCommon());
ImGui::StyleColorsDark();
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX9_Init(g_pd3dDevice);
/
/
开始执行绘制循环事件
WindowMessageLoop();
ImGui_ImplDX9_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();
CleanupDeviceD3D();
DestroyWindow(hwnd);
UnregisterClass(wc.lpszClassName, wc.hInstance);
return
0
;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
/
/
全局变量
static HWND hwnd;
static HWND GameHwnd;
static RECT WindowRectangle;
static
int
WindowWide, WindowHeight;
static LPDIRECT3D9 g_pD3D
=
NULL;
static LPDIRECT3DDEVICE9 g_pd3dDevice
=
NULL;
static D3DPRESENT_PARAMETERS g_d3dpp
=
{};
/
/
单选框设置状态
bool
show_another_window
=
false;
/
/
imgui 回调函数
/
/
By: LyShark
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
bool
CreateDeviceD3D(HWND hWnd)
{
if
((g_pD3D
=
Direct3DCreate9(D3D_SDK_VERSION))
=
=
NULL)
{
return
false;
}
ZeroMemory(&g_d3dpp, sizeof(g_d3dpp));
g_d3dpp.Windowed
=
TRUE;
g_d3dpp.SwapEffect
=
D3DSWAPEFFECT_DISCARD;
g_d3dpp.BackBufferFormat
=
D3DFMT_UNKNOWN;
g_d3dpp.EnableAutoDepthStencil
=
TRUE;
g_d3dpp.AutoDepthStencilFormat
=
D3DFMT_D16;
g_d3dpp.PresentationInterval
=
D3DPRESENT_INTERVAL_ONE;
if
(g_pD3D
-
>CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) <
0
)
{
return
false;
}
return
true;
}
void CleanupDeviceD3D()
{
if
(g_pd3dDevice)
{
g_pd3dDevice
-
>Release();
g_pd3dDevice
=
NULL;
}
if
(g_pD3D)
{
g_pD3D
-
>Release();
g_pD3D
=
NULL;
}
}
/
/
https:
/
/
www.cnblogs.com
/
lyshark
void ResetDevice()
{
ImGui_ImplDX9_InvalidateDeviceObjects();
HRESULT hr
=
g_pd3dDevice
-
>Reset(&g_d3dpp);
if
(hr
=
=
D3DERR_INVALIDCALL)
{
IM_ASSERT(
0
);
}
ImGui_ImplDX9_CreateDeviceObjects();
}
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if
(ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
{
return
true;
}
switch (msg)
{
case WM_SIZE:
if
(g_pd3dDevice !
=
NULL && wParam !
=
SIZE_MINIMIZED)
{
g_d3dpp.BackBufferWidth
=
LOWORD(lParam);
g_d3dpp.BackBufferHeight
=
HIWORD(lParam);
ResetDevice();
}
return
0
;
case WM_SYSCOMMAND:
if
((wParam &
0xfff0
)
=
=
SC_KEYMENU)
{
return
0
;
}
break
;
case WM_DESTROY:
PostQuitMessage(
0
);
return
0
;
}
return
DefWindowProc(hWnd, msg, wParam, lParam);
}
/
/
绘制主方法
/
/
lyshark.com
void DrawImGUI()
{
/
/
启动IMGUI自绘
ImGui_ImplDX9_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
static
float
f
=
0.0f
;
static
int
counter
=
0
;
static char sz[
256
]
=
{
0
};
ImGui::Begin(
"LyShark 辅助GUI主菜单"
);
ImGui::Text(
"这是一段测试字符串"
);
ImGui::Checkbox(
"弹出子窗口"
, &show_another_window);
ImGui::SliderFloat(
"浮点条"
, &f,
0.0f
,
1.0f
);
ImGui::InputText(
"输入内容"
, sz,
256
,
0
,
0
,
0
);
if
(ImGui::Button(
"点我触发"
))
counter
+
+
;
ImGui::SameLine();
ImGui::Text(
"触发次数 = %d"
, counter);
ImGui::Text(
"当前FPS: %.3f ms/frame (%.1f FPS)"
,
1000.0f
/
ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
ImGui::End();
if
(show_another_window)
{
ImGui::Begin(
"我是子窗体"
, &show_another_window);
ImGui::Text(
" 您好,LyShark !"
);
if
(ImGui::Button(
"关闭窗体"
))
show_another_window
=
false;
ImGui::End();
}
ImGui::EndFrame();
}
/
/
自身窗口循环事件
void WindowMessageLoop()
{
bool
done
=
false;
while
(!done)
{
/
/
每次都将窗体置顶并跟随游戏窗体移动
GetWindowRect(GameHwnd, &WindowRectangle);
WindowWide
=
(WindowRectangle.right)
-
(WindowRectangle.left);
WindowHeight
=
(WindowRectangle.bottom)
-
(WindowRectangle.top);
DWORD dwStyle
=
GetWindowLong(GameHwnd, GWL_STYLE);
if
(dwStyle & WS_BORDER)
{
WindowRectangle.top
+
=
23
;
WindowHeight
-
=
23
;
}
/
/
跟随窗口移动
MoveWindow(hwnd, WindowRectangle.left
+
8
, WindowRectangle.top
+
8
, WindowWide
-
11
, WindowHeight
-
11
, true);
/
/
开始消息循环
MSG msg;
while
(PeekMessage(&msg, NULL,
0U
,
0U
, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if
(msg.message
=
=
WM_QUIT)
{
done
=
true;
}
}
if
(done)
{
break
;
}
/
/
开始绘制
DrawImGUI();
g_pd3dDevice
-
>SetRenderState(D3DRS_ZENABLE, FALSE);
g_pd3dDevice
-
>SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
g_pd3dDevice
-
>SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
g_pd3dDevice
-
>Clear(
0
, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
0
,
1.0f
,
0
);
if
(g_pd3dDevice
-
>BeginScene() >
=
0
)
{
ImGui::Render();
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
g_pd3dDevice
-
>EndScene();
}
HRESULT result
=
g_pd3dDevice
-
>Present(NULL, NULL, NULL, NULL);
if
(result
=
=
D3DERR_DEVICELOST && g_pd3dDevice
-
>TestCooperativeLevel()
=
=
D3DERR_DEVICENOTRESET)
{
ResetDevice();
}
}
}
int
main(
int
argc, char
*
argv[])
{
/
/
注册窗体类
WNDCLASSEX wc;
/
/
附加到整个屏幕上
wc.cbClsExtra
=
NULL;
wc.cbSize
=
sizeof(WNDCLASSEX);
wc.cbWndExtra
=
NULL;
wc.hbrBackground
=
(HBRUSH)CreateSolidBrush(RGB(
0
,
0
,
0
));
wc.hCursor
=
LoadCursor(
0
, IDC_ARROW);
wc.hIcon
=
LoadIcon(
0
, IDI_APPLICATION);
wc.hIconSm
=
LoadIcon(
0
, IDI_APPLICATION);
wc.hInstance
=
GetModuleHandle(NULL);
wc.lpfnWndProc
=
(WNDPROC)WndProc;
wc.lpszClassName
=
L
" "
;
wc.lpszMenuName
=
L
" "
;
wc.style
=
CS_VREDRAW | CS_HREDRAW;
::RegisterClassEx(&wc);
/
/
屏幕宽度和高度
WindowWide
=
GetSystemMetrics(SM_CXSCREEN);
WindowHeight
=
GetSystemMetrics(SM_CYSCREEN);
/
/
创建窗体
HWND hwnd
=
CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TOOLWINDOW, L
" "
, L
" "
, WS_POPUP,
1
,
1
, WindowWide, WindowHeight,
0
,
0
, wc.hInstance,
0
);
/
/
显示窗口
SetLayeredWindowAttributes(hwnd,
0
,
1.0f
, LWA_ALPHA);
SetLayeredWindowAttributes(hwnd,
0
, RGB(
0
,
0
,
0
), LWA_COLORKEY);
ShowWindow(hwnd, SW_SHOW);
/
/
初始化D3D
if
(!CreateDeviceD3D(hwnd))
{
CleanupDeviceD3D();
UnregisterClass(wc.lpszClassName, wc.hInstance);
return
0
;
}
/
/
更新窗体
UpdateWindow(hwnd);
/
/
初始化ImGUI
ImGui::CreateContext();
ImGuiIO& io
=
ImGui::GetIO(); (void)io;
io.Fonts
-
>AddFontFromFileTTF(
"c:/windows/fonts/simhei.ttf"
,
13.0f
, NULL, io.Fonts
-
>GetGlyphRangesChineseSimplifiedCommon());
ImGui::StyleColorsDark();
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX9_Init(g_pd3dDevice);
/
/
开始执行绘制循环事件
WindowMessageLoop();
ImGui_ImplDX9_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();
CleanupDeviceD3D();
DestroyWindow(hwnd);
UnregisterClass(wc.lpszClassName, wc.hInstance);
return
0
;
}