第一章:windows程序内部运行机制
07-05-16 wednesday
一。API&SDK
1.如c语言的库函数printf等,由编译器的厂商提供。而windows系统也提供了许多函数,以方便windows应用程序的开发,他们是windows系统提供给用户编写应用程序的接口(Application Programming Interface应用程序接口)。其主要的函数在windows.h头文件中声明。
2.win32SDK(Software development Kit软件开发包)。一般包含api函数库,帮助文档,使用手册,辅助工具等。
二。窗口与句柄
资源通过句柄标识。
三。消息与消息队列
1.用户可以调os提供的函数,windows中os也可以调用用户程序——这个调用通过“消息”来进行。
2.os感知用户事件并将其包装成“消息”,投递到应用程序的消息队列中。os向应用程序“发消息”,即os调用应用程序中的消息处理函数(窗口过程)。
3.消息的结构:
typedef struct tagMSG
{
HWND hwnd; //Handle to the window whose window procedure receives the message.
UINT message; //Specifies the message identifier.
WPARAM wParam; //Specifies additional information about the message. The exact meaning depends on the value of the message member.
LPARAM lParam; //同上
DWORD time; //Specifies the time at which the message was posted.
POINT pt; //Specifies the cursor position, in screen coordinates, when the message was posted.
} MSG;
4.消息的进队与不进队:
a,进队消息被os放到消息队列,由应用程序取出并发送,发送给--窗口?--,os再调过程函数。
b,不进队消息则由os直接发送给--窗口?--os再调过程函数。
四。WinMain函数
1.windows系统启动一个程序时,实际上是插入到.exe文件中的启动代码调用WinMain函数。
2.程序步骤:a,WinMain函数定义。b,创建窗口。c,消息循环。 d,窗口过程函数。
3,WinMain函数定义:
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
);
4.创建窗口:
a,设计窗口类
typedef struct _WNDCLASS
{
UINT style;
WNDPROC lpfnWndProc; //Pointer to the window procedure.
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance; //Handle to the instance that contains the window procedure for the class.???
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
} WNDCLASS;
i)定义回调函数。
ii)用户将回调函数指针注册【RegisterClass(&wndclass)】给--调用者?(窗口?)--
iii)应用程序取出消息后,调用【DispatchMessage(&msg)】将消息回传给os,os由函数指针调用过程函数处理消息。
【一个窗口过程,其中有多个窗口函数】
【__stdcall与__cdecl是两种不同的函数调用约定,定义了函数参数入栈的顺序等。win32的API函数都遵循__stdcall约定,而VC++默认的编译选项是__cdecl。在windows程序中,回调函数必须遵循__stdcall约定,所以,声明回调函数时要使用CALLBACK。】
b,注册窗口类:
ATOM RegisterClass( CONST WNDCLASS *lpWndClass // class data );
c,创建窗口:
HWND CreateWindow(
LPCTSTR lpClassName, // pointer to registered class name
LPCTSTR lpWindowName, // pointer to window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window
HMENU hMenu, // menu handle or child identifier
HINSTANCE hInstance, // handle to application instance
LPVOID lpParam // window-creation data
);
d,显示及更新窗口:
BOOL ShowWindow
(
HWND hWnd, // handle to window
int nCmdShow // show state
);
BOOL UpdateWindow
(
HWND hWnd // handle to window
);
其通过发送一个WM_PAINT消息来刷新窗口。【此消息不入队!】
5,消息循环:
MSG msg;
while( GetMessage(&msg, NULL, 0, 0) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
…………其它函数如PeekMessage(),SendMessage(其发的消息不进队)???,PostMessage()???
TranslateMessage将虚拟键消息转为字符消息。【不修改原消息,只产生新消息并投递到消息队列中去】
DispatchMessage将消息回传给os,os调过程函数对消息响应。
不进队的消息用SendMessage。
07-05-16 thursday
6,写过程函数:
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
a,按字符产生WM_CHAR消息。MessageBox();
int MessageBox
(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
);
b,WM_LBUTTONDOWN左键。
DC ( Device Context )设备描述表
HDC,GetDC(),ReleaseDC(),TextOut();
HDC GetDC( HWND hWnd);
int ReleaseDC( HWND hWnd, HDC hDC);
BOOL TextOut
(
HDC hdc, // handle to DC
int nXStart, // x-coordinate of starting position
int nYStart, // y-coordinate of starting position
LPCTSTR lpString, // character string
int cbString // number of characters
);
c,WM_PAINT
PAINSTRUCT 接收绘制的信息。
HDC BeginPaint(
HWND hwnd, // handle to window
LPPAINTSTRUCT lpPaint // paint information
);如果背景没有擦除,则其会先发WM_EREASEBKGRD消息给窗口,系统会用背景色来擦除。
与EndPaint()相匹配。
d,WM_CLOSE,在用户按关闭按钮时产生。
DestroyWindow函数在销毁窗口后会向窗口过程发送WM_DESTROY消息。
DefWindowProc也可以调用DestroyWindow函数来响应该消息。其放到default语句中。
e,WM_DESTROY要退出必须响应它!
PostQuitMessage()向消息队列投递WM_QUIT消息。
五,实践:
Win32 Application 和 Win32 Console Application的区别。
六,消息循环的错误分析
七,变量的命名约定