This example is composed of three files:
This example is composed of three files:
//============================================================================= //RESOURCES: MENUS AND ACCELERATORS - Copyright © 2000,2005 Ken Fitlike //============================================================================= //API functions used: CreateDialog,DestroyWindow,DispatchMessage,GetLastError, //GetMessage,IsDialogMessage,IsWindow,LoadAccelerators,LoadImage, //MAKEINTRESOURCE,MessageBox,PostQuitMessage,PostMessage,SendMessage, //TranslateAccelerator,TranslateMessage,WinMain. //============================================================================= //This demonstrates the creation of menu and accelerator resources within a //modeless dialog box. //============================================================================= #include <windows.h> //include all the basics #include <tchar.h> //string and other mapping macros #include <string> #include <vector> #include "resources.h" //define an unicode string type alias typedef std::basic_string<TCHAR> ustring; //============================================================================= //message processing function declarations INT_PTR CALLBACK DlgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam); void OnCommand(const HWND,int,int,const HWND); INT_PTR OnInitDlg(const HWND,LPARAM); //non-message function declarations inline int ErrMsg(const ustring&); //============================================================================= int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int) { HWND hDlg=CreateDialog(hInst,MAKEINTRESOURCE(IDD_DIALOG1),0,DlgProc); if (!hDlg) { ErrMsg(_T("CreateDialog failed.")); return 0; } //Load keyboard accelerator so that it's available for use HACCEL hAccelTable=LoadAccelerators(hInst,MAKEINTRESOURCE(IDR_ACCELERATOR1)); //start message loop - windows applications are 'event driven' waiting on user, //application or system signals to determine what action, if any, to take. Note //that an error may cause GetMessage to return a negative value so, ideally, //this result should be tested for and appropriate action taken to deal with //it(the approach taken here is to simply quit the application). MSG msg; while (GetMessage(&msg,0,0,0)>0) { //first check if the message is from a resource defined keyboard accelerator key if (!TranslateAccelerator(hDlg,hAccelTable,&msg)) { //get default keyboard message handling for dialog box eg control tabbing if (!IsWindow(hDlg) || !IsDialogMessage(hDlg,&msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } } return static_cast<int>(msg.wParam); } //============================================================================= INT_PTR CALLBACK DlgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { switch (uMsg) { case WM_COMMAND: { OnCommand(hwnd,LOWORD(wParam),HIWORD(wParam), reinterpret_cast<HWND>(lParam)); return 0; } case WM_DESTROY: PostQuitMessage(0); //signal end of application return 0; case WM_INITDIALOG: { return OnInitDlg(hwnd,lParam); } default: return 0; //let system deal with msg } } //============================================================================= void OnCommand(const HWND hwnd,int id,int notifycode,const HWND hCntrl) { //handles WM_COMMAND message if (!hCntrl) { ustring txt; switch (id) { case IDCANCEL: txt=_T("exit"); break; case IDM_COPY: txt=_T("copy"); break; case IDM_PASTE: txt=_T("paste"); break; case IDM_CUT: txt=_T("cut"); break; case IDM_ABOUT: txt=_T("about"); break; case IDM_HELP: txt=_T("help"); break; case IDM_OPEN: txt=_T("open"); break; case IDM_SAVE: txt=_T("save"); break; } if (notifycode==0) { ustring title=_T("Menu Selected"); MessageBox(0,txt.c_str(),title.c_str(),MB_OK); } else if (notifycode==1) { ustring title=_T("Accelerator Selected"); MessageBox(0,txt.c_str(),title.c_str(),MB_OK); } } switch (id) { case IDOK: //RETURN key pressed or 'ok' button selected case IDCANCEL: //ESC key pressed or 'cancel' button selected DestroyWindow(hwnd); } } //============================================================================= INT_PTR OnInitDlg(const HWND hwnd,LPARAM lParam) { //set the small icon for the dialog. IDI_APPLICATION icon is set by default //for winxp SendMessage(hwnd,WM_SETICON,ICON_SMALL, reinterpret_cast<LPARAM>(LoadImage(0,IDI_APPLICATION,IMAGE_ICON, 0,0,LR_SHARED))); //ensure focus rectangle is properly draw around control with focus PostMessage(hwnd,WM_KEYDOWN,VK_TAB,0); return TRUE; } //============================================================================= inline int ErrMsg(const ustring& s) { return MessageBox(0,s.c_str(),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION); } //=============================================================================
//============================================================================= //Resource script constants for Resources: Menus and Accelerators example. //============================================================================= #define IDD_DIALOG1 200 #define IDR_MENU1 10000 #define IDM_OPEN 10001 #define IDM_SAVE 10002 #define IDM_COPY 10003 #define IDM_CUT 10004 #define IDM_PASTE 10005 #define IDM_UNDO 10006 #define IDM_HELP 10007 #define IDM_ABOUT 10008 #define IDR_ACCELERATOR1 20000
//============================================================================= //RESOURCES: MENUS AND ACCELERATORS - Copyright (c) 2000,2006 Ken Fitlike //resource script //============================================================================= #if !defined __BORLANDC__ #include <afxres.h> #endif #include "resources.h" //============================================================================= //Resource languages: Codes for languages and sub-languages are declared in //winnt.h eg. for US english replace SUBLANG_ENGLISH_UK with SUBLANG_ENGLISH_US //eg. for FRENCH replace LANG_ENGLISH with LANG_FRENCH and then replace //SUBLANG_ENGLISH_UK with either SUBLANG_FRENCH,SUBLANG_FRENCH_BELGIAN, //SUBLANG_FRENCH_CANADIAN,SUBLANG_FRENCH_SWISS,SUBLANG_FRENCH_LUXEMBOURG, //SUBLANG_FRENCH_MONACO depending on which national or regional variation of //the language corresponds best with your requirements. // LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK //============================================================================= //Dialog //============================================================================= IDD_DIALOG1 DIALOGEX 0, 0, 252, 149 STYLE DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME CAPTION "Resources: Menus and Accelerators" MENU IDR_MENU1 FONT 8, "MS Sans Serif" { DEFPUSHBUTTON "OK",IDOK,22,62,50,14 PUSHBUTTON "Cancel",IDCANCEL,111,63,50,14 } //============================================================================= //Menu //============================================================================= IDR_MENU1 MENU { POPUP "&File" { MENUITEM "&Open\tCtrl + O", IDM_OPEN MENUITEM "&Save\tCtrl + S", IDM_SAVE MENUITEM SEPARATOR MENUITEM "E&xit", IDCANCEL } POPUP "&Edit" { MENUITEM "Copy\tCtrl + C", IDM_COPY MENUITEM "Cut\tCtrl + X", IDM_CUT MENUITEM "Paste\tCtrl + V", IDM_PASTE MENUITEM "Undo\tCtrl + Z", IDM_UNDO, GRAYED } POPUP "Help" { MENUITEM "Help\tF1", IDM_HELP MENUITEM "About...\tShift + Alt + A", IDM_ABOUT } } //============================================================================= //Accelerators // //mingw does not recognise the 'control' statement with lowercase alphanumeric //keys but requires the caret (^) instead. If 'ASCII' is used instead of //VIRTKEY, msvc treats it as if VIRTKEY has been used. If uppercase letter is //used then mingw behaves properly with respect to the 'CONTROL' statement //============================================================================= IDR_ACCELERATOR1 ACCELERATORS { "C", IDM_COPY, VIRTKEY, CONTROL, NOINVERT "V", IDM_PASTE, VIRTKEY, CONTROL, NOINVERT "X", IDM_CUT, VIRTKEY, CONTROL, NOINVERT "Z", IDM_UNDO, VIRTKEY, CONTROL, NOINVERT "O", IDM_OPEN, VIRTKEY, CONTROL, NOINVERT "S", IDM_SAVE, VIRTKEY, CONTROL, NOINVERT VK_F1, IDM_HELP,VIRTKEY, NOINVERT "A", IDM_ABOUT, VIRTKEY, ALT, SHIFT, NOINVERT } //=============================================================================