sun_chuan 发表于 2024-8-22 22:08:16

win32子窗口求助

#include<windows.h>
#include<windowsx.h>
#include<strsafe.h>
//每行和每列格子数
#define LINE_COLUMN_BLOCK_COUNT 5
bool Range(int r, int min, int max);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
TCHAR* ChildWndClsName = (TCHAR*)TEXT("CHILD__");
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
        TCHAR* szAppName = (TCHAR*)TEXT("MyAppWindows");
        TCHAR* ChildWndClsName = (TCHAR*)TEXT("CHILD__");

        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);
        }

        wc.lpfnWndProc = ChildWndProc;
        wc.cbWndExtra =sizeof(long);
        wc.hIcon = NULL;
        wc.lpszClassName = ChildWndClsName;

        RegisterClass(&wc);

        hwnd = CreateWindow(szAppName, TEXT("我的窗口"),
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                NULL,
                NULL,
                hInstance,
                NULL);

        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)
{
        static HWND hwndChild;
        static int cxBlock, cyBlock, xIndex, yIndex;

        static int cxClient, cyClient;

        switch (message)
        {
        case WM_CREATE:

                for (size_t i = 0; i < LINE_COLUMN_BLOCK_COUNT; i++)
                {
                        for (size_t j = 0; j < LINE_COLUMN_BLOCK_COUNT; j++)
                        {
                                hwndChild = CreateWindow(ChildWndClsName, NULL,
                                        WS_CHILD | WS_VISIBLE,
                                        0,
                                        0,
                                        0,
                                        0,
                                        hwnd,
                                        (HMENU)(j << 8 | i),
                                        (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
                                        NULL);
                        }
                }
                return 0;


        case WM_SIZE:
                cxBlock = LOWORD(lparam) / LINE_COLUMN_BLOCK_COUNT;
                cyBlock = HIWORD(lparam) / LINE_COLUMN_BLOCK_COUNT;

                for (size_t i = 0; i < LINE_COLUMN_BLOCK_COUNT; i++)
                {
                        for (size_t j = 0; j < LINE_COLUMN_BLOCK_COUNT; j++)
                        {
                                MoveWindow(hwndChild, i * cxBlock, j * cyBlock, cxBlock, cyBlock, TRUE);
                        }
                }


                return 0;
        case WM_LBUTTONDOWN:
                MessageBeep(0);
                return 0;

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


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

LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;

        static int t,t0;
        switch (message)
        {
        case WM_CREATE:
                SetWindowLongPtr(hwnd, 0, 0);
                hdc = GetDC(hwnd);

                TextOut(hdc, 0, 0, TEXT("a"), 1);
                ReleaseDC(hwnd, hdc);
                return 0;
        case WM_LBUTTONDOWN:
                SetWindowLongPtr(hwnd, 0, (t0=!GetWindowLongPtr(hwnd, 0)));//在调试里面,这里t0明明是1
                hdc = GetDC(hwnd);

                t = GetWindowLongPtr(hwnd, 0);//但是在调试里面这里再获取的时候却莫名其妙变成0了???而且t0好像销毁不见了??
                ReleaseDC(hwnd, hdc);
                InvalidateRect(hwnd, NULL, FALSE);
                return 0;

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

                //画个矩形
                Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);

                //画两条对角线
                if (GetWindowLongPtr(hwnd, 0))
                {
                        MoveToEx(hdc, 0, 0, NULL);
                        LineTo(hdc, rect.right, rect.bottom);

                        MoveToEx(hdc, rect.right, 0, NULL);
                        LineTo(hdc, 0, rect.bottom);
                }
                EndPaint(hwnd, &ps);
                return 0;
        }

        return DefWindowProc(hwnd, message, wparam, lparam);
}请问为什么点击窗口没有反应?还有我在注释里面的两行问题,有没有大佬帮忙解答一下

FishC 发表于 2024-8-22 22:08:35

FishC的鱼油,您好!根据您提供的代码,我注意到有几个问题需要修改和完善,特别是最后部分节点的完整性问题。我们来集中解决这些问题。

1. **未正确关闭 `WM_CREATE` `case` 语句:**
一个显而易见的问题是代码在 `for` 循环中的 `CreateWindow` 调用之后中断,缺少逻辑完成句,特别是 `WM_CREATE` 消息处理未正确结束。

2. **变量名覆盖问题:**
局部变量 `ChildWndClsName` 在 `WinMain` 中重新声明,覆盖了全局变量 `ChildWndClsName`,这会导致后面代码使用局部变量,而不是全局变量,建议移除或避免重新声明。

3. **资源清理以及未处理 `PostQuitMessage`:**
在窗口销毁时,PostQuitMessage 没有进行处理。

下面是更改与补充后的代码:

#include <windows.h>

// 每行和每列格子数
#define LINE_COLUMN_BLOCK_COUNT 5
bool Range(int r, int min, int max);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);

TCHAR* ChildWndClsName = (TCHAR*)TEXT("CHILD__");

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    TCHAR* szAppName = (TCHAR*)TEXT("MyAppWindows");

    HWND hwnd;
    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);
      return 0;
    }

    wc.lpfnWndProc = ChildWndProc;
    wc.cbWndExtra = sizeof(long);
    wc.hIcon = NULL;
    wc.lpszClassName = ChildWndClsName;

    if (!RegisterClass(&wc))
    {
      MessageBox(NULL, TEXT("Internal Error: Child Window Registration"), TEXT("Error"), MB_OK);
      return 0;
    }

    hwnd = CreateWindow(szAppName, TEXT("我的窗口"),
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      NULL,
      NULL,
      hInstance,
      NULL);

    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)
{
    static HWND hwndChild;
    static int cxBlock, cyBlock, xIndex, yIndex;
    static int cxClient, cyClient;

    switch (message)
    {
    case WM_CREATE:
      for (size_t i = 0; i < LINE_COLUMN_BLOCK_COUNT; i++)
      {
            for (size_t j = 0; j < LINE_COLUMN_BLOCK_COUNT; j++)
            {
                hwndChild = CreateWindow(
                  ChildWndClsName, NULL,
                  WS_CHILD | WS_VISIBLE,
                  0, 0, 0, 0,
                  hwnd,
                  (HMENU)(j * LINE_COLUMN_BLOCK_COUNT + i),
                  (HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
                  NULL
                );

                if (!hwndChild)
                {
                  MessageBox(hwnd, TEXT("Child Window Creation Failed"), TEXT("Error"), MB_OK);
                  return -1;
                }
            }
      }
      return 0;

    case WM_SIZE:
      cxClient = LOWORD(lparam);
      cyClient = HIWORD(lparam);

      cxBlock = cxClient / LINE_COLUMN_BLOCK_COUNT;
      cyBlock = cyClient / LINE_COLUMN_BLOCK_COUNT;

      for (size_t i = 0; i < LINE_COLUMN_BLOCK_COUNT; i++)
      {
            for (size_t j = 0; j < LINE_COLUMN_BLOCK_COUNT; j++)
            {
                MoveWindow(
                  hwndChild,
                  j * cxBlock, i * cyBlock,
                  cxBlock, cyBlock,
                  TRUE
                );
            }
      }
      return 0;

    case WM_DESTROY:
      PostQuitMessage(0);
      return 0;
    }
    return DefWindowProc(hwnd, message, wparam, lparam);
}

LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    switch (message)
    {
    case WM_PAINT:
    {
      PAINTSTRUCT ps;
      HDC hdc = BeginPaint(hwnd, &ps);
      RECT rect;
      GetClientRect(hwnd, &rect);
      DrawText(hdc, TEXT("Child Window"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
      EndPaint(hwnd, &ps);
      return 0;
    }
    }
    return DefWindowProc(hwnd, message, wparam, lparam);
}

请根据需要对代码进行调整并检查运行结果。希望能够帮助到您!

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