窗口句柄为何未正确存储?

huangapple go评论112阅读模式
英文:

Why does the window handle not get stored properly?

问题

首先,您获得了一个MCWE(可能是一种自定义窗口编辑器)。您可能比我更了解如何使用它,但我建议从头开始构建一个C++项目,然后将其添加进去。它使用Unicode字符集,请确保将子系统设置为“windows”。

WM_CREATE消息的父窗口中,通过迭代Objects来创建窗口。

还注册了一个自定义窗口类,以便能够在该对象上进行自定义事件处理。在这个“子”过程的WM_LBUTTONDOWN中,您希望通过向其发送消息来修改另一个子窗口的文本。

输出是“Is not..”是因为窗口句柄没有正确传递,但我做错了什么?

我尝试将变量作为指针传递,但没有任何区别。

您遇到的问题可能与窗口句柄的作用域和生存期有关。在WM_CREATE消息处理程序中创建的窗口句柄只在该函数内部有效。要在其他消息处理程序中使用这些窗口句柄,您需要确保它们的生存期足够长。

一种解决方法是将窗口句柄存储在全局或静态变量中,以便在整个应用程序中访问它们。例如,在UiObjects 类中,您可以将 CanvasOutput 对象的窗口句柄存储为静态变量:

  1. static HWND hObjectCanvasWnd;
  2. static HWND hObjectOutputWnd;

然后,在WM_CREATE消息处理程序中将它们设置为相应窗口的句柄:

  1. hObjectCanvasWnd = CreateWindow(
  2. Object.lpClassName, // Window class
  3. Object.lpWindowName, // Window text
  4. Object.dwStyle, // Styles
  5. Object.x, // Horizontal position
  6. Object.y, // Vertical position
  7. Object.nWidth, // Width
  8. Object.nHeigth, // Height
  9. hWnd, // Parent window
  10. Object.hMenu, // No menu.
  11. hInstance,
  12. NULL // Pointer not needed.
  13. );
  14. MyObjects.Objects[i].hObjectWnd = hObjectCanvasWnd;
  15. if (lstrcmp(Object.lpWindowName, L"Output") == 0)
  16. {
  17. hObjectOutputWnd = hObjectCanvasWnd;
  18. }

现在,您可以在其他消息处理程序中使用 hObjectOutputWnd 来操作 Output 窗口。确保将相应的条件检查添加到 WM_LBUTTONDOWN 消息处理程序中,以确定您是否操作了正确的窗口。

希望这可以帮助您解决问题。如果还有其他问题,请随时提出。

英文:

First you get a MCWE. You know probably better than me how to use it but I would recommend to build a C++ project from scratch and add it then. It uses Unicode character set, make sure to use windows as the SubSystem.

  1. #include <vector>
  2. #include <windows.h>
  3. #include <windowsx.h>
  4. #using <System.dll>
  5. const int CANVAS_HOR_OFFSET = 10;
  6. const int CANVAS_VER_OFFSET = 10;
  7. const int CANVAS_WIDTH = 640;
  8. const int CANVAS_HEIGTH = 480;
  9. const int OUTPUT_VER_OFFSET = 10;
  10. const int OUTPUT_HEIGTH = 120;
  11. static class UiObjects
  12. {
  13. public:
  14. enum ObjectClass { Custom };
  15. struct Object {
  16. LPWSTR lpClassName;
  17. LPWSTR lpWindowName;
  18. DWORD dwStyle;
  19. LONG x;
  20. LONG y;
  21. LONG nWidth;
  22. LONG nHeigth;
  23. HMENU hMenu;
  24. HWND hObjectWnd;
  25. ObjectClass objectType;
  26. COLORREF color;
  27. };
  28. Object Canvas, Output;
  29. std::vector<Object> Objects;
  30. UiObjects();
  31. } MyObjects;
  32. UiObjects::UiObjects() {
  33. Canvas = {
  34. L"myVirtualSandbox Canvas Class",
  35. L"Canvas",
  36. WS_VISIBLE | WS_CHILD | WS_BORDER,
  37. CANVAS_HOR_OFFSET,
  38. CANVAS_VER_OFFSET,
  39. CANVAS_WIDTH,
  40. CANVAS_HEIGTH,
  41. NULL,
  42. NULL,
  43. ObjectClass::Custom
  44. };
  45. Objects.push_back(Canvas);
  46. Output = {
  47. L"EDIT",
  48. L"Output",
  49. WS_VISIBLE | WS_CHILD | WS_BORDER,
  50. CANVAS_HOR_OFFSET,
  51. CANVAS_VER_OFFSET + CANVAS_HEIGTH + OUTPUT_VER_OFFSET,
  52. CANVAS_WIDTH,
  53. OUTPUT_HEIGTH,
  54. NULL,
  55. NULL,
  56. ObjectClass::Custom
  57. };
  58. Objects.push_back(Output);
  59. }
  60. LRESULT CALLBACK wndProc(
  61. HWND hWnd,
  62. UINT uMsg,
  63. WPARAM wParam,
  64. LPARAM lParam
  65. );
  66. LRESULT CALLBACK canvasWndProc(
  67. HWND hWnd,
  68. UINT uMsg,
  69. WPARAM wParam,
  70. LPARAM lParam
  71. );
  72. int __stdcall wWinMain(
  73. _In_ HINSTANCE hInstance,
  74. _In_opt_ HINSTANCE hPrevInstance,
  75. _In_ LPWSTR lpCmdLine,
  76. _In_ int nShowCmd
  77. ) {
  78. const wchar_t CLASS_NAME[] = L"myVirtualSandbox Window Class";
  79. HWND hApplicationWnd;
  80. MSG msg = { };
  81. // A window class defines a set of behaviors that several windows
  82. // might have in common. Every window must be associated with a
  83. // window class. To register a window class, fill in a "WNDCLASS"
  84. // structure and call "RegisterClass" function afterwards.
  85. WNDCLASS applicationWndClass = { };
  86. applicationWndClass.lpfnWndProc = wndProc;
  87. applicationWndClass.hInstance = hInstance;
  88. applicationWndClass.lpszClassName = CLASS_NAME;
  89. RegisterClass(&applicationWndClass);
  90. // Create the window.
  91. hApplicationWnd = CreateWindow(
  92. CLASS_NAME, // Window class
  93. L"Learn to Program Windows", // Window text
  94. WS_OVERLAPPEDWINDOW, // Window style
  95. // Size and position
  96. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  97. NULL, // Parent window
  98. NULL, // Menu
  99. hInstance, // Instance handle
  100. NULL // Additional application data
  101. );
  102. if (hApplicationWnd == NULL)
  103. {
  104. return 0;
  105. }
  106. ShowWindow(hApplicationWnd, nShowCmd);
  107. while (GetMessage(&msg, NULL, 0, 0) > 0)
  108. {
  109. TranslateMessage(&msg);
  110. DispatchMessage(&msg);
  111. }
  112. return 0;
  113. }
  114. LRESULT CALLBACK wndProc(
  115. HWND hWnd,
  116. UINT uMsg,
  117. WPARAM wParam,
  118. LPARAM lParam
  119. ) {
  120. switch (uMsg)
  121. {
  122. case WM_CREATE:
  123. {
  124. HINSTANCE hInstance;
  125. WNDCLASS canvasWndClass;
  126. hInstance = (HINSTANCE)GetModuleHandle(NULL);
  127. canvasWndClass = { };
  128. canvasWndClass.lpfnWndProc = canvasWndProc;
  129. canvasWndClass.hInstance = hInstance;
  130. canvasWndClass.lpszClassName = L"myVirtualSandbox Canvas Class";
  131. RegisterClass(&canvasWndClass);
  132. // The following loop iterates through the container of user
  133. // interface objects.
  134. for (int i = 0; i < MyObjects.Objects.size(); i++) {
  135. UiObjects::Object& Object = MyObjects.Objects[i];
  136. HWND hObjectWnd;
  137. hObjectWnd = CreateWindow(
  138. Object.lpClassName, // Window class
  139. Object.lpWindowName, // Window text
  140. Object.dwStyle, // Styles
  141. Object.x, // Horizontal position
  142. Object.y, // Vertical position
  143. Object.nWidth, // Width
  144. Object.nHeigth, // Height
  145. hWnd, // Parent window
  146. Object.hMenu, // No menu.
  147. hInstance,
  148. NULL // Pointer not needed.
  149. );
  150. MyObjects.Objects[i].hObjectWnd = hObjectWnd;
  151. }
  152. break;
  153. }
  154. case WM_DESTROY:
  155. {
  156. PostQuitMessage(0);
  157. break;
  158. }
  159. // To paint the window the "WM_PAINT" message has to be
  160. // received by the window. It is sent by either the program
  161. // itself or the operating system.
  162. case WM_PAINT:
  163. {
  164. // The "rcPaint" member of the "PAINTSTRCUT" structure
  165. // returns a "RECT" structure that specifies the upper
  166. // left and lower right corners of the rectangle in which
  167. // the painting is requested.
  168. PAINTSTRUCT paintStruct;
  169. HDC hDeviceContext;
  170. HBRUSH hBrush;
  171. hDeviceContext = BeginPaint(hWnd, &paintStruct);
  172. hBrush = CreateSolidBrush(RGB(66,66,66));
  173. // Paint application background.
  174. FillRect(
  175. hDeviceContext,
  176. &paintStruct.rcPaint,
  177. hBrush
  178. );
  179. DeleteObject(hBrush);
  180. EndPaint(hWnd, &paintStruct);
  181. break;
  182. }
  183. }
  184. return DefWindowProc(hWnd, uMsg, wParam, lParam);
  185. }
  186. LRESULT CALLBACK canvasWndProc(
  187. HWND hCanvasWnd,
  188. UINT uMsg,
  189. WPARAM wParam,
  190. LPARAM lParam
  191. ) {
  192. switch (uMsg)
  193. {
  194. case WM_LBUTTONDOWN:
  195. {
  196. POINT point = { };
  197. point.x = GET_X_LPARAM(lParam);
  198. point.y = GET_Y_LPARAM(lParam);
  199. System::Diagnostics::Debug::WriteLine("Clicked in Canvas.");
  200. HWND hOutputWnd = MyObjects.Output.hObjectWnd;
  201. // Check if hObjectWnd is a valid handle
  202. if (IsWindow(MyObjects.Output.hObjectWnd))
  203. {
  204. SendMessage(MyObjects.Output.hObjectWnd, WM_SETTEXT, NULL, (LPARAM)L"Test.");
  205. }
  206. else {
  207. System::Diagnostics::Debug::WriteLine("Is not..");
  208. }
  209. break;
  210. }
  211. }
  212. return DefWindowProc(hCanvasWnd, uMsg, wParam, lParam);
  213. }

I create windows by iterating through Objects in the WM_CREATE message of the parent window.

I also register a custom window class to be able to have custom event handling on that object. In case of WM_LBUTTONDOWN of this "sub"-procedure I want to modify another child windows text by sending a message to it.

The Output is "Is not.." since the window handle is not passed properly but what am I doing wrong?

I tried to pass the variable as a pointer but that didn´t make a difference at all.

答案1

得分: 0

在你的WM_CREATE循环中,你将新的HWND分配给了来自向量的Object副本。你没有更新向量中的原始Object

将这个:

  1. UiObjects::Object Object = MyObjects.Objects[i];

改成这样:

  1. UiObjects::Object& Object = MyObjects.Objects[i];
  2. ^

另外,请注意,CanvasOutput等都是与存储在Objects向量中的Object不同的独立Object。因此,你的WM_CREATE循环也没有正确更新Output.hObjectWnd等。


更新:事实上,你正在填充CanvasOutput等数据,然后将那些对象的副本推送到Objects向量中。因此,即使你的WM_CREATE代码正确地将新的HWND分配给了Objects元素,CanvasOutput等也不会正确获取HWND

为了实现你尝试的功能,你需要将Objects向量更改为保存Object*指针而不是Object实例,例如:

  1. #include <vector>
  2. #include <windows.h>
  3. #include <windowsx.h>
  4. #using <System.dll>
  5. const int CANVAS_HOR_OFFSET = 10;
  6. const int CANVAS_VER_OFFSET = 10;
  7. const int CANVAS_WIDTH = 640;
  8. const int CANVAS_HEIGTH = 480;
  9. const int OUTPUT_VER_OFFSET = 10;
  10. const int OUTPUT_HEIGTH = 120;
  11. static class UiObjects
  12. {
  13. public:
  14. enum ObjectClass { Custom };
  15. struct Object {
  16. LPWSTR lpClassName;
  17. LPWSTR lpWindowName;
  18. DWORD dwStyle;
  19. LONG x;
  20. LONG y;
  21. LONG nWidth;
  22. LONG nHeigth;
  23. HMENU hMenu;
  24. HWND hObjectWnd;
  25. ObjectClass objectType;
  26. COLORREF color;
  27. };
  28. Object Canvas, Output;
  29. std::vector<Object*> Objects;
  30. UiObjects();
  31. } MyObjects;
  32. UiObjects::UiObjects() {
  33. Canvas = {
  34. L"myVirtualSandbox Canvas Class",
  35. L"Canvas",
  36. WS_VISIBLE | WS_CHILD | WS_BORDER,
  37. CANVAS_HOR_OFFSET,
  38. CANVAS_VER_OFFSET,
  39. CANVAS_WIDTH,
  40. CANVAS_HEIGTH,
  41. NULL,
  42. NULL,
  43. ObjectClass::Custom
  44. };
  45. Objects.push_back(&Canvas);
  46. Output = {
  47. L"EDIT",
  48. L"Output",
  49. WS_VISIBLE | WS_CHILD | WS_BORDER,
  50. CANVAS_HOR_OFFSET,
  51. CANVAS_VER_OFFSET + CANVAS_HEIGTH + OUTPUT_VER_OFFSET,
  52. CANVAS_WIDTH,
  53. OUTPUT_HEIGTH,
  54. NULL,
  55. NULL,
  56. ObjectClass::Custom
  57. };
  58. Objects.push_back(&Output);
  59. }
  60. LRESULT CALLBACK wndProc(
  61. HWND hWnd,
  62. UINT uMsg,
  63. WPARAM wParam,
  64. LPARAM lParam
  65. );
  66. LRESULT CALLBACK canvasWndProc(
  67. HWND hWnd,
  68. UINT uMsg,
  69. WPARAM wParam,
  70. LPARAM lParam
  71. );
  72. int __stdcall wWinMain(
  73. _In_ HINSTANCE hInstance,
  74. _In_opt_ HINSTANCE hPrevInstance,
  75. _In_ LPWSTR lpCmdLine,
  76. _In_ int nShowCmd
  77. ) {
  78. const wchar_t CLASS_NAME[] = L"myVirtualSandbox Window Class";
  79. // 窗口类定义了几个窗口可能具有的行为。每个窗口必须与窗口类相关联。
  80. // 要注册窗口类,请填写“WNDCLASS”结构,然后调用“RegisterClass”函数。
  81. WNDCLASS applicationWndClass = { };
  82. applicationWndClass.lpfnWndProc = wndProc;
  83. applicationWndClass.hInstance = hInstance;
  84. applicationWndClass.lpszClassName = CLASS_NAME;
  85. if (!RegisterClass(&applicationWndClass))
  86. {
  87. return 0;
  88. }
  89. // 创建窗口。
  90. HWND hApplicationWnd = CreateWindow(
  91. CLASS_NAME, // 窗口类
  92. L"Learn to Program Windows", // 窗口文本
  93. WS_OVERLAPPEDWINDOW, // 窗口样式
  94. // 大小和位置
  95. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  96. NULL, // 父窗口
  97. NULL, // 菜单
  98. hInstance, // 实例句柄
  99. NULL // 附加应用程序数据
  100. );
  101. if (hApplicationWnd == NULL)
  102. {
  103. return 0;
  104. }
  105. ShowWindow(hApplicationWnd, nShowCmd);
  106. MSG msg = { };
  107. while (GetMessage(&msg, NULL, 0, 0) > 0)
  108. {
  109. TranslateMessage(&msg);
  110. DispatchMessage(&msg);
  111. }
  112. return 0;
  113. }
  114. LRESULT CALLBACK wndProc(
  115. HWND hWnd,
  116. UINT uMsg,
  117. WPARAM wParam,
  118. LPARAM lParam
  119. ) {
  120. switch (uMsg)
  121. {
  122. case WM_CREATE:
  123. {
  124. HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
  125. WNDCLASS canvasWndClass = { };
  126. canvasWndClass.lpfnWndProc = canvasWndProc;
  127. canvasWndClass.hInstance = hInstance;
  128. canvasWndClass.lpszClassName = L"myVirtualSandbox Canvas Class";
  129. RegisterClass(&canvasWndClass);
  130. // 以下循环遍历用户界面对象的容器。
  131. for (int i = 0; i < MyObjects.Objects.size(); ++i) {
  132. UiObjects::Object* pObject = MyObjects.Objects[i];
  133. pObject->hObjectWnd = CreateWindow(
  134. pObject->lpClassName, // 窗口类
  135. pObject->lpWindowName, // 窗口文本
  136. pObject->dwStyle, // 样式
  137. pObject->x, // 水平位置
  138. pObject->y, // 垂直位置
  139. pObject->Width, // 宽度
  140. pObject->nHeigth, // 高度
  141. hWnd, // 父窗口
  142. pObject->hMenu, // 无菜单
  143. hInstance,
  144. NULL // 指针不需要。
  145. );
  146. }
  147. break;
  148. }
  149. case WM_DESTROY:
  150. {
  151. PostQuitMessage(0);
  152. break;
  153. }
  154. // 要绘制窗口,必须通过窗口接收“WM_PAINT”消息。它由程序本身或操作系统发送。
  155. case WM_PAINT:
  156. {
  157. // “PAINTSTRUCT”的“rcPaint”成员返回一个指定绘制请求的矩形的左上角和右下角。
  158. PAINTSTRUCT paintStruct = { };
  159. HDC hDeviceContext = BeginPaint(hWnd, &
  160. <details>
  161. <summary>英文:</summary>
  162. Inside your `WM_CREATE` loop, you are assigning the new `HWND` to a *copy* of the `Object` from the vector. You are not updating the original `Object` in the vector.
  163. Change this:

UiObjects::Object Object = MyObjects.Objects[i];

  1. To this:

UiObjects::Object& Object = MyObjects.Objects[i];
^

  1. Also, note that `Canvas`, `Output`, etc are separate `Object`s than the ones stored in the `Objects` vector. So, `Output.hObjectWnd` etc are likewise not being updated by your `WM_CREATE` loop, either.
  2. ---
  3. **UPDATE**: Indeed, you are filling `Canvas`, `Output`, etc with data, and then pushing *copies* of those objects into your `Objects` vector. So, even if your `WM_CREATE` code were assigning the new `HWND`s to the `Objects` elements correctly, `Canvas`, `Output`, etc would still not get the `HWND`s correctly.
  4. To do what you are attempting, you need to change your `Objects` vector to hold `Object*` pointers instead of `Object` instances, eg:

#include <vector>
#include <windows.h>
#include <windowsx.h>

#using <System.dll>

const int CANVAS_HOR_OFFSET = 10;
const int CANVAS_VER_OFFSET = 10;
const int CANVAS_WIDTH = 640;
const int CANVAS_HEIGTH = 480;

const int OUTPUT_VER_OFFSET = 10;
const int OUTPUT_HEIGTH = 120;

static class UiObjects
{
public:
enum ObjectClass { Custom };

  1. struct Object {
  2. LPWSTR lpClassName;
  3. LPWSTR lpWindowName;
  4. DWORD dwStyle;
  5. LONG x;
  6. LONG y;
  7. LONG nWidth;
  8. LONG nHeigth;
  9. HMENU hMenu;
  10. HWND hObjectWnd;
  11. ObjectClass objectType;
  12. COLORREF color;
  13. };
  14. Object Canvas, Output;
  15. std::vector&lt;Object*&gt; Objects;
  16. UiObjects();

} MyObjects;

UiObjects::UiObjects() {
Canvas = {
L"myVirtualSandbox Canvas Class",
L"Canvas",
WS_VISIBLE | WS_CHILD | WS_BORDER,
CANVAS_HOR_OFFSET,
CANVAS_VER_OFFSET,
CANVAS_WIDTH,
CANVAS_HEIGTH,
NULL,
NULL,
ObjectClass::Custom
};
Objects.push_back(&Canvas);

  1. Output = {
  2. L&quot;EDIT&quot;,
  3. L&quot;Output&quot;,
  4. WS_VISIBLE | WS_CHILD | WS_BORDER,
  5. CANVAS_HOR_OFFSET,
  6. CANVAS_VER_OFFSET + CANVAS_HEIGTH + OUTPUT_VER_OFFSET,
  7. CANVAS_WIDTH,
  8. OUTPUT_HEIGTH,
  9. NULL,
  10. NULL,
  11. ObjectClass::Custom
  12. };
  13. Objects.push_back(&amp;Output);

}

LRESULT CALLBACK wndProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);

LRESULT CALLBACK canvasWndProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);

int __stdcall wWinMain(
In HINSTANCE hInstance,
In_opt HINSTANCE hPrevInstance,
In LPWSTR lpCmdLine,
In int nShowCmd
) {
const wchar_t CLASS_NAME[] = L"myVirtualSandbox Window Class";

  1. // A window class defines a set of behaviors that several windows
  2. // might have in common. Every window must be associated with a
  3. // window class. To register a window class, fill in a &quot;WNDCLASS&quot;
  4. // structure and call &quot;RegisterClass&quot; function afterwards.
  5. WNDCLASS applicationWndClass = { };
  6. applicationWndClass.lpfnWndProc = wndProc;
  7. applicationWndClass.hInstance = hInstance;
  8. applicationWndClass.lpszClassName = CLASS_NAME;
  9. if (!RegisterClass(&amp;applicationWndClass))
  10. {
  11. return 0;
  12. }
  13. // Create the window.
  14. HWND hApplicationWnd = CreateWindow(
  15. CLASS_NAME, // Window class
  16. L&quot;Learn to Program Windows&quot;, // Window text
  17. WS_OVERLAPPEDWINDOW, // Window style
  18. // Size and position
  19. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  20. NULL, // Parent window
  21. NULL, // Menu
  22. hInstance, // Instance handle
  23. NULL // Additional application data
  24. );
  25. if (hApplicationWnd == NULL)
  26. {
  27. return 0;
  28. }
  29. ShowWindow(hApplicationWnd, nShowCmd);
  30. MSG msg = { };
  31. while (GetMessage(&amp;msg, NULL, 0, 0) &gt; 0)
  32. {
  33. TranslateMessage(&amp;msg);
  34. DispatchMessage(&amp;msg);
  35. }
  36. return 0;

}

LRESULT CALLBACK wndProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
) {
switch (uMsg)
{
case WM_CREATE:
{
HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);

  1. WNDCLASS canvasWndClass = { };
  2. canvasWndClass.lpfnWndProc = canvasWndProc;
  3. canvasWndClass.hInstance = hInstance;
  4. canvasWndClass.lpszClassName = L&quot;myVirtualSandbox Canvas Class&quot;;
  5. RegisterClass(&amp;canvasWndClass);
  6. // The following loop iterates through the container of user
  7. // interface objects.
  8. for (int i = 0; i &lt; MyObjects.Objects.size(); ++i) {
  9. UiObjects::Object* pObject = MyObjects.Objects[i];
  10. pObject-&gt;hObjectWnd = CreateWindow(
  11. pObject-&gt;lpClassName, // Window class
  12. pObject-&gt;lpWindowName, // Window text
  13. pObject-&gt;dwStyle, // Styles
  14. pObject-&gt;x, // Horizontal position
  15. pObject-&gt;y, // Vertical position
  16. pObject-&gt;Width, // Width
  17. pObject-&gt;nHeigth, // Height
  18. hWnd, // Parent window
  19. pObject-&gt;hMenu, // No menu.
  20. hInstance,
  21. NULL // Pointer not needed.
  22. );
  23. }
  24. break;
  25. }
  26. case WM_DESTROY:
  27. {
  28. PostQuitMessage(0);
  29. break;
  30. }
  31. // To paint the window the &quot;WM_PAINT&quot; message has to be
  32. // received by the window. It is sent by either the program
  33. // itself or the operating system.
  34. case WM_PAINT:
  35. {
  36. // The &quot;rcPaint&quot; member of the &quot;PAINTSTRCUT&quot; structure
  37. // returns a &quot;RECT&quot; structure that specifies the upper
  38. // left and lower right corners of the rectangle in which
  39. // the painting is requested.
  40. PAINTSTRUCT paintStruct = { };
  41. HDC hDeviceContext = BeginPaint(hWnd, &amp;paintStruct);
  42. HBRUSH hBrush = CreateSolidBrush(RGB(66,66,66));
  43. // Paint application background.
  44. FillRect(
  45. hDeviceContext,
  46. &amp;paintStruct.rcPaint,
  47. hBrush
  48. );
  49. DeleteObject(hBrush);
  50. EndPaint(hWnd, &amp;paintStruct);
  51. break;
  52. }
  53. }
  54. return DefWindowProc(hWnd, uMsg, wParam, lParam);

}

LRESULT CALLBACK canvasWndProc(
HWND hCanvasWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
) {
switch (uMsg)
{

  1. case WM_LBUTTONDOWN:
  2. {
  3. POINT point = { };
  4. point.x = GET_X_LPARAM(lParam);
  5. point.y = GET_Y_LPARAM(lParam);
  6. System::Diagnostics::Debug::WriteLine(&quot;Clicked in Canvas.&quot;);
  7. HWND hOutputWnd = MyObjects.Output.hObjectWnd;
  8. // Check if hObjectWnd is a valid handle
  9. if (IsWindow(hOutputWnd))
  10. {
  11. SendMessage(hOutputWnd, WM_SETTEXT, NULL, (LPARAM)L&quot;Test.&quot;);
  12. }
  13. else {
  14. System::Diagnostics::Debug::WriteLine(&quot;Is not..&quot;);
  15. }
  16. break;
  17. }
  18. }
  19. return DefWindowProc(hCanvasWnd, uMsg, wParam, lParam);

}

  1. </details>

huangapple
  • 本文由 发表于 2023年7月13日 21:40:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76680052.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定