近来由于项目的需要,开始接触Windows平台的编程,这于我而言,是一个不小的挑战,毕业之后,一直都在Linux平台下开发,虽然早前就想对Windows平台有所了解,孙鑫老师的视频一直存于电脑的某个文件夹内,但是几次践行都没有入得Windows的门槛,而近年来微软战略转向C#.NET平台后,使得原来的WIN32和MFC编程变得稀有起来,虽然还是有相当一部分人的拥护,但毕竟它最好的时代已经过去了。在此环境下,我还是希望借这个项目了解一下Windows平台编程,之所以想写下学习的过程,主要是因为发现接触的东西越来越多,很多新知识可能都派不上用场,这就会造成学习的愈多,而遗忘的也愈多,生命有崖,我希望有那些曾经学习过的知识得以保存的方法,这里的文章主要还是写给未来的自己看的。
学习Windows编程是从孙鑫老师的Windows编程视频开始,外辅侯俊杰老师的深入浅出MFC,之后我又买了一本Windows编程设计这部巨作,不过这本书实在太厚,所有看过的人,都说可以用它来当枕头用了。既然要学习它,当然还是要牺牲一点血本的。学习任何一门新的计算机技术一般都要首先了解这门技术所使用的语言,在了解语法的基础上,再进一步了解他的库函数,这是面向过程语言的一般学习方法,对于windows编程,可以使用的语言主要是VB、VC、C#这几种,VB非常适合于WIndows平台C/S模式的客户端软件,C#不用说是现在微软大力推广的语言,VC则像一个从高峰渐渐跌入低谷的语言,说了这么多,还是学习我的windows编程,所需要的语言还是VC。
首先需要了解的是windows程序的执行过程,所有程序都是从main函数入口,依次往下执行,windows程序当然也是从main开始,不过windows为了强调这是window平台,他采用WinMain作为入口函数。以下就是一个windows窗口的创建过程主要代码。结合我自己的见解,学习windows编程主要是要深入理解两大块,窗口创建过程,以及消息的处理过程。如果将能够理解者两大块,基本上也就清楚windows编程时怎么回事啦,剩下的事情就是吾日三省乎吾身,勤加练习积累经验的过程了。基本上MFC就是将这两部分进行分解,但只要了解了这基本的奥义,解读MFC还是不成问题,不过你要弄清楚那些系统函数可要苦练很长一段时间啦,侯俊杰在书中提到很多windows编程者只是机械的拖放控件者而根本不清楚这背后的框架,本着学习研究的态度,我们还是慢慢的学习吧。
#include <windows.h> LRESULT CALLBACK WinSunProc( HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam ); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { WNDCLASS wndcls; wndcls.cbClsExtra=0; wndcls.cbWndExtra=0; wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); wndcls.hCursor=LoadCursor(NULL,IDC_CROSS); wndcls.hIcon=LoadIcon(NULL,IDI_ERROR); wndcls.hInstance=hInstance; wndcls.lpfnWndProc=WinSunProc; wndcls.lpszClassName="windows2012"; wndcls.lpszMenuName=NULL; wndcls.style=CS_HREDRAW | CS_VREDRAW; RegisterClass(&wndcls); HWND hwnd; hwnd=CreateWindow("windows2012","windows学习",WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL); ShowWindow(hwnd,SW_SHOWNORMAL); UpdateWindow(hwnd); MSG msg; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; }以上代码只需要稍作修改就可以用到任何一个windows程序中,因为所有的windows程序基本都遵循一个步骤,1、注册窗口,2、创建窗口,3、显示窗口,4、更新窗口,5、消息获取和消息分发,6、消息处理。除了第6步,前面5个步骤都是在这个WinMain函数中完成的,而第6部则是在WinSunProc这个回调函数中完成的。了解这个步骤是我们掌握MFC编程的基础,这个在下一章再说。前5步在这个函数里已经很清楚的显示出来啦,只是第6步如何实现,这个就需要了解windows消息处理的主要过程啦。
LRESULT CALLBACK WinSunProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { switch(uMsg) { case WM_CHAR: char szChar[20]; sprintf(szChar,"char is %d",wParam); MessageBox(hwnd,szChar,"weixin",0); break; case WM_LBUTTONDOWN: MessageBox(hwnd,"mouse clicked","weixin",0); HDC hdc; hdc=GetDC(hwnd); TextOut(hdc,0,50,"计算机编程语言培训",strlen("计算机编程语言培训")); ReleaseDC(hwnd,hdc); break; case WM_PAINT: HDC hDC; PAINTSTRUCT ps; hDC=BeginPaint(hwnd,&ps); TextOut(hDC,0,0,"维新培训",strlen("维新培训")); EndPaint(hwnd,&ps); break; case WM_CLOSE: if(IDYES==MessageBox(hwnd,"是否真的结束?","weixin",MB_YESNO)) { DestroyWindow(hwnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd,uMsg,wParam,lParam); } return 0; }
以上就是windows处理消息的回调函数,这个回调函数是给windows系统调用的,windows处理消息的主要过程是这样的,系统接收一个消息,将其存放到消息队列中,然后进程捕获这个消息接着就是分发消息,系统就会调用进程注册的回调函数,由回调函数来对消息进行处理,如果回调消息没有处理这个消息,那么通过DefWindowProc函数,消息又将送给系统的默认方法进行处理。这就是windows将应用狠狠的绑定在自己身上,让其拥有一定的自主权,但是要向完全摆脱windows的控制则是不可能的。这就是windows编程的主要过程,不过光了解这些还是不够的,毕竟windows平台从当初的DOS平台到如今的windows8的诞生,他已经是一个庞然大物,没有冰冻三日的努力,还是很难有所建树的。
现在开始要学习的是MFC框架的学习,MFC的思想真的挺不错,如果真的能够办到,那就真的如侯俊杰老师所说的成为软甲IC装配厂的男工女工了。不过事实证明太高深的东西不是每个人都能够熟练运用的,MFC想尝试一个可以简化开发过程,使得开发软件者只需要关注自己的那一部分,将不关心的过程统统交给系统来处理。当然这是一个非常不错的注意,毕竟可以减少开发成本,但是MFC也有自己的开发地盘的,超出这个地盘MFC就爱莫能及了,闲谈的太多,还是记录MFC的学习心得吧。
>侯俊杰老师书中的第三章“MFC六大关键技术之仿真”已经将MFC的精华罗列出来,这要沿着这条路走下去,深入理解MFC是指日可待的,这六大关键技术就是,1、MFC程序的初始化过程,2、RTTI运行时类型识别,3、Dynamic Creation 动态创建,4、Persistence 永久保存,5、Message Mapping 消息映射,6、Command Routing 命令传递(第三章开头将这一步写作Message Routing 消息传递,这应该是排版时的疏忽)。看完之后,不得不佩服那些家伙设计的巧妙,采用几个宏定义就解决了2、3两个关键技术,初始化过程也是千转百回,不怕你头不晕,而第4步我还没有彻底的理解清楚,消息映射和命令传递设计也很精彩,纵观这六步,需要开发人员开发时特别专注就是第1步和5、6步,而这你会发现,就是上面我们探讨的那两个过程。所以我建议学习windows编程的同学,好好的深入理解这两个过程吧。
关于这两个过程,我也还在不断学习中,如果有新的心得再记录下来吧。