At the heart of every Windows program (and most operating systems), is an infinitely repeating loop we call the message loop and a data structure we call a message queue (some languages/operating systems use the term event instead of message). The message queue is managed by the operating system - it adds new events that the GUI needs to know about (i.e. a mouse click that occurred within the GUI) to this queue. The message loop is often embedded in the main function of the program, and continuously checks for new messages in the queue. When it finds one, it processes the message. Once the message is processed, the message loop again checks for a new message. The basic code for such a loop looks something like this:
function main initialize() while message != quit message := get_next_message() process_message(message) end while end function
This approach works well for most GUIs as once the program is drawn initially (during the
initialize() function), the appearance of the GUI will not change until it responds to some user action.
In a WPF or Windows Forms application, this loop is buried in the
class that the
App inherits from. Instead of writing the code to process these system messages directly, this class converts these messages into C# events, which are then consumed by the event listeners the programmer provides. We’ll look at these next.