1. 操作系统和应用程序之间的关系: 2. windows程序设计是种事件驱动方式的程序设计,主要基于消息的。当用户需要完成某种功能时,需要调用OS某种支持,然后OS将用户的需要包装成消息,并投入到消息队列中,最后应用程序从消息队列中取走消息并进行响应。 3. 创建一个完整的窗口需要经过下面四个操作步骤 1) 设计一个窗口类。如:WNDCLASS wndcls。 2) 注册窗口类。如:RegisterClass(&wndcls)。 3) 创建窗口。如:CreateWindow(),CreateWindowEX(); 4) 显示及更新窗口。如:ShowWindow(),UpdateWindow(); 4. 消息的结构: typedef struct tagMSG { HWND hwnd; //接收消息的窗口句柄,和哪个窗口相关联。 UINT message; //消息标识,消息本身是什么,如WM_CHAR WPARAM wParam; //消息的附加信息,具体取决于消息本身。 LPARAM lParam; DWORD time; //消息投递时间。 POINT pt; //消息投递时,光标在屏幕上的位置。 } MSG; 5. WinMain函数结构: int WINAPI WinMain( HINSTANCE hInstance, // 当前实例句柄。 HINSTANCE hPrevInstance, //上一个该程序的实例句柄,32位系统中此值都为NULL LPSTR lpCmdLine, // 命令行指针 int nCmdShow // (窗口)显示的状态 ); 要带参调用WinMain类似于命令行的功能,在Project->setting->Debug->Program arguments项填写参数 6. 窗口类WNDClass: typedef struct _WNDCLASS { UINT style; //窗口的类型 WNDPROC lpfnWndProc; //窗口过程函数指针(回调函数) int cbClsExtra; //窗口类附加字节,为该类窗口所共享。通常0。 int cbWndExtra; //窗口附加字节。通常设为0。 HANDLE hInstance; //当前应用程序事例句柄。 HICON hIcon; //图标句柄 LoadIcon(); HCURSOR hCursor; //光标句柄 LoadCursor(); HBRUSH hbrBackground; //画刷句柄 (HBRUSH)GetStockObject(); LPCTSTR lpszMenuName; //菜单名字 LPCTSTR lpszClassName; //类的名字 } WNDCLASS; 7. 源码(在VC中建立Win32 Application): #include<windows.h> #include<stdio.h> //回调函数声明 LRESULT CALLBACK WindowProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // pointer to command line int nCmdShow // show state of window ) { //第一步:设计窗口类 WNDCLASS wndcls; wndcls.cbClsExtra=0; wndcls.cbWndExtra=0; //The GetStockObject function retrieves a handle to one of the predefined stock pens, brushes, fonts, or palettes. wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); //得到预定义的画刷,画笔等 wndcls.hCursor=LoadCursor(NULL,IDC_CROSS); //如果采用预定义的光标,则第一参数为NULL wndcls.hIcon=LoadIcon(NULL,IDI_WARNING);//同上 wndcls.hInstance=hInstance; wndcls.lpfnWndProc=WindowProc; //回调函数 wndcls.lpszClassName="winmain"; //给本窗口类取个名字 wndcls.lpszMenuName=NULL; wndcls.style=CS_HREDRAW | CS_VREDRAW; //水平和垂直重画,这在窗口水平和垂直调整大小的时候告知窗口是否需要重画,如果填写上述两个参数,则表示重画,窗口上的内容将清除重画 //第二步:注册窗口类 RegisterClass(&wndcls); //第三步:创建窗口 HWND hwnd; hwnd=CreateWindow("winmain","this is first lesson",WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL, NULL,hInstance,NULL); //第四步:显示窗口 ShowWindow(hwnd,SW_SHOWNORMAL); //第五步:重刷一下窗口,该语句可有可无 UpdateWindow(hwnd); MSG msg; //每次循环从消息队列中取出一条消息进行处理。If the GetMessage retrieves a message other than WM_QUIT, the return value is nonzero.If the function retrieves the WM_QUIT message, the return value is zero. while(GetMessage(&msg,NULL,0,0)) { //该语句将类似于WM_KeyDown和WM_KeyUp转换生成新WM_CHAR投递给系统处理 //The WM_CHAR message is posted to the window with the keyboard focus //when a WM_KEYDOWN message is translated by the TranslateMessage function. //WM_CHAR contains the character code of the key that was pressed. TranslateMessage(&msg); //将消息投递出去给操作系统,操作系统会自动调用回调函数处理 DispatchMessage(&msg); } return 0; } LRESULT CALLBACK WindowProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { HDC hdc; switch(uMsg) { case WM_PAINT: PAINTSTRUCT ps; hdc=BeginPaint(hwnd,&ps); TextOut(hdc,0,10,"hello world!",strlen("hello world!")); EndPaint(hwnd,&ps); break; case WM_CHAR: char szChar[20]; sprintf(szChar,"char is %d",wParam); MessageBox(hwnd,szChar,"消息",MB_OK); case WM_LBUTTONDOWN: hdc=GetDC(hwnd); //得到当前窗口的上下文句柄 TextOut(hdc,0,50,"beijing2008!",strlen("beijing2008!")); ReleaseDC(hwnd,hdc); break; case WM_CLOSE: if(IDOK==MessageBox(hwnd,"确认要退出嘛?","消息",MB_OK)) { //销毁窗口,但进程中还是保留的,该函数直接抛出WM_DESTROY消息 DestroyWindow(hwnd); } break; case WM_DESTROY: PostQuitMessage(0); //终止消息循环,并抛出WM_QUIT消息,从而导致上面的消息循环退出 default: //对于代码中没有涉及到的消息,由提交给系统处理,此句一定要加,否则窗口不会出现 return DefWindowProc(hwnd,uMsg,wParam,lParam); } return 0; } |
|
来自: Alex@ZW > 《孙鑫VC学习笔记》