1目录第一章WindowsAPI开发概述...............................................................................................2第二章GDI编程......................................................................................................................9第三章文本输出与滚动条...................................................................................................15第四章鼠标、键盘及计时器...............................................................................................29第五章资源...........................................................................................................................47第六章Windows标准控件...................................................................................................72第七章调用DLL中的API.....................................................................................................94第八章多任务与多线程.....................................................................................................1102第一章WindowsAPI开发概述1.Dos与Windows的主要区别系统相同点不同点联系Dos系统1.都是系统软件2.都支持应用软件的操作字符界面Windows系统兼容Dos系统无鼠标单用户单任务不稳定,保密性差不支持多媒体Windows系统图文界面有鼠标多用户多任务稳定性、保密性强支持多媒体上表给出了两种系统的一些区别,究其主要区别还是在于Dos是基于过程驱动的方式,而Windows是基于消息驱动的方式。2.学习目的采用WindowsAPI直接对应用需求进行设计。尽管目前有着大量的快速开发工具可供选择,但如果不理解WindowsRing3层的基本工作原理,很难开发出好的软件,也很难在遇到特定问题时进行解决。因此,学习好本门课程对基于Windows的软件设计来说,是十分必要的。3.一个简单的Win32API应用程序:HelloWorld!3.1应用程序示例#includewindows.hLPCTSTRlpszAppName=TEXT(MyApp);LPCTSTRlpszTitle=TEXT(MyApplication);LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);intAPIENTRYWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPTSTRlpCmdLine,intnCmdShow){MSGmsg;HWNDhWnd;WNDCLASSwc;//建立主要的应用程序窗口类//............................................3wc.style=CS_HREDRAW|CS_VREDRAW;wc.lpfnWndProc=(WNDPROC)WndProc;wc.cbClsExtra=0;wc.cbWndExtra=0;wc.hInstance=hInstance;wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);wc.hCursor=LoadCursor(NULL,IDC_ARROW);wc.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);wc.lpszMenuName=lpszAppName;wc.lpszClassName=lpszAppName;if(!RegisterClass(&wc))//注册窗口类return(FALSE);//建立主要的应用程序窗口//....................................hWnd=CreateWindow(lpszAppName,lpszTitle,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);//判断窗口是否建立成功if(!hWnd)return(FALSE);//显示窗口ShowWindow(hWnd,nCmdShow);UpdateWindow(hWnd);//建立消息循环机制while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}return(msg.wParam);}LRESULTCALLBACKWndProc(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam){4//处理消息switch(uMsg){staticintuRed=0,uGreen=0,uBlue=0;//绘制消息caseWM_PAINT:{RECTrect;HDChdc;PAINTSTRUCTps;hdc=BeginPaint(hWnd,&ps);GetClientRect(hWnd,&rect);SetTextColor(hdc,RGB(uRed,uGreen,uBlue));DrawText(hdc,TEXT(Hello,World!),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);EndPaint(hWnd,&ps);}break;//按键消息caseWM_KEYDOWN:{uRed=rand()%255;uGreen=rand()%255;uBlue=rand()%255;InvalidateRect(hWnd,NULL,TRUE);}break;//窗口关闭消息caseWM_DESTROY:PostQuitMessage(0);break;//其它消息default:return(DefWindowProc(hWnd,uMsg,wParam,lParam));}return(0L);}53.2程序结构解析3.2.1Windows的入口函数WInMainWInMain函数与C中的main函数相似,其包含4个参数:HINSTANCEhInstance:实例句柄,唯一地标识了该程序。HINSTANCEhPrevInstance:为了与早期版本兼容,已经不再使用。LPTSTRlpCmdLine:启动命令行参数。intnCmdShow:以何种方式运行(正常、最大化、最小化)。3.2.2窗口类结构WNDCLASStypedefstructtagWNDCLASSA{UINTstyle;//窗口类风格WNDPROClpfnWndProc;//指向窗口过程的指针intcbClsExtra;//窗口类的扩展字节数intcbWndExtra;//窗口实例的扩展字节数HINSTANCEhInstance;//窗口实例句柄HICONhIcon;//类图标的句柄HCURSORhCursor;//类鼠标指针的句柄HBRUSHhbrBackground;//背景画刷句柄LPCSTRlpszMenuName;//窗口菜单名称LPCSTRlpszClassName;//窗口类名}WNDCLASS3.2.3矩形结构typedefstructtagRECT{LONGleft;//左上X坐标LONGtop;//左上Y坐标LONGright;//右下X坐标LONGbottom;//右下Y坐标}RECT3.2.4过程参数Windows消息的wParam参数保存了与消息相关的信息,如产生消息的窗口句柄和ID号(以后都称为“标识符”);lParam参数则保存了一些与消息无关的信息,如消息产生时鼠标位置的坐标值等。3.3消息处理与窗口过程3.3.1消息循环在调用了UpdateWindows之后,窗口就会出现在显示器上,此时Windows就为应用程序维护了一个“消息队列”。当Windows侦测到程序的用户键盘和鼠标输入数据时,就将输入的时间转化为一个“消息”,并将此消息放到程序的消息队列中。所有的应用程序都是通过“消息循环的代码”从消息队列中取出消息,代码如下:while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}6从消息队列中取出消息的函数为GetMessage,函数定义如下:BOOLGetMessageA(LPMSGlpMsg,HWNDhWnd,UINTwMsgFilterMin,UINTwMsgFilterMax);lpMsg:消息结构指针。hWnd:窗口句柄,当设置为NULL时是获取所有窗口的消息。wMsgFilterMin:获取消息ID编号最小值。wMsgFilterMax:获取消息ID编号最大值。返回值:只要消息队列中取出的消息message域不为WM_QUIT(0x0012),GetMessage就返回一个非零值。之后进行一些键盘消息的转换:TranslateMessage(&msg);最后发送给窗口过程进行消息的处理:DispatchMessage(&msg);3.3.2消息处理每个窗口都有与之相对应的窗口过程。窗口过程能够确定其窗口的外观和行为特性,这是通过对进入到窗口过程中的窗口消息的处理完成的。在第1章中,已经讲过了窗口过程的例子,虽然它只处理几个简单的消息,但确实实现了一个标准的窗口。窗口过程总是与已注册的特定窗口类相关联的,一个应用程序可以有几个窗口类,基于每个窗口类都可以创建多个窗口(通过CreateWindow等函数创建)。也就是说,同一个窗口过程可能要处理几个窗口中产生的消息。但是,在多窗口的应用程序中,Windows怎样辨别消息队列中的消息该发给哪个窗口的窗口过程处理呢?在WinMain函数中创建窗口如下所示:hWnd=CreateWindow(LPCTSTRlpClassName,//注册窗口类名//与窗口相关的其他参数)从以上代码可以看到,在创建窗口时,至少要完成两项工作:一项将窗口类及其相关联的窗口过程与新窗口关联起来,另一项是得到新窗口的句柄。这样,当新窗口中产生消息时,Windows的消息循环可以根据这个句柄找到相应的消息处理过程(窗口过程)。下面介绍窗口过程的定义,读者就会更易明白Windows的这一处理过程。LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)注意:窗口过程的hwnd参数指明了产生消息的窗口,其他几个参数则表明了消息信息。这与MSG结构的前四个域是相同的。WndProc被声明为CALLBACK(回调函数),回调函数是输出函数中特殊的一种,能够在Windows环境下直接调用。一个应用程序至少有一个回调函数,因为在应用程序处理消息时,Windows会调用回调函数,即窗口过程。它对应于一个活动的窗口,回调函数必须向Windows注册,