windowshello人脸不可用windowsh

如题所述

关于windows hello人脸不可用,windows h这个很多人还不知道,今天来为大家解答以上的问题,现在让我们一起来看看吧!
1、很多初中级程序员用C/C++编写WindwosAPI的程序时,经常面对面条式的switch...case语句当你在Window过程(回调函数、下称过程)中加入大量诸如WM_COMMAND or WM_CHAR的消息捕获时。
2、真是一场噩梦。
3、关于上千行代码的Window过程的问题,随着 C/C++ 7.0 编译器和Windows SDK forWindows 3.1发行时带的一个头文件而被解决。
4、这个头文件是以及所包含的大量的有用的宏。
5、按照微软的说法:这些头文件所带来的便利可重复用于下面这些地方(Groups):.在C程序中使用STRICT宏进行严格的类型检查。
6、.在windows程序中用宏简化公共性操作。
7、.使用控件宏同windows控件进行通讯。
8、.windows环境下的消息解析器(messagecrackers)(是一个方便的、可移植的、类型安全的处理消息的方法)以及和他相关的参数和返回值。
9、因为消息解析器向导是用于消息解析器的,其他由这头文件带来的一些有用的宏,我就跳过不讲了让我们说下消息解析器的优点,当然也包括为什么这里提供的这个工具是如此有用。
10、当你使用W32SDK编程,用windows过程(通常叫做WndProc)处理窗口和对话框消息时,使用swich-case来捕获你需要处理的消息是非常普遍的做法。
11、假设你想处理WM_COMMAND,WM_KEYUP, WM_CLOSE and WM_DESTROY消息,你是这样作的:LRESULT CALLBACK MainWndProc (HWND hwnd, UINT msg,WPARAM wParam, LPARAMlParam){switch(msg){case WM_COMMAND:// ...break;case WM_KEYUP:// ...break;case WM_CLOSE:// ...break;case WM_DESTROY://...break;default:return DefWindowProc(hwnd, msg, wParam,lParam);}}这是自从Windows1.0诞生以来处理消息最常见的风格了。
12、而且很肯定,它工作得很好。
13、但问题是,当你加入一个或多个复杂的特色到你的程序中时,如MDI,OLE公共控件等等,结果形成了一个上千行的Window过程,你开始用PageDn和PageUp来查找你想要修改的消息处理代码了。
14、消息解析器的第一个好处就是:他把面条式的case标签转换成类似MFC中易于维护和处理的函数。
15、第二个好处是:处理函数中合适的参数。
16、你可以简单使用switch(id)代替原先的switch(LOWORD(wparam)),因为消息解析器传递给你的是"已解析"的参数,他等价于LOWORD(wparam)。
17、HANDLE_MSG 这个消息处理宏在windowx.h中的定义如下:#define HANDLE_MSG(hwnd, message, fn)case (message) : return HANDLE_##message((hwnd), (wParam), (lParam),(fn))你想要把你的代码做成"消息解析"版的,你需要提供一个解析宏HANDLE_MSG及其函数来处理你的消息.在window过程里HANDLE_MSG宏需要三个参数:窗口句柄(hwnd),消息(WM_XXXX), 处理你消息的函数(function)。
18、为更好地解释这个:看下面,我们把上面那段代码转换成了下面的代码:LRESULT CALLBACK MainWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAMlParam){switch(msg){HANDLE_MSG (hwnd, WM_COMMAND,OnCommand);HANDLE_MSG (hwnd, WM_KEYUP, OnKeyup);HANDLE_MSG(hwnd, WM_CLOSE, OnClose);HANDLE_MSG (hwnd, WM_DESTROY,OnDestroy);default:return DefWindowProc(hwnd, msg, wParam,lParam);}}哇,太好了,紧凑且易于管理的window过程。
19、现在你可以去定义你的消息处理函数了(OnKeyUp, OnClose, andOnDestroy)还有一个真正的好处,你可以在visual studio IDE 环境中直接跳转到消息处理函数。
20、有个问题是:当你每加入一个消息处理,你必须在windowx.h中查找相关参数的定义。
21、因为消息处理参数的格式是明确的而不能由你随心所欲。
22、但在头文件中进行重复搜索是乏味且易出错的。
23、消息解析向导工具用于解决这个:他允许你粘贴你需要的函数参数,而你如果只是打草稿,他也会在在你消息处理中写上一个模板化的window或对话框过程(??这句有疑问)消息前驱宏(message fowarding): WINDOWSX.H 的另一个特色(消息前向?)WINDOWSX.H另一个特色是消息前驱的可能性,它是用于"解压"消息处理参数到其他函数调用(如PostMessage,SendMessage,CallWindowProc等)所需要的合适的WPARAM和LPARAM值。
24、假设我们想用SendMessage发送一个WM_COMMAND消息到父窗口,"模拟"一个在名为IDC_USERCTL控件上的双击(通过发送BN_DBLCLK的通知码)我们通常这么做的:SendMessage (hwndParent, WM_COMMAND,MAKEWPARAM(IDC_USERCTL, BN_DBLCLK),// WPARAM 的低16位是控件ID,高16位是通知码(LPARAM)GetDlgItem(hwnd, ID_USERCTL));//LPARAM为控件句柄这是相当复杂的语法。
25、SendMessage希望WPARAM参数的低字是控件ID而高字是通知码,LPARAM参数是控件句柄,句柄我们通过GetDlgItem这个API函数得到。
26、上述代码可以被转换为WINDOWSX.H的消息前驱宏,FORWARD_WM_xxxxx。
27、对于每个消息,消息前向宏用同样的方式"打包"消息解析向导创建的函数参数,并且传递给你的处理函数"已解压"的参数(LPARAM/WPARAMs)。
28、例如:对于一个myWnd窗口的WM_COMMAND消息,消息解析器向导将生成如下的函数原形:void myWnd_OnCommand (HWND hwnd, int id, HWND hwndCtl, UINTcodeNotify)那么,这些解析的参数也同样用于消息前驱宏,这样上面那使人混乱的SendMessage调用可以简化为:FORWARD_WM_COMMAND (hwndParent, IDC_USERCTL,GetDlgItem(hwnd,ID_USERCTL), BN_DBLCLK, SendMessage);使用所有这些消息解析器支持的消息简单可行。
29、(第一部分完)在使用消息分流器来处理一个消息之前,应该打开Wi n d o w s X . h文件并搜索要处理的消息。
30、例如,如果搜索W M _ C O M M A ND,将会找到文件中包含下面代码行的部分:/* void Cls_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)*/#define HANDLE_WM_COMMAND(hwnd, wParam, lParam, fn) ((fn)((hwnd),(int)(LOWORD(wParam)), (HWND)(lParam), (UINT)HIWORD(wParam)), 0L)#defineFORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, fn) (void)(fn)((hwnd), WM_COMMAND, MAKEWPARAM((UINT)(id),(UINT)(codeNotify)),(LPARAM)(HWND)(hwndCtl))第一行是注释行,展示要编写的函数原型。
31、下一行是H A N D L E _ W M _*宏,我们已经讨论过。
32、最后一行是消息转发器( f o r w a r d e r)。
33、假定在你处理W M _ C O M M A ND消息时,你想调用默认的窗口过程,并让它为你做事。
34、这个函数应该是这个样子:void Cls_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify){//Do some normal processing.//Do default processing.FORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, DefWindowProc);}F O RWA R D _ W M _ *宏将分流开的消息参数重新构造成等价的w P a r a m和l P a r am。
35、然后这个宏再调用你提供的函数。
36、在上面的例子中,宏调用D e f Wi n d o w P r o c函数,但你可以简单地使用S e n d M e s sa g e或P o s t M e s s a g e。
37、实际上,如果你想发送(或登记)一个消息到系统中的任何窗口,可以使用一个F O RWA R D _ W M_ *宏来帮助合并各个参数。
38、应注意Windows.h和Windowsx的不同之处.2.tchar.h 头文件3.CmnHdr.h 头文件它包含宏及链接程序指令.读者要想建立本书的示例程序,必须要对编译程序和链接程序的开关选项进行设置,笔者已经将设置方面的细节放在了CmmHdr.h头文件中了因为无法将所有的设置都放在这个头文件里,我们对每个示例程序的项目设置做了一些改变。
39、对每个项目,我们显示ProjectSettings对话框,然后做下面所说的改变。
40、? 在G e n e r a l栏,设定Output Files目录,这样所有最终的. e x e和.d l l文件都在一个目录之下。
41、? 在C / C + +栏,选择Code Generation 条目,并对Use Run-TimeLibrary 字段选择Multithreaded DLL。
42、注意要对每个项目的D e b u g建立和R e l e a s e建立都做上述两个改变。
43、所有的示例程序都要包含C m m H d r.h头文件,并且要在其他头文件之前包含.这是因为CmnHdr.h头文件中有一些链接程序指令,比如#define _WIN32_WINNT 0x0500(它是Windows版本建立选项)的定义必须放在Windows.h之前,才能调用了Microsoft Windows2000中提供的新函数.否则编译程序将产生错误。
44、微软用_ W I N 3 2 _ W I N NT符号来保护这些函数,以使程序员开发的应用程序能够运行在Windows 98及Windows NT的多个版本上。
45、Unicode建立选项.笔者编写的所有这些示例程序既可按A N S I来编译,也可按U n i c o d e来编译。
46、当针对x 8 6 C PU体系结构来编译这些程序时, A N S I为默认选择,这样程序可以在Windows 98上执行。
47、但对其他C P U体系结构建立程序就要用U n i c o de,这样程序可以占用较少的内存,并且执行得更快。
48、为了对x 8 6体系结构建立U n i c o d e版本,只需将定义U N I C O D E的那一行代码的注释符去掉,并重建程序。
49、通过在CmnHdr. h定义U N I C O D E宏,可以很容易地控制如何建立示例程序。
50、关于U n i c o d e的详细内容,可参见第2章。
51、窗口定义和第四级警告本节我确保警告级设定为3,而且C m nH d r. h包含标准的Wi n d o w s . h头文件。
52、当包含了Wi n do w s . h时,在我编译其余代码时就设置第4级警告。
53、在第4级警告上,编译程序对那些我不认为有问题的内容发出“警告”,这样我通过使用#pragmawarning指令显式地告诉编译程序忽略某些良性的警告错。
54、Pragma消息帮助宏使用chMsg宏,例如#pragma chMSG(Fix thislater),这个宏让编译程序输出源代码文件的名字,以及p r a g m a出现的行号。
55、使用Microsoft Visual DeveloperStudio,在输出窗口上双击这一行,将会自动定位到相应文件的确切位置上。
56、还有一个方便之处, c h M S G宏不要求对文本串使用引号。
57、.chINRANGE和chDIMOF宏chINRANGE宏用来查看一个数值是否在另外两个数值之间.chDIMOF只是返回一个数组中元素的数目,这个宏是用s i z e of操作符先计算整个数组的字节数,然后再用这个数除以数组中一个数据项所占的字节数,从而得出结果。
58、chBEGINTHREADEX宏多线程示例程序都使用了微软的C/C + +运行时函数库中的_ b e g i n t h r e a d ex函数,而不是操作系统的C r e a t e T h r e a d函数。
59、我使用这个函数是因为_ b e g i n t h r e a d ex函数为新线程做好了准备,使新线程能够使用C / C + +运行时函数库中的函数,而且还因为它保证在线程返回时清除每个线程的C / C ++运行时库信息.尽管_ b e g i n t h r e a d e x函数用的参数值同C r e a t e T h r e ad函数用的参数值是一样的,但二者的参数的数据类型都不相匹配。
60、为了避免编译程序警告,我在C m n H d r. h中定义了一个c h B E G I NT H RE A D E X宏,替我执行所有这些转换:chMB宏c h M B宏只是显示一个消息框。
61、消息框的标题是调用进程可执行代码的全路径名chASSERT和chVERIFY宏在我开发这些示例程序时,为了查找潜在的问题,我在整个代码中多处使用c h A S S ERT宏。
62、这个宏测试由x所标识的表达式是否为T R U E,如果不是,则显示一个消息框指出失败的文件、行和表达式。
63、在程序的发行建立中,这个宏什么也不做。
64、c h VE R I F Y宏与c h A S S E RT宏差不多,区别在于不论是调试建立(debug build)还是发行建立(release build),c hV E R I F Y都要对表达式进行测试。
65、chHANDLE_DLGMSG宏当你通过对话框使用消息分流器时,不应该使用微软的Wi n d o w s X . h 头文件中的H A N D L E _ M SG宏,因为这个宏并不能返回T R U E或FA L S E来指出消息是否由对话框的过程来处理。
66、我定义的c h H A N D L E _ D L G M SG宏会通知窗口消息的返回值,适当地处理返回值,以便在一个对话框过程中使用。
67、chSETDLGICONS宏由于多数示例程序使用一个对话框作为主窗口,你必须手工改变对话框图标,以便让它正确地显示在Ta s k b ar(任务条)、任务切换窗口和程序本身的标题上。
68、当对话框接收到一个W M _ I N I T D I A L O G消息时,总要调用c h S E T D L GI C O N S宏,以正确设置图标。
69、OS版本检查内联函数本书的大多数示例程序可运行在所有平台上,但也有一些程序要求一些Windows 95和Windows 98所不支持的特性,有些程序要求一些只在Windows2000中提供的特性。
70、每个程序在初始化时要检查宿主系统的版本,如果要求更适用的操作系统时,就显示一个通知。
71、对那些不能在Windows 95和Windows 98上运行的程序,你会看到,在程序的_ t Wi n M a i n函数中有一个对Wi n d o ws 9 x N o t A l l o w e d函数的调用。
72、对于要求Windows 2000的示例程序,你会看到在程序的_ t Wi n M a in函中有一个对c h Wi n d o w s 2 0 0 0 R e q u i r e d函数的调用。
73、确认宿主系统是否支持Unicode有一种办法能够知道我的程序是对U n i c o d e建立的,但可能在Windows98系统上运行。
74、所以我建立了一个CUnicodeSupported C++类。
75、这个类的构造函数只是检查宿主系统是不是对U n i c o de有良好的支持,如果不是,就显示一个消息框,并且进程结束。
76、读者会看到在C m n H d r. h中,我建立了这个类的一个全局的静态实例。
77、当我的程序启动时,C / C ++运行时库启动代码调用这个对象的构造函数。
78、如果这个构造函数检测到操作系统完全支持U n i c o de,构造函数返回而程序继续执行。
79、通过建立这个类的全局实例,我不需要在每个示例程序的源代码模块中再增加特殊的代码。
80、对于非U n i c o de的程序建立,不需要声明或实例化上述的C + +类。
81、让程序只管运行就是。
82、强制链接程序寻找(w)WinMain进入点函数我在C m n H d r. h中加入了一个p r a g m a,强制链接程序去寻找( w )Wi n M a i n进入点函数,即使是用Visual C++建立了一个Win32 ConsoleA p p l i c a t i o n项目.。
本文到此分享完毕,希望对大家有所帮助。
温馨提示:答案为网友推荐,仅供参考