The Big Picture: Everything Is a Window
The word "Windows" is not an accident. To the operating system, almost everything you see on screen is a window: the big program frame, but also each button, each text box, each scroll bar and even the desktop itself. A window here means a rectangle on screen that can receive input and draw itself.
A program such as Notepad is really a family of windows:
Notepad main window (top-level)
├── Menu bar
├── Edit box (the big white text area) ← a child window
├── Vertical scroll bar ← a child window
└── Status bar ← a child window
Each of these has its own identity number, its own owner, and its own code that decides how it reacts. This section explains those three ideas.
3.1 HWND: The Window Handle
What it is: An HWND (Handle to a WiNDow) is the identity number Windows gives to each window. A handle is a ticket number: you do not get the real object, only a token that you hand back to the OS and say "do this to that window".
Why not give programs a direct pointer? Because the real window object lives inside the kernel's memory (see 3.4 and Section 4), which a normal program must not touch. The handle is the safe way. This is the same idea you met for files and processes (Chapter 8 and Chapter 23).
| Idea | Plain meaning |
|---|---|
| Top-level window | A window with no parent: the big frame in the taskbar |
| Child window | Lives inside a parent: a button, a text box. It moves and closes with its parent |
| Owner window | A pop-up that belongs to another window (a dialog belongs to the app window that opened it) |
| Z-order | The stacking order of windows, from front to back. Think of papers on a desk: the top paper hides the ones below |
| Active / focus window | The window currently receiving your keyboard (Section 6) |
The desktop window is the parent of all top-level windows. Think of it as the table the papers lie on.
Seeing HWNDs yourself. PowerShell can list the main window of each running program:
Get-Process | Where-Object MainWindowTitle -ne '' | Select-Object Name, MainWindowTitle, MainWindowHandle| Column | Meaning |
|---|---|
Name | The process (program) name |
MainWindowTitle | The text in its title bar |
MainWindowHandle | The HWND, shown as a number. It changes every time the window is created, so it is only an identifier for now |
A process with no visible window (a service, a background tool) does not appear in this list. That is also why a program can be running in Task Manager but have no taskbar button.
Optional: Spy++ is a free tool that ships with Visual Studio. It shows the whole tree of windows and the messages sent to them. You do not need it. If you have Visual Studio installed, it is a great way to see the picture above for real.
3.2 Window Classes and Window Procedures
What it is: Before a program can create a window, it must register a window class. A class is a template: it says what type of window this is (its look, its cursor, its default colour) and, most importantly, which function handles its events.
That function is called the window procedure (often written WndProc). It is the window's "brain". Every message sent to the window arrives there.
Register class "MyApp" ─────► holds a pointer to WndProc
│
▼
Create window of class "MyApp" ─────► gets an HWND
│
▼
Messages for that HWND ─────► Windows calls WndProc(hwnd, message, ...)
Windows ships with built-in classes for the common controls, so programs do not need to write their own:
| Built-in class | What it is |
|---|---|
Button | Push button, checkbox, radio button |
Edit | Text box |
Static | A label |
ListBox, ComboBox | Lists and drop-downs |
You will also see class names in tools such as Notepad, CabinetWClass (a File Explorer folder window), and Shell_TrayWnd (the taskbar). Names like these are internal and can change between versions, so do not build anything important on them.
A WndProc is just a function with a big decision list:
| Message the procedure receives | What it usually does |
|---|---|
WM_PAINT | "Draw yourself." The window repaints its content |
WM_LBUTTONDOWN | "The left mouse button was pressed on you." |
WM_KEYDOWN, WM_CHAR | "A key went down", "this is the character typed" |
WM_SIZE | "You were resized." |
WM_CLOSE | "Someone asked you to close." |
(WM_ stands for Window Message.) If the procedure does not care about a message, it passes it to the default handler, DefWindowProc, which gives standard behaviour such as dragging by the title bar. That is why even a lazy program gets a working frame for free.
3.3 The Message Queue (One per Thread)
What it is: Windows is event-driven. A program does not run top to bottom and stop. It sits and waits for messages: "mouse moved", "key pressed", "time to repaint", "window closed". A message is a small package of numbers: which window, what happened, plus extra detail.
Every thread (Chapter 10) that creates windows gets its own message queue: an in-order waiting list of messages for the windows that thread owns. Only that thread should handle them.
The heart of nearly every Windows program is the message loop:
while ( GetMessage(&msg) ) // wait here until a message arrives
{
TranslateMessage(&msg); // turn key presses into characters
DispatchMessage(&msg); // call the right window's WndProc
}
In plain words:
┌──────────────────────────────────┐
│ Thread's message queue │
│ [mouse] [key] [paint] [timer] │
└───────────────┬──────────────────┘
│ GetMessage takes the next one
▼
DispatchMessage
│ finds the target HWND's class
▼
WndProc( hwnd, message ... )
│ runs the program's reaction
▼
back to GetMessage and wait again
Why it matters: "Not Responding". If a thread owning windows is busy doing a long job and stops calling GetMessage, nobody empties its queue. Clicks and paints pile up. The window cannot redraw. After a few seconds Windows notices that the window has not handled its messages and marks it "Not Responding", usually by fading the frame and showing the "waiting" cursor.
| What you see | Why |
|---|---|
| A window turns white or gray and its title says "(Not Responding)" | Its thread stopped pumping messages (busy or stuck) |
| It recovers after a while | The long job finished and the loop started again |
| It never recovers | The thread is waiting forever (a bug) or the process is truly stuck |
The fix for programmers: do heavy work on another thread and keep the window's thread free to pump messages. That is why well-made programs stay smooth while they load or save.
Important: "Not Responding" does not mean the whole PC is frozen. Other programs have their own threads and queues, so they keep working. (Do not try to cause a hang in the lab. Just know what it means.)
3.4 Where the Window Actually Lives (A Preview of Section 4)
Windows, handles and queues are managed by the window manager part of Windows. Programs reach it through user32.dll (Chapter 22 and Chapter 23). The data about each window, its position, its class, its owner thread and its queue, is kept in kernel memory, which normal programs cannot touch. So the program holds only the HWND. When it calls a function such as MoveWindow(hwnd, ...), user32.dll makes a call into the kernel, which validates the handle and does the work. Section 4 shows who draws the result.
Your program Kernel (window manager)
┌─────────────────┐ ┌─────────────────────────┐
│ holds: HWND 7A2 │ ─ MoveWindow ─►│ window object 7A2: │
│ (just a number) │ via │ class, position, owner │
└─────────────────┘ user32.dll │ thread, message queue │
└─────────────────────────┘
Summary
| Term | Plain meaning |
|---|---|
| Window | Any rectangle that can draw and receive input: frames, buttons, text boxes |
| HWND | The handle (ticket number) identifying one window |
| Top-level / child | Independent frame / part inside a parent |
| Z-order | Front-to-back stacking of windows |
| Window class | A template for windows, including which procedure handles them |
| WndProc | The function that reacts to messages for a window |
| WM_ message | A small event note: paint, click, key, close |
| Message queue | Per-thread waiting list of messages |
| Message loop | GetMessage then DispatchMessage, repeated |
| Not Responding | The thread stopped pumping messages |