【问题标题】:Unable to resize win 32 window无法调整 win 32 窗口的大小
【发布时间】:2021-11-22 00:19:48
【问题描述】:

我正在尝试学习如何在 win 32 中创建一个窗口。这是我所掌握的。我面临的问题是我无法创建一个可以由用户调整大小的窗口。我希望有人可以帮助我解决这个新手问题。

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
std::string msg = "";
UINT width = 0;
UINT height = 0;
switch(uMsg)
{
case WM_SIZE:
   width = LOWORD(lParam);
   height = HIWORD(lParam);
   if(width<(height*600)/800) SetWindowPos(hWnd, NULL, 0, 0, width, height, SWP_NOMOVE|SWPNOZORDER);
   return true;
case WM_SIZING:
   width = LOWORD(lParam);
   height = HIWORD(lParam);
   if(width<(height*600)/800) SetWindowPos(hWnd, NULL, 0, 0, width, height, SWP_NOMOVE|SWPNOZORDER);
   return true;
case WM_DESTROY:
   PostQuitMessage(0);
   return true;
default:
   return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR lpCmdLine, INT nCmdShow)
{
    WNDCLASSEX wnd = {0};
    wnd.lpszClassName = "WindowLearn";
    wnd.hInstance = hInstance;
    wnd.lpfnWndProc = windowProc;
    wnd.cbSize = sizeof(WNDCLASSEX);
    wnd.style = CS_HREDRAW | CS_VREDRAW;

    RegisterClassEx(&wnd);
    HWND hWnd = CreateWindowEx(NULL, "WindowLearn", "WindowLearnChild", WS_THICKFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, 0, 0, 800, 600, NULL, NULL, hInstance, NULL);
    ShowWindow(hWnd, nCmdShow);

    MSG msg = {0};
    float pTime = 0.0f;
    BOOL result;
    while(msg.message != WM_QUIT)
    {
     TranslateMessage(&msg);
     DispatchMessage(&msg);
    }
}

窗口创建正常,但是当我尝试调整窗口大小时,窗口会卡在鼠标上。

【问题讨论】:

  • 您有未定义的行为,所有返回路径的 WindowProc 中的返回在哪里?对于WM_SIZING,如果已处理,则必须返回true。
  • @rafix07 我尝试添加这些返回语句。它仍然有相同的结果。同样编辑了代码。请检查
  • 你对if(!WM_CREATE)有什么期望??? WM_CREATE 是一个非空常量,所以条件始终为假……但您应该只处理 WM_SIZE 或 WM_SIZING 消息进行特殊处理。如果您只想调整窗口大小,只需让DefWindowProc 处理消息并从您自己的windoc 过程中删除这些行。
  • @SergeBallesta 我尝试了DefWindowProc 处理大小,但仍然有相同的结果。至于 ``` WM_CREATE``` 检查,当我运行代码时窗口没有出现,我认为它正在创建一个大小为 0, 0 的窗口。不过你说的有道理。因此,我已将其更改为不同的检查并更新了代码。唉!我仍然没有可调整大小的窗口。
  • 如果您是 WinAPI 编程的初学者,您应该从 WinAPI 文档中的示例开始。我怀疑您的 CreateWindow 不正确,因此您的问题。一旦你有一个正在运行的代码显示一个(非功能性)窗口,但只有这样,你才能尝试添加你自己的代码。

标签: c++ win32gui


【解决方案1】:

您似乎想要空闲处理,这意味着当事件循环中不存在任何事件时为您的directX应用程序完成一些任务。

有两种不同的方法:

  • 为后台处理指定一个单独的线程。它增加了多处理的复杂性,但允许将所有处理作为单个代码进行,并让系统影响事件循环和后台处理的时间片。

  • 使用修改后的事件循环,在没有事件存在时执行后台处理。 PeekMessage 是这里的关键:

      ...
      MSG msg = {0};
      for (;;)
      {
          if (PeekMessage(&msg, NULL, 0, 0, 0, 0) {
              if (! GetMessage(&msg, NULL, 0, 0, 0)) break; // msg is WM_QUIT
              TranslateMessage(&msg);
              DispatchMessage(&msg);
          }
          else {
              // do some idle processing for a short time
              // no event will be processing during that
              ...
          }
      }
    

    好处是您不需要任何多线程,但您必须明确地将背景处理拆分为短时间片。

【讨论】:

  • 非常感谢。我稍作修改。现在它是完美的。谢谢你。
猜你喜欢
  • 1970-01-01
  • 2014-02-19
  • 1970-01-01
  • 2020-01-26
  • 2015-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多