Presentation is loading. Please wait.

Presentation is loading. Please wait.

Building a Win32API Application

Similar presentations


Presentation on theme: "Building a Win32API Application"— Presentation transcript:

1 Building a Win32API Application
Raw access to the API

2 Resources The resource script (.rc file):
separate from code and dynamic data compiled by a separate "Resource Compiler” Resources determine the app’s “look and feel” Examples: Keyboard Accelerators, Bitmaps, Cursors, Dialog Box values, Fonts, Icons, Menus, String Tables Separation of resources and program code separates tasks of programmer & designer can change user interface without touching code

3 Message Processing OS User input (mouse, keyboard) interrupt Msg loop:
GetMsg DispatchMsg msg Message queue msg WndProc: Evaluate msg, take action

4 Basic program flow RegisterClassEx() CreateWindowEx()
(you provide a pointer to a function (usually called WndProc) which handles windows messages such as WM_CREATE, WM_COMMAND, etc. CreateWindowEx() returns a handle (pointer) to that control. When the user clicks on a control you receive the WM_COMMAND message with the ID of that control. Now handle that event. SetWindowText() and GetWindowText() allow you to set/get the text of any control. ShowWindow() – displays the window UpdateWindow() – updates the buffer Start the message loop OS then calls WndProc() - Process O/S's messages

5 Message loop MSG msg; // probably a global vbl
while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); // tell OS to call my WndProc } Notes: the name of the window processor does NOT have to be "WndProc" The two 0's are filter max/min values

6 About msg loops O/S only creates a message queue for threads that perform operations which require one. Must create a window before entering loop GetMessage blocks until a filter-matching msg arrives See for a discussion of filter max/minvalues

7 Two 32-bit integer values (DWORDs)
Windows Messages Two 32-bit integer values (DWORDs) WPARAM – 2 16-bit WORDs inside a DWORD LPARAM – a 32-bit DWORD High-order and low order 16 bit WORDs Extract each WORD with C macros HIWORD(msg) gets high order LOWORD(msg) gets low order Meanings of HI and LO depend on the message

8 WinMain (replaces "main")
Win32API Programs WinMain (replaces "main") Primary entry point from OS Procedure definition Init Message processing loop WinProc (the "callback" function) Performs actions to process messages Switch statement based on msg# Reentered once for each message Pixel-by-pixel mouse move Mouse-click, etc.

9 LPARAM & WPARAM LPARAM & WPARAM are datatypes window message design:
if the message takes a pointer, the pointer is usually passed in the LPARAM, if the message takes a handle or an integer, it is passed in the WPARAM if a message takes both, the pointer goes in the LPARAM the integer goes in the WPARAM

10 wParam & lParam Not every message uses these WParam values
Each message uses them differently. WM_CLOSE message doesn't use either, so ignore both. WM_COMMAND message uses both, WParam contains two values, HIWORD (WParam) - notification message (if applicable) LOWORD (WParam) - control or menu id that sent the message. LParam - HWND (window handle) of control which sent the message NULL if the message isn't from a control.

11 example Given, some function "fn", extract the string from the parameter (which is a pointer) LRESULT class::fn (WPARAM wParam, LPARAM lParam) { //two steps required LPTSTR lpMessage = (LPTSTR) lParam; // get ptr to string CString s = lpMessage; // put string into needed type }

12 Important For WM_LBUTTONDOWN
Caution Important  For WM_LBUTTONDOWN Do not use the LOWORD or HIWORD macros to extract the x- and y- coordinates of the cursor position because these macros return incorrect results on systems with multiple monitors. Systems with multiple monitors can have negative x- and y- coordinates, and LOWORD and HIWORD treat the coordinates as unsigned quantities.

13 Two ways to inform a handler
Sending messages Two ways to inform a handler PostMessage Enqueues message for handler Retrieved with GetMsg Immediate return to caller (it's a non-blocking call) SendMessage Sends message to handler (NO queueing) BLOCKS until message received!!

14 WndProc Processes System Messages
LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) Typical operations: If msg is WM_CREATE, call CreateWindow(). If msg is WM_QUIT, terminate If msg is WM_PAINT, then redraw the window

15 When a menu item is selected Windows sends WM_COMMAND msg
Menus When a menu item is selected Windows sends WM_COMMAND msg low word of wParam will be the item ID extract with LOWORD(wParam) then do switch/case using LOWORD(wParam) value

16 Menus-1 Double-click your resource file's name (.rc) Click on menu/menu-name Enter names as needed

17 Double-click on "Resource.h" Scroll down to your menu items
Menus-2 Double-click on "Resource.h" Scroll down to your menu items Change the numeric values Increment to the next available integer

18 Misc Msg class specifies what kind of 'control' this window is e.g.; "edit" is a text box and "button" is a button. Each control (a window) must have a unique ID Use CString vs. STL string Remainder of STL is OK in all apps Note use of new datatypes, "_T", LPSTR Recommended: use _T() macro vs. char or wchar_t Use LPTSTR vs. char* or wchar_t*. Then set MBCS or _UNICODE & rebuild w/o code changes.

19 ANSI (Windows-1252 = ASCII, ISO-8859) String declaration types
Character strings Unicode 16 bit characters Allows for international alphabets/symbols ANSI (Windows-1252 = ASCII, ISO-8859) String declaration types "mystring" will use ANSI characters only L"mystring" will use Unicode characters only _T("mystring") Unicode if #define _UNICODE ANSI if not

20 Pointers to strings DO NOT use char* or wchar* Do use TCHAR* or LPTSTR LPCTSTR is for usage like: const char* Replace strcpy with _tcscpy To convert a byte-buffer to character-size buffer, use: bufflen/sizeof(TCHAR) pWnd->GetWIndowText(buffer, sizeof(buffer) / sizeof(TCHAR))

21 Callback skeleton for Win32API (for writing text)
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hDC; TCHAR greeting[ ] = _T ("DJ says, 'Hello World!'"); TCHAR click_greeting[] = _T ("Saw your click"); RECT rect; switch (message) {case WM_PAINT: hDC = BeginPaint (…, &ps); nHeight = -MulDiv (PointSize, GetDeviceCaps (…, LOGPIXELSY), 72); GetClientRect (…, &rect); /* set_font and color where his comment is */ TextOut (…, 5, y_position, greeting, _tcslen (greeting)); EndPaint (…, &ps); DeleteObject (SelectObject (…, hTmp)); break; case WM_LBUTTONDOWN: InvalidateRect (…, NULL, FALSE); // TRUE => erase current content increment_line_num (…); set_font (hDC); TextOut (hDC, 5, y_position, click_greeting, _tcslen (click_greeting)); EndPaint (…, &ps); break; case WM_DESTROY: PostQuitMessage (0); break; default: return DefWindowProc (…, message, wParam, lParam); break; } return 0; // return to the OS from the callback function

22 subroutines void increment_line_num (HDC hDC) { line_num++; y_position = (-1)*nHeight * line_num; // allow some space to avoid clipping // Remember that y-positions are more negative as you go DOWN the screen!! // i.e.; the top left corner is 0,0 }; Void SetFont () {if (line_num==0) hFont = CreateFont(nHeight, closest_match, escapement, orientation, FW_DONTCARE, no_italic, no_ul, no_xout, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DRAFT_QUALITY, VARIABLE_PITCH, TEXT("Times")); // TEXT ≡ _T }

23 Callback skeleton (for drawing)
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {PAINTSTRUCT ps; RECT rect; switch (message) {case WM_LBUTTONDOWN: iPrevX = LOWORD(lParam); iPrevY = HIWORD(lParam); return 0; case WM_MOUSEMOVE: if (wParam & MK_LBUTTON) { hdc = GetDC (hwnd); MoveToEx (…, …, …, …); // update current position. Get old position back in parm 4 LineTo(…, …, …); iPrevX = LOWORD(lParam); iPrevY = HIWORD(lParam); ReleaseDC (hwnd, hdc); } return 0; case WM_LBUTTONUP: InvalidateRect (…, …, …); return 0; case WM_PAINT: GetClientRect (hwnd, &rect); hdc = BeginPaint (hwnd, &ps); InvalidateRect (…, …, …); EndPaint (hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; return DefWindowProc(hwnd, message, wParam, lParam);

24 Draw a Circle case ID_DRAW_CIRCLE: /* draw a blue-bordered magenta-crosshatched circle */ hDC = GetDC(hWnd); /* get a DC for painting */ hPen = CreatePen(PS_SOLID, 3, RGB(0, 0, 255)); /* blue pen */ hBrush = CreateHatchBrush(HS_DIAGCROSS, RGB(255, 0, 255)); hOldPen = (HPEN)SelectObject(hDC, hPen); /* select into DC & */ hOldBrush = (HBRUSH)SelectObject(hDC, hBrush); /* save old object */ Ellipse(hDC, 100, 30, 180, 110); /* draw circle */ SelectObject(hDC, hOldBrush); /* displace brush */ DeleteObject(hBrush); /* delete brush */ SelectObject(hDC, hOldPen); /* same for pen */ DeleteObject(hPen); ReleaseDC(hWnd, hDC); /* release the DC to end painting */ break;

25 Draw a Rectangle case ID_DRAW_RECTANGLE: /* draw a red-bordered, cyan-filled rectangle */ hDC = GetDC(hWnd); /* get a DC for painting */ hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0)); /* red pen */ hBrush = CreateSolidBrush(RGB(0, 255, 255)); /* cyan brush */ hOldPen = (HPEN)SelectObject(hDC, hPen); /* select into DC & */ hOldBrush = (HBRUSH)SelectObject(hDC, hBrush); /* save old object */ Rectangle(hDC, 15, 15, 80, 60); /* draw rectangle */ SelectObject(hDC, hOldBrush); /* displace new brush */ DeleteObject(hBrush); /* delete it from DC */ SelectObject(hDC, hOldPen); /* same for pen */ DeleteObject(hPen); ReleaseDC(hWnd, hDC); /* get rid of DC */ break;

26 Applying defaults ATOM MyRegisterClass(HINSTANCE hInstance) { }
WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style= CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc= WndProc; wcex.cbClsExtra= 0; wcex.cbWndExtra= 0; wcex.hInstance= hInstance; wcex.hIcon= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32DRAWEXAMPLE)); wcex.hCursor= LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName= MAKEINTRESOURCE(IDC_WIN32DRAWEXAMPLE); wcex.lpszClassName= szWindowClass; wcex.hIconSm= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); }


Download ppt "Building a Win32API Application"

Similar presentations


Ads by Google