-1

I'm trying to learn how to create a window in win 32. This is as far as I have got with it. The problem I'm facing is I'm unable to create a window that can be resized by the user. I'm hoping that someone could help me solve this newbie problem.

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

Window gets created OK, but with this when I try to resize the window the window gets stuck to the mouse.

sandeep p
  • 21
  • 7
  • You have undefined behaviour, where is return in `WindowProc` for all return paths ? For `WM_SIZING` if processed, true must be returned. – rafix07 Sep 30 '21 at 06:52
  • @rafix07 I tried adding those return statements. still it has the same result. Have edited the code likewise. Please check – sandeep p Sep 30 '21 at 07:03
  • What do you expect from `if(!WM_CREATE)`??? `WM_CREATE` is a non null constant, so the condition is always false... But you should only process the WM_SIZE or WM_SIZING message for special processing. If you just want a window able to be resized just let `DefWindowProc` handle the messages and remove those lines from your own windoc procedure. – Serge Ballesta Sep 30 '21 at 07:18
  • @SergeBallesta I tried the ```DefWindowProc``` handle the size, but still has the same result. And as for the ``` WM_CREATE``` check, the window wasn't showing up when I ran the code, I assumed it was creating a window of size **0, 0**. But what you said made sense. So I have changed that to a different check and updated the code. Alas! I still don't have a resizable window. – sandeep p Sep 30 '21 at 07:34
  • If you are a beginner in WinAPI programming, you should start from examples from the WinAPI documentation. I suspect that your `CreateWindow` is not correct, hence your problems. Once you have a running code displaying a (not functional) window, but only then, you can try to add your own code. – Serge Ballesta Sep 30 '21 at 07:48
  • @SergeBallesta I already have a window. This is the same starter code they have in the docs. Just wanted to add a resizable functionality to it. – sandeep p Sep 30 '21 at 08:15
  • Do you want to resize it programmatically or by dragging a window corner? For the latter way, you should control the styles of your window. – Serge Ballesta Sep 30 '21 at 11:48
  • @SergeBallesta the latter(by dragging a window corner). I tried ```WS_OVERLAPPEDWINDOW``` , ```WS_SIZEBOX``` and ```WS_THICKFRAME``` but they all had the same result. That is when I click and drag a window border it gets stuck to the mouse pointer and no matter what I do it moves with the mouse. After clicking it like may be 100 times it lets go. – sandeep p Sep 30 '21 at 15:21
  • Close to a typo. The event loop should be `while (GetMessage(&msg, 0, 0, 0)) {...}`. (You have to read new messages from the queue...) – Serge Ballesta Oct 01 '21 at 12:26
  • @SergeBallesta but I need this window for a directX application. When I try ```GetMessage``` animation only plays when there is a window event like a mouse move or something. But as you said sizing only works with ```GetMessage``` not ``PeekMessage`` is there a work around for that? – sandeep p Oct 01 '21 at 13:53

1 Answers1

0

It appears that you want to to idle processing, meaning having some tasks done for your directX application when no event are present in the event loop.

There are 2 different ways of doing that:

  • dedicate a separate thread for background processing. It adds the complexity of multiprocessing, but allows to do all the processing as a single piece of code, and let the system affect time slices to the event loop and the background processing.

  • use a modified event loop that does chunks of background processing when no event are present. PeekMessage is the key here:

      ...
      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
              ...
          }
      }
    

    The nice point is that you do not need any multi-threading, but you have to explicitely split you backgroung processing in short time slices.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252