[原创] ImGUI 1.87 绘制D3D外部菜单
2022-9-30 10:12:0 Author: bbs.pediy.com(查看原文) 阅读量:7 收藏

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;

}


文章来源: https://bbs.pediy.com/thread-274595.htm
如有侵权请联系:admin#unsafe.sh