WindowsSDK编程学习日记(1)

学习日记……

 

2009年2月24日

 

如果不会SDK编程,MFC实在是像水中月,能看到却掌握不了……

 

Win32编程的开始就是了结Windows编程的概念。在Windows下,基本所有程序的功能都是通过直接或间接调用Windows API函数来完成的。

 

使用VC6编程,选择Win32 Application,建立空工程并添加一个cpp文件

 

Windows程序总是从WinMain()开始运行,如从前的控制台程序总是从main()开始运行。操作系统(实际上是程序的起始代码)将调用WinMain开始运行程序。

 

作为完全手动编写的第一个程序:

 

 #include<windows.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, // command line int nCmdShow // show state ) //hPrevInstance已经不再使用 { //新建一个窗口类 WNDCLASS wndcls; wndcls.cbClsExtra=0; wndcls.cbWndExtra=0; wndcls.hbrBackground=(HBRUSH)CreateSolidBrush(/*100<<16 | 100<<8 | 100)*/RGB(100,100,100)); // wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndcls.hCursor=LoadCursor(NULL,IDC_ARROW); wndcls.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1)); wndcls.hInstance=hInstance; wndcls.lpfnWndProc=WindowProc; wndcls.lpszClassName="Imoagn"; wndcls.lpszMenuName=NULL; wndcls.style=0; RegisterClass(&wndcls); HWND hwnd=CreateWindow("Imoagn","Imoagn", WS_OVERLAPPEDWINDOW ,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL); ShowWindow(hwnd,SW_SHOWNORMAL); UpdateWindow(hwnd); MSG msg; while(GetMessage(&msg,NULL,0,0)) { 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 ) { switch(uMsg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd,uMsg,wParam,lParam); break; } return 0; }    

 

 

WinMain可以从MSDN复制下声明来,其中的最常用的参数是hInstance,代表此程序的句柄(不知道同线程、进程对应关系如何呢……待解决)

 

 

 

 最简单的Windows窗口应用程序的框架是:

 

两个函数:WinMain函数、WindowProc函数(此函数名自定,参数声明是固定的,从MFC中查找声明)

 

其中WinMain函数的内容:

 

  1.  声明一个窗口类(所谓窗口类,是一个Structure结构体,是用来创建窗口的一个“模板”),如WNDCLASS wndcls;
  2. 为wndcls的每个成员变量赋值。其中hbrBackground需要的是一个画刷句柄。可以用GetStockObject来获取系统预定义画刷,也可以用CreateSolidBrush创建一个新画刷。CreateSolidBrush需要颜色参数,32位Int值的四个8bit分别代表a通道、和RGB三种颜色。这个值可以用RGB宏来定义,也可以用位运算符|,<<.>>来复合。
  3. 图标和光标也是用句柄,用LoadIcon和LoadCursor载入。如果使用系统预定义,hInstance为NULL,IDI,IDC开头的宏代表相应光标。如果用程序资源,需要建立资源,还需要用MAKEINTRESOURCE宏。(make*int*resource,是这么分吗汗)
  4. 之后注册窗口类,用RegisterClass(&wndcls);
  5. 注册后可以用CreateWindow创建窗口,要注意其中的参数信息
  6. 用ShowWindow与UpdateWindow显示窗口
  7. 创建消息循环。

实践总结:

 

  1. 消息循环的GetMessage中,句柄参数应该留空为NULL。如果设置了只接受某窗口(句柄hwnd)的消息,最后程序退出时,PostQuitMessage发出的WM_QUIT无法被处理。程序不能正常退出。
  2. TranslateMessage函数的作用是将WM_KEYDOWN,与WM_KEYUP整合后再发出一个WM_CHAR消息。如果没有调用这个函数,程序永远不会收到WM_CHAR消息。之所以转换,是因为WM_KEYDOWN消息所携带的wParam参数内容是虚拟键编码,不易使用。经过转换的WM_CHAR消息所携带的参数是所按键的ASCII编码。
  3. WindowProc中消息条件处理的default标签必须添加return DefWindowProc(...).首先,如果没有DefWindowProc,未被手动处理的消息将被搁浅,程序会卡死。第二,必须直接return。因为DefWindowProc不一定返回0,其返回值不确定,为了将其返回值正确返回调用方(操作系统),必须此处return而不是使用WindowProc函数最后的返回(一般是return 0)

欠缺:对CS、WS等开头的窗口样式十分陌生,有待熟悉。

 

你可能感兴趣的:(编程,windows,null,mfc,callback,winapi)