鱼C论坛

 找回密码
 立即注册
查看: 765|回复: 1

win32子窗口问题

[复制链接]
发表于 2024-9-16 00:50:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include<windows.h>
  2. #include<windowsx.h>
  3. //定义下三个子窗口的id
  4. #define WNDHOUR_ID 0
  5. #define WNDMINUTE_ID 1
  6. #define WNDSECOND_ID 2

  7. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

  8. //显示小时的子窗口回调函数
  9. LRESULT CALLBACK WndHourProc(HWND, UINT, WPARAM, LPARAM);

  10. //显示分钟的子窗口回调函数
  11. LRESULT CALLBACK WndMinuteProc(HWND, UINT, WPARAM, LPARAM);

  12. //显示秒的子窗口回调函数
  13. LRESULT CALLBACK WndSecondProc(HWND, UINT, WPARAM, LPARAM);


  14.         //剩下仨子窗口类名
  15. //剩下仨子窗口类名
  16. static TCHAR WndClsHourProcName[] = TEXT("WndHorProc");
  17. static TCHAR WndClsMinuteProcName[] = TEXT("WndMinuteProc");
  18. static TCHAR WndClsSecondProcName[] = TEXT("WndSecondProc");

  19. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
  20. {
  21.         static PTCHAR szAppName = (PTCHAR)TEXT("ShowTime");

  22.         HWND hwnd = NULL;
  23.         MSG msg;
  24.         WNDCLASS wc;
  25.         wc.style = CS_HREDRAW | CS_VREDRAW;
  26.         wc.lpfnWndProc = WndProc;
  27.         wc.cbClsExtra = 0;
  28.         wc.cbWndExtra = 0;
  29.         wc.hInstance = hInstance;
  30.         wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  31.         wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  32.         wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  33.         wc.lpszMenuName = NULL;
  34.         wc.lpszClassName = szAppName;

  35.         if (!RegisterClass(&wc))
  36.         {
  37.                 MessageBox(NULL, TEXT("Need Windows NT!!!!"), TEXT("Error"), MB_OK);
  38.         }

  39.         hwnd = CreateWindow(szAppName, TEXT("数字时钟"),
  40.                 WS_OVERLAPPEDWINDOW,
  41.                 CW_USEDEFAULT,
  42.                 CW_USEDEFAULT,
  43.                 CW_USEDEFAULT,
  44.                 CW_USEDEFAULT,
  45.                 NULL,
  46.                 NULL,
  47.                 hInstance,
  48.                 NULL);
  49.        
  50.         //分别再注册剩下的子窗口
  51.         wc.lpszClassName = WndClsHourProcName;
  52.         wc.lpfnWndProc = WndHourProc;
  53.         wc.hIcon = NULL;
  54.         RegisterClass(&wc);

  55.         wc.lpszClassName = WndClsMinuteProcName;
  56.         wc.lpfnWndProc = WndMinuteProc;
  57.         wc.hIcon = NULL;
  58.         RegisterClass(&wc);

  59.         wc.lpszClassName = WndClsSecondProcName;
  60.         wc.lpfnWndProc = WndSecondProc;
  61.         wc.hIcon = NULL;
  62.         RegisterClass(&wc);



  63.         ShowWindow(hwnd, iCmdShow);

  64.         UpdateWindow(hwnd);

  65.         while (GetMessage(&msg, NULL, 0, 0))
  66.         {
  67.                 TranslateMessage(&msg);
  68.                 DispatchMessage(&msg);
  69.         }

  70.         return msg.wParam;
  71. }
  72. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
  73. {
  74.         HDC hdc;
  75.         PAINTSTRUCT ps;
  76.         RECT rect;

  77.         //窗口的宽和高
  78.         static int cxClient, cyClient;
  79.         //定义三个子窗口的句柄
  80.         static HWND hHourWnd, hMinuteWnd, hSecondWnd;
  81.         //用到的画笔和画刷
  82.         static HPEN hPen = CreatePen(PS_SOLID, 0, RGB(100, 100, 100));
  83.         static HBRUSH hBrush = CreateSolidBrush(RGB(100, 100, 100));

  84.         switch (message)
  85.         {
  86.         case WM_CREATE:
  87.                 //获取窗口宽高
  88.                 cxClient = LOWORD(lparam);
  89.                 cyClient = HIWORD(lparam);
  90.                 //创建那三个子窗口
  91.                
  92.                 hHourWnd   = CreateWindow(WndClsHourProcName  , NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU)WNDHOUR_ID,   (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), 0);
  93.                 hMinuteWnd = CreateWindow(WndClsMinuteProcName, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU)WNDMINUTE_ID, (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), 0);
  94.                 hSecondWnd = CreateWindow(WndClsSecondProcName, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU)WNDSECOND_ID, (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), 0);


  95.                 return 0;
  96.         case WM_SIZE:
  97.                 //把窗口移动到指定位置(平均分成三份)
  98.                 MoveWindow(hHourWnd, 0, 0, cxClient / 3, cyClient, FALSE);

  99.                 return 0;
  100.         case WM_PAINT:
  101.                 hdc = BeginPaint(hwnd, &ps);
  102.                 GetClientRect(hwnd, &rect);

  103.                 EndPaint(hwnd, &ps);
  104.                 return 0;

  105.         case WM_DESTROY://接受WM_DESTROY消息并发送WM_QUIT消息
  106.                 PostQuitMessage(0);
  107.                 return 0;
  108.         }


  109.         return DefWindowProc(hwnd, message, wparam, lparam);
  110. }

  111. //显示小时的子窗口过程
  112. LRESULT CALLBACK WndHourProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
  113. {
  114.         //窗口的宽和高
  115.         static int cxClient, cyClient;
  116.         PAINTSTRUCT ps;
  117.         HDC hdc;
  118.         switch (message)
  119.         {
  120.         case WM_CREATE:
  121.                 cxClient = LOWORD(lparam);
  122.                 cyClient = HIWORD(lparam);
  123.                 return 0;
  124.         case WM_PAINT:
  125.                 //用线标记自己
  126.                 hdc = BeginPaint(hwnd, &ps);
  127.                 Rectangle(hdc,0,0,cxClient,cyClient);
  128.                 EndPaint(hwnd, &ps);
  129.                 return 0;

  130.         }

  131.         return DefWindowProc(hwnd, message, wparam, lparam);

  132. }

  133. //显示分钟的子窗口过程
  134. LRESULT CALLBACK WndMinuteProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
  135. {
  136.         //窗口的宽和高
  137.         static int cxClient, cyClient;
  138.         return DefWindowProc(hwnd, message, wparam, lparam);

  139. }

  140. //显示秒的子窗口过程
  141. LRESULT CALLBACK WndSecondProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
  142. {
  143.         //窗口的宽和高
  144.         static int cxClient, cyClient;

  145.         return DefWindowProc(hwnd, message, wparam, lparam);

  146. }
复制代码
这段代码的效果应该是在窗口左边1/3处画一个方框,但是为什么实际上什么也没有画?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-9-16 00:57:48 | 显示全部楼层
看来你在实现一个包含子窗口的Win32应用程序时遇到了一些问题。下面是对你代码中几处问题的分析和修正建议,确保代码简洁易懂并且能够正常运行:

1. **包含头文件**:`#include` 和 `#include` 行末没有指明具体头文件,应该是 `#include <windows.h>` 和 `#include <tchar.h>`。

2. **字符串类型问题**:你的代码中使用了 `TCHAR` 类型,而在WinMain中 `szAppName` 应该是 `TCHAR` 类型而不是 `PTCHAR`:

  
  1. static TCHAR szAppName[] = TEXT("ShowTime");
复制代码


3. **未定义消息处理函数**:你已经声明了子窗口的回调函数,但没有定义。为确保程序可运行,先给出一个简单的定义:

  
  1. LRESULT CALLBACK WndHourProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  2.    {
  3.        switch (message)
  4.        {
  5.        case WM_CREATE:
  6.            return 0;
  7.        case WM_PAINT:
  8.            return 0;
  9.        case WM_DESTROY:
  10.            return 0;
  11.        default:
  12.            return DefWindowProc(hwnd, message, wParam, lParam);
  13.        }
  14.    }

  15.    LRESULT CALLBACK WndMinuteProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  16.    {
  17.        switch (message)
  18.        {
  19.        case WM_CREATE:
  20.            return 0;
  21.        case WM_PAINT:
  22.            return 0;
  23.        case WM_DESTROY:
  24.            return 0;
  25.        default:
  26.            return DefWindowProc(hwnd, message, wParam, lParam);
  27.        }
  28.    }

  29.    LRESULT CALLBACK WndSecondProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  30.    {
  31.        switch (message)
  32.        {
  33.        case WM_CREATE:
  34.            return 0;
  35.        case WM_PAINT:
  36.            return 0;
  37.        case WM_DESTROY:
  38.            return 0;
  39.        default:
  40.            return DefWindowProc(hwnd, message, wParam, lParam);
  41.        }
  42.    }
复制代码


4. **主窗口过程**:你也应该定义主窗口回调函数,否则会编译失败:

  
  1. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  2.    {
  3.        switch (message)
  4.        {
  5.        case WM_DESTROY:
  6.            PostQuitMessage(0);
  7.            return 0;
  8.        default:
  9.            return DefWindowProc(hwnd, message, wParam, lParam);
  10.        }
  11.    }
复制代码


5. **创建设备字体**: `MessageBox` 错误提示中应该直接使用 `TEXT` 宏包裹字符串,而不是 `szAppName`。

以下是修正后的代码:

  1. #include <windows.h>
  2. #include <tchar.h>

  3. // 定义三个子窗口的ID
  4. #define WNDHOUR_ID 0
  5. #define WNDMINUTE_ID 1
  6. #define WNDSECOND_ID 2

  7. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

  8. // 显示小时的子窗口回调函数
  9. LRESULT CALLBACK WndHourProc(HWND, UINT, WPARAM, LPARAM);

  10. // 显示分钟的子窗口回调函数
  11. LRESULT CALLBACK WndMinuteProc(HWND, UINT, WPARAM, LPARAM);

  12. // 显示秒的子窗口回调函数
  13. LRESULT CALLBACK WndSecondProc(HWND, UINT, WPARAM, LPARAM);

  14. // 子窗口类名
  15. static TCHAR WndClsHourProcName[] = TEXT("WndHourProc");
  16. static TCHAR WndClsMinuteProcName[] = TEXT("WndMinuteProc");
  17. static TCHAR WndClsSecondProcName[] = TEXT("WndSecondProc");

  18. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
  19. {
  20.     static TCHAR szAppName[] = TEXT("ShowTime");

  21.     HWND hwnd = NULL;
  22.     MSG msg;
  23.     WNDCLASS wc;
  24.     wc.style = CS_HREDRAW | CS_VREDRAW;
  25.     wc.lpfnWndProc = WndProc;
  26.     wc.cbClsExtra = 0;
  27.     wc.cbWndExtra = 0;
  28.     wc.hInstance = hInstance;
  29.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  30.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  31.     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  32.     wc.lpszMenuName = NULL;
  33.     wc.lpszClassName = szAppName;

  34.     if (!RegisterClass(&wc))
  35.     {
  36.         MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_OK);
  37.         return 0;
  38.     }

  39.     hwnd = CreateWindow(szAppName, TEXT("Digital Clock"),
  40.         WS_OVERLAPPEDWINDOW,
  41.         CW_USEDEFAULT,
  42.         CW_USEDEFAULT,
  43.         CW_USEDEFAULT,
  44.         CW_USEDEFAULT,
  45.         NULL,
  46.         NULL,
  47.         hInstance,
  48.         NULL);

  49.     if (!hwnd)
  50.     {
  51.         MessageBox(NULL, TEXT("Window creation failed!"), szAppName, MB_OK);
  52.         return 0;
  53.     }

  54.     // 再注册剩下的子窗口
  55.     wc.hIcon = NULL;

  56.     wc.lpszClassName = WndClsHourProcName;
  57.     wc.lpfnWndProc = WndHourProc;
  58.     RegisterClass(&wc);

  59.     wc.lpszClassName = WndClsMinuteProcName;
  60.     wc.lpfnWndProc = WndMinuteProc;
  61.     RegisterClass(&wc);

  62.     wc.lpszClassName = WndClsSecondProcName;
  63.     wc.lpfnWndProc = WndSecondProc;
  64.     RegisterClass(&wc);

  65.     ShowWindow(hwnd, iCmdShow);
  66.     UpdateWindow(hwnd);

  67.     while (GetMessage(&msg, NULL, 0, 0))
  68.     {
  69.         TranslateMessage(&msg);
  70.         DispatchMessage(&msg);
  71.     }

  72.     return msg.wParam;
  73. }

  74. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  75. {
  76.     switch (message)
  77.     {
  78.     case WM_DESTROY:
  79.         PostQuitMessage(0);
  80.         return 0;
  81.     default:
  82.         return DefWindowProc(hwnd, message, wParam, lParam);
  83.     }
  84. }

  85. LRESULT CALLBACK WndHourProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  86. {
  87.     switch (message)
  88.     {
  89.     case WM_CREATE:
  90.         return 0;
  91.     case WM_PAINT:
  92.         return 0;
  93.     case WM_DESTROY:
  94.         return 0;
  95.     default:
  96.         return DefWindowProc(hwnd, message, wParam, lParam);
  97.     }
  98. }

  99. LRESULT CALLBACK WndMinuteProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  100. {
  101.     switch (message)
  102.     {
  103.     case WM_CREATE:
  104.         return 0;
  105.     case WM_PAINT:
  106.         return 0;
  107.     case WM_DESTROY:
  108.         return 0;
  109.     default:
  110.         return DefWindowProc(hwnd, message, wParam, lParam);
  111.     }
  112. }

  113. LRESULT CALLBACK WndSecondProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  114. {
  115.     switch (message)
  116.     {
  117.     case WM_CREATE:
  118.         return 0;
  119.     case WM_PAINT:
  120.         return 0;
  121.     case WM_DESTROY:
  122.         return 0;
  123.     default:
  124.         return DefWindowProc(hwnd, message, wParam, lParam);
  125.     }
  126. }
复制代码


希望这能帮到你!如有任何其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-7 15:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表