Sie sind auf Seite 1von 46

Module 1

Windows Programming Components of Windows API- Distinction with ordinary programs Event Driven Programming WinMain Function Creating Windows Message loop Window procedures - Menus & Buttons Drawing on Windows.

Windows Programming
When IBM-PC was launched in 1981 the operating system for the PC was MS-DOS(Microsoft Disk Operating System) . But it was not sufficient for sophisticated graphical environment.

Why the windows came into existence?

1. Though MSDOS offers good functionality, the text interface was boring and difficult for a common user .Also it was easy to remember the convoluted DOS commands. Windows offered a Visual Interface or a GUI which was intuitive to use. Windows programs have keyboard and mouse interface.

2. In order to meet more demands of the user the size of the programs get increased in DOS based programs. It was realized that most programs uses the some common features are repeating. Eg. Menu management This problem was addressed in Windows programming by making menu management logic part of OS rather than part of programs. Since such common chores stopped getting out of hand. become the OSs responsibility the program sizes

3. Every DOS program has different user interface which user was required to get used to before he can start getting work out of the program. Eg: Wordstar,

Lotus 1-2-3 different types of menus Windows offers a consistent user interface. So we can say that the look and feel of all windows based programs was same which allow the user took little time in learning how to interact with the program. 4. DOS supports serial multitasking :- In this one program is stopped temporarily while another is allowed to execute .At any given time only one task is run Eg: Human working on a computer stop his work to answer a ringing phone and the having finished with call, switches back to the computer. Windows supports Multitasking, ie, the user could run several programs simultaneously in memory. Non-preemptive multitasking (Windows 3.1):- Windows did not use the system timer to allocate processing time among the various programs running under the system. The programs themselves have to give up the control , so the that other programs could run. Unless one program gave up the control the other programs could not run. Preemptive multitasking(Windows 95):- Programs themselves can split into multiple threads of execution that seen to run concurrently.

Difference between Windows programs and ordinary programs( here we are comparing with DOS programs). 1. Windows programs wait till it receives a message from windows OS about the occurrence of an event, like hitting the key from keyboard or clicking a mouse button. MS DOS programs calls the OS to get the user input.

2. Windows environment has built-in support for all hardware, so no need to bother about the details of hardware they are running on. OS will take care of it. So the windows programmer can spend time in writing code for the application rather than for hardware on which the application is going to run.. DOS programs have to bother about the details of the hardware they are running on. Also these programs are wrote directly to video

memory and printer port.

3. Windows calls a program running under it by calling the window procedure which is a part of every windows program. Window places messages in queue notifying the program about the occurrence of an event. The messages form queue are handled by the window procedure . DOS never calls a program running under it.

4. Windows offer preemptive multitasking and non-preemptive multitasking DOS offers serial multitasking.

Windows Software Development Kit (SDK) It is a set of tools designed to help C programmers to create windows application. It consists of the following elements. i. A large set of book describing functions messages, structures, macros and resources. ii. Tools including a dialog editor and image editor. iii. A help document ( including on line) files. iv. A set of windows libraries and header files. v. A sample set of programs in C.

Windows Application Programming Interface(API)


It is simply a set of functions that are part of Windows OS. Programs can be created by simply calling the functions present in API. Programmer doesn't have to bother about the internal working of the functions. By just knowing the function protype and return value, he can invoke the API functions. Windows API are of 2 basic varieties API for 16-bit windows ( Win16 API ) API for 32-bit windows ( Win32

API )

Difference between Win16 and Win32 API Win16 is a 16 bit API that was created for 16 bit processors and it relies on 16 bit values eg: Windows 3.1. Win32 is a 32 bit API created for 32 bit CPU and it relies on 32 bit values eg: Windows NT, Windows 95.

Win16 and Win32 API ar similar in most respects. Win16 API can be considered as the subset of Win32 .

NB:- Win32 for 64 bit Windows: previously known as Win64, version of API targeted for 64 bit versions of windows namely windows XP professional x64 , Windows server 2003 x64 etc . The 64 bit are just two more supported platforms within NT architecture so both 32 bit and 64 bit versions of an application can still be accommodated from single base.

Components of API As its core relies on the 3 main components to provide most of the functionality of windows.

Win16 API USER.EXE

Win 32 API USER32.DLL

Description The USER component is responsible for window management , menus, cursors, communications, timer etc

GDI.EXE

GDI32.DLL

It take care of the user interface and graphics drawing including windows meta files, bitmaps, device

contexts and fonts. KRNL386.EXE KERNEL32.DLL The KERNEL component handle the low level function of memory , task and resource management that are heart of windows.

Although the Win16 versions of these components have .EXE extensions , they are actually all DLL and cannot execute on their own. Functionalities provided by windows API

1. Base Services Provide access to the fundamental resources available to a Windows system like file systems, devices, processes and threads, access to the Windows registry, and error handling. These functions reside in kernel.exe, krnl286.exe or
krnl386.exe files on 16-bit Windows, and kernel32.dll and advapi32.dll on

32-bit Windows.

2. Graphics Device Interface Provide the functionality for outputting graphical content to monitors, printers and other output devices. It resides in gdi.exe on 16-bit Windows, and gdi32.dll on 32-bit Windows.

3. User Interface Provides the functionality to create and manage screen windows and most basic controls, such as buttons and scrollbars, receive mouse and keyboard input, and other functionality associated with the GUI part of Windows. This functional unit resides in user.exe on 16-bit Windows, and user32.dll on 32-bit Windows. Since Windows XP versions, the basic controls reside in comctl32.dll, together

with the common controls (Common Control Library).

4. Common Dialog Box Library Provides applications the standard dialog boxes for opening and saving files, choosing color and font etc. The library resides in a file called commdlg.dll on 16-bit Windows, and comdlg32.dll on 32-bit Windows. It is grouped under the User Interface category of the API.

5. Common Control Library Gives applications access to some advanced controls provided by the operating system. These include things like status bars, progress bars, toolbars and tabs. The library resides in a DLL file called commctrl.dll on 16-bit Windows, and
comctl32.dll on 32-bit Windows. It is grouped under the User Interface

category of the API.

6. Windows Shell Component of the Windows API allows applications to access the functionality provided by the operating system shell, as well as change and enhance it.

7. Network Services Give access to the various networking capabilities of the operating system. Its sub-components include NetBIOS, Winsock, NetDDE, RPC and many others.

8. Advanced services Provides access to functionalities that isan addition to the kernel. Include things are like the windows registry, shutdown/restart the system, start/stop/create a window service, manage user accounts.

Web related APIs


The Internet Explorer web browser also uses many APIs that are considered as part of the Windows API. Internet Explorer has been an integrated component of the operating

system since Windows 98, and provides web related services to applications. The integration will stop with Windows Vista. It provides: An embeddable web browser control, contained in shdocvw.dll and
mshtml.dll.

The URL monitor service, held in urlmon.dll, which provides COM objects to applications for resolving URLs. Applications can also provide their own URL handlers for others to use. A library for assisting with multi-language and international text support (mlang.dll). DirectX Transforms, a set of image filter components. XML support (the MSXML components). Access to the Windows Address Book.

What is DLL? DLL is an executable binary file that provides a shared library of functions, objects and resources All the API functions are contained in DLL. The function contained in DLL can be linked during execution. These functions can be shared between several applications running in Windows. Since linking is done dynamically the functions do not become part of the executable files .As a result the size of EXE files do not go out of hand.

Importance of DLL Sharing common code between different executable files. Breaking an application into component parts to provide a way to easily upgrade applications components. Keeping resource data out of an applications executable , but still readily

accessible to an application.

NB:- DLL provides a way for a process to call a function that is not part of its
executable code. The executable code for the function is located is a DLL, which contains one or more function that are compiled, linked and stored separately from the process that use them.

Programming Models

1) Procedural Programming Model

Traditional programming model in which flow of program execution follows a predefined path set down by the programmers. Eg: In a C program execution begins with the first line in the function named main and ends when main returns. In between main might call other functions and these functions might call even more functions and these functions might call even more functions, but ultimately it is the program- not the operating system that determines what gets called and when

2) Sequence Driven Programming

The OS simply executes the program and then waits for it to finish. If the program desires, it can take help of the OS to do jobs like file opening, saving, printing etc.

3) Event Driven programming

Windows programming model In this an application on execution set up variables and structure an perform other

initializations . Once this is over the activity ceases. Windows application just sits there, waiting for the user input in the form of mouse click or a keystroke. As soon as the user provides this input, a series of events follows and application respond to the events.

Windows Programming Model

Event driven programming. In this an application on execution set up variables and structure an perform other initializations . Once this is over the activity ceases. Windows application just sits there, waiting for the user input in the form of mouse click or a keystroke. As soon as the user provides this input, a series of events follows and application respond to the events.

Fig: Windows Programming model

Windows programs operate differently. They use the eventdriven programming model illustrated in Figure , in which applications respond to events by processing messages sent by the operating system. An event could be a keystroke, a mouse click, or a command for a window to repaint itself, among other things. The entry point for a Windows program is a function named WinMain, but most of the action takes place in a function known as the window procedure. The window procedure processes

messages sent to the window. WinMain creates that window and then enters a message loop, alternately retrieving messages and dispatching them to the window procedure. Messages wait in a message queue until they are retrieved. A typical Windows application performs the bulk of its processing in response to the messages it receives, and in between messages, it does little except wait for the next message to arrive.
The message loop ends when a WM_QUIT message is retrieved from the message queue, signaling that it's time for the application to end. This message usually appears because the user selected Exit from the File menu, clicked the close button (the small button with an X in the window's upper right corner), or selected Close from the window's system menu. When the message loop ends, WinMain returns and the application terminates. The window procedure typically calls other functions to help process the messages it receives. It can call functions local to the application, or it can call API functions provided by Windows. API functions are contained in special modules known as dynamic-link libraries, or DLLs. The Win32 API includes hundreds of functions that an application can call to perform various tasks such as creating a window, drawing a line, and performing file input and output. In C, the window procedure is typically implemented as a monolithic function containing a large switch statement with cases for individual messages. The code provided to process a particular message is known as a message handler. Messages that an application doesn't process are passed on to an API function named DefWindowProc, which provides default responses to unprocessed messages.

Messages, Messages, and More Messages


Where do messages come from, and what kinds of information do they convey? Windows defines hundreds of different message types. Most messages have names that begin with the letters "WM" and an underscore, as in WM_CREATE and WM_PAINT. These messages can be classified in various ways, but for the moment classification is not nearly as important as realizing the critical role messages play in the operation of an application. The following table shows 10 of the most common messages. A window receives a WM_PAINT message, for example, when its interior needs repainting. One way to characterize a Windows program is to think of it as a collection of message

handlers. To a large extent, it is a program's unique way of responding to messages that gives it its personality.

Common Windows Messages Message WM_CHAR WM_COMMAND Sent When A character is input from the keyboard. The user selects an item from a menu, or a control sends a notification to its parent. WM_CREATE WM_DESTROY WM_LBUTTONDOW N WM_LBUTTONUP WM_MOUSEMOVE WM_PAINT WM_QUIT WM_SIZE The left mouse button is released. The mouse pointer is moved. A window needs repainting. The application is about to terminate. A window is resized. A window is created. A window is destroyed. The left mouse button is pressed.

A message manifests itself in the form of a call to a window's window procedure. Bundled with the call are four input parameters: the handle of the window to which the message is directed, a message ID, and two 32-bit parameters known as wParam and lParam. The window handle is a 32-bit value that uniquely identifies a window. Internally, the value references a data structure in which Windows stores relevant information about the window such as its size, style, and location on the screen. The message ID is a numeric value that identifies the message type: WM_CREATE, WM_PAINT, and so on. wParam and lParam contain information specific to the message type. When a WM_LBUTTONDOWN message arrives, for example, wParam holds a series of bit flags identifying the state of the Ctrl and Shift keys and of the mouse buttons. lParam

holds two 16-bit values identifying the location of the mouse pointer when the click occurred. Together, these parameters provide the window procedure with all the information it needs to process the WM_LBUTTONDOWN message.

C- Under Windows

Windows includes all sorts of built-in functions and data. For example, it include functions with the ability to draw text in different size and styles using font data. Windows application make use of these built in functions and do not need to supply the program logic to do these tasks. The application programs end up smaller than then they would be if each program had to include all that logic. This leads to several advantages: Application program consumes less space. All application programs tends to have the same look and feel because they are using the same built-in logic to draw text, display menus, etc. In addition to these advantages, the fundamental advantage is that the windows allows many programs to operate at the same time. Eg: Controlling of the calculator program using mouse. Communication between the windows OS and the application is established by message passing. When the user click the mouse button over the x,y co-ordinate on the calculator window, then windows will send a message to the calculator program that a user event has occurred and do what ever is possible. To pass the message data to the program, window write the information into a memory area for each running program. As soon as windows write message data into the memory, windows allows the program to execute its instruction. The program reads the message data from the memory block, decides what to do and return control back to windows. Message Cycle:- It allows windows to send message to any number of programs in memory. Each application program have unique message memory locations.

Structure of a windows program Windows program basically does 2 things: Perform initial activities when the program is first loaded into memory. - Activities consist of creating the program's own window and startup activities, such as setting aside some memory space.

Process messaging from windows. The first step is creating the program's own window, which is the piece of the screen that the program will control. Application programs will only write inside their own window, not in other programs windows or on the background of the screen. In an application window several programs are coexist on the same screen(Fig ).

Elements of windows program (Code and Resources) A application program contains of both Instructions and static data. A static data is any portion of the program that is not executed as machine installations and which does not change as the program executes. eg data to create font , character string etc.... .

Fig : Structure of Windows

Dynamic data is differ from static data and is stored in separate file in which the program reads and writes. Windows programs handle the static data separately from the program code, and it represent the static data as Resource data or Resources. By separating static codes from program code , the windows use a standard C/C++ compiler to create the code portion the windows program and they only had to write a Resources compiler to use. Advantages of separating code from resource data create the specialized resources that windows programs

Reduce memory demand Making programs more portable Note

A programmer can work on a programs logic but a designer works on how the programs looks.

Hungarian Notation

Hungarian notation is a naming convention in computer programming, in which the name of a variable indicates its type . In Hungarian notation, a variable name starts with one or more lower-case letters which are mnemonics for the type or purpose of that variable, followed by whatever the name the programmer has chosen; this last part is sometimes distinguished as the given name. The first character of the given name can be capitalized to separate it from the type indicators. The original Hungarian notation, which would now be called Apps Hungarian, was invented by Charles Simonyi, Chief Architect of Microsoft. Hungarian notations used in windows programming are: b or fused as a prefix for booleans (f stands for flag). c - used as a prefix to chars.1 n - used as a prefix to shorts. h - used as a prefix for a handle. Handles in Win32 are numbers used to identify resources or windows. They are not pointers or pointers to pointers. Think of

them as ID numbers. l - used as a prefix to a long. w - used as a prefix to a word. dw - used as a prefix to a double word. s - used as a prefix to a string.

sz - used as a prefix to a null-terminated string.2 p - used as a prefix to a pointer. lp - used as a prefix to a long pointer fn - used as a prefix to function parameters.

Program Instances Programs generally consist of two elements: code and data. When you run a program twice the data will be different for each (e.g. paint programs will open two different images) but the code will be the same. Windows saves memory by only loading the code once and creating program "instances" instead. Each instance is just a case of the program running, usually with it's own window. Instances share the same code but are given a unique data space to work with.

Calling Conventions (standards) Calling conventions describe the interface of called code: The order in which parameters are allocated ( may be left to right or right to left). Where parameters are placed (pushed on the stack or placed in registers) . Which registers may be used by the function . Whether the caller or the callee is responsible for unwinding the stack on return. VC++ supports several different calling conventions for function calling, they are _cdecl _stdcall _fastcall _thiscall

Flowchart - Working of Windows Program A windows program contains a WinMain() function, that is the entry point into the windows program. This function initializes certain values such as background,icons to be

used in windows to be created. Each window is registered using Register Class Function. When CreateWindow is called, WM_CREATE message or event is automatically created and passed on to the function WndProc, where the message is processed using a switch case structure. The message loop or while loop in WinMain() that receives the user action as message. The message processed by message loop are termed as Queued message. eg:Maximizing the windows, clicking etc .. . The message loop passes the message to the WinProc() where they are processed. Buttons , scrollbars etc are termed as child window, which are created when WM_CTEATE message is processed.

Fig 1.3 Working of Windows Program

Program Entry Point.


WinMain()

The WinMain function is the entry point of the application. When a user double clicks, Windows carries out some initialization code then passes control to

this function. Its just like main() in C. In this function the application is set up and then enter a loop that will continue until the application is closed. i.e. The WinMain function is the conventional name for the user-provided entry point for a Microsoft Windows-based application. Syntax:int WINAPI WinMain( HINSTANCE hInstance, LPSTR lpCmdLine, int nCmdShow ); HINSTANCE hPrevInstance,

It receives 4 parameters: I. hInstance: It is the instance handle for running application. Windows creates a unique ID number when the application starts .if we start more than one instances of a program each will have a unique instance handle. II. hPrevInstance : More than one copy of the same instance can run at the same time. If another copy is started, hPrevInstance will contain the hInstance value for the last copy started. If this is the only instance of the application running, hPrevInstance will be zero. III. lpszCmdLine : A pointer to the character string containing the command line arguments passed to the program. This is similar to to the argv, argc parameters to main() . IV. iCmdShow: An integer value that is passed to the function .This number tells the program whether the window it creates should appears minimized or maximized when first displayed. . This parameter can be one of the following values. o SW_HIDE - Hides the window and activates another window. o SW_MAXIMIZE - Maximizes the specified window.

o SW_MINIMIZE - Minimizes the specified window and activates the next top-level window in the Z order. o SW_RESTORE -Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when restoring a minimized window. o SW_SHOW -Activates the window and displays it in its current size and position. o SW_SHOWMAXIMIZED - Activates the window and displays it as a maximized window. o SW_SHOWMINIMIZED -Activates the window and displays it as a minimized window. o SW_SHOWMINNOACTIVE -Displays the window as a minimized window. This value is similar to SW_SHOWMINIMIZED, except the window is not activated. o SW_SHOWNA -Displays the window in its current size and position. This value is similar to SW_SHOW, except the window is not activated. o SW_SHOWNOACTIVATE -Displays a window in its most recent size and position. This value is similar to SW_SHOWNORMAL, except the window is not made active. o SW_SHOWNORMAL -Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.

NB:- HINSTANCE, LPSTR are macros which are defined in windows .h.
WINAPI resolves to _stdcall which is used foe all windows API calls ( WINAPI is defined in WINDEF.H)

Windows Programming, SDK-Style


If you haven't programmed Windows in C before, it's instructive to see what the source code for a simple program looks like. The program listed creates a window and responds to WM_PAINT messages by drawing an ellipse in the window's upper left corner. This code is similar to the source code you'll find in books such as Charles Petzold's Programming Windows (1998, Microsoft Press) and other books that teach Windows programming in C. Example 1
#include <windows.h>

LONG WINAPI WndProc (HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { WNDCLASS wc; HWND hwnd; MSG msg;

wc.style = 0; wc.lpfnWndProc = (WNDPROC) WndProc; address wc.cbClsExtra = 0; bytes wc.cbWndExtra = 0; bytes wc.hInstance = hInstance; wc.hIcon = LoadIcon (NULL, IDI_WINLOGO); wc.hCursor = LoadCursor (NULL, IDC_ARROW);

// Class style // Window procedure

// Class extra

// Window extra

// Instance handle // Icon handle // Cursor handle

wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); // Background color wc.lpszMenuName = NULL; wc.lpszClassName = "MyWndClass"; // Menu name // WNDCLASS name

RegisterClass (&wc);

hwnd = CreateWindow ( "MyWndClass", "SDK Application", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hInstance, NULL ); // WNDCLASS name // Window title // Window style // Horizontal position // Vertical position // Initial width // Initial height // Handle of parent window // Menu handle // Application's instance handle // Window-creation data

ShowWindow (hwnd, nCmdShow); UpdateWindow (hwnd);

while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessage (&msg); } return msg.wParam; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc;

switch (message) {

case WM_PAINT: hdc = BeginPaint (hwnd, &ps); Ellipse (hdc, 0, 0, 200, 100); EndPaint (hwnd, &ps); return 0;

case WM_DESTROY: PostQuitMessage (0); return 0; } return DefWindowProc (hwnd, message, wParam, lParam); }

WinMain begins by calling the API function RegisterClass to register a window class. The window class defines important characteristics of a window such as its window procedure address, its default background color, and its icon. These and other properties are defined by filling in the fields of a WNDCLASS structure, which is subsequently passed to RegisterClass. An application must specify a window class when it creates a window, and a class must be registered before it can be used. That's why RegisterClass is called at the outset of the program. Keep in mind that a WNDCLASStype window class is not the same as a C++ window class. The term window class will refer to C++ classes derived from MFC's CWnd class. Once the WNDCLASS is registered, WinMain calls the all-important CreateWindow function to create the application's window. The first parameter to CreateWindow is the name of the WNDCLASS from which the window will be created. The second parameter is the text that will appear in the window's title bar. The third specifies the window style. WS_OVERLAPPEDWINDOW is a commonly used style that creates a top-level window with a resizing border, a title bar, a system menu, and buttons for minimizing, maximizing, and closing the window. The next four parameters specify the window's initial position and size. CW_USEDEFAULT tells Windows to use default values for both. The final four parameters specify, in order, the handle of the window's parent window (HWND_DESKTOP for an application's main window); the handle of the menu

associated with the window, if any; the application's instance handle (a value that lets the programmer differentiate between the program itself and the modulesthat is, DLLs that it loads); and a pointer to application-specific window-creation data. I could easily devote a section of this book to CreateWindow and its parameters, but as you'll see later, MFC hides much of this detail inside the class library. A typical MFC application doesn't have a WinMain function (at least not one you can see), and it doesn't call RegisterClass or CreateWindow. The window that CreateWindow creates is not initially visible on the screen because it was not created with the WS_VISIBLE style. (Had it been used, WS_VISIBLE would have been combined with WS_OVERLAPPEDWINDOW in the call to CreateWindow.) Therefore, WinMain follows CreateWindow with calls to ShowWindow and UpdateWindow, which make the window visible and ensure that its WM_PAINT handler is called immediately. Next comes the message loop. In order to retrieve and dispatch messages, WinMain executes a simple while loop that calls the GetMessage, TranslateMessage, and DispatchMessage API functions repeatedly. GetMessage checks the message queue. If a message is available, it is removed from the queue and copied to msg; otherwise, GetMessage blocks on the empty message queue until a message is available. msg is an instance of the structure MSG, whose fields contain pertinent message parameters such as the message ID and the time at which the message was placed in the queue. TranslateMessage converts a keyboard message denoting a character key to an easier-to-use WM_CHAR message, and DispatchMessage dispatches the message to the window procedure. The message loop executes until GetMessage returns 0, which happens only when a WM_QUIT message is retrieved from the message queue. When this occurs, WinMain ends and the program terminates. Messages dispatched with DispatchMessage generate calls to the window procedure WndProc. The sample program processes just two message types, WM_PAINT and WM_DESTROY; all other messages are passed to DefWindowProc for default processing. A switch-case block inspects the message ID passed in the message parameter and executes the appropriate message handler. The WM_PAINT handler calls

the BeginPaint API function to obtain a device context handle before painting begins and the EndPaint API function to release the handle when painting is finished. In between, the Ellipse API function draws an ellipse that is 200 pixels wide and 100 pixels high. A device context handle is the "magic cookie" that permits a Windows application to draw on the screen. Without it, functions such as Ellipse won't work. The WM_DESTROY handler calls the PostQuitMessage API function to post a WM_QUIT message to the message queue and ultimately cause the program to terminate. The WM_DESTROY message is sent to a window just before it is destroyed. A top-level window must call PostQuitMessage when it receives a WM_DESTROY message, or else the message loop will not fall through and the program will never end.

Example 2 of a Windows program with extended version


#include <windows.h>

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MessageBox (NULL, "Hello World! This is my first WIN32 program", "Lesson 1", MB_OK); return 0; }

Output

Lets break down the code. #include <windows.h> All Windows programs must include the header file windows.h. This file has the definitions of Windows system calls or the WinAPI. The WinAPI has everything necessary for programming under windows. WinMain (..) This is the entry point of a windows application. This is like the main() of a console based application. WinMain is declared as,
int WINAPI WinMain( HINSTANCE hInst, instance */ HINSTANCE hPrevInstance,/* Handle to the previous instance */ LPSTR lpCmdLine, line arguments */ int nCmdShow); window */ /* show state of the /* pointer to command /* Handle to the current

The parameters of WinMain are self-explainatory, except perhaps nCmdShow. nCmdShow tells you in what manner you are expected to display this window (Maximized, Minimized, etc). We haven't used any of these parameters in this lesson, but we'll see their uses in the coming lessons.

MessageBox(..) This is a windows function which displays a messagebox. The MessageBox function is declared as,
int MessageBox( HWND hWnd, */ LPCTSTR lpText, message box */ LPCTSTR lpCaption, message box */ UINT uType); /* Style of message box */ /* Address of title of /* Address of text in /* Handle of owner window

return 0 This is the return value to the system.

Create a blank windows project


1 2 3 4 5 6 // Callback function LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam); 7 8 9 // Windows entry point int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow) 10 { 11 12 13 MSG msg; // MSG structure to store messages WNDCLASSEX wcx; // WINDOW class information HWND hwndMain; //Main window handle #include <windows.h>

14 15 16

// Initialize the struct to zero ZeroMemory(&wcx,sizeof(WNDCLASSEX)); wcx.cbSize = sizeof(WNDCLASSEX); // Window size. Must always be sizeof(WNDCLASSEX)

17 18

wcx.style = CS_HREDRAW|CS_VREDRAW |CS_DBLCLKS ; // Class styles wcx.lpfnWndProc = (WNDPROC)MainWndProc; // Pointer to the callback procedure

19

wcx.cbClsExtra = 0; // Extra byte to allocate following the wndclassex structure

20

wcx.cbWndExtra = 0; // Extra byte to allocate following an instance of the structure

21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

wcx.hInstance = hInstance; // Instance of the application wcx.hIcon = NULL; // Class Icon wcx.hCursor = LoadCursor(NULL, IDC_ARROW); // Class Cursor wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW); // Background brush wcx.lpszMenuName = NULL; // Menu resource wcx.lpszClassName = "Lesson2"; // Name of this class wcx.hIconSm = NULL; // Small icon for this class

// Register this window class with MS-Windows if (!RegisterClassEx(&wcx)) return 0;

// Create the window hwndMain = CreateWindowEx(0, //Extended window style "Lesson2", // Window class name "Lesson 2 - A simple win32 application", // Window title

37 38

WS_OVERLAPPEDWINDOW, // Window style CW_USEDEFAULT,CW_USEDEFAULT, // (x,y) pos of the window

39

CW_USEDEFAULT,CW_USEDEFAULT, // Width and height of the window

40

HWND_DESKTOP, // HWND of the parent window (can be null also)

41 42

NULL, // Handle to menu hInstance, // Handle to application instance

43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 } 62 }

NULL); // Pointer to window creation data

// Check if window creation was successful if (!hwndMain) return 0;

// Make the window visible ShowWindow(hwndMain,SW_SHOW);

// Process messages coming to this window while (GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg);

// return value to the system return msg.wParam;

63 LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) 64 { 65 66 67 68 69 70 71 72 73 74 75 76 } } return 0; switch (msg) { case WM_DESTROY: // User closed the window PostQuitMessage(0); break; default: // Call the default window handler return DefWindowProc(hwnd,msg,wParam,lParam);

Output

Breaking it up
Messages and the MSG Structure
The MSG structure is what stores the messages received by your application. Before going any further, lets take a look at the event-driven programming model.

Event driven programming model


To understand event driven programming, we draw analogies from the real world. A person places an order at a restaurant. The waiter conveys this order to the chef. The chef gets busy and soon the order is served. 1. The user clicks the maximize button. 2. Windows tells your application that the maximize button has been pressed. 3. Your application then redraws its window so that it covers the screen. Every time windows has to communicate with your application, it sends messages to your application. Once all initializations have been done and the window shown on screen, all your application has to do is poll for windows messages. The lines upto 51 create and show the window and the lines 52-57 poll for messages. The GetMessage() function gets the next message to be processed from the message

queue. GetMessage() returns a non-zero value for every message other than WM_QUIT. This means that the while loop continues until it is time to quit.
TranslateMessage() translates virtual key messages to character messages. DispatchMessage() dispatches the message to a window procedure. This means that for

messages coming to our window, the MainWndProc() is called by Windows(tm) through


DispatchMessage().

How does Windows(tm) know which function to call? Well, we tell Windows(tm) during WNDCLASSEX initialization [line 18].

WNDCLASSEX structure
Every window that you create has an associated WNDCLASSEX structure. The WNDCLASSEX structure provides all the information necessary for Windows(tm) to do perform window related functions like drawing its icon, cursor, menu, calling the callback function which will receive messages and so on. The WNDCLASSEX structure is defined as,
typedef struct _WNDCLASSEX { UINT UINT cbSize; style;

WNDPROC lpfnWndProc; int int HANDLE HICON cbClsExtra; cbWndExtra; hInstance; hIcon;

HCURSOR hCursor; HBRUSH hbrBackground;

LPCTSTR lpszMenuName; LPCTSTR lpszClassName; HICON hIconSm;

} WNDCLASSEX;

cbSize

This must always be set to sizeof(WNDCLASSEX). style This specifies the class styles. Take a look at your SDK documentation for the values this member can take. lpfnWndProc Pointer to the WndProc which will handle this windows' messages. cbClsExtra Number of extra bytes to allocate at the end of the WNDCLASSEX structure. cbWndExtra Number of extra bytes to allocate at the end of the window instance. hInstance Identifies the instance that the window procedure of this class is within. hIcon Handle to the icon associated with windows of this class. hCursor Handle to the cursor for windows of this class. hbrBackground Identifies the class background brush. lpszMenuName Identifies the menu for windows of this class. lpszClassName Pointer to a NULL terminated string or an atom specifying the class of this structure. hIconSm Handle to the small icon associated with this class.

Registering your window class


After you've created your window class, you need to tell Windows(tm) about it. This is done by registering the class with windows. The function call is RegisterClassEx(..). Once this is done, you can create instances of this window by calling
CreateWindowEx(..) with the proper arguments.

Creating the window


A window is created by calling the CreateWindowEx(..) defined as,
HWND CreateWindowEx( DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, // extended window style // pointer to registered class name // pointer to window name // window style // horizontal position of window // vertical position of window // window width // window height // handle to parent or owner window // handle to menu, or child-window identifier HINSTANCE hInstance, LPVOID lpParam ); // handle to application instance // pointer to window-creation data

Lines 34-43 create the window. If the creation was successful a non-zero handle is returned by CreateWindowEx after which ShowWindow() shows the window on the screen.

Callback functions
A callback function is the one that receives the messages sent to your application. This is where you do something about the message. We provide a pointer to this function while defining the window class [line 18]. Callback functions have to be defined as,
LRESULT CALLBACK function-name( HWND hwnd, message UINT msg, // The message // Handle of window which received this

WPARAM wParam, // Extra information LPARAM lParam ); // Extra information

HWND hwnd The handle of the window is specified so that you know which window to act upon. This is necessary because you may have created more than one instance of the window. UINT msg This contains the message sent. WPARAM wParam and WPARAM lParam wParam and lParam are used to pass extra info about the message. For example a WM_LBUTTONDOWN (left mouse button down) message will have the x and y co-ordinates as the upper and lower word of lParam and wParam will tell if any modifier keys (ctrl, alt, shift) have been pressed.

MainWndProc
63 LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) 64 { 65 66 switch (msg) { ...

WM_DESTROY
... 67 68 69 70 ... case WM_DESTROY: // User closed the window PostQuitMessage(0); break;

The WM_DESTROY message is sent to your application when the user teminates the application either by clicking the X at the upper right corner, pressing Alt+F4, or quits the application by other means.
PostQuitMessage() causes GetMessage(..) [line 53] to return false and thus breaking

out of the while loop and exiting the application. The argument to PostQuitMessage is the return value to the system.

DefWindowProc(..)
What about the other 200 or so messages? Surely you, the programmer, aren't going to write code for all the 200 messages. Fortunately, Windows(tm) provides the
DefWindowProc(..) function which handles all the messages. For the purposes of

displaying a simple window, your MainWndProc could very well have consisted of
LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) { return DefWindowProc(hwnd,msg,wParam,lParam); }

What this means is that every time you want to do something about a message, add the case switch for the message and write the code which does something about it. All messages that you don't want to handle should be passed to the DefWindowProc(). This is what we have done in our code.
... 71 72 73 ... default: // Call the default window handler return DefWindowProc(hwnd,msg,wParam,lParam);

Adding Functionality

Lets pop up a MessageBox which will display the co-ordinates of the point where the left mouse button was pressed. To do this you will have to handle the WM_LBUTTONDOWN message. Add this code at line 70
... 68 69 70 71 72 73 PostQuitMessage(0); break; case WM_LBUTTONDOWN: pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); wsprintf(str,"Co-ordinates are\nX=%i and

Y=%i",pt.x,pt.y); 74 75 76 MessageBox(hwnd, str, "Left Button Clicked", MB_OK); break; default: ...

NB:- Message loop Message Loop

Messages come in the form of an MSG data type. This data object is passed to the GetMessage() function, which reads a message from the message queue, or waits for a new message from the system. Next, the message is sent to the TranslateMessage() function, which takes care of some simple tasks such as translating to Unicode or not. Finally, the message is sent to the window for processing using the DispatchMessage() function. A simple message loop consists of one function call to each of these three functions: GetMessage, TranslateMessage, and DispatchMessage. If there is an error, GetMessage returns -1 -- thus the need for the special testing.

Entering the Message Loop Once the main window is created and displayed, the WinMainfunction can begin its primary task, which is to read messages from the application queue and dispatch them to the appropriate window. The system does not send input directly to an application. Instead, it places all mouse and keyboard input from the user into a message queue, along with messages posted by the system and other applications. The application must read the message queue, retrieve the messages, and dispatch them so that the can process them. The Generic application uses the following message loop:
BOOL bRet;

while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0 ) { if (bRet == -1 ) { // handle the error and possibly exit } else

{ TranslateMessage( &msg ); DispatchMessage( &msg ); } }

The GetMessage function retrieves a message from the queue. The DispatchMessage function sends each message to the appropriate window procedure. The TranslateMessage function translates virtual-key message into character messages. In Generic, this is necessary to implement menu access keys.

Buttons

Button Class

Push buttons A push button is a rectangle enclosing text specified in the window text parameter of the CreateWindow call. The push button controls are used mostly to trigger an immediate action without retaining any type of on/off indication The two types of push button controls have window styles called BS_PUSHBUTTON and BS_DEFPUSHBUTTON .The DEF stands for default .Pressing the push button causes the button to be repainted .Releasing the mouse button restores the original appearance and sends a WM_COMMAND message to the parent window with the notification code BN_CLICKED .

Checkbox A check box is a square box with text to the right .The most common styles for a checkbox are BS_CHECKBOX and BS_AUTOCHECKBOX..The state of a check box can be set by a message BS_SETCHECK message. The state of the checkbox can be retrieved by using the BS_GETCHECK message.

Radio Button The radio button looks very much like a check box except that it contains a little circle rather than a box .A dot within the circle indicates that the button is checked. The radio button has the 3 window styles BS_RADIOBUTTON or BS_AUTORADIOBUTTON

GROUPBOX Groupboxes are used to enclose other button controls. The group box is a rectangular outline with its window text at the top. It neither processes mouse or keyboard input nor sends WM_COMMAND message to its parents.

Changing the button text We can change the text in a button by calling SetWindowText

SetWindowText (hwnd, pszString);

Where hwnd is a handle to the window whose text is being changed and the pszString is a pointer to a null terminated string .For a normal window this text is the text of the caption bar. For a button control, it is the text displayed with the button.

The Button Colors

Each of the different Buttons requires multiple colors.

COLOR_BTNFACE is used for the main surface color of the push buttons and the back ground color of others. COLOR_BTNSHADOW - for suggesting a shadow at the right and bottom sides of the push buttons and the insides of the checkbox squares and radio button circles. COLOR_BTNTEXT - For text color

MENUS
A menu is the most important part of the consistent user interface that windows program offer. A menu is a list of application commands. Each command is replaced by a string or bitmap called a menu item. When ever the user chooses a menu item, windows sends the application a command message that indicates which menu item the user choose. Menu items I pop ups can be enabled , disabled or grayed.

Menu has a hierarchical structure .A menu bar resides at the uppermost level of hierarchy, immediately below the caption bar. The top level menu has a menu handle. Each popup menu within a top level menu has its own handle. Selecting an item from the menu bar activates the popup menu.

Menus and messages

Windows sends several different messages to the window procedure when the user selects a menu item. Eg :
8. WM_MENUSELECT A menu tracking message . A program can receive many WM_MENUSELECT messages as the user moves the cursor or mouse among the menu items

9. WM_COMMAND Indicates that user has chosen an enabled menu item from the windows menu. 10. WM_SYSCOMMAND - Indicates that user has chosen an enabled menu item from the system menu. 11. WM_MENUCHAR - this message is issued in 2 circumstances. Ie when user presses ALT and a character that does not correspond to a menu item. A character key that does not correspond to an item in pop up.

Menu functions

5. Append Menu-Adds a new menu item to the end of a menu 6. CheckMenuItem-checks or unchecks the menu item 7. CreatePopupMenu-creates a popup menu 8. CreateMenu-creates a new empty menu 9. DeleteMenu-removes an item from a menu 10. DestroyMenu-removes a menu from the memory 11. DrawMenuBar-forces a windows menu bar to be repainted 12. EnableMenuItem-Changes a menu item to/from enabled 13. GetMenu-Retrieves a handle to the windows menu 14. GetMenuItemCount- gets the no of menuitems in a menu. 15. GetMenuItemID- retrieves the ID value associated with the menuitem 16. GetMenuState-finds the no of items in a menu or the status of an item 17. GetMenuString-retrieves the label displayed in a menu item. 18. GetSubMenu-retrieves a handle toa popup menu 19. GetSystemMenu-retrieves a handle to the system menu 20. InsertMenu-Inserts a new menu item to an existing menu 21. ModifyMenu-changes the properties of a menu item

Drawing on windows

Drawing on Windows

The subsystem of Microsoft Windows responsible for displaying graphics on video displays and printers is known as the Graphics Device Interface (GDI). GDI is an extremely important part of Windows. Not only do the applications we write for Windows use GDI for the display of visual information, but windows itself uses GDI for the visual display of user interfaces. GDI consist of several hundred function calls and some associated data types, macros and structures. Windows uses the device context to store "attributes" that govern how the GDI functions operate on the display

1) SetPixel(hdc,x,y,crColor); 2) crColor=GetPixel(hdc,x,y); 3) LineTo(hdc,x,y);-Draws straight line 4) Polyline and PolylineTo draws a series of connected straight lines 5) PolyPolyline Draws multiple polylines. 6) Arc-Draws elliptical lines 7) PolyBezier and PolBezierTo Draw Bezier splines 8) ArcTo and AngleArc Draw elliptical lines 9) PolyDraw Draws a series of connected straight lines and Bezier splines 10) Rectangle Draws a rectangle 11) Ellipse Draws an ellipse 12) RoundRect Draws a rectangle with rounded corners. 13) Pie- Draws a part of an ellipse that looks like a pie slice 14) Chord Draws part of an ellipse formed by a chord

To draw a straight line, you must call two functions. The first function specifies the point at which the line begins, and the second function specifies the end point of the line: MoveToEx (hdc, xBeg, yBeg, NULL) LineTo (hdc, xEnd, yEnd) ; MoveToEx doesn't actually draw anything instead, it sets the attribute of the device

context known as the "currentposition. LineTo function then draws a straight line from the current position to the point specified in the LineTo function. Rectangle, Ellipse, RoundRect, Chord, and Pie functions are not strictly line-drawing algorithms, but they draw lines and also fill the enclosed area with the current areafilling brush vi. Rectangle (hdc, xLeft, yTop, xRight, yBottom) ; vii. Ellipse (hdc, xLeft, yTop, xRight, yBottom) ; viii.RoundRect (hdc, xLeft, yTop, xRight, yBottom, xCornerEllipse, yCornerEllipse); ix. Arc (hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd) x. Chord (hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd) xi. Pie (hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd)

Pens and Brushes


GDI uses the concept of Pens and Brushes. A Pen defines the style and colour that pixels will be drawn in while a brush determines the fill colour of shapes. A number of the GDI drawing functions can be effected by the pen or brush chosen. Pens To create a pen we need to obtain a handle to one. This handle is named HPEN, we can keep hold of this handle during the lifetime of our program but must remember to delete it before exiting. To create a pen we use the function: HPEN CreatePen( int fnPenStyle, int nWidth, COLORREF crColor); This function takes a style, a pen width and a colour. The style must be one of the predefined styles. The main ones are shown below:

PS_SOLID - Pen is solid. PS_DASH - Pen is dashed. PS_DOT - Pen is dotted. PS_DASHDOT - Pen has alternating dashes and dots. PS_DASHDOTDOT - Pen has alternating dashes and double dots. PS_NULL - Pen is invisible. So to create a solid green pen of 1 pixel width we would write: HPEN greenPen=CreatePen(PS_SOLID, 1, RGB(0,255,0)); It is a good idea to create our pens (and brushes) in advance of drawing and then apply them as required. To apply a pen so future drawing commands use it we must select it. This is known as selecting it into the device context and is achieved by using SelectObject. One thing we must be aware of is that when we no longer want to use our pen we need to re-select the old pen. Luckily SelectObject returns the old pen. So to use our green pen to draw a line we may do this: // Select our green pen into the device context and remember previous pen HGDIOBJ oldPen=SelectObject(hdc,greenPen); // Draw our line Polyline(hdc, pntArray, 2); // Select the old pen back into the device context SelectObject(hdc,oldPen); Brushes Creating and using Brushes is very similar to pens. We can use CreateSolidBrush to create a solid coloured brush or CreateBrushIndirect to create a brush with specific styles (like hatched) or even using a loaded bitmap. You can use a bitmap as a repeating pattern for your brush using CreatePatternBrush. Here I will describe CreateSolidBrush for the others please look int he MSDN help file.

HBRUSH CreateSolidBrush( COLORREF crColor) This is a very simple function that takes the required colour and returns a handle to a brush. We can use it in much the same way as the pen. To create a blue brush we would write: HBRUSH blueBrush=CreateSolidBrush(RGB(0,280,0));

Das könnte Ihnen auch gefallen