The Old-School Way: WinAPI
Back in the day, before fancy frameworks, we rolled up our sleeves and used the Windows API (WinAPI) directly. It was like cooking from scratch—no pre-made ingredients.
Here’s a basic example:
|
|
Its a simple app with a label, a text box, and a button.
When you type your name and hit the button, a message box will pop up saying, “Hello " with whatever you typed in the text edit field..
Breaking Down the Code
Includes and Defines: We include the
windows.h
header and define IDs for our button and text box.Window Procedure: This function,
WindowProc
, handles messages sent to our window. It’s like the brain of our application.WM_CREATE
: This message is sent when the window is created. We create a static label, an edit control (text box), and a button here.WM_COMMAND
: This is sent when an action occurs, like a button click. We check if our button was clicked, retrieve the text from the text box, and display it in a message box.WM_DESTROY
: Sent when the window is about to be destroyed. We post a quit message to end the application.
WinMain Function: The entry point of a Windows application.
- We define and register a window class.
- Create the window with
CreateWindowEx
. - Show the window using
ShowWindow
. - Enter the message loop, where we retrieve and dispatch messages.
The Message Loop
Ah, the message loop—a core concept in Windows applications. It’s like the heartbeat, keeping the app responsive.
|
|
For a deeper dive into message loops, check out this MSDN article.
Multi-Threading !!! ???
Everything is actually one thread, and when the messages are processed, your code is owning the whole GUI thread.
This is why Windows C apps can have a UI freeze if they spend too much time processing the message.
Also in early windows (1.0-3.1) the WHOLE OS shared one thread!
So if you got into an infinte loop while responding to a message, you can freeze the whole OS!.
This was a motivating factor in the development of Windows 95 and Windows Nt…
You still have a message pump and it still works like this, but if your app goes into an infinite loop, it freezes only your app and NOT the whole operating system…
The Challenge of Managing State
Now, while this approach works, managing data and state can get tricky. Imagine you have multiple instances of the same window. Each window uses the same window procedure, so how do you keep track of data for each instance?
A common trick was to use a dictionary-like data structure, mapping each window handle (HWND
) to its associated data. This way, you could look up the data based on the window that’s interacting with the user.
Enter C++ Frameworks: OWL, MFC, and later Qt
To make life easier, C++ frameworks like Object Windows Library (OWL) and Microsoft Foundation Class (MFC) were introduced. They allowed developers to associate instance data with C++ objects tied to windows, simplifying state management.
[!NOTE] Where is the message pump in the C++ Sample Code Below?
The message loop is handled internally by the framework, making it simpler for developers. There are ways to override and change it, but for most C++ Windows Gui apps this is not needed.
MFC Example
Here’s how you’d create a similar application using MFC:
|
|
OWL Example
|
|
Qt Example
|
|
The Evolution of C++ GUI Frameworks
Framework | Initial Release | Windows OS Released In Same Period |
---|---|---|
MFC | 1992 | Windows 3.1 (1992) |
OWL | 1991 | Windows 3.0 (1990) |
Qt | 1995 | Windows 95 (1995) |
Key Ideas
Concept | Description |
---|---|
Windows API | Old-school method for creating Windows apps in C. |
Message Loop | Handles Windows events/messages. |
Managing State | Tricky in C; often used dictionaries to map HWND to data. |
MFC, OWL, Qt | GUI frameworks making state management easier. |