Windows Architecture

advertisement
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
message;
WPARAM
wParam;
LPARAM
lParam;
DWORD
time;
POINT
pt;
} MSG;
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 (nonclient area) and also parts your own
application is responsible for (client area).
Style of a Window



WS_OVERLAPPEDWINDOW - is used for the “main” window,
top level window. It can be resized and moved to any part of the
screen. There is no parent 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_OVERLAPPEDWINDOW
WS_POPUPWINDOW
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 4th 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, // left upper corner
CW_USERDEFAULT, // left upper corner
CW_USERDEFAULT, // width
CW_USERDEFAULT, // height
NULL,
// parent
NULL,
// menu
hInstance,
// program’s descriptor
NULL);
// 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);
Download