由于这节课对我的跨度比较大,我之前从未认真学过WIN32编程,都是学基本程序员该知道的C语法```所以做些整理```` 在Windows程序中,编写图形界面程序需要调用大量的Windows gui函数。其实这对于用户和程序员都有好处。对于用户,面对的都是同一套标准的窗口,对这些窗口的操作几乎是一样的,使用不同的程序无需在重新学习。对程序员来说这些gui代码都是随时可以拿来用的。当然至于具体的写程序对于程序员还是有难度的。为了创建基于窗口的程序必须严格遵守规范。做到这一点不难,只要用模块化和面向对象的编程方法即可。 显示一个窗口的步骤: 1. 得到你应用程序的实例句柄(必须) 2. 得到命令行参数(如果你想从命令行得到参数,可选) 3. 注册窗口类(必须,除非你使用windows预定义的窗口类,如 MessageBox等 4. 产生窗口(必须) 5. 在桌面显示窗口(必须,除非你不想立即显示它) 6. 刷新窗口客户区 7. 进入无限的消息循环 8. 如果有消息到达,则由负责该窗口的窗口回调函数处理。 9. 如果用户关闭窗口,则进行退出处理。 Code #include "windows.h"
char szClassName[] = {"First Window"}; HWND hParent;
// LRESULT 类型是一个32位值,指的是从窗口过程或者回调函数返回的32位值 。 CALLBACK指定此函数为回调函数
LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch(uMsg) {
case WM_CLOSE: {
DestroyWindow(hwnd); PostQuitMessage(0); } break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASS stWndClass; MSG stMsg;
RtlZeroMemory(&stWndClass, sizeof(stWndClass) + sizeof(stMsg)); //填充 WndClass结构 + MSG结构 stWndClass.style = CS_VREDRAW | CS_HREDRAW; stWndClass.lpfnWndProc = &WindowProc; stWndClass.hInstance = hInstance; stWndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); stWndClass.hCursor = LoadCursor(NULL, IDC_ARROW); stWndClass.hbrBackground =(HBRUSH)COLOR_WINDOW; stWndClass.lpszClassName = szClassName;
//注册窗口类
RegisterClass(&stWndClass);
//创建窗口
hParent = CreateWindowEx(0, szClassName, "我的第一个窗口程序 黑客防线", WS_OVERLAPPEDWINDOW, \ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if(!hParent) return 0;
//显示窗口 ShowWindow(hParent, SW_SHOWNORMAL);
//刷新客户区 UpdateWindow(hParent);
//消息循环 while(GetMessage(&stMsg, NULL, 0, 0) != 0) {
TranslateMessage(&stMsg); DispatchMessage(&stMsg);
}
return stMsg.wParam; }
void EntryPoint() {
WinMain(GetModuleHandle(NULL), NULL, NULL, 0); ExitProcess(0); } 疑问1:HWND 只是一个数据类型而已,VS2010 LIB中给的定义如下: DECLARE_HANDLE (HWND); #ifdef STRICT typedef void *HANDLE; #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name #else typedef PVOID HANDLE; #define DECLARE_HANDLE(name) typedef HANDLE name #endif 我也整理了句柄的相关资料```地址:http://www.portwatcher.tk/blog/win32_api_hwnd_jury/2010-04-24-18 -------------------------------------------------------------------------------- 疑问2:WindowProc()函数 MSDN中WindowProc()的相关: The WindowProc function is an application-defined function that processes messages sent to a window. The WNDPROC type defines a pointer to this callback function. WindowProc is a placeholder for the application-defined function name. Syntax LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); Parameters hwnd [in] Handle to the window. uMsg [in] Specifies the message. wParam [in] Specifies additional message information. The contents of this parameter depend on the value of the uMsg parameter. lParam [in] Specifies additional message information. The contents of this parameter depend on the value of the uMsg parameter. Return Value The return value is the result of the message processing and depends on the message sent. -------------------------------------------------------------------------------- 疑问3:RtlZeroMemory()函数 GOOGLE了一下,看雪论坛上的有人跟我有用样的疑惑````看雪上有人对这个函数的说明是: 这个函数一般是用来初始化局部变量的缓冲区用的。这个函数可以将缓冲区的所有数据重归为0 这个函数只有两个参数,第一个是需填充的起始地址,第二个自然是填充的长度了,这里经常会使用到sizeof()函数来返回数据的长度```` 该函数在这里的作用相当明显```不难理解``` -------------------------------------------------------------------------------- 疑问4:ExitProcess()函数 根据这个函数的名字```我猜想这个函数是用来结束任务退出程序的``` 通过查阅MSDN,证明我的猜想是正确的```` MSDN中的相关: Ends the calling process and all its threads. Syntax VOID WINAPI ExitProcess( __in UINT uExitCode ); Parameters uExitCode [in] The exit code for the process and all threads. Return Value This function does not return a value. -------------------------------------------------------------------------------- 疑问5:TranslateMessage(&stMsg); DispatchMessage(&stMsg); 其中,TranslateMessage是用来把虚拟消息转化为字符消息。由于Windows对所有键盘编码都是采用虚拟键的定义,这样当按键按下时,并不得字符消息,需要键盘映射转换为字符的消息。 TranslateMessage函数用于将虚拟键消息转换为字符消息。字符消息被投递到调用线程的消息队列中,当下一次调用GetMessage函数时被取出。当我们敲击键盘上的某个字符键时,系统将产生WM_KEYDOWN和WM_KEYUP消息。这两个消息的附加参数(wParam和lParam)包含的是虚拟键代码和扫描码等信息,而我们在程序中往往需要得到某个字符的ASCII码,TranslateMessage这个函数就可以将WM_KEYDOWN和WM_ KEYUP消息的组合转换为一条WM_CHAR消息(该消息的wParam附加参数包含了字符的ASCII码),并将转换后的新消息投递到调用线程的消息队列中。注意,TranslateMessage函数并不会修改原有的消息,它只是产生新的消息并投递到消息队列中。 也就是说TranslateMessage会发现消息里是否有字符键的消息,如果有字符键的消息,就会产生WM_CHAR消息,如果没有就会产生什么消息。 函数TranslateMessage声明如下: WINUSERAPI BOOL WINAPI TranslateMessage( __in CONST MSG *lpMsg); lpMsg是检查需要转换的消息。 DispatchMessage()函数将消息传送到指定窗口函数 先向应用程序发消息,当应用程序接到消息后,然后它会把消息通过DispatchMessage(&msg)传递给窗口函数wndproc,窗口函数就会对照事先由程序编写好的消息对照表调用对应的方法来处理消息。
|