(全)windows+sdk编程系列文章_第1页
(全)windows+sdk编程系列文章_第2页
(全)windows+sdk编程系列文章_第3页
(全)windows+sdk编程系列文章_第4页
(全)windows+sdk编程系列文章_第5页
已阅读5页,还剩466页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

s编程系列文章消息框在本中,们将用言写个程,程运行将弹一个消息框并显"helloworld"。理论:Windows为编应用序提了大量的资源。其中最重要的是API(ApplicationProgrammingInterface)。API是一大功能大的数它们本身驻在中人们随时用这些函数的大部分包含在几动态接(DLL)中,如:kernel32.dll、user32.dll和gdi32.dll。中的函数主处理存管和进调度;user32.dll中的数主控制户界面gdi32.dll中的数则负责形方面的作。除了面主的三动态接库您还可以调用包含在他动链接中的函数,当然您必须要有关这些函数足够的资。动态接库顾名义,这些的代码本身并不包含在可执文件中,是当要使时才加载为了应用程序在行时找到些函数,就必须事先把有关的定位信息入到应用序的执行件中这些息存于引入中,由链接把相信息引入库中找出插入到可执行文中。您必指定正确引入,因只有确的入库才会有正确的重定位信。当应程序加载时会查这信息这些信息包态链库的名和其中调用函数名检查到这的信息Windows就会加载相应的动态链接库,并定位用的函数语入,以在用函时控能到函数内部。如从的关分API有:是理的一是理的。一函数名的部一个,理则一个"W"(我是代思)。们的是以NULL的一数组,一个是一个。于语系,ANSI足够了于有上个一的几方言系只用了。一个有个,一就可以一中使用个不了。几个有处理这的,如:MessageBoxA和MessageBoxW,其中是用于处理的。是用于UNICODE的。在中了用,这个进了定义。一使用MessageBox。的时会编定是使用还是使用。面WINUSER.H中于MessageBox的定义。WINUSERAPIintWINAPIMessageBoxA(HWNDhWndLPCSTRlpText,LPCSTRlpCaption,UINTuType);WINUSERAPIintWINAPIMessageBoxW(HWNDhWndLPCWSTRlpText,LPCWSTRlpCaption,UINTuType);#ifdefUNICODE#defineMessageBoxMessageBoxW#else#defineMessageBoxMessageBoxA#endif其中WINUSERAPI是个,义其的函是其他库中入,是身定义。#if!defined(_USER32_)#defineWINUSERAPIDECLSPEC_IMPORT#else#defineWINUSERAPI#endif为了可以,在处理时,我们用。会的,将的为应。:Helloword)#include"windows.h"#include"tchar.h"int_stdcallWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnShowCmd){MessageBox(NULL,_T("helloworld"),_T("MyFirstWindowsProgram"),MB_OK);return1;}分析:当我们在工程中Settings里面设置下图所示的UNICODE,_UNICODE时,代码中的world")和_T("MyFirstWindows编时都转化为字。MessageBox也会使用函。的置,使MBCS.代码中的_T("helloworld")和_T("MyFirstProgram")译时都转化为ANSI字MessageBox也使用A函数。windows编系列章简单窗口程序理论:Windows程序中,在图形用界面时需要用大量标准Windows函数其实这用户程序员说都好处,于用户,对的是一套准的窗,对些窗口操作是一样,所使用不的应程序时须重学习操。对序员来说些源代码都是经过了微软严格测试随时拿来可以用的然至于具体地写程序对于程序员来说还是有难度的。为了创建基于窗口的应用程序,必须严格遵守规范。作到这一点并不难,只要用模块化或面向对象的编程方法即可。下面我就列出在桌面显示一个窗口的几个步骤:

得到您应用程序的句柄(对于C程序,可选);得到命令行参数(如果您想从命令行得到参数,可选);注册窗口类(必需,除非您使用预定义的窗口类,如MessageBox或dialogbox;产生窗口(必需);在桌面显示窗口(必需,除非您不想立即显示它);刷新窗口客户区;进入无限的获取窗口消息的循环;如果有消息到达,由负责该窗口的窗口回调函数处理;如果用户关闭窗口,进行退出处理。相对于单用户的的编程来说Windows下的程序框架结构是相当复杂的但是和系统架构上是截然不的。Windows是一个的作系统,系统时有个应用程序行这就要Windows程员必须严格遵守编程范,并的编程格。:FirstWindow)#include"Windows.h"#include"tchar.h"HWNDhWinMain;TCHARszClassName[]=_T("MyClass");TCHARszCaptionMain[]=_T("MyFirstWindow!");TCHARszText[]=_T("Win32program,Simpleandpowerful!");WNDCLASSEXstdWndClass;//如有消息到达,负责该窗口的口回调函数处理LRESULTCALLBACKProcWinMain(HWNDhWnd,UINTMsg,WPARAMwParam,LPARAMlParam){switch(Msg){//如用户关闭窗口,进退出处理caseWM_CLOSE:{DestroyWindow(hWinMain);PostQuitMessage(NULL);}break;default:returnDefWindowProc(hWnd,Msg,wParam,lParam);}return0;}intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow){MSGstMsg;WNDCLASSEXstdWndClass;RtlZeroMemory(&stdWndClass,stdWndClass.hCursor=LoadCursor(0,IDC_ARROW);stdWndClass.cbSize=sizeof(stdWndClass);stdWndClass.style=CS_HREDRAW|CS_VREDRAW;stdWndClass.lpfnWndProc=ProcWinMain;stdWndClass.hbrBackground=(HBRUSH)COLOR_WINDOW;stdWndClass.lpszClassName=szClassName;stdWndClass.hInstance=hInstance;//注册窗口RegisterClassEx(&stdWndClass);//产生窗口hWinMain=CreateWindowEx(WS_EX_CLIENTEDGE,szClassName,szCaptionMain,\WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,NULL,hInstance,NULL);if(!hWinMain)return0;//在桌面显示窗口ShowWindow(hWinMain,SW_SHOWNORMAL);//刷新窗口客户区UpdateWindow(hWinMain);//进入无限的获取窗口消息的循环while(GetMessage(&stMsg,NULL,0,0)){TranslateMessage(&stMsg);DispatchMessage(&stMsg);}returnstMsg.wParam;}分析:看到一个简单的程序有这么多行您是不是有点想撤?但是您必须要知道的是上面的大多数代码都是模板而已模板的意思即是指这些代码对差不多所有标准程序来说都是相同的。在写Windows程序时您可以把这些代码拷来拷去,当然把这些重复的代码写到一个库中也挺好。其实真正要写的代码集中在中。这和一些编器一样,无须要关心集中精力于WinMain函数。唯不的是编器要求您源码必有一个函数叫。否则C无法知道将哪个函数和有关的前后码链接。相对供了较大的灵活,它不强行求一个叫的函数。下面我们开始分析,您可得好思想准备这可不是一件太轻松的活。头文件:是编写windows程序必须包含,因为中包大量要到的量和,有包含windows所有的量和,对于序中们用到在windows.h的,我可以看到函数在的头件和文件,含进行了们得我们程序用的在(:CreateWindowEx,RegisterWindowClassEx)和kernel32.dll(ExitProcess)中函数,所以必须链接个。接下来我:您要么链入您的程序?是:到您要用的函数在么中,后包进来。在的中已包了用的所示。因,我们在代码中无显的用到的。显式加载的方法是在代码中加入一句,例如:#pragmacomment(lib,"kernel32.lib“)我们在前面曾经讲过,windows提供的函数封装在几个DLL,调用DLL中的这些API函数,有两种方法,我们现在用的就是其中一种,即静态加载办法。还有一种是动态加载,我们将在后面讲DLL的时候,再给大家介绍。windows应用程序中必须要有WinMain函数,这个函数是由C编译器需要的,代码编译后,在程序运行时,该函数由运行库调用,传入个参数。用户可以把它作是程序的入口。该函数共有个参数:应用程序的实例句柄,该应用程序的前一实例句柄,命令行参数串指针和窗口如何显示。Win32没有前一实例句柄的概念,所以第二个参数总为。之所以保留它是为了和Win16兼容的考虑,在下,如果是,则该函数是第一次运行。函数声明如下:intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow);特别注意:WIN32下的实例句柄实际上是您应用程序在内存中的线性地址。即HINSTANCEhInstance。如果你要处理命令行,可以从lpCmdLine参数中得到程序传入的命令行串。WINAPI是一个宏,#defineWINAPI__stdcall#defineCALLBACK__stdcall这个是一种函数调用约定。在API中几乎所有的函数,都是采用WINAPI这种函数约定。这种调用约称为标准调用约定。指定了用一个函数,函数采用从右到左的栈方式,自己在退出时清。VC将函数编译后在函数前面加上下线前,在函数后上参的数还有几种调用约定在这作绍。_cdecl调用约定从右左的序压数入栈由调用把参数出栈。传参的内存是由调的为,实可参的函数用该调约定),在函约方面有所。_cdecl是和C程序的调方式。一个调用它函数都清栈代码,以的行大调用stdcall函的。函数采用从右到左压栈方式。VC将函数译后在函数面加上下线。是调用定。_fastcall调用定是""如其它的要就是为是过存器参的实际上,它用ECXEDX传前两个DWORD)的参数,下的参自左栈传,调用的函数前理传参数的内栈),在函数约方面,和前两。_fastcall方式函数采存传参数,VC将函编译后在函数前面上"@",在函数加上"@"和数的数。__stdcall__cdecl和_fastcall可加要出的函前可在编译的Setting...C/C++CodeGeneration。加在出函数前的编译中的时,加在出数前的。它们应的命令行参数别Gz/Gd和/Gr。态为Gd,即__cdecl。WinMain函数中用的,是一个宏。#defineRtlZeroMemory(Destination,Length)memset((Destination),0,(Length))在中主要概念就是窗口类(windowclass),一个窗口类就是一个有关窗口的规范,这个规范定义了几个主要的窗口的元素,如:图标、光标、背景色、和负责处理该窗口的函数。您产生一个窗口时就必须要有这样的一个窗口类。如果您要产生不止一个同种类型的窗口时,最好的方法就是把这个窗口类存储起来,这种方法可以节约许多的内存空间。如果您要定义自己的创建窗口类就必须:在一个或结构体中指明您窗口的组成元素,然后调用RegisterClass或RegisterClassEx,再根据该窗口类产生窗口。对不同特色的窗口必须定义不同的窗口类。有几个预定义的窗口类,譬如:按钮、编辑框等。要产生该种风格的窗口无须预先再定义窗口类了,只要包预定义类的类名作为参数调用即可。WNDCLASSEX中最重要的成员莫过于lpfnWndProc了。前缀lpfn表示该成员是一个指向函数的长指针。在中由于内存模式是型,所以没有或far的区别。每一个窗口类必须有一个窗口过程,当把属于特定窗口的消息发送给该窗口时,该窗口的窗口类负责处理所有的消息,如键盘消息或鼠标消息。由于窗口过程差不多智能地处理了所有的窗口消息循环所以您只要在其中加入消息处理过程即可对于WNDCLASSEX的定义见WINUSER.H可以看了用不同的,定义了个结构体。后有一个宏,根据编来定用个结构。typedefstructtagWNDCLASSA{UINTstyle;WNDPROClpfnWndProc;intcbClsExtra;intcbWndExtra;HINSTANCEhInstance;HICONhIcon;HCURSORhCursor;HBRUSHhbrBackground;LPCSTRlpszMenuName;LPCSTRlpszClassName;}WNDCLASSA,*PWNDCLASSA,NEAR*NPWNDCLASSA,FAR*LPWNDCLASSA;typedefstructtagWNDCLASSW{UINTstyle;WNDPROClpfnWndProc;intcbClsExtra;intcbWndExtra;HINSTANCEhInstance;HICONhIcon;HCURSORhCursor;HBRUSHhbrBackground;LPCWSTRlpszMenuName;LPCWSTRlpszClassName;}WNDCLASSW,*PWNDCLASSW,NEAR*NPWNDCLASSW,FAR*LPWNDCLASSW;#ifdefUNICODEtypedefWNDCLASSWWNDCLASS;typedefPWNDCLASSWPWNDCLASS;typedefNPWNDCLASSWNPWNDCLASS;typedefLPWNDCLASSWLPWNDCLASS;#elsetypedefWNDCLASSAWNDCLASS;typedefPWNDCLASSAPWNDCLASS;typedefNPWNDCLASSANPWNDCLASS;typedefLPWNDCLASSALPWNDCLASS;#endif//UNICODE

cbSizeWNDCLASSEXsizeofWNDCLASSEXstylelpfnWndProccbClsExtracbWndExtraCLASSDLGWINDOWEXTRAhInstancehIconhCursorhbrBackgroundlpszMenuNamelpszClassNamehIconSmNULLhCursorCreateWindowEx12

dwExStyleCreateWindow9X/NTStyle任NULLlpClassNameASCIIZ式地址自义预上所说lpWindowNameASCIIZ形地显条空条什都dwStyle外零样就系也没最化最化钮没闭钮样按闭它普WS_OVERLAPPEDWINDOW种按掩码样“or”望或起像WS_OVERLAPPEDWINDOW就由几种最普遍或起XY左上角像素位屏幕坐位缺省地CW_USEDEFAULT样会动最位置nWidthnHeight像缺地CW_USEDEFAULT样会动最hWndParent父告诉Windows子他父谁多文档同子并会局父客区内他告Windows各之父系便父销同其子销毁子因只故NULLhMenuWINDOWS只系NULL头WNDCLASSEXlpszMenuName它也缺任若他需其双义方面若自义代表另方面若预义代表ID号Windows据lpClassName分自义预义hInstancelpParam选欲给体据型MDI递CLIENTCREATESTRUCT情况下总零表没传递给通GetWindowLong检索hWinMain=CreateWindowEx(WS_EX_CLIENTEDGE,szClassName,szCaptionMain,\CreateWindowEx功eax存备刚会自显示ShowWindow按望方显接UpdateWindow更客户区ShowWindow(hWinMain,SW_SHOWNORMAL);UpdateWindow(hWinMain);已示屏上了它还能外界接收消息所给提消通过息循完工每仅消循断GetMessageWindows消息GetMessage传递MSG体给Windows然Windows充消直到Windows找到并填充好消息GetMessage才会返回段间内系统控制权能会给其他样就Win16多任务GetMessageWM_QUITFALSETranslateMessageWM_CHARASCIIDispatchMessagewhile(GetMessage(&stMsg,NULL,0,0)){TranslateMessage(&stMsg);DispatchMessage(&stMsg);}MSGwParamWindowsreturnstMsg.wParam;LRESULTCALLBACKProcWinMain(HWNDhWnd,

windowsWindowsUINTMsg,WPARAMwParam,LPARAMlParam);hWnduMsguMsgMSGDWORDWindowsWindows能些wParam和附加方递更据LRESULTCALLBACKProcWinMain(HWNDhWnd,UINTMsg,WPARAMwParam,LPARAMlParam){switch(Msg){caseWM_CLOSE:{DestroyWindow(hWinMain);//PostQuitMessage(NULL);//}break;default:returnDefWindowProc(hWnd,Msg,wParam,lParam);}return0;}约CALLBACK即也采准约LRESULTCALLBACKWindowProc(HWNDhwndUINTuMsgWPARAMwParam,LPARAMlParam);兴趣则加完再0否必须即递缺省所必WM_DESTROYWindows传进来说屏幕失仅通销毁须己准备Windows此做些清作无法阻止要样WM_CLOSE清工作必WM_QUIT传而GetMessage0WINDOWSDestroyWindowWM_DESTROY自迫indowsdk编系文章绘制本本课学习何客户区“绘”字串将习“设备境”概念论:Windows中的文本是一个(图形用户界面)对象。每一个字符实际上是由多的像素点组成,这些点在有笔画的地方显示出来,这样就会出现字符。这也是为什么我说“绘制”字符,而不是写字符。通常您都是在您应用程序的客户区“绘制”字符串(尽管您也可以在客户区外“绘制”)。Windows下的“绘制”字符串方法和Dos下的截然不同,在下,您以把屏幕想象成25的一个平面,而Windows下由于屏幕上同时有几个应用程序的画面,所以您必须严遵规。Windows过把每一个应用程序限制在他的客户区来做到这一点。当然客户区的大小是可变,随可调。在您在客户区“绘制”字符串前,您必须从Windows那里得到您客户区的大小,确实您无法像在下那样随心所欲地在屏幕上任何地方“绘制”制前您必须得到Windows的许后Windows会诉您客户区的大小体和它对象属。您以这来客区“制。什是“备境”(DC)呢?实是由内部维护的个据构一“备境”个定设相。像印和示。于示来,“备境”个相。“备境”的些性和有,:颜,体。您以时所是您可以“备境”成是您的个绘环,而可随性。当应程序绘制时,您必须得到一个“设备环境”通常几法。

在中用在他中用的您须的是在个必须“设环境”不在个中得“备境”,而在一个中在它。我在WM_PAINT时绘制户区,Windows不会客户区的内,它用是方是“绘机制(当客户区一个应用序的户区)Windows会把WM_PAINT应用序的。绘窗的客户区是个窗口的任,您的是窗口过程WM_PAINT的部绘制什么和绘制。您必须的一是“无区”Windows把一小绘方区做无区当Windows现一个”无区“后,它会应用程序一个,在的过程中,窗口得到一个有关绘图的结构体,里面无区等。您可以通过用BeginPaint“无区有,您不WM_PAINT,调用的窗口数DefWindowProc,调用无区”有。您的用程序会到无无尽的。下面是应的:得“设环”绘制客户“设环”,您须地“无区”有,这个由。您可在和Endpaint,调用所有的绘制。所有的数都“设环”数。:(FirstWindow2)下面我一个应用程序,它在户的心示"Win32program,Simpleandpowerful!"#include"Windows.h"#include"tchar.h"HWNDhWinMain;TCHARszClassName[]=_T("MyClass");TCHARszCaptionMain[]_T("MyFirstWindow!");TCHARszText[]=_T("Win32program,Simpleandpowerful!");WNDCLASSEXstdWndClass;LRESULTCALLBACKProcWinMain(HWNDhWnd,UINTMsg,WPARAMwParam,LPARAM){PAINTSTRUCTstPs;RECTstRect;HDChDC;switch(Msg){caseWM_PAINT:{hDC=BeginPaint(hWnd,&stPs);GetClientRect(hWnd,&stRect);rawText(hDC,szText,-1,&stRect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);ndPaint(hWnd,&stPs);}break;caseWM_CLOSE:{DestroyWindow(hWinMain);PostQuitMessage(NULL);}break;default:returnDefWindowProc(hWnd,Msg,wParam,lParam);}return0;}intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow){MSGstMsg;WNDCLASSEXstdWndClass;RtlZeroMemory(&stdWndClass,sizeof(stdWndClass));stdWndClass.hCursor=LoadCursor(0,IDC_ARROW);stdWndClass.cbSize=sizeof(stdWndClass);stdWndClass.style=CS_HREDRAW|CS_VREDRAW;stdWndClass.lpfnWndProc=ProcWinMain;stdWndClass.hbrBackground=(HBRUSH)COLOR_WINDOW;stdWndClass.lpszClassName=szClassName;stdWndClass.hInstance=hInstance;RegisterClassEx(&stdWndClass);hWinMain=CreateWindowEx(WS_EX_CLIENTEDGE,szClassName,szCaptionMain,\WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,NULL,hInstance,NULL);if(!hWinMain)return0;ShowWindow(hWinMain,SW_SHOWNORMAL);UpdateWindow(hWinMain);while(GetMessage(&stMsg,NULL,0,0)){TranslateMessage(&stMsg);DispatchMessage(&stMsg);}returnstMsg.wParam;}分析:这里的大多数代码和第三课中的一样。我只解释其中一些不相同的地方。PAINTSTRUCTstPs;RECTstRect;HDChDC;这些局部变量由处理消息中的数调用。hdc用来存放调用返回的“设备环境”句柄ps是一个PAINTSTRUCT数类的变。通您不用到其的许多值它由传递给BeginPaint,在结束绘制后再原封不动的传递给EndPaint。rect是一个结体类参,它定义如:{top;和是正方形左上角的坐标和是正方形右下角的坐标。客户区的上角的坐标是,y=0,样对于,y=10的坐标点就在它的下面。=BeginPaint(hWnd,&stPs);szText,-1,&stRect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);在处理消时您用函,传给它一窗口句柄和未初始化的型数。调用成功后在中得到返回“设备环境”的句柄。下一次,调用以得到户区的大,大小放在rect中,然后把它传给DrawTextDrawText的语法如下:WINUSERAPIintWINAPIDrawTextA(HDChDC,LPCSTRlpString,intnCount,LPRECTlpRect,UINTuFormat);DrawText是一个高层的调用函数。它能自动处理像换行、把文本放到客户区中间这些杂事。所以您只管集中精力“绘制”字符串就可以了。我们会在下一课中讲解低一层的函数,该函数在一个正方形区域中格式化一个文本串。它用当前选择的字体、颜色和背景色。它处理换行以适应正方形区域。它会返回以设备逻辑位度量的文本的高度,我们这里的度量单位是像素点。让我们来一该函数的参数:

hdc:“设备环境”的句柄。lpString的文本串,该文本串以NULL结,nCount中它的。nCount:文本的。以NULL结,该参数是1。lpRect:文本串的正方形区域的,该方形是一区,就是该区域的字符能。uFormat:定如我可以用把以标一ooo

DT_SINGLELINE:是行。DT_CENTER:是中。是。结束制,用“设环”句柄。,在们把绘”文本串点如:1.始和结束处调用EndPaint在间调用所绘制数如其的消息处中制户区,您以选择:用和ReleaseDCBeginPaint和调用InvalidateRect让客户区WINDOWS把用息客区。

多于“绘制文本的我们多了文本的多如字体和色等。理:Windows的颜色是用值来的色色色如您一颜就给颜色的值RGB的是0到255如您得到色就对RGB2550色255255,255。我们下面中可以用于数字的色不,这您对和颜的。您可以用函数SetTextColor和SetBkColor来“制”背景色和字符颜色传递一个“设备环境”的句和RGB值参数COLORREF类型用来绘一个RGB颜色。其义如:typedefDWORDCOLORREF;typedefDWORD*LPCOLORREF;0x00bbggrrRGB_valuestruct{byteunused;bytebluebytegreenbytered;};00COLORREFRGB(byRed,//ofbyGreen,//ofbyBlue//blueof);备境

CreateFont把选“设成随有“”文串都把作:见光盘FirstWindow3)#include"Windows.h"#include"tchar.h"TCHARszClassName[]_T("MyClass");TCHARszCaptionMain[]_T("MyFirstWindow!");TCHARszText[]program,Simpleandpowerful!");TCHARFontName[]=_T("script");WNDCLASSEXstdWndClass;LRESULTCALLBACKProcWinMain(HWNDhWnd,Msg,WPARAMwParam,LPARAMlParam){PAINTSTRUCTstPs;HDChDC;HFONThFont,hOldFont;switch(Msg){{hDC=BeginPaint(hWnd,&stPs);hFont=CreateFont(24,16,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SCRIPT,FontName);hOldFont=(HFONT)SelectObject(hDC,hFont);SetTextColor(hDC,RGB(200,200,50));etBkColor(hDC,RGB(0,0,255));extOut(hDC,0,0,szText,sizeof(szText));SelectObject(hDC,hOldFont);EndPaint(hWnd,&stPs);}break;caseWM_DESTROY:{PostQuitMessage(NULL);}break;default:returnDefWindowProc(hWnd,Msg,wParam,lParam);}return0;}intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow){MSGstMsg;WNDCLASSEXstdWndClass;RtlZeroMemory(&stdWndClass,sizeof(stdWndClass));stdWndClass.hCursor=LoadCursor(0,IDC_ARROW);stdWndClass.cbSize=sizeof(stdWndClass);stdWndClass.style=CS_HREDRAW|CS_VREDRAW;stdWndClass.lpfnWndProc=ProcWinMain;stdWndClass.hbrBackground=(HBRUSH)COLOR_WINDOW;stdWndClass.lpszClassName=szClassName;stdWndClass.hInstance=hInstance;RegisterClassEx(&stdWndClass);hWinMain=CreateWindowEx(WS_EX_CLIENTEDGE,szClassName,szCaptionMain,\WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,NULL,hInstance,NULL);if(!hWinMain)return0;ShowWindow(hWinMain,SW_SHOWNORMAL);UpdateWindow(hWinMain);while(GetMessage(&stMsg,NULL,0,0)){TranslateMessage(&stMsg);DispatchMessage(&stMsg);}returnstMsg.wParam;}分析:CreateFont函数产生一种逻辑字体,它尽可能地接近参数中指定的各相关值。这个函数大概是所有WindowsAPI函数中所带参数最多的一个。它返回一个指向逻辑字体的句柄供调用SelectObject函数使用。下面我们详细讲解该函数的参数:intnHeight,//heightfontint,//intnEscapement,//ofintnOrientation,//int,//fontfdwItalic//fdwUnderline//fdwStrikeOut//fdwCharSet//,,//fdwQuality//output,LPCTSTR

name);nHeight0nWidth0Windows16nEscapement0900901902700270nOrientationnWeightWindowsFW_DONTCARE0FW_THIN100FW_EXTRALIGHT200FW_ULTRALIGHT200FW_LIGHT300FW_NORMAL400FW_REGULAR400FW_MEDIUM500FW_SEMIBOLD600FW_DEMIBOLD600FW_BOLD700FW_EXTRABOLD800FW_ULTRABOLD800FW_HEAVY900FW_BLACK900cItalic0cUnderline0cStrikeOut0cCharSetOEM_CHARSETWindowscOutputPrecisioncClipPrecisioncQualityGDI

OUT_DEFAULT_PRECISCLIP_DEFAULT_PRECISDEFAULT_QUALITYPROOF_QUALITYDRAFT_QUALITYcPitchAndFamily族lpFacename名称上面描述不理解要到更多信息参考hOldFont=(HFONT)SelectObject(hDC,hFont);逻句柄后必须SelectObject函数进“函把GDI“函“句必须句柄后把调SelectObject函后函数SetTextColor(hDC,RGB(200,200,50));SetBkColor(hDC,RGB(0,0,255));RGB后SetTextColorSetBkColorTextOut(hDC,0,0,szText,sizeof(szText));调TextOut“SelectObject(hDC,hOldFont);在我们“绘制”完成后,必须恢复“设备环境”。我们必须每一次都这么做。s编程系列文章处理键盘输入息在本中,我们将学习序是如何处理键盘消的。理论:因为多数的只有一个键盘所以所有运行中的WINDOWS程序必须用它WINDOWS将责把击键消送到有输入焦点那个用程序中去尽管屏幕上可能同时几个用程序窗口,但一个时刻仅有一个窗口有入焦。有输入焦点那个用程序标题条总是亮度显示的。实上您以从两个角来看盘消息:一是您可以把它看是一堆的按键消息的集合,在这情况下当您按下个键WINDOWS就发送一个WM_KEYDOWN给输入点的那个应用序提醒它有一键被下。当您放键时,WINDOWS又会发一个WM_KYEUP息,告诉一个被释放。您把每一个键当成是一个按钮;一种况是:您可把键盘看成字符输入设备按下a”键时发送个WM_CHAR消给有输入焦点的应用程诉它a”键被下。实际上WINDOWS内部发送WM_KEYDOWN和消给有入焦点的应程序而这些消息通过调用TranslateMessage翻译成WM_CHAR消息。窗口程函数决定否处理所收的消,一般说来不大去处理WM_KEYDOWNWM_KEYUP消,在息循环中TranslateMessage数会把上息成WM_CHAR息。我们的课程将只处理WM_CHAR。:(盘FirstWindow4)#include"Windows.h"#include"tchar.h"HWNDhWinMain;TCHARszClassName[]=_T("MyClass");TCHARszCaptionMain[]_T("MyFirstWindow!");TCHARFontName[]=_T("script");WNDCLASSEXstdWndClass;WPARAMkeyChar=0x20;//0x20是的ascii,有按键的时程显示。LRESULTCALLBACKProcWinMain(HWNDhWnd,UINTWPARAMwParam,LPARAMlParam){PAINTSTRUCTstPs;HDCHFONThFont,hOldFont;switch(Msg){caseWM_PAINT:{hDC=BeginPaint(hWnd,&stPs);hFont=CreateFont(24,16,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SCRIPT,FontName);hOldFont(HFONT)SelectObject(hDC,hFont);SetTextColor(hDC,RGB(200,200,50));etBkColor(hDC,RGB(0,0,255));extOut(hDC,0,0,(char*)&keyChar,1);SelectObject(hDC,hOldFont);EndPaint(hWnd,&stPs);}break;caseWM_CHAR:{keyCharwParam;InvalidateRect(hWnd,NULL,TRUE);}break;caseWM_DESTROY:{PostQuitMessage(NULL);}break;default:returnDefWindowProc(hWnd,Msg,wParam,lParam);}return0;}intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow){MSGstMsg;WNDCLASSEXstdWndClass;RtlZeroMemory(&stdWndClass,sizeof(stdWndClass));stdWndClass.hCursor=LoadCursor(0,IDC_ARROW);stdWndClass.cbSize=sizeof(stdWndClass);stdWndClass.style=CS_HREDRAW|CS_VREDRAW;stdWndClass.lpfnWndProc=ProcWinMain;stdWndClass.hbrBackground=(HBRUSH)COLOR_WINDOW;stdWndClass.lpszClassName=szClassName;stdWndClass.hInstance=hInstance;RegisterClassEx(&stdWndClass);hWinMain=CreateWindowEx(WS_EX_CLIENTEDGE,szClassName,szCaptionMain,\WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,NULL,hInstance,NULL);if(!hWinMain)return0;ShowWindow(hWinMain,SW_SHOWNORMAL);UpdateWindow(hWinMain);while(GetMessage(&stMsg,NULL,0,0)){TranslateMessage(&stMsg);DispatchMessage(&stMsg);}returnstMsg.wParam;}分析:WPARAMkeyChar=0x20;这个变量将保存从键盘接收到的字符。因为它是在窗口过程中通过WPARAM型变量传送的,所以我们简单地把它定义为型。由我们的口在初次刷新(也刚被创的那一次)是没有盘入的所以们他设成空格符(20h),样显时您就么看不。case{=}这一段是用来处理WM_CHAR消息的。它把接收到的字放入变量keyChar中着InvalidateRect,而使客样WM_PAINTWM_PAINT消WINDOWS重客语下:BOOL,CONSTRECT*lpRect,bErase//eraselpRectNULLWINDOWSTRUEBeginPaintWM_PAINTWINDOWSGetDCReleaseDC也能出确之接收到会而稍前会失为让直确地示必须它到中而本中即InvalidateRectWM_PAINT被到WINDOWS窗口流WM_PAINTBeginPaint到TextOut(00)输按键论您什键能左角显论怎窗口(迫使它)会地显必须动作到WM_PAINT去s编系列章鼠标输入本课学习何口中标按示例示何待左按按位置示串论和键输入WINDOWS捉鼠动作并它到窗口活动括左、右按、移动、双击鼠标还包滚轮WM_WHEELWINDOWS键盘输入鼠导入焦窗任何鼠标窗口接到标论输入焦外窗还接收到鼠标非移动WM_NCMOVE)多情况会忽对鼠标钮两WM_LBUTTONDOWN,WM_RBUTTONDOWN对三鼠标还会WM_MBUTTONDOWN和WM_MBUTTONUP当鼠标窗口移动窗接到口若WM_LBUTTONDBCLKWM_RBUTTONDBCLK它窗口类必CS_DBLCLKS风格它就会接受到按键起落(WM_XBUTTONDOWN或WM_XBUTTONUP)对窗口传参lParam包鼠标位置中底位为标高为坐些标对口左wParam中包含鼠标按钮状态见光盘FirstWindow5)==TCHAR=_T("宋=0x20;空ascii,按键常=UINTMsg,LPARAMlParam){HDC{case{==={}}case{===}case{keyChar=wParam;}case{}default:Msg,}}WINAPI){stMsg;========0;{}}分析:{===}窗口程处了消息,接收该消时,lParam中含了对于口客区左角的标,们把它保存下来放到个结体变(POINT)中,该结构体量的义如:tagPOINT{}然后们把志量MouseClick设为,这表明至有一在客区的键按消息。=TRUE;于lParam是一个、16位别括了所做些以里用两宏HIWORD分别高位和16位的值。两宏于WINDEF.H。:#define#define&0xFFFF))==完志MouseClick为理WM_PAINT时用来判否鼠调InvalidateRect函迫重。{}绘制客户区的代码首先检测标志,再决定是否重绘。因为我在次示窗口时还没左键按下的消息,所以我们初时把该标志设为,诉WINDOWS不要重绘客户区,有左键按的消息时,它会在鼠标按下的位置绘制字符串。注意在调用TextOut()函数时,关于字符长度的参是调用lstrlen(函数来计算的。sdk程系列文章菜单本课我们在我的应用程序中加入一个菜单。WINDOWS.,,..:"File""Edit","Help",.,(...).,,,.,器指又.任何文本编辑器编写脚本文件,文件指呈现来观些属.当然更直观法编辑器,通常编辑器都打编译环境,VisualC++,BorlandC++都带编辑器.按来MyMenuMENU{list}C语言非常MyMenu类似于被变关键当然另办法BEGINEND来代替花风格相列POPUP语句MENUITEM当不激语法"&text",开紧MENUITEM指名称号““第带画线也快捷当被WINDOWS息处来区分毫疑问号必唯options属性

GRAYED代表处于非激活状态当消息灰代表处于非激活状态当不产生消息颜随显示列随齐独使上志也或起当然INACTIVEGRAYED不使POPUP语法{[menu被子另特别类型MENUITEM句MENUITEMSEPARATOR表示置条隔线完使脚本或叫做使

WNDCLASSEX结构体成员lpszMenuName““按法联系窗(见FirstWindow6-1)TCHAR==MenuName;CreateWindowEx函指柄(见TCHAR===着什不同呢法由派不同使第二法通过函数CreateWindowEx指“WNDCLASSEX结构体知窗口过程的:户选择了一个菜单时,WINDOWS口过程会接收到一个消息,传进来参数底字节包含了菜单项的号。好了,上面就是关于菜单项一切,下面我们就来实践。例子:#include#include"tchar.h"#defineIDM_TEST1#defineIDM_HELLO2#define3#defineIDM_EXIT4TCHARMenuName[]=_T("FirstMenu");TCHAR=_T("Youselectedmenuitem");TCHARHello_string[]=_T("Hello,myfriend");TCHARGoodbye_string[]=_T("Seeyouagain,bye");HWNDhWinMain;TCHAR=_T("MyClass");TCHARszCaptionMain[]=_T("MyFirstWindow!");TCHARFontName[]=宋体);=是空格的码保证没有按键的时候程序正显示。BOOL=hWnd,UINT){HDChDC;{case{hDC==={}}case{{casecasecasebreak;caseIDM_EXIT:DestroyWindow(hWnd);break;}}break;caseWM_LBUTTONDOWN:{hitPoint.x=LOWORD(lParam);hitPoint.y=HIWORD(lParam);MouseClick=TRUE;InvalidateRect(hWnd,NULL,TRUE);}break;caseWM_CHAR:{keyChar=wParam;InvalidateRect(hWnd,NULL,TRUE);}break;caseWM_DESTROY:{PostQuitMessage(NULL);}break;default:returnDefWindowProc(hWnd,Msg,wParam,lParam);}return0;}intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow){MSGstMsg;WNDCLASSEXstdWndClass;RtlZeroMemory(&stdWndClass,sizeof(stdWndClass));stdWndClass.hCursor=LoadCursor(0,IDC_ARROW);stdWndClass.cbSize=sizeof(stdWndClass);stdWndClass.style=CS_HREDRAW|CS_VREDRAW;stdWndClass.lpfnWndProc=ProcWinMain;stdWndClass.hbrBackground=(HBRUSH)COLOR_WINDOW;stdWndClass.lpszClassName=szClassName;stdWndClass.hInstance=hInstance;stdWndClass.lpszMenuName=MenuName;RegisterClassEx(&stdWndClass);hWinMain=CreateWindowEx(WS_EX_CLIENTEDGE,szClassName,szCaptionMain,\WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,NULL,hInstance,NULL);if(!hWinMain)return0;ShowWindow(hWinMain,SW_SHOWNORMAL);UpdateWindow(hWinMain);while(GetMessage(&stMsg,NULL,0,0)){TranslateMessage(&stMsg);DispatchMessage(&stMsg);}returnstMsg.wParam;}1#defineIDM_HELLO2#define34{{"Say}"&Test",}{分析:我们来分析资源件:1IDM_TEST#defineIDM_HELLO2#define34的。项必ID任用MENU定。{"&Say"Say}定义一个有四个菜单项的子菜单,其中第三个菜单项是一个分隔线。"&Test",主中一。看代==Testmenu=TCHAR=_T("Seeagain,MenuName是资文件中指定菜单的名。因为您可以在脚本文件中定义任意多个菜单,所以在使前必须指定您要使用那一个,接下来的行是在选中菜单项时显示在相关对话框中的字符串。1;2equ34在WINDOWS项号。这些。case{{casecase}}在本口过中我处理WM_COMMAND消息户了一菜单时项的放数中被同时到的窗过程我们它保到寄存器以便预定的菜单项较用。前种情下,我们中Hello、SayGoodBye菜单项时,弹出一个对话框其中示一相关的字符串,选择单项,我就调函数DestroyWindow,其中的数是我们窗的句柄,这样就销毁了窗口。您所看到,通过在一个窗类指菜单名的法来给一个应用程序生成一个单简单而直观的除此方法外您还以另种方法,中资源文件是一样,源文件中也只少的动,这些改动如:HMENU变句:==调用LoadMenu函数该函句名字指句给数CreateWindowEx句。indow章再谈

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论