building a win32api application raw access to the api

25
Building a Win32API Application Raw access to the API

Upload: justin-beasley

Post on 21-Dec-2015

232 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Building a Win32API Application Raw access to the API

Building a Win32API Application

Raw access to the API

Page 2: Building a Win32API Application Raw access to the API

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

Page 3: Building a Win32API Application Raw access to the API

Message Processing

WndProc:Evaluate msg, take action

Msg loop:GetMsgDispatchMsg

User input(mouse,

keyboard) OSinterrupt

msg

Message queue

msg

Page 4: Building a Win32API Application Raw access to the API

Basic program flow– RegisterClassEx()

(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

Page 5: Building a Win32API Application Raw access to the API

Message loop

MSG msg; // probably a global vblwhile (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg); // tell OS to call my WndProc}Notes: 1. the name of the window processor does NOT have

to be "WndProc"2. The two 0's are filter max/min values

Page 6: Building a Win32API Application Raw access to the API

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 http://msdn.microsoft.com/en-us/library/windows/desktop/ms644936(v=vs.85).aspx for a discussion of filter max/minvalues

Page 7: Building a Win32API Application Raw access to the API

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

Page 8: Building a Win32API Application Raw access to the API

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.

Page 9: Building a Win32API Application Raw access to the API

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

Page 10: Building a Win32API Application Raw access to the API

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.

Page 11: Building a Win32API Application Raw access to the API

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 stringCString s = lpMessage; // put string into needed type

}

Page 12: Building a Win32API Application Raw access to the API

Caution

• Important For WM_LBUTTONDOWNDo 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.

Page 13: Building a Win32API Application Raw access to the API

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!!

Page 14: Building a Win32API Application Raw access to the API

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

Page 15: Building a Win32API Application Raw access to the API

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

Page 16: Building a Win32API Application Raw access to the API

Menus-1

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

Page 17: Building a Win32API Application Raw access to the API

Menus-2

• Double-click on "Resource.h"• Scroll down to your menu items• Change the numeric values

– Increment to the next available integer

Page 18: Building a Win32API Application Raw access to the API

Misc– Msg class specifies what kind of 'control' this

window ise.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.

Page 19: Building a Win32API Application Raw access to the API

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

Page 20: Building a Win32API Application Raw access to the API

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))

Page 21: Building a Win32API Application Raw access to the API

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 contenthDC = BeginPaint (…, &ps);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

}

Page 22: Building a Win32API Application Raw access to the API

subroutinesvoid 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

}

Page 23: Building a Win32API Application Raw access to the API

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);}

Page 24: Building a Win32API Application Raw access to the API

Draw a Circlecase 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;

Page 25: Building a Win32API Application Raw access to the API

Draw a Rectanglecase 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;