sun_chuan 发表于 2024-9-16 00:50:54

win32子窗口问题

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

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

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

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

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


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

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

        HWND hwnd = NULL;
        MSG msg;
        WNDCLASS wc;
        wc.style = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc = WndProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = hInstance;
        wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wc.lpszMenuName = NULL;
        wc.lpszClassName = szAppName;

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

        hwnd = CreateWindow(szAppName, TEXT("数字时钟"),
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                NULL,
                NULL,
                hInstance,
                NULL);
       
        //分别再注册剩下的子窗口
        wc.lpszClassName = WndClsHourProcName;
        wc.lpfnWndProc = WndHourProc;
        wc.hIcon = NULL;
        RegisterClass(&wc);

        wc.lpszClassName = WndClsMinuteProcName;
        wc.lpfnWndProc = WndMinuteProc;
        wc.hIcon = NULL;
        RegisterClass(&wc);

        wc.lpszClassName = WndClsSecondProcName;
        wc.lpfnWndProc = WndSecondProc;
        wc.hIcon = NULL;
        RegisterClass(&wc);



        ShowWindow(hwnd, iCmdShow);

        UpdateWindow(hwnd);

        while (GetMessage(&msg, NULL, 0, 0))
        {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }

        return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;

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

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


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

                return 0;
        case WM_PAINT:
                hdc = BeginPaint(hwnd, &ps);
                GetClientRect(hwnd, &rect);

                EndPaint(hwnd, &ps);
                return 0;

        case WM_DESTROY://接受WM_DESTROY消息并发送WM_QUIT消息
                PostQuitMessage(0);
                return 0;
        }


        return DefWindowProc(hwnd, message, wparam, lparam);
}

//显示小时的子窗口过程
LRESULT CALLBACK WndHourProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
        //窗口的宽和高
        static int cxClient, cyClient;
        PAINTSTRUCT ps;
        HDC hdc;
        switch (message)
        {
        case WM_CREATE:
                cxClient = LOWORD(lparam);
                cyClient = HIWORD(lparam);
                return 0;
        case WM_PAINT:
                //用线标记自己
                hdc = BeginPaint(hwnd, &ps);
                Rectangle(hdc,0,0,cxClient,cyClient);
                EndPaint(hwnd, &ps);
                return 0;

        }

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

}

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

}

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

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

}
这段代码的效果应该是在窗口左边1/3处画一个方框,但是为什么实际上什么也没有画?

FishC 发表于 2024-9-16 00:57:48

看来你在实现一个包含子窗口的Win32应用程序时遇到了一些问题。下面是对你代码中几处问题的分析和修正建议,确保代码简洁易懂并且能够正常运行:

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

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

   static TCHAR szAppName[] = TEXT("ShowTime");

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

   LRESULT CALLBACK WndHourProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
   {
       switch (message)
       {
       case WM_CREATE:
         return 0;
       case WM_PAINT:
         return 0;
       case WM_DESTROY:
         return 0;
       default:
         return DefWindowProc(hwnd, message, wParam, lParam);
       }
   }

   LRESULT CALLBACK WndMinuteProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
   {
       switch (message)
       {
       case WM_CREATE:
         return 0;
       case WM_PAINT:
         return 0;
       case WM_DESTROY:
         return 0;
       default:
         return DefWindowProc(hwnd, message, wParam, lParam);
       }
   }

   LRESULT CALLBACK WndSecondProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
   {
       switch (message)
       {
       case WM_CREATE:
         return 0;
       case WM_PAINT:
         return 0;
       case WM_DESTROY:
         return 0;
       default:
         return DefWindowProc(hwnd, message, wParam, lParam);
       }
   }

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

   LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
   {
       switch (message)
       {
       case WM_DESTROY:
         PostQuitMessage(0);
         return 0;
       default:
         return DefWindowProc(hwnd, message, wParam, lParam);
       }
   }

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

以下是修正后的代码:

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

// 定义三个子窗口的ID
#define WNDHOUR_ID 0
#define WNDMINUTE_ID 1
#define WNDSECOND_ID 2

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

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

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

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

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

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

    HWND hwnd = NULL;
    MSG msg;
    WNDCLASS wc;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = szAppName;

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

    hwnd = CreateWindow(szAppName, TEXT("Digital Clock"),
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      NULL,
      NULL,
      hInstance,
      NULL);

    if (!hwnd)
    {
      MessageBox(NULL, TEXT("Window creation failed!"), szAppName, MB_OK);
      return 0;
    }

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

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

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

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

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }

    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_DESTROY:
      PostQuitMessage(0);
      return 0;
    default:
      return DefWindowProc(hwnd, message, wParam, lParam);
    }
}

LRESULT CALLBACK WndHourProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CREATE:
      return 0;
    case WM_PAINT:
      return 0;
    case WM_DESTROY:
      return 0;
    default:
      return DefWindowProc(hwnd, message, wParam, lParam);
    }
}

LRESULT CALLBACK WndMinuteProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CREATE:
      return 0;
    case WM_PAINT:
      return 0;
    case WM_DESTROY:
      return 0;
    default:
      return DefWindowProc(hwnd, message, wParam, lParam);
    }
}

LRESULT CALLBACK WndSecondProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CREATE:
      return 0;
    case WM_PAINT:
      return 0;
    case WM_DESTROY:
      return 0;
    default:
      return DefWindowProc(hwnd, message, wParam, lParam);
    }
}

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: win32子窗口问题