1. #include <Windows.h>
    2. #include <Windowsx.h>
    3. #include "resource.h"
    4. #ifdef _UNICODE
    5. #if defined _M_IX86
    6. #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
    7. #elif defined _M_X64
    8. #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
    9. #else
    10. #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
    11. #endif
    12. #endif
    13. // 保存以前的按钮回调函数,为了将消息传递回去
    14. WNDPROC OldButtonProc = nullptr;
    15. // 新的按钮窗口回调函数,用于处理按钮的消息
    16. INT_PTR CALLBACK ButtonProc(HWND hButton, UINT uMsg, WPARAM wParam, LPARAM lParam)
    17. {
    18. switch (uMsg)
    19. {
    20. // 按钮控件的点击事件实际上就是 WM_LBUTTONDOWN+UP
    21. case WM_LBUTTONUP:
    22. {
    23. MessageBox(hButton, L"WM_LBUTTONUP", L"控件", MB_OK);
    24. SetWindowLong(hButton, GWL_WNDPROC, (LONG)OldButtonProc);
    25. // 模拟消息的打包发送给父窗口,但是容易崩溃
    26. // SendMessage(GetParent(hButton), WM_COMMAND, MAKEWPARAM(IDC_BUTTON1, BM_CLICK), (LPARAM)hButton);
    27. break;
    28. }
    29. }
    30. // 将所有的按钮操作,都交还给原始的按钮回调函数来完成
    31. return OldButtonProc(hButton, uMsg, wParam, lParam);
    32. }
    33. // 对话框的回调函数,消息处理了返回 TRUE,没有处理返回 FALSE
    34. INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
    35. {
    36. switch (uMsg)
    37. {
    38. // 当用户点击了关闭按钮时产生的消息,对话框要求必须使用 EndDialog 退出
    39. case WM_CLOSE:
    40. {
    41. EndDialog(hDlg, 0);
    42. break;
    43. }
    44. // 对于标准控件,例如按钮,应该使用 WM_COMMAND 进行响应
    45. case WM_COMMAND:
    46. {
    47. if (LOWORD(wParam) == IDC_BUTTON1)
    48. {
    49. MessageBox(hDlg, L"WM_COMMAND", L"父窗口", MB_OK);
    50. // 如果按钮被点击了,我们将按钮的回调函数修改成自己的函数,返回修改前的内容
    51. OldButtonProc = (WNDPROC)SetWindowLong((HWND)lParam, GWL_WNDPROC, (LONG)ButtonProc);
    52. }
    53. break;
    54. }
    55. default:
    56. {
    57. return FALSE;
    58. }
    59. }
    60. return TRUE;
    61. }
    62. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    63. {
    64. // 1. 是实例句柄,用于标识资源所在的位置
    65. // 2. 资源的ID,大多数时候会使用 MAKEINTRESOURCE 进行转换
    66. // 3. 对话框的父窗口,NULL 表示桌面
    67. // 4. 回调函数,用于响应对话框产生的所有消息
    68. DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
    69. return 0;
    70. }

    image.png