三、Windows键盘快捷键—菜单与快捷键应用程序POPPAD
在第九章,我们建立了一个叫做POPPAD1的程序,它使用了子窗口编辑控件来实作基本的笔记本功能。在这一章中,我们将加入「File」和「Edit」菜单,并称此程序为POPPAD2。「Edit」菜单的菜单项的功能全部可用;我们将在第十一章中完成「File」功能,在 第十三章中完成「Print」功能。POPPAD2如程序10-9所示。
	程序10-9 POPPAD2
	
        
POPPAD2.C
        
/*---------------------------------------------------------------------------
        
  POPPAD2.C --          Popup Editor Version 2 (includes menu)
        
                                                         (c) Charles Petzold, 1998
        
---------------------------------------------------------------------------*/
        
#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 ;
        
           }
        
   
        
           hwnd = CreateWindow (szAppName, szAppName,
        
                     WS_OVERLAPPEDWINDOW,
        
                    GetSystemMetrics (SM_CXSCREEN) / 4,
        
                   GetSystemMetrics (SM_CYSCREEN) / 4,
        
                    GetSystemMetrics (SM_CXSCREEN) / 2,
        
                    GetSystemMetrics (SM_CYSCREEN) / 2,
        
                    NULL, NULL, hInstance, NULL) ;
        
   
        
           ShowWindow (hwnd, iCmdShow) ;
        
           UpdateWindow (hwnd) ;
        
   
        
           hAccel = LoadAccelerators (hInstance, szAppName) ;
        
           while (GetMessage (&msg, NULL, 0, 0))
        
           {
        
                 if (!TranslateAccelerator (hwnd, hAccel, &msg))
        
                          {
        
                                         TranslateMessage (&msg) ;
        
                                         DispatchMessage (&msg) ;
        
                  }
        
           }
        
           return msg.wParam ;
        
}
        
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:
        
                  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:
        
                  MoveWindow (hwndEdit, 0, 0, LOWORD (lParam), HIWORD (lParam), TRUE) ;
        
                  return 0 ;
        
        
        
           case   WM_INITMENUPOPUP:
        
                  if (lParam == 1)
        
                  {
        
                                         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) ;
        
             
        
                                         iSelect = SendMessage (hwndEdit, EM_GETSEL, 0, 0) ;
        
            
        
                                         if (HIWORD (iSelect) == LOWORD (iSelect))
        
                                                         iEnable = MF_GRAYED ;
        
                                         else
        
                                                         iEnable = MF_ENABLED ;
        
             
        
              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 ;
        
        
        
                  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:
        
                  if (IDYES == AskConfirmation (hwnd))
        
                                         return 1 ;
        
                  else
        
                                         return 0 ;
        
        
        
           case   WM_DESTROY:
        
                  PostQuitMessage (0) ;
        
                  return 0 ;
        
    }
        
           return DefWindowProc (hwnd, message, wParam, lParam) ;
        
}
        
	POPPAD2.RC (摘录)
	
        
//Microsoft Developer Studio generated resource script.
        
#include "resource.h"
        
#include "afxres.h"
        
/////////////////////////////////////////////////////////////////////////////
        
// Icon
        
POPPAD2                    ICON    DISCARDABLE     "poppad2.ico"
        
/////////////////////////////////////////////////////////////////////////////
        
// Menu
        
POPPAD2 MENU DISCARDABLE
        
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 DISCARDABLE
        
BEGIN
        
   VK_BACK,                      IDM_EDIT_UNDO,          VIRTKEY, ALT, NOINVERT
        
   VK_DELETE,                    IDM_EDIT_CLEAR,               VIRTKEY, NOINVERT
        
   VK_DELETE,                    IDM_EDIT_CUT,           VIRTKEY, SHIFT, NOINVERT
        
   VK_F1,                        IDM_HELP_HELP,          VIRTKEY, NOINVERT
        
   VK_INSERT,                    IDM_EDIT_COPY,          VIRTKEY, CONTROL, NOINVERT
        
   VK_INSERT,                    IDM_EDIT_PASTE,         VIRTKEY, SHIFT, NOINVERT
        
   "^C",         IDM_EDIT_COPY,          ASCII,  NOINVERT
        
   "^V",         IDM_EDIT_PASTE,         ASCII,  NOINVERT
        
  "^X",         IDM_EDIT_CUT,           ASCII,  NOINVERT
        
   "^Z",         IDM_EDIT_UNDO,          ASCII,  NOINVERT
        
END
        
	RESOURCE.H (摘录)
	
        
// Microsoft Developer Studio generated include file.
        
// Used by POPPAD2.RC
        
#define IDM_FILE_NEW                 40001
        
#define IDM_FILE_OPEN                40002
        
#define IDM_FILE_SAVE                40003
        
#define IDM_FILE_SAVE_AS             40004
        
#define IDM_FILE_PRINT               40005
        
#define IDM_APP_EXIT                 40006
        
#define IDM_EDIT_UNDO                40007
        
#define IDM_EDIT_CUT                 40008
        
#define IDM_EDIT_COPY                40009
        
#define IDM_EDIT_PASTE              40010
        
#define IDM_EDIT_CLEAR               40011
        
#define IDM_EDIT_SELECT_ALL          40012
        
#define IDM_HELP_HELP               40013
        
#define IDM_APP_ABOUT                40014
        
| 
					 POPPAD2.ICO  | 
			

POPPAD2.RC资源描述文件包含菜单和快捷键。您将注意到,所有快捷键都表示在制表符(\t)后的「Edit」弹出式菜单的字符串中。
