二路货 发表于 2018-8-25 15:06:55

windows程序设计子窗口问题

#include <windows.h>

#define DIVISIONS 5

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

TCHAR szChildClass[] = TEXT("CHECKER3_CHILD");

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
        static TCHAR szAppName[] = TEXT("MyWindows");
        HWND hwnd;
        MSG msg;
        WNDCLASS wndclass;

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

        if (!RegisterClass(&wndclass))
        {
                MessageBox(NULL, TEXT("这个程序需要在 Windows NT 才能执行!"), szAppName, MB_ICONERROR);
                return 0;
        }

    wndclass.lpfnWndProc = ChildWndProc;
    wndclass.cbWndExtra = sizeof(long);
    wndclass.hIcon = NULL;
    wndclass.lpszClassName = szChildClass;

    RegisterClass(&wndclass);

        hwnd = CreateWindow(szAppName,
                TEXT("鱼C工作室"),
                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;
    int cxBlock, cyBlock, x, y;

        switch (message)
        {
    case WM_CREATE:
      for (x = 0; x < DIVISIONS; x++)
      {
            for (y = 0; y < DIVISIONS; y++)
            {
                hwndChild = CreateWindow(szChildClass,
                  NULL,
                  WS_CHILD | WS_VISIBLE,
                  0, 0, 0, 0,
                  hwnd, (HMENU)(y << 8 | x),
                  (HINSTANCE)GetWindowLongPtr(hwnd, GWL_HINSTANCE),
                  NULL);
            }
      }
      return 0;

    case WM_SIZE:
      cxBlock = LOWORD(lParam) / DIVISIONS;
      cyBlock = HIWORD(lParam) / DIVISIONS;

      for (x = 0; x < DIVISIONS; x++)
      {
            for (y = 0; y < DIVISIONS; y++)
            {
                MoveWindow(hwndChild, x * cxBlock, y * cyBlock, cxBlock, cyBlock, TRUE);
            }
      }

    case WM_LBUTTONDOWN:
      MessageBeep(0);
      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)
{
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rect;

    switch (message)
    {
    case WM_CREATE:
      SetWindowLongPtr(hwnd, 0, 0);
      return 0;

    case WM_LBUTTONDOWN:
      SetWindowLongPtr(hwnd, 0, 1 ^ GetWindowLongPtr(hwnd, 0));
      InvalidateRect(hwnd, NULL, FALSE);
      return 0;

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

      GetClientRect(hwnd, &rect);
      Rectangle(hdc, 0, 0, rect.right, rect.bottom);

      if (GetWindowLongPtr(hwnd, 0))
      {
            MoveToEx(hdc, 0, 0, NULL);
            LineTo(hdc, rect.right, rect.bottom);
            MoveToEx(hdc, 0, rect.bottom, NULL);
            LineTo(hdc, rect.right, 0);
      }

      EndPaint(hwnd, &ps);
      return 0;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

上面是小甲鱼windows程序设计教程里的一个使用子窗口的程序Checker3

我想请教为什么创建的子窗口是执行 ChildWndProc函数里的代码而不是WndProc函数
子窗口和 ChildWndProc函数又是怎样联系起来的。

这是我第一次发提问帖悬赏,因此对应该放多少悬赏金不是很了解,还请多多指教!

TyCk 发表于 2018-8-25 15:06:56

wndclass.lpfnWndProc = ChildWndProc;
窗口执行哪个回调函数,取决于以上代码赋值指向的函数,命名都在自己,创建窗口时,是以wndclass为标准建立的,所以不同窗口执行的回调函数不一定相同,要看代码。
第二个疑问,一个意思,子窗口创建时,使用了wndclass的类名称,也就使用当前wndclass的各元素的具体值为标准建立窗口。
页: [1]
查看完整版本: windows程序设计子窗口问题