先做个广告:个人架设了论坛http://www.crazyctime.com/,欢迎各位热爱C/C++编程技术的朋友进来交流学习

 

上节中我们把界面完成了,可是只是界面,没有一点作用,这节我们就让上面的菜单和快捷键其作用,上节中已经介绍了,
在我们单击菜单或者快捷键时,Windows会把相应的ID传给窗口处理过程。这个时候我们只要在消息处理代码中加入要处
理的代码之后,那么这个程序就可以响应菜单和快捷键了。今天大家又要了解两个新函数,主要是处理快捷键,有点小特别。
首先和其他资源一样要先载入快捷键资源,这里用到LoadAccelerators函数,具体情况如下:

LoadAccelerators

  函数功能:调入加速键表。该函数调入指定的加速键表。

  函数原型:HACCEL LoadAccelerators(HINSTANCE hlnstance,LPCTSTR lpTableName);

  参数:

  hlnstance:模块的一个事例的句柄,该模块的可执行文件中包含将要调入的加速键表。

  IpTableName:指向一个以空结尾的字符串的指针,该字符串包含了即将调入的加速键表的名字。另一种可选的方案是,该参数可以在加速键表资源的低位字中指定资源标识符,而高位字中全零。MADEINTRESOURCE宏可被用于创建该值。

  返回值:若函数调用成功,则返回非零值。若函数调用失败,则返回值为零。若要获得更多的错误信息,可以调用GetLastError函数。

  备注:若加速键表尚未装入,该函数可从指定的可执行文件中将它装入。从资源中装入的加速键表,在程序结束时可自动释放。Windows CE:资源不被拷贝到RAM中,因而不能被修改。

 
对于加速键的消息处理也有点特别,因为程序发现消息来源是快捷键就直接把消息发送到窗口处理过程(窗口处理函数)进行处
理,和其他消息不太一样,所以这次消息处理代码需要这样来了:
代码

while(GetMessage(&Msg,NULL,0,0))
{
if(!TranslateAccelerator(hWnd,hAccel,&Msg))
{
TranslateMessage(
&Msg);//翻译消息
DispatchMessage(&Msg);//分派消息
}
}
return Msg.message;
需要先行判断是不是快捷键消息,不是才进行消息的翻译和派送。
下面请看TranslateAccelerator的详细内容:

TranslateAccelerator

  函数功能:翻译加速键表。该函数处理菜单命令中的加速键。该函数将一个WM_KEYDOWN或WM_SYSKEYDOWN消息翻译成一个WM_COMMAND或WM_SYSCOMMAND消息(如果在给定的加速键表中有该键的入口),然后将WM_COMMAND或WM_SYSCOMMAND消息直接送到相应的窗口处理过程。

  TranslateAccelerator直到窗口过程处理完消息后才返回。

  函数原型:int TranslateAccelerator(HWND hWnd,HACCEL hAccTable,LPMSG IpMsg);

  参数:

  hWnd:窗口句柄,该窗口的消息将被翻译。

  hAccTable:加速键表句柄。加速键表必须由LoadAccelerators函数调用装入或由CreateAccd_eratorTable函数调用创建。

  LpMsg:MSG结构指针,MSG结构中包含了从使用GetMessage或PeekMessage函数调用线程消息队列中得到的消息内容。

  返回值:若函数调用成功,则返回非零值;若函数调用失败,则返回值为零。若要获得更多的错误信息,可调用GetLastError函数。

  备注:为了将该函数发送的消息与菜单或控制发送的消息区别开来,使WM_COMMAND或WM_SYSCOMMAND消息的wParam参数的高位字值为1。用于从窗口菜单中选择菜单项的加速键组合被翻译成WM_SYSCOMMAND消息:所有其他的加速键组合被翻译成WM_COMMAND。若TransLateAccelerator返回非零值且消息已被翻译,应用程序就不能调用TranslateMessage函数对消息再做处理。每个加速键不一定都对应于菜单命令。若加速键命令对应于菜单项,则WM_INITMEMU和WM_INITMENUPOPUP消息将被发送到应用程序,就好像用户正试图显示该菜单。然而,如下的任一条件成立时,这些消息将不被发送:窗口被禁止,菜单项被禁止。

  加速键组合无相应的窗口菜单项且窗口己被最小化。鼠标抓取有效。有关鼠标抓取消息,参看SetCapture函数。若指定的窗口为活动窗口且窗口无键盘焦点(当窗口最小化时一般是这种情况),TranslatMssage翻译WM_SYSDEYUP和WM_SYSKEYDOWN消息而不是WM_KEYUP和WM_KEYDOWN消息。

  当按下相应于某菜单项的加速键,而包含该菜单的窗口又已被最小化时,TranslateMessage不发送WM_COMMAND消息。但是,若按下与窗口菜单或某单项的任一项均不对应的加速键时,TranslateMessage将发送一WM_COMMAND消息,即使窗口己被最小化。

 
既然已经理论了一番,那么下来就实践了,来,让我把这可恨有该死的编程代码贴出来供大家参考下:

 

 

代码

/*****MyMenu.c Written by XHK 2009.3.3****/
#include
<windows.h>

#define ICO_MAIN 0X1000 //图标
#define IDM_MAIN 0X2000 //菜单
#define IDA_MAIN 0X2000 //快捷键

#define IDM_OPEN 0X4101 //“打开”菜单项
#define IDM_INACTIVE 0X4201 //“被禁用的菜单项”
#define IDM_GRAYED 0X4202 //“灰化的菜单项”
#define IDM_HELP 0X4301 //“帮助”菜单项

//回调函数
LRESULT WINAPI WinProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
switch(Msg)//处理消息过程,什么是消息,下节再讲
{
case WM_COMMAND:
switch(0x0000ffff&wParam)
{
case IDM_OPEN:
MessageBox(hWnd,
"你单击了\"打开\"菜单项","提示",MB_OK);
break;
case IDM_HELP:
MessageBox(hWnd,
"你单击了\"帮助主题\"菜单项","提示",MB_OK);
break;
}
break;
case WM_DESTROY://响应鼠标单击关闭按钮事件
PostQuitMessage(0);//退出消息队列,至于什么是消息队列,下节说
return 0;//退出函数
}
return DefWindowProc(hWnd,Msg,wParam,lParam);
}

//主函数
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
char *cName = "myWindow";
char *cCaption = "带目录的窗口 - Made By XHK";
WNDCLASSEX wc;
HWND hWnd;
HACCEL hAccel;
//快捷键表句柄
MSG Msg;

wc.cbClsExtra
= 0;
wc.cbWndExtra
= 0;
wc.cbSize
= sizeof(WNDCLASSEX);
wc.hbrBackground
= (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor
= NULL;
wc.hIcon
= LoadIcon(hInstance,MAKEINTRESOURCE(ICO_MAIN));//载入图标
wc.hIconSm = NULL;
wc.hInstance
= hInstance;
wc.lpfnWndProc
= WinProc;
wc.lpszClassName
=(LPSTR)cName;
wc.lpszMenuName
= NULL;
wc.style
= CS_HREDRAW | CS_VREDRAW;

RegisterClassEx(
&wc);

hWnd
= CreateWindowEx(WS_EX_CLIENTEDGE,cName,cCaption,WS_OVERLAPPEDWINDOW,
400,300,300,200,NULL,LoadMenu(hInstance,MAKEINTRESOURCE(IDM_MAIN)),hInstance,NULL);
if(hWnd == NULL)
{
//容错处理
MessageBox(NULL,"There\'s an Error","Error Title",MB_ICONEXCLAMATION|MB_OK);
return 0;
}
ShowWindow(hWnd,nShowCmd);
//显示窗口
UpdateWindow(hWnd);

//获取快捷键句柄
hAccel=LoadAccelerators(hInstance,MAKEINTRESOURCE(IDA_MAIN));

while(GetMessage(&Msg,NULL,0,0))
{
//先判断是不是快捷键消息
if(!TranslateAccelerator(hWnd,hAccel,&Msg))
{
TranslateMessage(
&Msg);//翻译消息
DispatchMessage(&Msg);//分派消息
}
}
return Msg.message;
}

 

 

大家想写的写下练练手,不想的就直接拷吧,如果有错误就自己该吧,总之最后,你得使你的程序可以响应击目录和快捷键,废话不
说了,就此打住。

 

 

版权声明:本文为20090802原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/20090802/archive/2010/03/03/1677544.html