您的位置:首页 > 其它

第十章 菜单及其它资源part4

2010-04-15 15:34 253 查看
键盘快捷键

快捷键是产生WM_COMMAND消息(有些情况下是WM_SYSCOMMAND)的键组合。

为什么要使用快捷键

Windows将键盘消息发送给目前活动窗口的窗口消息处理程序。然而对于快捷键,Windows把WM_COMMAND消息发送给窗口消息处理程序.该窗口消息处理程序的句柄在Windows函数TranslateAccelerator中给出快捷键中,应该避免使用Tab、Enter、Esc和Spacebar键,因为这些键常常用于完成系统功能。

快捷键表的加载

使用LoadAccelerators函数把快捷键表加载内存,并获得该表的句柄。

LoadAccelerators叙述非常类似于LoadIcon、LoadCursor和LoadMenu叙述。

HANDLE hAccel ;

hAccel = LoadAccelerators (hInstance, TEXT ("MyAccelerators")) ;

键盘代码转换

下面代码的修改是为了方便使用快捷键

while (GetMessage (&msg, NULL, 0, 0)) {

if (!TranslateAccelerator (hwnd, hAccel, &msg)) {

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

TranslateAccelerator函数确认存放在msg消息结构中的消息是否为键盘消息。如果是,该函数将找寻句柄为hAccel的快捷键表。如果找到了一个符合的,则呼叫句柄为hwnd的窗口消息处理程序。如果快捷键ID与系统菜单的菜单项一致,则消息就是WM_SYSCOMMAND;否则,消息为WM_COMMAND。

快捷键表

当您为菜单项定义快捷键时,应该将键的组合包含到菜单项的文字中。制表符(/t)将文字与快捷键分割开,将快捷键列在第二列。

如果活动窗口已经被最小化,那么TranslateAccelerator将为与启用的系统菜单项相对应的快捷键向窗口消息处理程序发送WM_SYSCOMMAND消息, 而不是WM_COMMAND消息。

#include <windows.h>
#include "resource.h"

#define ID_EDIT  1
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
TCHAR szAppName[] = TEXT ("PopPad2");

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR  szCmdLine,  int
iCmdShow)
{
HACCEL hAccel;
HWND   hwnd;
MSG    msg;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra  = 0 ;
wndclass.cbWndExtra  = 0 ;
wndclass.hInstance   = hInstance ;
wndclass.hIcon       = LoadIcon(hInstance, szAppName) ;
wndclass.hCursor     = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName  = szAppName ;
wndclass.lpszClassName = szAppName ;

if (!RegisterClass (&wndclass))
{
MessageBox(NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
HMENU hMenu = LoadMenu(hInstance,MAKEINTRESOURCE(POPPAD2));
hwnd = CreateWindow (szAppName, szAppName,
WS_OVERLAPPEDWINDOW,
GetSystemMetrics (SM_CXSCREEN) / 4,
GetSystemMetrics (SM_CYSCREEN) / 4,
GetSystemMetrics (SM_CXSCREEN) / 2,
GetSystemMetrics (SM_CYSCREEN) / 2,
NULL, hMenu, hInstance, NULL) ;

ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd);

//hInstance是应用程序实例句柄,
//用来从程序的资源文件里查找到快捷键定义。
//lpTableName是快捷键的定义表格。
hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(POPPAD2));
while (GetMessage(&msg, NULL, 0, 0))
{
//当快捷键与系统菜单中的菜单项相对应时,
//TranslateAccelerator给窗口消息处理程序发
//送一个WM_SYSCOMMAND消息
//否则,TranslateAccelerator给窗口消息处理程序发送
//一个WM_COMMAND消息。
if (!TranslateAccelerator(hwnd, hAccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}

//显示一个请求确认关闭程序的消息框
int AskConfirmation(HWND hwnd)
{
return MessageBox(hwnd, TEXT ("Really want to close PopPad2?"),
szAppName, MB_YESNO | MB_ICONQUESTION) ;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
static HWND      hwndEdit;
int              iSelect, iEnable;

switch (message)
{
case WM_CREATE:
//创建edit编辑区域
hwndEdit = CreateWindow (TEXT ("edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
WS_BORDER | ES_LEFT | ES_MULTILINE |
ES_AUTOHSCROLL | ES_AUTOVSCROLL,
0, 0, 0, 0, hwnd, (HMENU)ID_EDIT,
((LPCREATESTRUCT) lParam)->hInstance, NULL);
return 0;

case WM_SETFOCUS:
SetFocus(hwndEdit);
return 0;

case WM_SIZE:
//lParam参数包含32位的int型整数,
//低16位是窗口客户区长度,高16位是高度
MoveWindow(hwndEdit,0,0,LOWORD(lParam),HIWORD(lParam),TRUE);
return 0 ;

case WM_INITMENUPOPUP:
if (lParam == 1)
{
//只有选择了编辑控件中的文字,
//「Cut」「Copy」和「Delete」选项才能够被启用
EnableMenuItem((HMENU)wParam, IDM_EDIT_UNDO,
SendMessage(hwndEdit, EM_CANUNDO, 0, 0)?MF_ENABLED : MF_GRAYED);

EnableMenuItem((HMENU)wParam, IDM_EDIT_PASTE,
IsClipboardFormatAvailable (CF_TEXT)?MF_ENABLED : MF_GRAYED);
//给编辑控件发送一条EM_GETSEL消息
//并传回包含此信息的整数
iSelect = SendMessage(hwndEdit, EM_GETSEL, 0, 0) ;
//iSelect的低位字是第一个被选中字符的位置,
//iSelect的高字组是下一个被选中字符的位置。
//如果这两个字相等,则表示没有选中文字:
if (HIWORD(iSelect) == LOWORD(iSelect))
iEnable = MF_GRAYED;
else
iEnable = MF_ENABLED;
//然后可以将iEnable的值用于「Cut」「Copy」和「Delete」选项
EnableMenuItem((HMENU) wParam, IDM_EDIT_CUT,   iEnable) ;
EnableMenuItem((HMENU) wParam, IDM_EDIT_COPY,  iEnable) ;
EnableMenuItem((HMENU) wParam, IDM_EDIT_CLEAR, iEnable) ;
return 0 ;
}
break ;
case WM_COMMAND:
if (lParam)
{
if (LOWORD (lParam) == ID_EDIT &&
(HIWORD (wParam) == EN_ERRSPACE ||
HIWORD (wParam) == EN_MAXTEXT))
MessageBox (hwnd, TEXT ("Edit control out of space."),
szAppName, MB_OK | MB_ICONSTOP) ;
return 0 ;
}
else switch (LOWORD(wParam))
{
case IDM_FILE_NEW:
case IDM_FILE_OPEN:
case IDM_FILE_SAVE:
case IDM_FILE_SAVE_AS:
case IDM_FILE_PRINT:
MessageBeep (0) ;
return 0 ;
//涉及如何
//完成「Edit」菜单中的「Undo」「Cut」「Copy」 「Paste」「Clear」和「Select All」
//选项。正是编辑控件使得这种处理变得容易,
//因为对于每一个选项我们只需向编辑控件发送
//一个消息即可
case IDM_APP_EXIT:
SendMessage(hwnd, WM_CLOSE, 0, 0) ;
return 0 ;

case IDM_EDIT_UNDO:
SendMessage(hwndEdit, WM_UNDO, 0, 0) ;
return 0 ;

case IDM_EDIT_CUT:
SendMessage(hwndEdit, WM_CUT, 0, 0) ;
return 0 ;

case IDM_EDIT_COPY:
SendMessage(hwndEdit, WM_COPY, 0, 0) ;
return 0 ;

case IDM_EDIT_PASTE:
SendMessage(hwndEdit, WM_PASTE, 0, 0) ;
return 0 ;

case IDM_EDIT_CLEAR:
SendMessage(hwndEdit, WM_CLEAR, 0, 0) ;
return 0 ;

case IDM_EDIT_SELECT_ALL:
SendMessage(hwndEdit, EM_SETSEL, 0, -1) ;
return 0 ;

case IDM_HELP_HELP:
MessageBox(hwnd, TEXT("Help  not yet implemented!"),
szAppName, MB_OK | MB_ICONEXCLAMATION) ;
return 0 ;

case IDM_APP_ABOUT:
MessageBox(hwnd, TEXT("POPPAD2 (c) Charles Petzold, 1998"),
szAppName, MB_OK | MB_ICONINFORMATION) ;
return 0 ;
}
break ;

case WM_CLOSE:
if (IDYES == AskConfirmation(hwnd))
DestroyWindow(hwnd);
return 0 ;

case WM_QUERYENDSESSION:
//当使用者要关闭Windows时,Windows开始向每个窗
//口消息处理程序发送一个WM_QUERYENDSESSION消息
if (IDYES == AskConfirmation(hwnd))
return 1;
else
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}


PopPad2.rc

/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

POPPAD2 MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&New",                        IDM_FILE_NEW
MENUITEM "&Open...",                    IDM_FILE_OPEN
MENUITEM "&Save",                       IDM_FILE_SAVE
MENUITEM "Save  &As...",                IDM_FILE_SAVE_AS
MENUITEM SEPARATOR
MENUITEM "&Print",                      IDM_FILE_PRINT
MENUITEM SEPARATOR
MENUITEM "E&xit",                       IDM_APP_EXIT
END
POPUP "&Edit"
BEGIN
MENUITEM "&Undo/tCtrl+Z",               IDM_EDIT_UNDO
MENUITEM SEPARATOR
MENUITEM "Cu&t/tCtrl+X",                IDM_EDIT_CUT
MENUITEM "&Copy/tCtrl+C",               IDM_EDIT_COPY
MENUITEM "&Paste/tCtrl+V",              IDM_EDIT_PASTE
MENUITEM "De&lete/tDel",                IDM_EDIT_CLEAR
MENUITEM SEPARATOR
MENUITEM "&Select  All",                IDM_EDIT_SELECT_ALL
END
POPUP "&Help"
BEGIN
MENUITEM "&Help...",                    IDM_HELP_HELP
MENUITEM "&About PopPad2...",           IDM_APP_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//

POPPAD2 ACCELERATORS
BEGIN
VK_DELETE,      IDM_EDIT_CLEAR,         VIRTKEY, NOINVERT
"^C",           IDM_EDIT_COPY,          ASCII,  NOINVERT
VK_INSERT,      IDM_EDIT_COPY,          VIRTKEY, CONTROL, NOINVERT
"^X",           IDM_EDIT_CUT,           ASCII,  NOINVERT
VK_DELETE,      IDM_EDIT_CUT,           VIRTKEY, SHIFT, NOINVERT
"^V",           IDM_EDIT_PASTE,         ASCII,  NOINVERT
VK_INSERT,      IDM_EDIT_PASTE,         VIRTKEY, SHIFT, NOINVERT
"^Z",           IDM_EDIT_UNDO,          ASCII,  NOINVERT
VK_BACK,        IDM_EDIT_UNDO,          VIRTKEY, ALT, NOINVERT
VK_F1,          IDM_HELP_HELP,          VIRTKEY, NOINVERT
END
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: