Does Delphi VCL use Windows messages? In Delphi you see that VCL controls have an event tab in the Object Inspector.
If you double click "OnKeyDown" there, then a procedure for that event is automatically added to your code. You may not know that Delphi receives and processes a windows system message (WM_KEYDOWN) to trigger this event. Windows uses a Message Process ("Window Proc" function) to give all created windows and Apps input for things that are happening in the windows system, this is a fundamental and very important method of the Windows System.
From keystroke to WM_KEYDOWN...
A keyboard key press generates an electrical contact which is turned into a scan code (device dependent identifier) for that keyboard. The keyboard device driver uses a scan code to translate (maps) it to a virtual-key code (device-independent value). After translating a scan code, the keyboard driver creates a window's system message that includes the scan code, the virtual-key code, and other information about that keystroke, and then places that message into the system message storage (waiting area or queue, since Windows is multitasking environment, it must wait for available processor cycles). Windows removes that keyboard message from the system message queue and posts it to the message queue of the thread with the focused window.
A program gets these keyboard messages out of its threads message queue by using a block of code called a "message loop" (see GetMessage loop below). When the message loop processes that message, it sends it to that window's "Window Proc" to use your code for that message or get default processing (see the WndMessageProc a "Window Proc" in the program below). Every window has this "Window Proc", that the OS calls whenever it has input (messages) for the window.
A "Window Proc" is a special function that receives and is responsible for processing all messages sent to the window. All windows have a registered Class, and every registered Class has a "Window Proc", and every window created with that class uses that same "Window Proc" to process and respond to messages.
The OS sends a message to a "Window Proc" along with the 2 message data integers LParam and WParam. The "Window Proc" then tests the message (Msg parameter) to see if it is one that it wants to use, it then may check the message window identifier (Handle, the hWnd parameter) or, to use the message, tests or translates the LParam and WParam. A "Window Proc" does not usually ignore a message. If it does not use and process a message, it should send the message to the system for its default processing. A "Window Proc" does this by calling the DefWindowProc function, which performs a default action and returns the default message result. The "Window Proc" should return this value as its own message function result. Many "Window Proc" functions use just a few messages (like WM_COMMAND or WM_CLOSE) and send the others on to the system by calling DefWindowProc(hWnd, Msg, WParam, LParam).
Because a "Window Proc" is shared by all windows belonging to the same class, it can process messages for several different windows. To identify the specific window affected by the message, a "Window Proc" can test the hWnd parameter and execute the code need for that window. But if there is only one window created for that class, you do not need to use the hWnd parameter.
Message Structure, the TMsg type
Whenever the user moves the mouse, clicks the mouse buttons, or types on the keyboard, the driver for that device converts the input into messages and places them in the system message queue. Windows removes the messages, one at a time in the order they were put in, from the system message queue, determines the destination window, and then sends them to the message queue of the thread that created the destination window. A thread's message queue gets all the mouse and keyboard messages for all the windows created by that thread. See your local API Help for GetMessage. The thread uses a GetMessage function to remove messages from its queue, usually in a while loop so the programs execution will continue until GetMessage is False. The system sends a message by filling a MSG (TMsg) structure and then places it in the message queue.
Information in MSG includes: the handle (hWnd) of the window for which the message is intended, the message identifier (message), the two message parameters (LParam and WParam), the time (time) the message was posted, and the mouse cursor position (pt).
type
PMsg = ^TMsg;
tagMSG = packed record
hwnd: HWND; // Handle of destination window
message: UINT; // message to be processed
wParam: WPARAM; // 4-Byte message information
lParam: LPARAM; // 4-Byte message information
time: DWORD; // the time the messages was posted
pt: TPoint; // screen location for mouse
end;
TMsg = tagMSG;
MSG = tagMSG;
end;
|
If you look at the next line:
WndMessageProc(hWnd: HWnd; Msg: UINT; WParam: WPARAM; LParam: LPARAM): UINT; stdcall;
you will see that it also has a Msg variable, but these are of different types, and would correspond to the TMsg.message type (UINT). I will use "Msg: TMsg" here, but in the following examples I will switch the variable's name to "mainMSG: TMsg" to help avoid confusing the many references to Msg.
A thread can send a message to its own message queue or to the queue of another thread by using the SendMessage or PostMessage function. These functions will be covered in the following chapters.
We can now move to a discussion on message loops and WndMessageProc function....
Next page > On message loops and WndMessageProc function > Page 1, 2, 3, 4, 5, 6
A guide to developing Delphi programs in raw Windows API: Next Chapter >>
>>
The TOC