【问题标题】:Button didn't show up when menu value is set and shows odd style when not set设置菜单值时按钮不显示,未设置时显示奇怪的样式
【发布时间】:2021-01-07 22:02:23
【问题描述】:

我想将特定窗口设置为按钮的父级,但我得到了预期的行为。

当设置CreateWindow() 上的hMenu 值时,按钮不显示:

CreateWindow(L"Button",
                            L"Click me!",
                            WS_TABSTOP,
                            20, 
                            50,
                            60,
                            90,
                            NULL, 
                            (HMENU)1, 
                            NULL, NULL); 

但是当我删除hMenu 参数时,按钮确实会显示出来,但样式很奇怪:

CreateWindow(L"Button",
                        L"Click me!",
                        WS_TABSTOP,
                        20, 
                        50,
                        60,
                        90,
                        NULL, 
                        NULL, 
                        NULL, NULL); 

我没有将主窗口的CreateWindow() 返回的HWND 传递给按钮的hwndParent,因为它们不是按那个顺序调用的。

以下代码是我真实代码的简化版本。

我错过了什么?

完整代码:

#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")

#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE

#include <windows.h>

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

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PWSTR pCmdLine, int nCmdShow) {

  MSG  msg = {0};
  WNDCLASSW wc = {0};

  wc.lpszClassName = L"Window";
  wc.hInstance     = hInstance;
  wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
  wc.lpfnWndProc   = WndProc;
  wc.hCursor = LoadCursor(0, IDC_ARROW);
  
  RegisterClassW(&wc);
  
  HWND
  hwndMainWindow = CreateWindow(wc.lpszClassName, L"Window",
                    WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                    CW_USEDEFAULT, CW_USEDEFAULT, 500, 350, 
                    NULL, NULL, hInstance, NULL);
    HWND hButton = CreateWindow(L"Button",
                                L"Click me!",
                            WS_TABSTOP,
                            20, 
                            50,
                            60,
                            90,
                            NULL, 
                            NULL, 
                            NULL, NULL); 

    SetParent(hButton, hwndMainWindow);
    ShowWindow(hButton, SW_SHOWNORMAL);
    UpdateWindow(hwndMainWindow);

  while (GetMessage(&msg, NULL, 0, 0))
  {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
  }
  
  return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

  switch(msg)
  {
      case WM_CLOSE:
        DestroyWindow(hwnd);
        break;

      case WM_DESTROY:
          PostQuitMessage(0);
          return 0;
  }

  return DefWindowProcW(hwnd, msg, wParam, lParam);
}

【问题讨论】:

    标签: c winapi button parent


    【解决方案1】:

    您没有在按钮上指定WS_CHILD 样式。 SetParent() 不会为您设置此样式。

    当您设置没有WS_CHILD 的窗口的“父级”时,实际上是在设置它的“所有者”。 Owner and Parent are not the same thing。另见A window can have a parent or an owner but not both

    您的按钮不会出现在主窗口中,因为该按钮不是主窗口的子窗口。

    因此,在创建按钮时,您需要包含WS_CHILD 样式。您还应该包含WS_VISIBLE 样式而不是使用ShowWindow()(除非您想创建最初隐藏的按钮)。并且您应该在创建时指定父窗口,而不是使用SetParent()

    您还应该将按钮创建移动到主窗口WndProc()WM_CREATE 处理程序中。

    试试这个:

    #pragma comment(lib, "user32.lib")
    #pragma comment(lib, "Comctl32.lib")
    #pragma comment(lib, "Gdi32.lib")
    
    #define WIN32_LEAN_AND_MEAN
    #define UNICODE
    #define _UNICODE
    
    #include <windows.h>
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PWSTR pCmdLine, int nCmdShow) {
    
      MSG  msg = {0};
      WNDCLASS wc = {0};
    
      wc.lpszClassName = L"Window";
      wc.hInstance     = hInstance;
      wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
      wc.lpfnWndProc   = WndProc;
      wc.hCursor       = LoadCursor(0, IDC_ARROW);
      
      RegisterClass(&wc);
      
      HWNDhwndMainWindow = CreateWindow(wc.lpszClassName, L"Window",
                               WS_OVERLAPPEDWINDOW,
                               CW_USEDEFAULT, CW_USEDEFAULT, 500, 350, 
                               NULL, NULL, hInstance, NULL);
    
      ShowWindow(hwndMainWindow, SW_SHOWNORMAL);
      UpdateWindow(hwndMainWindow);
    
      while (GetMessage(&msg, NULL, 0, 0))
      {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }
      
      return (int) msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
      switch(msg)
      {
          case WM_CREATE:
              CreateWindow(L"Button",
                           L"Click me!",
                           WS_CHILD | WS_VISIBLE | WS_TABSTOP,
                           20, 
                           50,
                           60,
                           90,
                           hwnd,
                           (HMENU)1, 
                           NULL, NULL); 
              break;
    
          case WM_COMMAND:
              if ((LOWORD(wParam) == 1) && (HIWORD(wParam) == BN_CLICKED)) {
                  MessageBox(hwnd, L"Yea, you clicked me!", L"Window", MB_OK);
                  return 0;
              }
              break;
    
          case WM_CLOSE:
              DestroyWindow(hwnd);
              break;
    
          case WM_DESTROY:
              PostQuitMessage(0);
              return 0;
      }
    
      return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-22
    • 1970-01-01
    • 1970-01-01
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    • 2013-11-01
    相关资源
    最近更新 更多