Windows_Program_Via_C_Translate_Win32编程的背景知识/基础知识_包括基本输入输出机制介绍
SomeBasicBackgroundStoryofTheWin32APIs Win32API背景故事/背景知识 TheWin32applicationprogramminginterface(API)providesbuildingblocksusedbyapplicationswrittenfortheMicrosoftWindowsoperatingsystemfamily. Itdefinesthe32-bitmembersoftheWindowsfamilyfromtheprogrammer'spointofviewandyouwillfindoutlater,64-bitmembersalsoincluded.SomemembersoftheWindowsfamilyusetheentireWin32API,whileothersusesubsets. Win32API提供在微软windows操作系统平台上编制应用程序的函数功能块,Win32API从应用程序程序员的角度定义32位windows家族平台下应用程序系统接口,在以后的windows版本将将能够看到64位windows平台的WinAPI(注:实际上在XP平台已经有64位版本的WinAPI)。一些windows平台使用全部的Win32API函数,而一些windows版本则使用Win32API的子集(注:在工业控制和移动应用中大家熟知的WinCE使用的就是Win32API的子集,西门子的MP系列触摸屏使用的就是一个子集,在里面编程可以使用VBscript脚本)。 TheMicrosoftFoundationClassLibrary(MFC)encapsulates,or"wraps,"mostoftheWin32APIbutnotall. 微软基础类库封装了Win32API,但是不是所有的API函数都封装到了MFC. MFCversions2.xandearlierencapsulatedthe16-bitWindowsAPI.MFCsuppliesclassesrepresentingkeyWindowsobjects,suchaswindows,dialogboxes,brushes,pens,andfonts. 2.x版本或更早版本的MFC封装了部分16位的WinAPI,MFC支持windows面向对象编程的中的对象的概念,例如窗口类、对话框类、画刷类、画笔类和字体类等。 ThememberfunctionsoftheseclasseswrapmostoftheimportantWin32APIfunctionsassociatedwiththeencapsulatedobject. 这些类的成员函数封装了与这些对象相关的大部分重要的Win32API函数。 TheMFCclassmemberfunctioncallstheWin32APIfunction,andmightaddfunctionality. MFC类程序员调用Win32API函数,并且可能自封装一些实现其他功能的成员函数。 TheActiveTemplateLibrary(ATL)isasetoftemplate-basedC++classesthatletyoucreatesmall,fastComponentObjectModel(COM)objects.ATLwrapsWin32andCrun-timelibraryAPIs,butdoesnotwrapWin32totheextentthatMFCdoes. ATL类库是C++模板类库的一个子集,它让你可以创建小而快速的对象组建模型的对象。ATL封装了Win32和C语言运行时类库函数,但是和MFC不一样的是它没有封装一些给予Win32的MFC扩展。 WithVisualC++,youcanprogramforWindowsusingeither: CorC++andtheWin32API. C++andMFCor C++andATL. 通过VisualC++你能够使用下下列模型来编制应用程序: 1、C语言、C++或者Win32API。 2、C++或者MFC 3、C++或者ATL。 ForinformationaboutWin32programmingwenormallyrefertoWin32APIandthedocumentationisavailableinthePlatformSDK. 当提及Win32编程时,我们通常描述的是基于Win32API和平台SDK的相关文档。 InthepreviousModulewehavebeenintroducedtosomeoftheMicrosoftimplementationoftheCusingtheCRun-time(CRT)libraries.InthisModulewewillexploretheWin32APIswithC. 在前面的板块我们已经介绍过基于C和C语言运行时库CRT来完成一些微软Windows的应用实现,这里我们将介绍利用Win32和C来的应用实现。 ThisAPIisdesignedforusebyC/C++programmersbutinthisModulewestilldroptheWindowsgraphicaluserinterfaceandmessage-drivenrelatedthings,theMFCandATL.Don’tworry;C/C++codesarereusableintheMFCandATL. API是为使用C/C++的程序员设计的,但是在这里我们讨论windows的图形用户界面接口和事件驱动机制,以及MFC和ATL相关的知识。不必担心,C/C++的代码可以在MFC和ATL中复用(注:这里指的是可以交叉使用)。 Whateveritis,fromC/C++view,theseAPIsarejustfunctions.Asusual,wearegoingtolearnhowtousethosefunctions. 然而从C/C++的观点来看,API只是函数,和通常一样我们将学习如何使用这些函数。 WewilllearnseveralcategoriesoftheavailableAPIs.Forothers,pleaserefertothePlatformSDKdocumentations. 接下来我们将学习集中不同种类的API函数,为了更好的使用这些函数,或者需要更多的信息,请参考微软提供的平台SDK文档。 FirstofallletstartwiththemostbasicinformationrequiredtofullyunderstandhowtousetheWin32APIs:theWindowsdatatypes,headerfilesissueandhandles. 首先,让我们来看看要完全学会使用Win32API的最基本的内容:windows数据类型、windows头文件和句柄。 OtherthanthestandarddatatypesthatyouhavefoundwhendoingtheC/C++programming,thereisalotmoreinWin32programming. 这些内容不仅仅是标准的C/C++的数据结构类型,而是为Win32编程设计的数据类型。 BecauseoftheupdateissueandthevariousWindowsOSversions,usingthesameWindowsheaderfiledoesn’tmeanyouwillbeprovidedwiththesamefunctionalities.Thisissuewillbesolvedbyusingmacros. 由于windows操作系统的版本不断的更新,当你在不同的windows版本下使用相同的头文件和相同的Win32API函数名时可能会实现不同的函数功能,这些函数在某些版本上可能会使用宏实现(注:这里在VC++里面与库的实现相关,至于在调用过程中是调用宏还是调用函数,请查询库的相关实现文档) LateronwewillconcentrateonthefilemanagementfunctionsthatavailableinWin32APIsbycollectingtherequiredandrelatedinformationandthentrybuildingsimpleworkingprograms. 接下来我们将学习Win32API中关于文件系统管理的相关内容,我们将尝试收集相关的信息,并且尝试建立我们自己的实例应用程序实体。 Thesefunctionsusedtodealwithvolumes,disks,directories(includingpaths)andfilesmanagement.ThefilesystemusedinthediscussionisNTFS. 这些函数实现卷标管理、磁盘管理、目录管理和文件管理,这里我们的讨论都将基于NTFS文件系统。 ThenotsounderstandablestoriesaboutWindowsfilesystemandstoragecanbefoundSupplementaryforWindowsfilesystem. 在整个过程中将不再额外地叙述windows文件系统和存储的相关的基础知识。 ThereisnonewconstructsyouwillfindinthisModuleexceptfunctions,arrays,pointersandstructures. 这里将不再描述除了函数、数组、指针和结构体外的新的数据类型。 WindowsDataTypes Windows数据类型 ThedatatypessupportedbyMicrosoftWindowsareusedtodefinefunctionreturnvalues,functionandmessageparameters,structuremembersandvariables.Theydefinethesizeandmeaningoftheseelements. 被微软windows平台支持的数据类型用阿里定义:函数的返回值、函数和消息参数、结构体的结构成员和便面。Windows数据类型定义这些元素的大小和意义信息。 ThefollowingTablecontainstypesofcharacter,integer,Boolean,pointer,andhandle.Thecharacter,integer,andBooleantypesarecommontomostC/C++compilers.Thetypesalsoincludethe64bitssize. 下表例举了一些数据类型如:字符型、整型、布尔型、指针型和句柄类型。字符、整型和布尔类型被大多数的C/C++编译器支持。这些数据类型中还包括64位的数据类型。 Ifyouhavenoticed,manytypesactuallyarederivedfromthebasictypeswithnewnameusingthetypedefor#defineandsomearespecificforthegraphicfunctions. 也许你会注意到,很多数据类型具有相同的基类型,他们只不过是通过typedef机制定义的数据类型的别名(注:严格来说不能说是数据类型别名,应该就是新的数据类型);或者为图形界面下编程函数使用而用#define定义的宏 Mostofthepointer-typenamesbeginwithaprefixofPorLP(longpointer)andhandlewithH. 大部分的指针类型的类型名前面都加了P或者LP(长指针)前缀,而句柄类型则加了H前缀。 HandlesrefertoaresourcethathasbeenloadedintomemoryandwillbediscussedinanotherModule. 句柄标识被系统加载至内存区域的一中资源,在后面的模块将会专门的介绍句柄这种数据类型。 Well,wehavesomanydatatypeshere:o). Thesevariousdatatypesdefinedinseveralheaderfilessuchaswindef.h,basetsd.h,ddeml.h,shellapi.h,winuser.h,winsvc.handwinnt.h. 哦哦,在windows环境下面有太多的数据类型,:o). 说明 Keyword 关键字 Description 描述 ATOM 原子类型 Atom.Thistypeisdeclaredinwindef.hasfollows:typedefWORDATOM; 原子类型,在windef.h头文件定义。 定义语法: typedefWORDATOM; BOOL 布尔类型 Booleanvariable(shouldbeTRUEorFALSE).Thistypeisdeclaredinwindef.hasfollows:typedefintBOOL; 布尔型变量(变量取值:TRUE和FALSE),在头文件windef.h里面定义。 定义语法: typedefintBOOL; BOOLEAN 布尔类型 Booleanvariable(shouldbeTRUEorFALSE).Thistypeisdeclaredinwinnt.hasfollows:typedefBYTEBOOLEAN; 布尔型变量(变量取值:TRUE和FALSE),在头文件windef.h里面定义。 定义语法: TypedefBYTEBOOLEAN; BYTE 字节类型 Byte(8bits).Thistypeisdeclaredinwindef.hasfollows:typedefunsignedcharBYTE; 字节类型,8位数据宽度。在头文件windef中定义。 定义语法: typedefunsignedcharBYTE; CALLBACK 回调函数标识 Callingconventionforcallbackfunctions.Thistypeisdeclaredinwindef.hasfollows:#defineCALLBACK__stdcall 回调函数调用规则指示符,知识函数参数的调用规则(这个一般由编译器定义),在头文件windef.h中声明。 声明语法如下: #difineCALLBACK__stdcall CHAR 字符类型 8-bitWindows(ANSI)character.Thistypeisdeclaredinwinnt.hasfollows: typedefcharCHAR; 8位的ANSI字符类型,在头文件winnt.h中定义。 定义语法: typedefcharCHAR; COLORREF 颜色数据类型 Red,green,blue(RGB)colorvalue(32bits).Thistypeisdeclaredinwindef.hasfollows:typedefDWORDCOLORREF; 基于红、绿、蓝三原色(RGB)定义的数据结构,32为数据位宽度。在windef.h头文件中定义。 定义语法: typedefDWORDCOLORREF; CONST 只读变量修饰符 Variablewhosevalueistoremainconstantduringexecution.Thistypeisdeclaredinwindef.hasfollows:#defineCONSTconst 表示变量的值在运行期间只读的修饰符,在windef.h头文件中声明。 声明语法: #defineCONSTconst DWORD 双字类型 32-bitunsignedinteger.Thistypeisdeclaredinwindef.hasfollows: typedefunsignedlongDWORD; 32位无符号整型,在头文件windef.h中定义。 定义语法: typedefunsignedlongDWORD; DWORDLONG 长双字类型 64-bitunsignedinteger.Thistypeisdeclaredinwinnt.hasfollows: typedefULONGLONGDWORDLONG; 64位无符号整型,在winnt.h头文件中定义。 定义语法: typedefULONGLONGDWORDLONG; DWORD_PTR 双字类型指针 Unsignedlongtypeforpointerprecision.Usewhencastingapointertoalongtypetoperformpointerarithmetic.Alsocommonlyusedforgeneral32-bitparametersthathavebeenextendedto64bitsin64-bitWindows.Thistypeisdeclaredinbasetsd.hasfollows:typedefULONG_PTRDWORD_PTR;精确指针Unsignedlong类型,通常在将一个指针类型转换为长整型数据类型时使用。通常在64位windows里面将32位参数扩展位64位是使用,在头文件basetsd.h中定义。 定义语法: typedefULONG_PTRDWORD_PTR; DWORD32 32位无符号整型。 32-bitunsignedinteger.Thistypeisdeclaredinbasetsd.hasfollows: typedefunsignedintDWORD32; 32位无符号整型,在头文件basetsd.h中定义。 定义语法: typedefunsignedintDWORD32; DWORD64 64位无符号整型 64-bitunsignedinteger.Thistypeisdeclaredinbasetsd.hasfollows: typedefunsigned__int64DWORD64; 64位无符号整型,在basetsd.h头文件中定义 定义语法: typedefunsigned__int64DWORD64; FLOAT 浮点类型 Floating-pointvariable.Thistypeisdeclaredinwindef.hasfollows:typedeffloatFLOAT; 浮点型变量类型,在windef.h中定义。 定义语法: typedeffloatFLOAT; HACCEL 加速器表句柄 Handletoanacceleratortable.Thistypeisdeclaredinwindef.hasfollows: acceleratortable. 加速器表句柄,在windef头文件中定义。 定义语法: acceleratortable. HANDLE 句柄 Handletoanobject.Thistypeisdeclaredinwinnt.hasfollows:typedefPVOIDHANDLE; 对象句柄,在winnt头文件中定义。 定义语法: typedefPVOIDHANDLE; HBITMAP 位图对象句柄 Handletoabitmap.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLEHBITMAP; 位图对象句柄,在windef头文件中定义。 定义语法: typedefHANDLEHBITMAP; HBRUSH 画刷句柄 Handletoabrush.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLEHBRUSH; 画刷对象句柄,在windef头文件中定义。 定义语法: typedefHANDLEHBRUSH; HCOLORSPACE 颜色空间定义 Handletoacolorspace.Thistypeisdeclaredinwindef.hasfollows: if(WINVER>=0x0400) typedefHANDLEHCOLORSPACE; 颜色空间对象句柄,在头文件windef中定义。 定义语法: if(WINVER>=0x0400) typedefHANDLEHCOLORSPACE; HCONV 动态数据交换对象句柄。 Handletoadynamicdataexchange(DDE)conversation.Thistypeisdeclaredinddeml.hasfollows:typedefHANDLEHCONV; 动态数据交换对象句柄,在头文件ddeml中定义。 定义语法: typedefHANDLEHCONV; HCONVLIST 动态数据交换对象列表句柄 HandletoaDDEconversationlist.Thistypeisdeclaredinddeml.hasfollows: typedefHANDLEHCONVLIST; 动态数据交换列表句柄;在头文件ddeml中定义。 定义语法: typedefHANDLEHCONVLIST; HCURSOR 光标句柄 Handletoacursor.Thistypeisdeclaredinwindef.hasfollows: typedefHICONHCURSOR; 光标句柄,在头文件windef中定义。 定义语法: typedefHICONHCURSOR; HDC 设备内容对象句柄 Handletoadevicecontext(DC).Thistypeisdeclaredinwindef.hasfollows: typedefHANDLEHDC; 设备的内容句柄,在头文件windef中定义。 定义语法: typedefHANDLEHDC; HDDEDATA 动态交换数据句柄 HandletoDDEdata.Thistypeisdeclaredinddeml.hasfollows: typedefHANDLEHDDEDATA; 动态交换数据句柄,在头文件ddeml中定义。 定义语法: typedefHANDLEHDDEDATA; HDESK 桌面对象句柄 Handletoadesktop.Thistypeisdeclaredinwindef.hasfollows: typedefHANDLEHDESK; 桌面对象句柄,在头文件windef中定义。 定义语法: typedefHANDLEHDESK; HDROP Handletoaninternaldropstructure.Thistypeisdeclaredinshellapi.hasfollows:typedefHANDLEHDROP; ??? HDWP Handletoadeferredwindowpositionstructure.Thistypeisdeclaredinwinuser.hasfollows:typedefHANDLEHDWP; ??? HENHMETAFILE Handletoanenhancedmetafile.Thistypeisdeclaredinwindef.hasfollows: typedefHANDLEHENHMETAFILE; 增强型metafile对象句柄,在头文件windef中定义。 定义语法: typedefHANDLEHENHMETAFILE; HFILE HandletoafileopenedbyOpenFile(),notCreateFile().Thistypeisdeclaredinwindef.hasfollows:typedefintHFILE; 通过函数OpenFile打开的文件的句柄,不是CreateFile函数创建的文件句柄。在头文件windef中定义。 定义语法: typedefintHFILE; HFONT 字体对象句柄 Handletoafont.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLEHFONT; 字体对象句柄。在头文件windef中定义, 定义语法: typedefHANDLEHFONT; HGDIOBJ HandletoaGDIobject.Thistypeisdeclaredinwindef.hasfollows: typedefHANDLEHGDIOBJ; 图形设备接口对象句柄,在头文件windef中定义。 定义语法: typedefHANDLEHGDIOBJ; HGLOBAL 全局内存块句柄 Handletoaglobalmemoryblock.Thistypeisdeclaredinwindef.hasfollows: typedefHANDLEHGLOBAL; 全局内存块对象句柄,在头文件windef中定义。 定义语法: typedefHANDLEHGLOBAL; HHOOK HOOK钩子句柄 Handletoahook.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLEHHOOK; Hook钩子对象句柄,在头文件windef中定义。 定义语法: typedefHANDLEHHOOK; HICON 图标句柄 Handletoanicon.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLEHICON; 图标句柄,在头文件windef中定义。 定义语法: typedefHANDLEHICON; HINSTANCE Handletoaninstance.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLEHINSTANCE; 实例句柄,在头文件windef中定义。 定义语法: typedefHANDLEHINSTANCE; HKEY Handletoaregistrykey.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLEHKEY; 注册表项件句柄,在头文件windef中定义。 定义语法: typedefHANDLEHKEY; HKL Inputlocaleidentifier.Thistypeisdeclaredinwindef.hasfollows: typedefHANDLEHKL; 本地输入标识符句柄,在头文件windef中定义。 定义语法: typedefHANDLEHKL; HLOCAL Handletoalocalmemoryblock.Thistypeisdeclaredinwindef.hasfollows: typedefHANDLEHLOCAL; 局部内存块对象句柄,在头文件windef中定义。 定义语法: typedefHANDLEHLOCAL; HMENU Handletoamenu.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLEHMENU; 菜单句柄,在头文件windef中定义。 定义语法: typedefHANDLEHMENU; HMETAFILE Handletoametafile.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLEHMETAFILE; Metafile对象句柄,在头文件windef中定义。 定义语法: typedefHANDLEHMETAFILE; HMODULE Handletoamodule.Thevalueisthebaseaddressofthemodule.Thistypeisdeclaredinwindef.hasfollows:typedefHINSTANCEHMODULE; HMONITOR Handletoadisplaymonitor.Thistypeisdeclaredinwindef.hasfollows: if(WINVER>=0x0500) typedefHANDLEHMONITOR; HPALETTE Handletoapalette.Thistypeisdeclaredinwindef.hasfollows: typedefHANDLEHPALETTE; HPEN Handletoapen.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLEHPEN; HRESULT Returncodeusedbyinterfaces.Itiszerouponsuccessandnonzerotorepresentanerrorcodeorstatusinformation.Thistypeisdeclaredinwinnt.hasfollows: typedefLONGHRESULT; HRGN Handletoaregion.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLEHRGN; HRSRC Handletoaresource.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLEHRSRC; HSZ HandletoaDDEstring.Thistypeisdeclaredinddeml.hasfollows:typedefHANDLEHSZ; HWINSTA Handletoawindowstation.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLEWINSTA; HWND Handletoawindow.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLEHWND; INT 32-bitsignedinteger.Thistypeisdeclaredinwindef.hasfollows:typedefintINT; INT_PTR Signedintegraltypeforpointerprecision.Usewhencastingapointertoanintegertoperformpointerarithmetic.Thistypeisdeclaredinbasetsd.hasfollows: #ifdefined(_WIN64) typedef__int64INT_PTR; #else typedefintINT_PTR; INT32 32-bitsignedinteger.Thistypeisdeclaredinbasetsd.hasfollows:typedefsignedintINT32; INT64 64-bitsignedinteger.Thistypeisdeclaredinbasetsd.hasfollows:typedefsigned__int64INT64; LANGID Languageidentifier.Thistypeisdeclaredinwinnt.hasfollows:typedefWORDLANGID; LCID Localeidentifier.Thistypeisdeclaredinwinnt.hasfollows:typedefDWORDLCID; LCTYPE Localeinformationtype.Thistypeisdeclaredinwinnls.hasfollows:typedefDWORDLCTYPE; LGRPID Languagegroupidentifier.Thistypeisdeclaredinwinnls.hasfollows:typedefDWORDLGRPID; LONG 32-bitsignedinteger.Thistypeisdeclaredinwinnt.hasfollows:typedeflongLONG; LONGLONG 64-bitsignedinteger.Thistypeisdeclaredinwinnt.hasfollows: typedef__int64LONGLONG; #else typedefdoubleLONGLONG; LONG_PTR Signedlongtypeforpointerprecision.Usewhencastingapointertoalongtoperformpointerarithmetic.Thistypeisdeclaredinbasetsd.hasfollows: #ifdefined(_WIN64) typedef__int64LONG_PTR; #else typedeflongLONG_PTR; LONG32 32-bitsignedinteger.Thistypeisdeclaredinbasetsd.hasfollows:typedefsignedintLONG32; LONG64 64-bitsignedinteger.Thistypeisdeclaredinbasetsd.hasfollows:typedef__int64LONG64; LPARAM Messageparameter.Thistypeisdeclaredinwindef.hasfollows:typedefLONG_PTRLPARAM; LPBOOL Pointertoabool.Thistypeisdeclaredinwindef.hasfollows:typedefBOOL*LPBOOL; LPBYTE PointertoaBYTE.Thistypeisdeclaredinwindef.hasfollows:typedefBYTE*LPBYTE; LPCOLORREF PointertoaCOLORREFvalue.Thistypeisdeclaredinwindef.hasfollows:typedefDWORD*LPCOLORREF; LPCSTR Pointertoaconstantnull-terminatedstringof8-bitWindows(ANSI)characters.Thistypeisdeclaredinwinnt.hasfollows:typedefCONSTCHAR*LPCSTR; LPCTSTR AnLPCWSTRifUNICODEisdefined,anLPCSTRotherwise. Thistypeisdeclaredinwinnt.hasfollows: #ifdefUNICODE typedefLPCWSTRLPCTSTR; #else typedefLPCSTRLPCTSTR; LPCVOID Pointertoaconstantofanytype.Thistypeisdeclaredinwindef.hasfollows: typedefCONSTvoid*LPCVOID; LPCWSTR Pointertoaconstantnull-terminatedstringof16-bitUnicodecharacters.Thistypeisdeclaredinwinnt.hasfollows:typedefCONSTWCHAR*LPCWSTR; LPDWORD PointertoaDWORD.Thistypeisdeclaredinwindef.hasfollows:typedefDWORD*LPDWORD; LPHANDLE PointertoaHANDLE.Thistypeisdeclaredinwindef.hasfollows:typedefHANDLE*LPHANDLE; LPINT Pointertoanint.Thistypeisdeclaredinwindef.hasfollows:typedefint*LPINT; LPLONG PointertoaLONG.Thistypeisdeclaredinwindef.hasfollows:typedeflong*LPLONG; LPSTR Pointertoanull-terminatedstringof8-bitWindows(ANSI)characters.Thistypeisdeclaredinwinnt.hasfollows:typedefCHAR*LPSTR; LPTSTR AnLPWSTRifUNICODEisdefined,anLPSTRotherwise.Thistypeisdeclaredinwinnt.hasfollows: #ifdefUNICODE typedefLPWSTRLPTSTR; #else typedefLPSTRLPTSTR; LPVOID Pointertoanytype.Thistypeisdeclaredinwindef.hasfollows:typedefvoid*LPVOID; LPWORD PointertoaWORD.Thistypeisdeclaredinwindef.hasfollows:typedefWORD*LPWORD; LPWSTR Pointertoanull-terminatedstringof16-bitUnicodecharacters.Thistypeisdeclaredinwinnt.hasfollows:typedefWCHAR*LPWSTR; LRESULT Signedresultofmessageprocessing.Thistypeisdeclaredinwindef.hasfollows:typedefLONG_PTRLRESULT; PBOOL Pointertoabool.Thistypeisdeclaredinwindef.hasfollows:typedefBOOL*PBOOL; PBOOLEAN Pointertoabool.Thistypeisdeclaredinwinnt.hasfollows:typedefBOOLEAN*PBOOLEAN; PBYTE PointertoaBYTE.Thistypeisdeclaredinwindef.hasfollows:typedefBYTE*PBYTE; PCHAR PointertoaCHAR.Thistypeisdeclaredinwinnt.hasfollows:typedefCHAR*PCHAR; PCSTR Pointertoaconstantnull-terminatedstringof8-bitWindows(ANSI)characters.Thistypeisdeclaredinwinnt.hasfollows:typedefCONSTCHAR*PCSTR; PCTSTR APCWSTRifUNICODEisdefined,aPCSTRotherwise. Thistypeisdeclaredinwinnt.hasfollows: #ifdefUNICODE typedefLPCWSTRPCTSTR; #else typedefLPCSTRPCTSTR; PCWSTR Pointertoaconstantnull-terminatedstringof16-bitUnicodecharacters.Thistypeisdeclaredinwinnt.hasfollows:typedefCONSTWCHAR*PCWSTR; PDWORD PointertoaDWORD.Thistypeisdeclaredinwindef.hasfollows:typedefDWORD*PDWORD; PDWORDLONG PointertoaDWORDLONG.Thistypeisdeclaredinwinnt.hasfollows:typedefDWORDLONG*PDWORDLONG; PDWORD_PTR PointertoaDWORD_PTR.Thistypeisdeclaredinbasetsd.hasfollows:typedefDWORD_PTR*PDWORD_PTR; PDWORD32 PointertoaDWORD32.Thistypeisdeclaredinbasetsd.hasfollows:typedefDWORD32*PDWORD32; PDWORD64 PointertoaDWORD64.Thistypeisdeclaredinbasetsd.hasfollows:typedefDWORD64*PDWORD64; PFLOAT PointertoaFLOAT.Thistypeisdeclaredinwindef.hasfollows:typedefFLOAT*PFLOAT; PHANDLE PointertoaHANDLE.Thistypeisdeclaredinwinnt.hasfollows:typedefHANDLE*PHANDLE; PHKEY PointertoanHKEY.Thistypeisdeclaredinwindef.hasfollows:typedefHKEY*PHKEY; PINT Pointertoanint.Thistypeisdeclaredinwindef.hasfollows:typedefint*PINT; PINT_PTR PointertoanINT_PTR.Thistypeisdeclaredinbasetsd.hasfollows:typedefINT_PTR*PINT_PTR; PINT32 PointertoanINT32.Thistypeisdeclaredinbasetsd.hasfollows:typedefINT32*PINT32; PINT64 PointertoanINT64.Thistypeisdeclaredinbasetsd.hasfollows:typedefINT64*PINT64; PLCID PointertoanLCID.Thistypeisdeclaredinwinnt.hasfollows:typedefPDWORDPLCID; PLONG PointertoaLONG.Thistypeisdeclaredinwinnt.hasfollows:typedefLONG*PLONG; PLONGLONG PointertoaLONGLONG.Thistypeisdeclaredinwinnt.hasfollows:typedefLONGLONG*PLONGLONG; PLONG_PTR PointertoaLONG_PTR.Thistypeisdeclaredinbasetsd.hasfollows:typedefLONG_PTR*PLONG_PTR; PLONG32 PointertoaLONG32.Thistypeisdeclaredinbasetsd.hasfollows:typedefLONG32*PLONG32; PLONG64 PointertoaLONG64.Thistypeisdeclaredinbasetsd.hasfollows:typedefLONG64*PLONG64; POINTER_32 32-bitpointer.Ona32-bitsystem,thisisanativepointer.Ona64-bitsystem,thisisatruncated64-bitpointer.Thistypeisdeclaredinbasetsd.hasfollows: #ifdefined(_WIN64) #definePOINTER_32__ptr32 #else #definePOINTER32 POINTER_64 64-bitpointer.Ona64-bitsystem,thisisanativepointer.Ona32-bitsystem,thisisasign-extended32-bitpointer.Thistypeisdeclaredinbasetsd.hasfollows: #definePOINTER_64__ptr64 PSHORT PointertoaSHORT.Thistypeisdeclaredinwinnt.hasfollows:typedefSHORT*PSHORT; PSIZE_T PointertoaSIZE_T.Thistypeisdeclaredinbasetsd.hasfollows:typedefSIZE_T*PSIZE_T; PSSIZE_T PointertoaSSIZE_T.Thistypeisdeclaredinbasetsd.hasfollows:typedefSSIZE_T*PSSIZE_T; PSTR Pointertoanull-terminatedstringof8-bitWindows(ANSI)characters.Thistypeisdeclaredinwinnt.hasfollows:typedefCHAR*PSTR; PTBYTE PointertoaTBYTE.Thistypeisdeclaredinwinnt.hasfollows:typedefTBYTE*PTBYTE; PTCHAR PointertoaTCHAR.Thistypeisdeclaredinwinnt.hasfollows:typedefTCHAR*PTCHAR; PTSTR APWSTRifUNICODEisdefined,aPSTRotherwise.Thistypeisdeclaredinwinnt.hasfollows: #ifdefUNICODE typedefLPWSTRPTSTR; #else typedefLPSTRPTSTR; PUCHAR PointertoaUCHAR.Thistypeisdeclaredinwindef.hasfollows:typedefUCHAR*PUCHAR; PUINT PointertoaUINT.Thistypeisdeclaredinwindef.hasfollows:typedefUINT*PUINT; PUINT_PTR PointertoaUINT_PTR.Thistypeisdeclaredinbasetsd.hasfollows:typedefUINT_PTR*PUINT_PTR; PUINT32 PointertoaUINT32.Thistypeisdeclaredinbasetsd.hasfollows:typedefUINT32*PUINT32; PUINT64 PointertoaUINT64.Thistypeisdeclaredinbasetsd.hasfollows:typedefUINT64*PUINT64; PULONG PointertoaULONG.Thistypeisdeclaredinwindef.hasfollows:typedefULONG*PULONG; PULONGLONG PointertoaULONGLONG.Thistypeisdeclaredinwindef.hasfollows:typedefULONGLONG*PULONGLONG; PULONG_PTR PointertoaULONG_PTR.Thistypeisdeclaredinbasetsd.hasfollows:typedefULONG_PTR*PULONG_PTR; PULONG32 PointertoaULONG32.Thistypeisdeclaredinbasetsd.hasfollows:typedefULONG32*PULONG32; PULONG64 PointertoaULONG64.Thistypeisdeclaredinbasetsd.hasfollows:typedefULONG64*PULONG64; PUSHORT PointertoaUSHORT.Thistypeisdeclaredinwindef.hasfollows:typedefUSHORT*PUSHORT; PVOID Pointertoanytype.Thistypeisdeclaredinwinnt.hasfollows:typedefvoid*PVOID; PWCHAR PointertoaWCHAR.Thistypeisdeclaredinwinnt.hasfollows:typedefWCHAR*PWCHAR; PWORD PointertoaWORD.Thistypeisdeclaredinwindef.hasfollows:typedefWORD*PWORD; PWSTR Pointertoanull-terminatedstringof16-bitUnicodecharacters.Thistypeisdeclaredinwinnt.hasfollows:typedefWCHAR*PWSTR; SC_HANDLE Handletoaservicecontrolmanagerdatabase.Thistypeisdeclaredinwinsvc.hasfollows:typedefHANDLESC_HANDLE; SC_LOCK Locktoaservicecontrolmanagerdatabase.Thistypeisdeclaredinwinsvc.hasfollows:typedefLPVOIDSC_LOCK; SERVICE_STATUS_HANDLE Handletoaservicestatusvalue.Thistypeisdeclaredinwinsvc.hasfollows: typedefHANDLESERVICE_STATUS_HANDLE; SHORT Shortinteger(16bits).Thistypeisdeclaredinwinnt.hasfollows:typedefshortSHORT; SIZE_T Themaximumnumberofbytestowhichapointercanpoint.Useforacountthatmustspanthefullrangeofapointer.Thistypeisdeclaredinbasetsd.hasfollows:typedefULONG_PTRSIZE_T; SSIZE_T SignedSIZE_T.Thistypeisdeclaredinbasetsd.hasfollows:typedefLONG_PTRSSIZE_T; TBYTE AWCHARifUNICODEisdefined,aCHARotherwise.Thistypeisdeclaredinwinnt.hasfollows: #ifdefUNICODE typedefWCHARTBYTE; #else typedefunsignedcharTBYTE; TCHAR AWCHARifUNICODEisdefined,aCHARotherwise.Thistypeisdeclaredinwinnt.hasfollows: #ifdefUNICODE typedefWCHARTCHAR; #else typedefcharTCHAR; UCHAR UnsignedCHAR.Thistypeisdeclaredinwindef.hasfollows:typedefunsignedcharUCHAR; UINT Unsignedint.Thistypeisdeclaredinwindef.hasfollows:typedefunsignedintUINT; UINT_PTR UnsignedINT_PTR.Thistypeisdeclaredinbasetsd.hasfollows: #ifdefined(_WIN64) typedefunsigned__int64UINT_PTR; #else typedefunsignedintUINT_PTR; UINT32 UnsignedINT32.Thistypeisdeclaredinbasetsd.hasfollows:typedefunsignedintUINT32; UINT64 UnsignedINT64.Thistypeisdeclaredinbasetsd.hasfollows:typedefunsigned__int64UINT64; ULONG UnsignedLONG.Thistypeisdeclaredinwindef.hasfollows:typedefunsignedlongULONG; ULONGLONG 64-bitunsignedinteger.Thistypeisdeclaredinwinnt.hasfollows: typedefunsigned__int64ULONGLONG; #else typedefdoubleULONGLONG ULONG_PTR UnsignedLONG_PTR.Thistypeisdeclaredinbasetsd.hasfollows: #ifdefined(_WIN64) typedefunsigned__int64ULONG_PTR; #else typedefunsignedlongULONG_PTR; ULONG32 UnsignedLONG32.Thistypeisdeclaredinbasetsd.hasfollows:typedefunsignedintULONG32; ULONG64 UnsignedLONG64.Thistypeisdeclaredinbasetsd.hasfollows:typedefunsigned__int64ULONG64; USHORT UnsignedSHORT.Thistypeisdeclaredinwindef.hasfollows:typedefunsignedshortUSHORT; USN Updatesequencenumber(USN).Thistypeisdeclaredinwinnt.hasfollows:typedefLONGLONGUSN; VOID Anytype.Thistypeisdeclaredinwinnt.hasfollows:#defineVOIDvoid WCHAR 16-bitUnicodecharacter.Thistypeisdeclaredinwinnt.hasfollows:typedefwchar_tWCHAR; WINAPI Callingconventionforsystemfunctions.Thistypeisdeclaredinwindef.hasfollows:#defineWINAPI__stdcall WORD 16-bitunsignedinteger.Thistypeisdeclaredinwindef.hasfollows:typedefunsignedshortWORD; WPARAM Messageparameter.Thistypeisdeclaredinwindef.hasfollows:typedefUINT_PTRWPARAM; Table1:Windowsdatatypes. LargeIntegers 大整数 Thistopicdescribesthesupportforoperationsonlarge(64-bit)integersprovidedby32-bitWindows.Applicationscanmultiplysignedorunsigned32-bitintegers,generating64-bitresults,byusingtheInt32x32To64()andUInt32x32To64()functions.Applicationscanshiftbitsin64-bitvaluestotheleftorrightbyusingtheInt64ShllMod32(),Int64ShraMod32(),andInt64ShrlMod32()functions.Thesefunctionsprovidelogicalandarithmeticshifting. 这里讨论32位windows对64位整型数据的支持。应用程序通过使用Int32X32To64()函数或者UInt32X32To64()函数能够将有符号、无符号的32位整型数据相乘得到64位的结果。应用程序同样能够通过使用Int64ShllMod32()函数和Int64ShraMod32()函数和Int64ShrlMod32()函数进行移位操作;这些函数提供逻辑和算术移位操作功能。 Applicationscanalsomultiplyanddivide32-bitvaluesinasingleoperationbyusingtheMulDiv()function.Althoughtheresultoftheoperationisa32-bitvalue,thefunctionstorestheintermediateresultasa64-bitvalue,sothatinformationisnotlostwhenlarge32-bitvaluesaremultipliedanddivided. 应用程序可以使用MulDiv()函数在一次运算过程中实现32位数据的乘法和除法操作。虽然这个函数的返回值是一个32位的值,但是因为在函数内部使用的是64位数据进行计算,因此在计算超过32位长度的数值是不会丢失数据精度。 SomeWindowsfunctionsusetheLARGE_INTEGERstructuretorepresent64-bitsignedintegervalues,andtheULARGE_INTEGERstructuretospecify64-bitunsignedintegervalues.YourCcompilermaysupport64-bitintegersnatively.Forexample,Microsoft®VisualC++®supportsthe__int64sizedintegertype. 一些windows函数使用LARGE_INTEGER结构来支持64位有符号整型,而使用ULARGE_INTEGER结构来支持64位无符号整型。你的C编译器可能内置支持64位的整型数据;例如微软的VisualC++支持__int64位长度的整型。 TheNewDataTypes 新数据类型 Therearethreeclassesofnewdatatypes:fixed-precisiondatatypes,pointer-precisiontypes,andspecific-precisionpointers.Thesetypeswereaddedtothedevelopmentenvironment(specifically,tobasetsd.h)toallowdeveloperstopreparefor64-bitMicrosoft®Windows®wellbeforeitsintroduction.ThesenewtypeswerederivedfromthebasicC-languageintegerandlongtypes,sotheyworkinexistingcode.Therefore,usethesedatatypesinyourcodenow,testyourcodeon32-bitWindows,andrecompilewiththe64-bitcompilerwhen64-bitWindowsisavailable. 在windows中提供了3种新的数据类型:定精度数据类型、指针指向型数据结构和指定数据精度指针类型。这些数据类型在开发环境中(有basetsd.h头文件提供定义支持)增加是为了允许开发者开发64位windows应用程序做准备,这些数据类型派生与基本C语言数据类型,这些数据类型已经在使用。因此可以在你windows32位平台的代码中使用这些数据类型,当你使用64位windows的时候重新编译你的代码。 Thereisanadditionalbenefittoadoptingthesenewdatatypesnow:itwillmakeyourcodemorerobust.Tousethesedatatypes,youmustscanyourcodeforpotentiallyunsafepointerusage,polymorphism,anddatadefinitions.Tobesafe,usethenewtypes.Forexample,whenavariableisoftypeULONG_PTR,itisclearthatitwillbeusedforcastingpointersforarithmeticoperationsorpolymorphism.Itisnotpossibletoindicatesuchusagedirectlybyusingtheexistingdatatypes.YoucandothisbyusingderivedtypenamingorHungariannotation,butbothtechniquesarepronetoerrors. 现在使用这些新的数据类型还有一个好处,它可以使你的代码更加健壮。为了使用这些数据类型,你必须排查你代码中潜在的不安全的指针、polymorphism、和数据定义。为了代码安全,请使用新的数据类型。例如,当定义一个ULONG_PTR类型变量时,很显然他将在用于数据类型转换或者polymorphism中将指针进行转换成目标数据类型。利用现有的数据结构或者类型就不能这么清楚的指明这一点。你能通过使用内置的数据类型或者Hungariannotation,但是两种方法都容易产生错误。 FixedPrecision 定精度数据 Fixed-precisiondatatypesarethesamelengthinboth32-and64-bitWindows.Tohelpyourememberthis,theirprecisionispartofthenameofthedatatype.Thefollowingarethefixed-precisiondatatypes. 定精度数据在32位或者64位windows中具有相同的数据位宽度。为了便于记忆,这些数据的精度(注:数据宽度)是数据类型的一部分。下表例举了定精度的数据类型: Type Definition DWORD32 32-bitunsignedinteger DWORD64 64-bitunsignedinteger INT32 32-bitsignedinteger INT64 64-bitsignedinteger LONG32 32-bitsignedinteger LONG64 64-bitsignedinteger UINT32 UnsignedINT32 UINT64 UnsignedINT64 ULONG32 UnsignedLONG32 ULONG64 UnsignedLONG64 Table2:Fixedprecisiondatatypes PointerPrecision 指针精度/指针长度 Asthepointerprecisionchanges(thatis,asitbecomes32bitson32-bitWindowsand64bitswith64-bitWindows),thesedatatypesreflecttheprecisionaccordingly.Therefore,itissafetocastapointertooneofthesetypeswhenperformingpointerarithmetic;ifthepointerprecisionis64bits,thetypeis64bits.Thecounttypesalsoreflectthemaximumsizetowhichapointercanrefer.Thefollowingarethepointer-precisionandcounttypes. 当指针精度/指针长度改变,这些数据类型的长度就自动改变(当在32位windows时这些数据类型位32位,在64位windows时是64位长度);因此在将指针转化为这些数据类型后进行数据运算是安全的,当指针精度是64位时,转化后的数据类型也是64位的。计数器类型同样影响一个指针能引用的最大数据宽度。下表例举了一些指针长度类型和计数器类类型。 Type Definition DWORD_PTR Unsignedlongtypeforpointerprecision. HALF_PTR Halfthesizeofapointer.Usewithinastructurethatcontainsapointerandtwosmallfields. INT_PTR Signedintegraltypeforpointerprecision. LONG_PTR Signedlongtypeforpointerprecision. SIZE_T Themaximumnumberofbytestowhichapointercanrefer.Useforacountthatmustspanthefullrangeofapointer. SSIZE_T SignedSIZE_T. UHALF_PTR UnsignedHALF_PTR. UINT_PTR UnsignedINT_PTR. ULONG_PTR UnsignedLONG_PTR. Table3:Pointerprecision SpecificPointer-PrecisionTypes 指定长度指针类型 Therearealsonewpointertypesthatexplicitlysizethepointer.Becautiouswhenusingpointersin64-bitcode:Ifyoudeclarethepointerusinga32-bittype,theoperatingsystemcreatesthepointerbytruncatinga64-bitpointer.Allpointersare64bitson64-bitWindows. 同样存在显示指出数据位宽的新的指针类型。当在64位代码中使用这些数据类型的时候要注意:如果你声明一个32位长度的指针变量,操作系统将自动截取为32位的指针。记住在64位系统中所有的指针变量都是64位长度/位宽。 Type Definition POINTER_32 A32-bitpointer.On32-bitWindows,thisisanativepointer.On64-bitWindows,thisisatruncated64-bitpointer. 32位指针,在32位系统中,是缺省长度指针,而在64位系统,是一个64位指针经系统截取后的指针。 POINTER_64 A64-bitpointer.On64-bitWindows,thisisanativepointer.On32-bitWindows,thisisasign-extended32-bitpointer.Notethatitisnotsafetoassumethestateofthehighpointerbit. 64位指针,在64位系统中是指针缺省长度。在32位系统中,是从32位指针扩展的出来的指针。注意:主观假定一个指针的高位状态是一个不安全的行为。 Table4:Anotherpointerprecisiontypes. MultipleVersionsofWindowsHeaderFiles Windows头文件的版本 HeaderfilesfortheWindowsAPIenableyoutocreate32-and64-bitapplicationsthatrunonvariousMicrosoftWindowsversions. WindowsAPI相关的头文件允许你创建在不同的windows版本上允许的32位或者64位的应用程序。 Theyusedatatypesthatallowyoutobuildboth32-and64-bitversionsofyourapplicationfromasinglesourcecodebase. 这些API使用不同的数据类型,允许你用同一份代码建立可以在32位和64位版本windows下运行的程序。(注:通过数据类型扩展应用程序的应用范围,就是数据类型) MicrosoftVisualC++includescopiesoftheWindowsheaderfilesthatwerecurrentatthetimeVisualC++wasreleased.Therefore,ifyouinstallupdatedheaderfilesfromanSDK,youmayendupwithmultipleversionsoftheWindowsheaderfilesonyourcomputer. 在VisualC++包括它被发布时的windowsAPI相关的头文件。因此当你用一个SDK开发包升级你的VisualC++时,你可能会遇到很多不同版本的windowsAPI相关的头文件。 IfyoudonotsurethatyouareusingthelatestversionoftheSDKheaderfiles,youwillreceivethefollowingerrorcodewhencompilingcodethatusesfeaturesthatwereintroducedafterVisualC++wasreleased:errorC2065:undeclaredidentifier. 如果没有确保你在编译时使用的是最新版本的SDK头文件,而在你的代码中使用了VisualC++发布时介绍的新特性,那么在编译代码的过程中你将可能看到如下的错误代码:errorC2065:undeclaredidentifier. CertainfunctionsthatdependonaparticularversionofWindowsaredeclaredusingconditionalcode.Thisenablesyoutousethecompilertodetectwhetheryourapplicationusesfunctionsthatarenotsupportedonitstargetversion(s)ofWindows. 某些依赖于特定的windows版本的函数使用条件编译代码来进行声明;这样保证你的编译器能检测你的代码中是否了使用了目标Windows系统不支持的函数。 Tocompileanapplicationthatusesthesefunctions,youmustdefinetheappropriatemacros.Otherwise,youwillreceivetheC2065errormessage. Thefollowingtableindicatesthecommonmacrosyoumustdefinetotargeteachmajoroperatingsystemrelease. 为了在一个应用程序中使用这些函数,你必须定义合适的宏。否则你将会看到编译器报C2065错误。下面的表指出了你必须定义的来适合你的操作系统发布的主要版本号通用宏。 Individualheaderfilesmayusedifferentmacros;therefore,ifheaderfilesrelatedcompilationproblemsoccur,checktheheaderfilethatcontainsthedefinitionforconditionaldefinitionsdirectly. 不同的头文件可能会只用不同的宏,因此如果头文件发生编辑错误,那么就直接检查包含条件宏的头文件。 Minimumsystemrequired 最小系统要求 Macrostodefine 宏定义 ... ... WindowsServer2003family _WIN32_WINNT>=0x0502 WINVER>=0x0502 WindowsXP _WIN32_WINNT>=0x0501 WINVER>=0x0501 Windows2000 _WIN32_WINNT>=0x0500 WINVER>=0x0500 WindowsNT4.0 _WIN32_WINNT>=0x0400 WINVER>=0x0400 WindowsMe _WIN32_WINDOWS=0x0500 WINVER>=0x0500 Windows98 _WIN32_WINDOWS>=0x0410 WINVER>=0x0410 Windows95 _WIN32_WINDOWS>=0x0400 WINVER>=0x0400 InternetExplorer6.0 _WIN32_IE>=0x0600 InternetExplorer5.6 _WIN32_IE>=0x0560 InternetExplorer5.01,5.5 _WIN32_IE>=0x0501 InternetExplorer5.0,5.0a,5.0b _WIN32_IE>=0x0500 InternetExplorer4.01 _WIN32_IE>=0x0401 InternetExplorer4.0 _WIN32_IE>=0x0400 InternetExplorer3.0,3.01,3.02 _WIN32_IE>=0x0300 Table5:MacrosfordifferentWindowsheaderfileversionsanddifferentWindowsOS. 表5不同的windows操作系统和不同版本的系统能够里不同的宏定义 注:从这里可以看出,微软通过宏定义来控制版本信息 SomefeaturesintroducedinthelatestversionofWindowsmaybeaddedtoaservicepackforapreviousversionofWindows.Therefore,totargetaservicepack,youmayneedtodefine_WIN32_WINNTwiththevalueforthenextmajoroperatingsystemrelease. 一些在高版本Windows的特性可以通过SP升级补丁的在低版本的Windows中应用,因此对于一个SP升级包可能需要定义_WIN32_WINNT宏来适应下一个发布版的Windows主版本号。 Forexample,theGetDllDirectory()functionwasintroducedinWindowsServer2003andisconditionallydefinedif_WIN32_WINNTis0x0502orgreater.ThisfunctionwasalsoaddedtoWindowsXPSP1.Therefore,ifyouweretodefine_WIN32_WINNT0x0501totargetWindowsXP,youwouldmissfeaturesthataredefinedinWindowsXPSP1. 例如,GetDllDirectory函数在WindowsServer2003里面,如果_WIN32_WINNT宏定义代表的值大于等于0X0502,那么它就被定义。同样这个函数在WinXPSP1中同样可用。因此如果你已经定义使用于WinXP的_WIN32_WINNT宏,那么XPSP1的一些特性将不可用。 Youcandefinethesesymbolsbyusingthe#definestatementineachsourcefile,orbyspecifyingthe/DcompileroptionsupportedbyVisualC++. 你可以在每一个源文件文件的头部用#define预处理指令来定义这些符号(这里指:宏),或者通过VC++IDE环境支持的/D的编译器选项来支持这宏扩展功能。 ForVisualC++7.0:Tospecifycompileroptions,gototheProjectsmenuandclickProperties. 对于VC++7.0,为了设置编译器编译选项,那么通过工程——》属性菜单来进行设置。 ForVisualC++6.0:Tospecifycompileroptions,gototheProjectsmenuandclickSettings,thenselecttheC/C++tab. 对于VC++6.0,为了设置编译器编译选项,那么通过工程——》设置打开设置对话框,然后选择C/C++标签页进行设置。 WindowsSystemErrorCodes Windows系统错误代码 TheerrorcodesreturnedbyafunctionarenotpartoftheWindowsAPIspecificationandcanvarybyoperatingsystemordevicedriver.Forthisreason,therearefunctionswhosedocumentationdoesnotincludealistoferrorcodesthatcanbereturned. 返回错误代码的函数不是WindowsAPI的一部分,并且函数的返回值可能随操作系统的改变或者硬件设备不同而改变。由于这个原因,这些函数的相关文档并没有罗列这些函数应该返回什么值。 YoushouldcalltheGetLastError()functionimmediatelywhenafunction'sreturnvalueindicatesthatsuchacallwillreturnusefuldata.ThatisbecausesomefunctionscallSetLastError()withazerowhentheysucceed,wipingouttheerrorcodesetbythemostrecentlyfailedfunction. 当你的函数调用会返回一个非常重要的值的时候,你应该立即调用GetLastError()函数来获取函数的返回状态,那是因为一些函数在成功执行时会调用SetLastError函数来设定函数错误状态全局存储空间,这样就会覆盖最后调用失败的函数的错误代码。(注:就是为了防止错误代码在被使用之前改变,最好在调用重要函数之后马上调用一下GetLastError函数获取函数执行情况的信息) Mostfunctionsthatsetthethread'slasterrorcodevaluesetitwhentheyfail;afewfunctionssetitwhentheysucceed. 大部分函数会在执行失败之后设定其执行线程的错误代码值,只有小部分的函数会在执行成功时设置错误代码值。 Functionfailureistypicallyindicatedbyareturnvalueerrorcodesuchaszero,NULL,or–1.SomefunctionscallSetLastError()underconditionsofsuccess. Errorcodesare32-bitvalues(bit31isthemostsignificantbit).Bit29isreservedforapplication-definederrorcodes;nosystemerrorcodehasthisbitset. 典型的指示函数执行错误的返回值是例如0、NULL或-1.一些函数会在成功之后调用SetLastError函数;错误代码是一个32位的返回值(D31位尤其重要)。D29位是为应用程序自定义错误代码保留的,系统错误代码不会设置D29这一位。 (注:也就是说用户可以设置D29这一位来指示用户需要定义的错误类型) Ifyouaredefininganerrorcodeforyourapplication,setthisbittoone.Thatindicatesthattheerrorcodehasbeendefinedbyanapplication,andensuresthatyourerrorcodedoesnotconflictwithanyerrorcodesdefinedbythesystem. 如果你需要自定义应用程序的错误代码,那么你可以设置D29这一位;这就说明函数返回的错误代码已经被应用程序重定义过,你必须保证应用程序自定义的错误代码不与系统定义的缺省错误代码冲突。 AcompletelistoferrorcodesprovidedbytheoperatingsystemcanbefoundatWindowserrorcodes.Toobtainanerrorstringforsystemerrorcodes,youcanusetheFormatMessage()function. 可以通过WindowsErrorCodes可以查看完整的关于windows操作系统定义的错误代码。你可以调用FormatMessage函数来将错误代码转换成你需要的关于函数返回错误原因的字符串信息。 WindowsObjectsandHandles Windows对象和句柄 InWindows,anobjectisadatastructurethatrepresentsasystemresource,suchasafile,thread,orgraphicimage.So,inWindowswearedealingwithobjects. 在Windows下,对象就是一个结构体,它标示系统资源,例如文件、线程、图像等。因此在Windows下我们处理的是对象。 Anapplicationcannotdirectlyaccess(communicateorinteractwith)objectdataorthesystemresourcethatanobjectrepresents. 应用程序不能直接访问对象的数据或者系统资源对象。 Instead,anapplicationmustobtainanobject’shandle,whichwillbeusetoaccess,examineormodifythesystemresource. 相反的,应用程序必须先获取一个对象的句柄,应用程序这个句柄来访问、检查和修改系统资源。 Eachhandlehasanentryinaninternallymaintainedtable.Theseentriescontaintheaddressesoftheresources(memoryaddresses?)andthemeanstoidentifytheresourcetype. 每一句柄在系统维护的系统资源表中都对应一个入口点。这个入口点信息包含资源的地址(是内存地址吗?)并且它还指示出资源的类型。 WindowsObjectCategories Windows对象类型/种类 InWindows,systemprovidesthreecategoriesofobjects:user,graphicsdeviceinterface(GDI),andkernel. 在Windows系统中,操作系统提供了3大种类对象:用户对象、GDI对象和内核对象。 Thesystemuses: Userobjectstosupportwindowmanagement. GDIobjectstosupportgraphics,andKernelobjectstosupportmemorymanagement,processexecution,andinterprocesscommunications(IPC). 系统使用: 1、用户对象来支持窗口管理。 2、GDI对象来支持图形。 3、内核对象来支持内存管理、进程执行和进程间通讯。 ThefollowingTablesarethelistoftheWindowsobjectcategoriesandinthisTutorialwewillfocusonsomeofthekernelobjects。 下表例举了windows对象的种类,并且在这一节我们将讨论一些关于内核对象的内容。 Userobject 用户对象 Icon,Caret,Cursor,DynamicDataExchange(DDE)conversation,Hook,Acceleratortable,Menu,Window,Windowposition. 图标、光标、动态数据交换、钩子、加速器表、菜单、窗口和窗口位置。 GraphicDeviceInterface(GDI)object GDI对象 Bitmap,Brush,DeviceContext(DC),Enhancedmetafile,Enhanced-metafileDC,Font,MemoryDC,Metafile,MetafileDC,Palette,Region,Penandextendedpen. 位图、画刷、设备内容、增强metafile、增强metafile设备内容、内存映像文件、MeteFile等 Kernelobject Accesstoken,Changenotification,Communicationsdevice,Consoleinput,Consolescreenbuffer,Desktop,Event,Eventlog,File,Filemapping,Heap,Job,Mailslot,Module,Mutex,Pipe,Process,Semaphore,Socket,Thread,Timer,Timerqueue,Windowstation,Updateresource,Timer-queuetimer. 访问信令、控制台输入、控制台缓存、桌面、事件、事件日志、文件、文件映像文件、堆、作业、模块、互斥对象、管道、进程、套接字、线程、定时器、定时器队列、 Table6:Windowsobjectcategories. Window是对象类别 HandleandObjectFunctions 句柄和对象函数 Thefollowingfunctionsareusedwithhandlesandobjects. 下面的例举了一些与句柄和对象使用相关的函数 Function Description GetHandleInformation() 获取句柄信息 Retrievescertainpropertiesofanobjecthandle. 获取某个对象句柄特定的信息。 SetHandleInformation() 设置句柄信息 Setscertainpropertiesofanobjecthandle. 设置某个句柄的属性 CloseHandle() 关闭句柄 Closesanopenobjecthandle. 关闭一个打开对象的句柄/撤销一个对象句柄 DuplicateHandle() 复制句柄 Duplicatesanobjecthandle. 复制一个对象句柄。 Table7:Handleandobjectfunctions. 句柄和对象函数 Asanexampleforinformationcollection,thefollowingTableliststheneededinformationinordertousetheGetHandleInformation()function. 下面是一个关于收集句柄信息的示例。表中罗列了使用GetHandleInformation函数所需要的信息。 Information 信息 Description 描述/解释 Thefunction 函数 GetHandleInformation(). Theuse 函数作用 Retrievescertainpropertiesofanobjecthandle. 返回一个对象句柄的属性信息 Theprototype 函数原型 BOOLGetHandleInformation(HANDLEhObject,LPDWORDlpdwFlags); Example 示例 HANDLEhFile; DWORDlpdwFlags[100]; hFile=CreateFile(...); GetHandleInformation(hFile,lpdwFlags); Theparameters 参数 hObject-[in]Handletoanobjectwhoseinformationistoberetrieved.Youcanspecifyahandletooneofthefollowingtypesofobjects:accesstoken,event,file,filemapping,job,mailslot,mutex,pipe,printer,process,registrykey,semaphore,serialcommunicationdevice,socket,thread,orwaitabletimer. InWindowsServer2003,WindowsXP/2000,thisparametercanalsobeahandletoaconsoleinputbufferoraconsolescreenbuffer. hObject-[in]:需要获取信息的对象的句柄。你可以位这个参数传递下列对象的句柄:访问信令、事件、文件、文件映像文件、作业、互斥对象、管道、打印机、进程、注册表键、串行通信设备、套接字、线程或定时器。 在WindowsServer2003、WindowsXP/2000,这个参数还可以是控制台输入缓存或者控制台屏幕缓存。 (注:目前大部分系统的,字符界面输入都是缓冲型的) lpdwFlags-[out]Pointertoavariablethatreceivesasetofbitflagsthatspecifypropertiesoftheobjecthandle.Thefollowingvaluesaredefined: HANDLE_FLAG_INHERIT-Ifthisflagisset,achildprocesscreatedwiththebInheritHandlesparameterofCreateProcess()settoTRUEwillinherittheobjecthandle. HANDLE_FLAG_PROTECT_FROM_CLOSE-Ifthisflagisset,callingtheCloseHandle()functionwillnotclosetheobjecthandle. lpdwFlagstaff-[out]变量指针,指针指向的变量是一个位旗标,通过位旗标来指示句柄对象的属性。下面是一些预定义值: HANDLE_FLAG_INHERIT:如果这个设置了这个位旗标,那么表示通过CreateProcess函数创建的子进程对象将继承父进程的对象句柄的特性。 HANDLE_FLAG_PROTECT_FROM_CLOSE:如果设置了这个位旗标,那么在调用CloseHandle函数的时候将不能正常撤销对象句柄。 Thereturnvalue Ifthefunctionsucceeds,thereturnvalueisnonzero. Ifthefunctionfails,thereturnvalueiszero.Togetextendederrorinformation,callGetLastError(). 如果这个函数成功执行,那么返回值是一个非零值。 如果函数执行失败,那么将返回0.如果需要获取更多的错误信息,可以调用GetLastError函数。 Theheaderfile <windows.h> 头文件:windows.h Table8:GetHandleInformation()information. GetHandleInformation函数的使用方法 FromtheinformationinthepreviousTable,thefollowingprogramexampleshowshowtoobtainanobjecthandle(file)andtheuseoftheGetHandleInformation()function. 基于上面表格描述的信息,下面的代码示例展示了如何使用GetHandleInformation函数和如何获取一个文件对象的句柄。 #include<windows.h> #include<stdio.h> intmain() { //handleforfile HANDLEhFile; //fileandpath charfname[30]="c:\\testfile.txt"; DWORDlpdwFlags[100]; hFile=CreateFile(fname,//filetobeopened GENERIC_WRITE,//openforwriting FILE_SHARE_WRITE,//shareforwriting NULL,//defaultsecurity CREATE_ALWAYS,//createnewfileonly FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_ARCHIVE|SECURITY_IMPERSONATION, //normalfilearchiveandimpersonateclient NULL);//noattr.template if(hFile==INVALID_HANDLE_VALUE) printf("Couldnotopen%sfile,error%d\n",fname,GetLastError()); printf("File'sHANDLEisOK!\n"); BOOLtest=GetHandleInformation(hFile,lpdwFlags); printf("Thereturnvalueis%d,error%d\n",test,GetLastError()); CloseHandle(hFile); DeleteFile(fname); return0; } Asampleoutput: File'sHANDLEisOK! Thereturnvalueis1,error0 Pressanykeytocontinue 上面的部分是一个可能的输出结果。 ThisModulewilltrytofollowthesamesteps: Collectingtherequiredandrelatedinformation,presentedinaTableand Usetheinformationtobuildasimpleworkingprogram. 接下来我们会通过同样的方法和步骤来演示怎样建立一个可以运行的程序: 收集必需的和相关的信息,建立一个这些信息的表格,然后利用这些信息完成一个实现。 AndanotherexampleoftherequiredinformationinordertouseCloseHandle()function. 一个关于CloseHandle的示例和相关的信息。 Information 信息 Description 描述/解释 Thefunction 函数 CloseHandle(). Theuse 作用 Closesanopenobjecthandle. 关闭一个对象的句柄 Theprototype 函数原型 BOOLCloseHandle(HANDLEhObject); Example 示例代码 hFile=CreateFile(fname,//filetobeopened GENERIC_WRITE,//openforwriting FILE_SHARE_WRITE,//shareforwriting NULL,//defaultsecurity CREATE_ALWAYS,//createnewfileonly FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_ARCHIVE|SECURITY_IMPERSONATION, //normalfilearchiveandimpersonateclient NULL);//noattributetemplate CloseHandle(hFile); Theparameters 形参 hObject-[in,out]Handletoanopenobject. hObject参数,输入/输出参数,指向一个打开的对象的句柄。 Thereturnvalue 返回值 Ifthefunctionsucceeds,thereturnvalueisnonzero. Ifthefunctionfails,thereturnvalueiszero.Togetextendederrorinformation,callGetLastError(). 如果函数执行成功,返回值是非零。 如果函数执行失败,那么将返回0.如果需要获取更多的错误信息,可以调用GetLastError函数。 Theheaderfile 头文件 <windows.h> Table9:CloseHandle()information. Theduplicatehandlereferstothesameobjectastheoriginalhandle.Therefore,anychangestotheobjectarereflectedthroughbothhandles. Forexample,thecurrentfilemarkforafilehandleisalwaysthesameforbothhandles. 复制对象句柄和原句柄一样可以用来访问对象。因此,可以通过复制对象句柄和原句柄来访问对象。例如thecurrentfilemarkforafilehandleisalwaysthesameforbothhandles.//这句有点没看明白。 NotethatDuplicateHandle()shouldnotbeusedtoduplicatehandlestoI/Ocompletionports.Inthiscase,noerrorisreturned,buttheduplicatehandlecannotbeused. 注意DuplicateHandle函数不能用来复制完整的I/O端口对象句柄。这种情况下,将不会返回错误,但是复制对象句柄不能使用。 Insomecases,thenewhandlecanhavemoreaccessrightsthantheoriginalhandle.However,inothercases,DuplicateHandle()cannotcreateahandlewithmoreaccessrightsthantheoriginal. 在某些情况下,复制对象句柄可能具有比原句柄更高的访问权限,而在另外一些情况下复制对象句柄可能具有比原句柄更低的访问权限。 Forexample,afilehandlecreatedwiththeGENERIC_READaccessrightcannotbeduplicatedsothatithasboththeGENERIC_READandGENERIC_WRITEaccessright. 例如,一个具有GENERIC_READ访问控制权限的文件句柄不能被复制,因此它将具有GENERIC_READ和GENERIC_WRITE访问权限。 DuplicateHandle()canbecalledbyeitherthesourceprocessorthetargetprocess(oraprocessthatisboththesourceandtargetprocess). DuplicateHandle函数能够被原进程调用也能被目标进程调用(或者被一个既是原进程,又是目标进程)。 Forexample,aprocesscanuseDuplicateHandle()tocreateanon-inheritableduplicateofaninheritablehandle,orahandlewithdifferentaccessthantheoriginalhandle. 例如,一个进程可以使用DuplicateHandle函数创建一个可继承对象句柄的复制对象句柄,或者创建一个与原句柄对象访问权限不一样的进程。 ThefollowingTableliststherequiredinformationinordertousetheDuplicateHandle()function. 下表描述了DuplicateHandle函数的必要信息和怎样使用DuplicateHandle函数。 Information Description Thefunction DuplicateHandle(). Theuse Duplicatesanobjecthandle. 复制一个对象句柄 Theprototype 函数原型 BOOLDuplicateHandle(HANDLEhSourceProcessHandle,HANDLEhSourceHandle,HANDLEhTargetProcessHandle,LPHANDLElpTargetHandle,DWORDdwDesiredAccess,BOOLbInheritHandle,DWORDdwOptions); Example HANDLEhStdinRd,hStdinWrDup; BOOLfSuccess; fSuccess=DuplicateHandle( GetCurrentProcess(),//process'shandletobeduplicated hStdinWr,//standardinputhandle GetCurrentProcess(),//processtoreceivetheduplicatedhandle &hStdinWrDup,//pointertovariableforduplicatedhandleprocessreceiver 0,//accessfortheduplicated/newhandle FALSE, //notinherited DUPLICATE_SAME_ACCESS);//sameaccessasthesourcehandle if(!fSuccess) printf("DuplicateHandle()failed\n"); Theparameters hSourceProcessHandle-[in]Handletotheprocesswiththehandletoduplicate.ThehandlemusthavethePROCESS_DUP_HANDLEaccessright. hSourceProcessHandle-[in]:待复制对象句所在进程的句柄。这个进程句柄必须具有PROCESS_DUP_HANDLE的访问权限。 hSourceHandle-[in]Handletoduplicate.Thisisanopenobjecthandlethatisvalidinthecontextofthesourceprocess. hSourceHandle-[in],需要复制的句柄,一个在源进程中打开的有效的句柄。 hTargetProcessHandle-[in]Handletotheprocessthatistoreceivetheduplicatedhandle.ThehandlemusthavethePROCESS_DUP_HANDLEaccessright. hTargetProcessHandle-[in]用来存储目标复制句柄的进程对象句柄,这个进程句柄必须具有:PROCESS_DUP_HANDLE访问权限。 lpTargetHandle-[out]Pointertoavariablethatreceivestheduplicatehandle.Thishandlevalueisvalidinthecontextofthetargetprocess.IfhSourceHandleisapseudohandlereturnedbyGetCurrentProcess()orGetCurrentThread(),DuplicateHandle()convertsittoarealhandletoaprocessorthread,respectively.IflpTargetHandleisNULL,thefunctionduplicatesthehandle,butdoesnotreturntheduplicatehandlevaluetothecaller.Thisbehaviorexistsonlyforbackwardcompatibilitywithpreviousversionsofthisfunction.Youshouldnotusethisfeature,asyouwilllosesystemresourcesuntilthetargetprocessterminates. lpTargetHandle-[out],接收复制对象句柄的句柄指针,这个句柄值在复制句柄所在的进程中是有效的。如果hSourceHandle句柄是一个通过GetCurrentProcess函数、GetCurrentThread函数返回的虚对象句柄,那么Duplicatehandle函数就将他转换为一个指向进程或者线程的实对象句柄。如果传递给复制对象句柄指针lpTargetHandle是一个NULL值,那么DuplicateHandle函数依然复制对象句柄,但是不会将对象句柄返回给调用他的函数空间里面。这种现象只在为了向后兼容的情况线存在;你不应该使用这个特性,否则你将会丢失一些系统资源,直到目标进程终止。(注:这里资源回收需要应用程序和系统共同维护) dwDesiredAccess-[in]Accessrequestedforthenewhandle.Fortheflagsthatcanbespecifiedforeachobjecttype.ThisparameterisignoredifthedwOptionsparameterspecifiestheDUPLICATE_SAME_ACCESSflag.Otherwise,theflagsthatcanbespecifieddependonthetypeofobjectwhosehandleistobeduplicated. dwDesiredAccess-[in]:复制对象句柄的访问权限限制,这个参数位旗标可以针对每个对象类型指定。如果dwOptions参数设置成DUPLICATE_SAME_ACCESS,那么这个参数的设置将被忽略。同时这个参数的设置还与要源对象句柄的类型有关。 bInheritHandle-[in]Indicateswhetherthehandleisinheritable.IfTRUE,theduplicatehandlecanbeinheritedbynewprocessescreatedbythetargetprocess.IfFALSE,thenewhandlecannotbeinherited. bInheritHandle-[in]:这个参数设置复制对象句柄的继承特性,如果设置为TRUE,那么复制对象句柄的特性将可以继承。如果是FALSE,那么复制对象句柄的属性将不可以被继承。(注:就是说新创建的复制对象句柄的属性不可以被它的子对象所继承) dwOptions-[in]Optionalactions.Thisparametercanbezero,oranycombinationofthefollowingvalues.DUPLICATE_CLOSE_SOURCE-Closesthesourcehandle.Thisoccursregardlessofanyerrorstatusreturned.DUPLICATE_SAME_ACCESS-IgnoresthedwDesiredAccessparameter.Theduplicatehandlehasthesameaccessasthesourcehandle. dwOptions-[in]:可选参数。这个参数可以设置为0,或者是下面预定义宏的组合值(注:位旗标的或运算结果) 1、DUPLICATE_CLOSE_SOURCE 指示关闭源对象句柄,表示不管是否发生错误,都不返回值。 2、DUPLICATE_SAME_ACCESS 指示忽略dwDesiredAccess参数的设定,而指定复制对象句柄也源对象句柄具有同样的访问权限。 Thereturnvalue Ifthefunctionsucceeds,thereturnvalueisnonzero. Ifthefunctionfails,thereturnvalueiszero.Togetextendederrorinformation,callGetLastError(). 如果函数执行成功,返回值是非零。 如果函数执行失败,那么将返回0.如果需要获取更多的错误信息,可以调用GetLastError函数。 Theheaderfile <windows.h> 需要保护windows.h头文件才能引用该函数。 Table10:DuplicateHandle()information. 复制句柄函数的相关信息。 HandlesreturnedbyGetStdHandle()canbeusedbyapplicationsthatneedtoreadfromorwritetotheconsole. GetStdHandle函数可以在需要读写控制台的时候返回控制台句柄。 Whenaconsoleiscreated,thestandardinputhandleisahandletotheconsole'sinputbuffer,andthestandardoutputandstandarderrorhandlesarehandlesoftheconsole'sactivescreenbuffer. 当控制台被创建后,标准输入设备句柄是一个指向标准输入缓存区的句柄,标准输出设备句柄和标准错误输出设备句柄是一个指向控制台窗口缓冲区的句柄。 ThesehandlescanbeusedbytheReadFile()andWriteFile()functions,orbyanyoftheconsolefunctionsthataccesstheconsoleinputbufferorascreenbuffer,forexample,theReadConsoleInput(),WriteConsole(),orGetConsoleScreenBufferInfo()functions. 这些句柄可以被ReadFile函数和WriteFile函数使用,或者被其他可以访问控制台输入缓存区和控制台窗口缓存区的函数使用,例如可以被ReadConsoleInput函数、WriteConsole函数、以及GetConsoleScreenBufferInfo函数使用。 ThestandardhandlesofaprocessmayberedirectedbyacalltoSetStdHandle(),inwhichcaseGetStdHandle()returnstheredirectedhandle. Ifthestandardhandleshavebeenredirected,youcanspecifytheCONIN$valueinacalltotheCreateFile()functiontogetahandletoaconsole'sinputbuffer.Similarly,youcanspecifytheCONOUT$valuetogetahandletoaconsole'sactivescreenbuffer. 一个进程的标准句柄也许会通过调用SetStdHandle句柄来进行重定向,这种情况下可以通过GetStdHandle函数返回重定向后的指针。如果标准句柄被重定向后,你可以在调用CreateFile函数时传递CONIN$变量来获取控制台输入缓冲区的句柄。类似的,你可以指定CONOUT$值来获取一个指向活动的控制台窗口缓冲区的句柄。 ThefollowingTableliststherequiredinformationinordertousetheGetStdHandle()function. 下表描述部分GetStdHandle函数的必要信息,以及如何使用它的一些信息。 Information Description 描述/解释 Thefunction GetStdHandle(). Theuse Retrievesahandleforthestandardinput,standardoutput,orstandarderrordevice. 返回标准输入输出设备的句柄。 Theprototype HANDLEGetStdHandle(DWORDnStdHandle); 函数的原型 Example 示例 HANDLEhStdout; hStdout=GetStdHandle(STD_OUTPUT_HANDLE); Theparameters nStdHandle-[in]Standarddeviceforwhichahandleistobereturned.Thisparametercanbeoneofthefollowingvalues: STD_INPUT_HANDLE-Handletothestandardinputdevice.Initially,thisisahandletotheconsoleinputbuffer,CONIN$. STD_OUTPUT_HANDLE-Handletothestandardoutputdevice.Initially,thisisahandletotheactiveconsolescreenbuffer,CONOUT$. STD_ERROR_HANDLE-Handletothestandarderrordevice.Initially,thisisahandletotheactiveconsolescreenbuffer,CONOUT$. nStdHandle-[in]:指出将要返回那个标准设备的句柄值,这个参数可以取下面几个宏中的一个: 1、STD_INPUT_HANDLE 指出返回标准输入设备的句柄,通常这个句柄是一个指向控制台输入缓冲区CONIN$的句柄。 2、STD_OUTPUT_HANDLE 指出返回的是标准输出设备的句柄,通常这个句柄是一个指向当前激活控制台窗口缓冲区CONOUT$的句柄。 3、STD_ERROR_HANDLE 指出函数返回的是标准错误输出设备的句柄,通常这个句柄是一个指向当前激活的控制台窗口缓冲区CONOUT$的句柄。 Thereturnvalue Ifthefunctionsucceeds,thereturnvalueisahandletothespecifieddevice,oraredirectedhandlesetbyapreviouscalltoSetStdHandle().ThehandlehasGENERIC_READandGENERIC_WRITEaccessrights,unlesstheapplicationhasusedSetStdHandle()tosetastandardhandlewithlesseraccess. Ifthefunctionfails,thereturnvalueisINVALID_HANDLE_VALUE.Togetextendederrorinformation,callGetLastError(). Ifanapplicationdoesnothaveassociatedstandardhandles,suchasaservicerunningonaninteractivedesktop,andhasnotredirectedthem,thereturnvalueisNULL. 如果这个函数成功执行,那么返回值就是一个指向指定设备的句柄,或者是一个指向通过SetStdHandle函数重定向的设备的句柄值。 返回的句柄具有GENERIC_READ和GENERIC_WRITE的访问权限,除非应用程序通过SetStdHandle函数设定标准句柄具有其他更低的权限。 如果函数执行失败,返回值是INVALID_HANDLE_VALUE,若要获取更多的错误信息,可以调用GetLastError函数。 如果一个应用程序没有标准设备句柄,或者没有重定向标准设备,例如一个内部桌面运行的一个服务,那么函数将返回一个NULL值。 Theheaderfile <windows.h> 需要包含windows.h头文件。 Table11:GetStdHandle()information. ThestandardhandlesofaprocessmayhavebeenredirectedbyacalltoSetStdHandle(),inwhichcaseGetStdHandle()willreturntheredirectedhandle. Ifthestandardhandleshavebeenredirected,youcanspecifytheCONIN$valueinacalltotheCreateFile()functiontogetahandletoaconsole'sinputbuffer. 一个进程的标准输入输出设备可能会通过调用SetStdHandle函数进行重定向,这种情况下可以通过GetStdHandle函数来获取进程经过重定向后的标注输入输出设备的句柄。如果标准输入输出设备被重定向了,那么在应用程序中调用CreateFile函数时可以通过指定CONIN$参数来获取一个指向控制台输入缓冲区的句柄。 Similarly,youcanspecifytheCONOUT$valuetogetahandletotheconsole'sactivescreenbuffer. 类似的还可以指定CONNOUT$值来获取指向当前激活的控制台窗口缓冲区的句柄。 ThefollowingTableliststherequiredinformationinordertousetheSetStdHandle()function. Information Description Thefunction SetStdHandle(). 重定向标准输入输出设备 Theuse Setsthehandleforthestandardinput,standardoutput,orstandarderrordevice. 设定标准输入设备、标准输出设备、标准错误设备的句柄。 Theprototype BOOLSetStdHandle(DWORDnStdHandle,HANDLEhHandle); 函数原型 Example HANDLEhStdout; BOOLsuccess=SetStdHandle(STD_OUTPUT_HANDLE,hStdout); //ifsomethingwrongwithhandle if(!success) //justexit exit(1); 示例代码 Theparameters nStdHandle-[in]Standarddeviceforwhichthehandletobeset.Thisparametercanbeoneofthefollowingvalues: STD_INPUT_HANDLE-Handletothestandardinputdevice. STD_OUTPUT_HANDLE-Handletothestandardoutputdevice. STD_ERROR_HANDLE-Handletothestandarderrordevice. nStdHandle-[in]:指出要被重新设定的标准设备。可以取下面几个值: 1、STD_INPUT_HANDLE 指出要设定的是标准输入设备。 2、STD_OUTPUT_HANDLE 指出要设定的设备是标准输出设备 3、STD_ERROR_HANDLE 指出要设定的是标准错误输出设备 hHandle-[in]Handletosettothespecifieddevice. hHandle-[in]要重定向给标准设备的对象的句柄。 Thereturnvalue Ifthefunctionsucceeds,thereturnvalueisnonzero. Ifthefunctionfails,thereturnvalueiszero.Togetextendederrorinformation,callGetLastError(). 如果函数执行成功,返回值是非零。 如果函数执行失败,那么将返回0.如果需要获取更多的错误信息,可以调用GetLastError函数。 Theheaderfile <windows.h> 要包含头文件window.h Table12:SetStdHandle()information. SetStdHandle函数相关信息 ThefollowingprogramexampleusesGetStdHandle()functionforstandardinputandoutputhandles. 下面是一个使用GetStdHandle函数来获取标准输入输出设备句柄的示例。 #include<windows.h> #include<stdio.h> #defineBUFSIZE2048 intmain() { charchrBuf[BUFSIZE]; DWORDdwRead,dwWritten; HANDLEhStdin,hStdout; BOOLfSuccess; //standardoutputhandle hStdout=GetStdHandle(STD_OUTPUT_HANDLE); //standardinputhandle hStdin=GetStdHandle(STD_INPUT_HANDLE); //ifsomethingwrongwithhandleforstandardinputoroutput if((hStdout==INVALID_HANDLE_VALUE)||(hStdin==INVALID_HANDLE_VALUE)) //justexit exit(1); printf("Waitingdatafromstandardinput:\n"); printf("--EOFtoend--\n"); //tostop,pressendoffilecharacters for(;;) { //readfromstandardinput,keyboard. fSuccess=ReadFile(hStdin,chrBuf,BUFSIZE,&dwRead,NULL); if(!fSuccess||dwRead==0) break; printf("Datatothestandardoutput:\n"); //writetostandardoutput,console. fSuccess=WriteFile(hStdout,chrBuf,dwRead,&dwWritten,NULL); if(!fSuccess) break; } return0; } Asampleoutput: Waitingdatafromstandardinput: --EOFtoend-- Thislineoftextisfromstandardinput Datatothestandardoutput: Thislineoftextisfromstandardinput Thenredirectedtostandardoutput... Datatothestandardoutput: Thenredirectedtostandardoutput... ^Z Pressanykeytocontinue ThefollowingisasampleoutputrunusingVC++ExpressEditiononWinXPProSP2withWindowsSDK.