Windows programs with masm32
14 Sep 2015In a previous post I wrote about the basics of getting a program written and compiled using masm32 for the windows platform. In today’s post, I’m going to walkthrough the basic anatomy of a windows program that play the key roles in your application.
This information is language agnostic. It’s standard windows programming knowledge that I’ll present in the form of assembly programming with masm32. By the end of this blog post, you’ll have a good starting point (in boilerplate code) for any program that you want to write with masm32.
The basic pieces
In any windows program (using the Win32 API) there are some basic pieces that you’ll see most of the time.
- Main entry point (WinMain)
- Window creation
- Window handler procedure (WNDPROC)
- Message pump
These basic building blocks that you’ll see in just about all windows applications.
WinMain
This is your application’s main entry point. It’s analogous to the main
function that you use when writing applicatioons in C/C++. From Microsoft’s site:
The user-provided entry point for a graphical Windows-based application.
Its function signature takes the following form:
This definition needs to be translated from C into assembly language. The HINSTANCE
, LPSTR
and int
data types all reduce down to DWORD
easily, so:
Being at the assembly layer, we’re exposed a little earlier in the process than what WinMain
affords us, so we have extra work to do in terms of getting our application running. We as the implementers of the program need to invoke WinMain
directly as this is not done for us.
GetModuleHandle
allows us to fill the hInstance
parameter and GetCommandLine
gives us lpszCmdLine
. hPrevInstance
, according to the documentation is always NULL
and nShowCmd
is an SW_
series value that controls how our main application window is shown.
Window creation
The creation of a window is broken down into a few smaller steps:
- Register a window class
- Create the window
- Show the window
Registering a window class is just filling out the WNDCLASSEX
structure and calling RegisterClassEx
. Registering a windows class establishes base or common attributes about a window that you can re-use in subsequent calls to CreateWindow
.
The macro szText
is setup to allow you to ad-hoc define string variables where ever you need to. The rest of this is mainly filling out the structure and finally registering it. Setting lpfnWndProc
has special significance to us here as we’ll go on to describe WNDPROC
and its role in the application.
WindowProc callback function
When an application receives messages from the operating system, it handles this information through the window procedure. The window procedure interface is defined as:
Again, translating this into assembly:
The message pump
Finally, the thing that’s keeping our application alive is the message pump. It’s a loop of GetMessage
, TranslateMessage
and DispatchMessage
.
All together now
The following gist is all of the pieces assembled in a basic application that’s runnable (once assembled and linked).