Transcript Windows Architecture
Windows Architecture
Common User Interface
Share UI functional libraries Built-in dispatcher for windows / menus
Windows Messaging
Windows Messaging =
Queued Input
Usual DOS program would use
polling
Windows: all the messages are transferred to the responsible applications. No need to control and check the state of a device every single moment of time. All you have to do is to design the response.
Independent Input/Output
DOS: each application should have its own device driver Windows: shared GDI (Graphics Device Interface). The interface is responsible for the output. You should not think about the monitor’s model used.
Event-driven Programming
Usual DOS program: the main thing is
main()
. Hierarchical structure. Windows application: all the functions are designed to respond to the events.
Events: mouse-click, timer, functions etc.
It is not necessary to process all the events. We can let Windows respond to them.
Ways of messages get generated
Hardware level: interrupts. Responsible is: ISR (Interrupt Service Routine) ISR: input data gets formatted and stored Another internal subroutine then extracts the data stored in registers and places it into the messages into hardware queue of messages.
Each event forces a new message to be created. Sometimes a set of events is reflected in one single message.
Type of queue FIFO (first-in, first-out).
Objectives of a message
Messaging is a fundamental mechanism of communication between programs inside Windows. All the messages are generated by one of 3 different sources: 1. Hardware level events: kbd, mouse, timer. Often are called
enqueued events
since they always go through the hardware queue of messages.
Objectives of a message
2. Dispatcher of windows. Messages are generated to reflect user actions – windows resize operation, cursor movement, menu selection. An example of an event sent more often –
WM_PAINT
which means that the current window should be refreshed (redrawn).
Objectives of a message
3. Individual windows can also send messages to other windows. Example: a directive for a text window to be cleared:
WM_SETTEXT
. Text window uses the same mechanism to report about text changed event by sending
EN_CHANGE
.
All the messages use mnemonic identifiers like
WM
(Windows Message),
EN
(Edit Notification) etc. All them (constants) are defined in
windows.h
Extraction of windows.h
#define WM_NULL
#define WM_CREATE
#define WM_DESTROY
#define WM_MOVE
#define WM_SIZE
…
0x0000 0x0001 0x0002 0x0003 0x0005
What the message actually is
The message of Windows is a C structure called
MSG
that includes 6 different fields:
Typedef struct tag MSG { HWND hwnd; UINT WPARAM message; wParam; LPARAM DWORD POINT } MSG; lParam; time; pt;
Description of a message
HWND hwnd
– each window in Windows has its own unique identifier. The value in this field represent the window descriptor the message is addressed to.
UINT message
– unsigned integer that keeps the identifier of a message (like
WM_PAINT
), representing the type of a message
Description of a message
WPARAM wParam
– an additional information that can be found useful to process a message. For example it can keep the identifier of an item in a menu selected. Each type of a message uses this field on its own purpose. 32 bits.
LPARAM lParam
– is used like
wParam
, having extra information. 64 bits. Depending on the type of a message one (wParam) or both (wParam and lParam) can be used.
Description of a message
DWORD time
– the value of the system clock of the moment the message was generated. This is used to place the message into the right position in the queue.
POINT pt
cursor’s position on the screen when the message was generated.
Windows Programming Ideology
Using Software Developer’s Kit (SDK) which means use of Windows API MFC
Windows Application’s Architecture
Each application is a collection of windows What the window is? A square area that has properties and other areas.
Client and non-client areas –
each window has parts Windows is responsible for (
non client area
) and also parts your own application is responsible for (
client area
).
Style of a Window
WS_OVERLAPPEDWINDOW
screen. There is no
parent
is used for the “main” window, top level window. It can be resized and moved to any part of the window for such type of window.
WS_POPUPWINDOW
– is used for dialog windows. They usually have parent window, but can “flow” in front of the parent window and can be moved to any part of the screen.
WS_CHILDWINDOW
– is used for control elements. Command button is a child window the same way text window or scrolling bars are. It can be moved only in parent window’s area.
WS_POPUPWINDOW WS_OVERLAPPEDWINDOW WS_CHILDWINDOW
How does the program work (API)
1. Initialization 2. Realization 3. Calling the loop of messages 4. Responding to the messages Three first are always done by
WinMain()
. It is the entry point for any Windows program. The 4 th task is implemented by function called
WndProc()
(actually can you call it the way you want, it does no matter.
Inside the
WinMain()
- Initialization
To define the class of the window choose the name of it like “MyWindowClass”. Then it should be associated with the style of a window (for example
WS_OVERLAPPEDWINDOW
) and with the procedure that will process all the messages for window class. When this is done, Windows will use your definition of a class as a template during the creation of an instance of your class on demand.
Inside the
WinMain()
- Initialization
To define a class an instance of
WNDCLASS
should be created first.
WNDCLASS
is a structure that incorporated different field that need to be filled. The most important fields are name of the class and address of the function (that will be created) to organize the responding action to the messages. Below is a short instance of such a code:
static char MyClassName [] = “MyClass”; WNDCLASS wc; wc.lpfnWndProc = WndProc; wc.lpszClassName = MyClassName; // … all the other fields omitted
Inside the
WinMain()
- Initialization
WndProc
was the address of the procedure that will receive the Windows message. Other 8 fields should be filled as well (like icon, mouse cursor type etc.) Windows takes the control. The process is called
registration of a class
and is performed by Windows API function
RegisterCalss()
:
RegisterClass ($wc);
Inside the
WinMain()
- Realization
After the class is registered the window has to be created by calling API function
CreateWindow()
that receives 11 parameters. If
CreateWindow()
terminates successfully then the window’s descriptor is returned. Descriptor is used for future operations with window.
An example follows
Inside the
WinMain()
- Realization
HWND hwnd = CreateWindow ( MyClassName, “ Hi Mom “, // title WS_OVERLAPPEDWINDOW, // style CW_USERDEFAULT, CW_USERDEFAULT, // left upper corner // left upper corner CW_USERDEFAULT, CW_USERDEFAULT, NULL, NULL, hInstance, NULL); // width // height // parent // menu // program’s descriptor // extra data
Inside the
WinMain()
- Realization
When the main window is created, couple more things should be done before your program can be executed. Initially your window is not visible.
ShowWindow (hwnd, nCmdShow); hwnd
- is the descriptor that was returned back by
CreateWindow()
. Second parameter,
nCmdShow
is one of the parameters, that
WinMain()
receives by itself. Values define is the window active, minimized or maximized.
WM_PAINT
has the lowest priority and it can take some time before the window will be actually shown by default. To force this action:
UpdateWindow (hwnd);
Which tell the Windows “do it now!”
Inside the
WinMain()
– The loop
Almost done but not yet – the message dispatching should be set since the program will take the messages and process them.
GetMessage()
. When it is called, it receives adm address of the
MSG
structure. If there is a message waiting in the line for
your
program to be processed, windows makes all the fields of
MSG
filled and the
WinMain()
gets the TRUE value. On the other hand if the
WM_QUIT
is waiting in the queue then
GetMessage()
returns FALSE and the program is terminated.
Inside the
WinMain()
– The loop
In general the loop will look like follows:
MSG msg; while(GetMessage($msg,NULL,0,0,)) { // process messages } // terminate the process if the // GetMessage() has returned // us WM_QUITE message
The real code
TranslateMessage ($msg); DispatchMessage ($msg);