Handling Window Resize
Introduction
Welcome back to Interactive Controls and Layouts. We are now in Lesson 5, and that means we have already built a small interface with a label, an edit box, and a button that moves text from one control to another. That is strong progress. In this lesson, we will make that interface react when the main window is resized.
Our goal is simple and practical: when the window becomes wider or narrower, the controls should adjust instead of staying frozen in place. To do that, we will handle WM_SIZE and update control positions with MoveWindow.
Why Resize Handling Matters
A window can usually be resized by the user, but child controls do not rearrange themselves automatically. If we do nothing, a larger window leaves awkward empty space, and a smaller window can make the layout feel cramped. So, just like in other UI systems, we need a layout rule.
For this lesson, our rule is intentionally simple:
- The label should stretch left to right.
- The edit box should also stretch left to right.
- The button should stay at a fixed size near the left side.
This is a basic form of responsive layout, and it gives us a clean first step into dynamic interfaces.
Understanding WM_SIZE
The new behavior begins with the resize message. Windows sends WM_SIZE whenever the client area changes size, which makes it the right place to recompute layout values.
lParam stores the new client dimensions. LOWORD(lParam) extracts the width, and HIWORD(lParam) extracts the height. Here we only use cx because this lesson adjusts horizontal layout. The commented cy line is still useful to see because it reminds us that vertical sizing information is available too. Also, this is the client size, not the full outer window size, so borders and the title bar are not included.
Looking Up Controls And Measuring Space
Moving Controls After Resize
With the handles and width ready, we can apply the new layout. This is the heart of the lesson: every resize event leads to new control positions and sizes.
MoveWindow updates both position and size in one call. The label and edit box keep the same x and y positions, but their width becomes usableW, so they stretch as the window width changes. The button behaves differently: it keeps a width of 120 and stays near the left edge. The final TRUE tells Windows to repaint the control after moving it. A similar result could also be achieved with SetWindowPos, but MoveWindow is very direct for this task.
Preserving Existing Interaction
The resize logic changes the layout, but it does not replace the behavior we built in the previous lesson. Our button still reads text from the edit control and writes it into the label when clicked.
This is a good example of separate responsibilities inside one window procedure. WM_SIZE manages where controls appear; WM_COMMAND manages what happens when the user interacts with them. The two cases work together cleanly. After resizing, the controls may be wider, but the text flow remains exactly the same: the button click reads from the edit box and updates the label.
Conclusion and Next Steps
In this lesson, we gave our interface a simple but very useful layout system. We kept the familiar control IDs, added a shared padding constant, handled WM_SIZE, read the new client width from lParam, and used MoveWindow to stretch the label and edit box while keeping the button fixed near the left side.
This pattern is small, but it teaches an important WinAPI idea: layout is often something we control manually in response to window messages. In the practice section ahead, we will strengthen that skill by reshaping controls ourselves and watching the interface adapt with confidence.
