การสร้างผู้ใช้สามารถแก้ไข Accelerators

ตัวอย่างนี้แสดงวิธีการสร้างกล่องโต้ตอบที่อนุญาตให้ผู้ใช้สามารถเปลี่ยนแปลงลัดที่เกี่ยวข้องกับรายการเมนู กล่องโต้ตอบจะประกอบด้วยกล่องคำสั่งผสมที่ประกอบด้วยรายการเมนู กล่องคำสั่งผสมที่ประกอบด้วยชื่อของคีย์ และกล่องกาเครื่องหมายสำหรับการเลือกการ ctrl, alt และแป้น shift ภาพประกอบต่อไปนี้แสดงในกล่องโต้ตอบ.

ตัวอย่างต่อไปนี้แสดงวิธีกำหนดกล่องโต้ตอบในแฟ้มข้อกำหนดทรัพยากร.

EdAccelBox โต้ตอบ 5, 17, 193, 114 DS_MODALFRAME STYLE | WS_POPUP | WS_VISIBLE | WS_CAPTION CAPTION "แก้ไข Accelerators" เริ่ม COMBOBOX IDD_MENUITEMS, 10, 22, 52, 53, CBS_SIMPLE | CBS_SORT | WS_VSCROLL | 
                        WS_TABSTOP ควบคุม "ควบคุม" IDD_CNTRL "ปุ่ม" BS_AUTOCHECKBOX | WS_TABSTOP, 76, 35, 40, 10 ควบคุม "Alt", IDD_ALT "ปุ่ม" BS_AUTOCHECKBOX | WS_TABSTOP, 76, 48, 40, 10 ควบคุม "กะ" IDD_SHIFT "ปุ่ม" BS_AUTOCHECKBOX | WS_TABSTOP, 76, 61, 40, 10 COMBOBOX IDD_KEYSTROKES, 124, 22, 58, 58, CBS_SIMPLE | CBS_SORT | WS_VSCROLL | 
                        WS_TABSTOP PUSHBUTTON "ตกลง" IDOK, 43, 92, 40, 14 PUSHBUTTON "ยกเลิก" IDCANCEL, 103, 92, 40, 14 LTEXT "เลือกสินค้า: ", 101, 10, 12, 43, 8 LTEXT "เลือกแป้นพิมพ์: ", 102, 123, 12, 60 สิ้นสุดที่ 8 

 

แถบเมนูของโปรแกรมประยุกต์ที่ประกอบด้วยเมนูย่อยของอักขระที่มีสินค้าที่มีส่วนช่วยดำเนินการเกี่ยวข้องกับพวกเขา.

เมนู MainMenu {POPUP "แอมป์ตัวอักษร" { MENUITEM " & Regular\tF5 ", IDM_REGULAR MENUITEM " & Bold\tCtrl + B ", IDM_BOLD MENUITEM " & Italic\tCtrl + I ", IDM_ITALIC MENUITEM " & Underline\tCtrl + U ", IDM_ULINE }
} FontAccel ACCELERATORS { VK_F5, IDM_REGULAR, VIRTKEY "B", IDM_BOLD ควบคุม VIRTKEY "ฉัน" IDM_ITALIC ควบคุม VIRTKEY "U", IDM_ULINE ควบคุม VIRTKEY } 

 

เมนูรายการค่าสำหรับแม่แบบของเมนูมีค่าคงที่กำหนดดังในแอพลิเคชันของส่วนหัวของแฟ้ม.

#กำหนด IDM_REGULAR 1100
#กำหนด IDM_BOLD 1200
#กำหนด IDM_ITALIC 1300
#กำหนด IDM_ULINE 1400

กล่องโต้ตอบการใช้อาร์เรย์โครงโปรแกรมประยุกต์กำหนด VKEY สร้าง แต่ละที่ประกอบด้วยสายอักขระข้อความกดแป้นพิมพ์และเป็นสายอักขระข้อความเร่งความเร็ว เมื่อกล่องโต้ตอบสร้าง มันแยกวิเคราะห์อาร์เรย์ และเพิ่มแต่ละสายอักขระข้อความกดแป้นพิมพ์เพื่อเลือก แป้นพิมพ์กล่องคำสั่งผสม เมื่อผู้ใช้คลิกที่ปุ่มOKกล่องโต้ตอบการค้นหาสายอักขระข้อความกดแป้นพิมพ์ที่เลือก และดึงสายอักขระข้อความเร่งที่สอดคล้องกัน กล่องโต้ตอบการผนวกเร่งข้อความในข้อความของรายการเมนูที่ผู้ใช้เลือก ตัวอย่างต่อไปนี้แสดงโครงสร้าง VKEY อาร์เรย์:

/ / สนับสนุนการค้นหา VKey #กำหนด MAXKEYS 25 typedef struct _VKEYS { char * pKeyName 
    char * pKeyString 
} VKEYS 
 
VKEYS vkeys [MAXKEYS] = { "BkSp" "กลับ Space", "PgUp", "Page Up", "PgDn", "Page Down" "จบ" "จบ" "Home", "Home", "Lft", "Left", "Up", "Up", "Rgt", "Right", "Dn", "Down", "Ins", "Insert", "Del" "ลบ" "Mult" "คูณ" "Add", "Add", "Sub" "ลบ" "DecPt" "จุดทศนิยม" "Div" "หาร" "F2", "F2", "F3", "F3", "F5", "F5", "F6", "F6", "F7", "F7", "F8", "F8", "F9", "F9", "F11", "F11", "F12", "F12" } 

 

ขั้นตอนการเริ่มต้นของกล่องโต้ตอบการกรอกข้อมูลในกล่องคำสั่งผสมของสินค้าที่เลือกและเลือกแป้นพิมพ์ หลังจากที่ผู้ใช้เลือกรายการเมนูและการเร่งความเร็วสัมพันธ์ กล่องโต้ตอบการตรวจสอบควบคุมในกล่องโต้ตอบรับของผู้ใช้ที่เลือก ปรับปรุงข้อความของรายการเมนู แล้ว สร้างตารางใหม่เร่งที่ประกอบด้วยเร่งตัวใหม่ที่ผู้ใช้กำหนด ตัวอย่างต่อไปนี้แสดงขั้นตอนในกล่องโต้ตอบ หมายเหตุว่าคุณต้องการเตรียมใช้งาน hwndMain ในกระบวนงานของหน้าต่างของคุณ.

 // Global variables 
 
HWND hwndMain;      // handle to main window 
HACCEL haccel;      // handle to accelerator table 
 
// Dialog-box procedure 
 
BOOL CALLBACK EdAccelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    int nCurSel;            // index of list box item 
    UINT idItem;            // menu-item identifier 
    UINT uItemPos;          // menu-item position 
    UINT i, j = 0;          // loop counters 
    static UINT cItems;     // count of items in menu 
    char szTemp[32];        // temporary buffer 
    char szAccelText[32];   // buffer for accelerator text 
    char szKeyStroke[16];   // buffer for keystroke text 
    static char szItem[32]; // buffer for menu-item text 
    HWND hwndCtl;           // handle to control window 
    static HMENU hmenu;     // handle to "Character" menu 
    PCHAR pch, pch2;        // pointers for string copying 
    WORD wVKCode;           // accelerator virtual-key code 
    BYTE fAccelFlags;       // fVirt flags for ACCEL structure 
    LPACCEL lpaccelNew;     // address of new accelerator table 
    HACCEL haccelOld;       // handle to old accelerator table 
    int cAccelerators;      // number of accelerators in table 
    static BOOL fItemSelected = FALSE; // item selection flag 
    static BOOL fKeySelected = FALSE;  // key selection flag 
 
    switch (uMsg) 
    { 
        case WM_INITDIALOG: 
 
            // Get the handle to the menu-item combo box. 
 
            hwndCtl = GetDlgItem(hwndDlg, IDD_MENUITEMS); 
 
            // Get the handle to the Character submenu and
            // count the number of items it has. In this example, 
            // the menu has position 0. You must alter this value 
            // if you add additional menus. 
            hmenu = GetSubMenu(GetMenu(hwndMain), 0); 
            cItems = GetMenuItemCount(hmenu); 
 
            // Get the text of each item, strip out the '&' and 
            // the accelerator text, and add the text to the 
            // menu-item combo box. 
 
            for (i = 0; i < cItems; i++) 
            { 
                if (!(GetMenuString(hmenu, i, szTemp, 
                        sizeof(szTemp), MF_BYPOSITION))) 
                    continue; 
                for (pch = szTemp, pch2 = szItem; *pch != '\0'; ) 
                { 
                    if (*pch != '&') 
                    { 
                        if (*pch == '\t') 
                        { 
                            *pch = '\0'; 
                            *pch2 = '\0'; 
                        } 
                        else *pch2++ = *pch++; 
                    } 
                    else pch++; 
                } 
                SendMessage(hwndCtl, CB_ADDSTRING, 0, 
                    (LONG) (LPSTR) szItem); 
            } 
 
            // Now fill the keystroke combo box with the list of 
            // keystrokes that will be allowed for accelerators. 
            // The list of keystrokes is in the application-defined 
            // structure called "vkeys". 
 
            hwndCtl = GetDlgItem(hwndDlg, IDD_KEYSTROKES); 
            for (i = 0; i < MAXKEYS; i++) 
            {
                SendMessage(hwndCtl, CB_ADDSTRING, 0, 
                    (LONG) (LPSTR) vkeys[i].pKeyString); 
            }
 
            return TRUE; 
 
        case WM_COMMAND: 
            switch (LOWORD(wParam)) 
            { 
                case IDD_MENUITEMS: 
 
                    // The user must select an item from the combo 
                    // box. This flag is checked during IDOK
                    // processing to be sure a selection was made. 
 
                    fItemSelected = TRUE; 
                    return 0; 
 
                case IDD_KEYSTROKES: 
 
                    // The user must select an item from the combo
                    // box. This flag is checked during IDOK
                    // processing to be sure a selection was made. 
 
                    fKeySelected = TRUE; 
 
                    return 0; 
 
                case IDOK: 
 
                    // If the user has not selected a menu item 
                    // and a keystroke, display a reminder in a 
                    // message box. 
 
                    if (!fItemSelected || !fKeySelected) 
                    { 
                        MessageBox(hwndDlg, 
                            "Item or key not selected.", NULL, 
                            MB_OK); 
                        return 0; 
                    } 
 
                    // Determine whether the CTRL, ALT, and SHIFT 
                    // keys are selected. Concatenate the 
                    // appropriate strings to the accelerator- 
                    // text buffer, and set the appropriate 
                    // accelerator flags. 
 
                    szAccelText[0] = '\0'; 
                    hwndCtl = GetDlgItem(hwndDlg, IDD_CNTRL); 
                    if (SendMessage(hwndCtl, BM_GETCHECK, 0, 0) == 1) 
                    { 
                        lstrcat(szAccelText, "Ctl+"); 
                        fAccelFlags |= FCONTROL; 
                    } 
                    hwndCtl = GetDlgItem(hwndDlg, IDD_ALT); 
                    if (SendMessage(hwndCtl, BM_GETCHECK, 0, 0) == 1) 
                    { 
                        lstrcat(szAccelText, "Alt+"); 
                        fAccelFlags |= FALT; 
                    } 
                    hwndCtl = GetDlgItem(hwndDlg, IDD_SHIFT); 
                    if (SendMessage(hwndCtl, BM_GETCHECK, 0, 0) == 1) 
                    { 
                        lstrcat(szAccelText, "Shft+"); 
                        fAccelFlags |= FSHIFT; 
                    } 
 
                    // Get the selected keystroke, and look up the 
                    // accelerator text and the virtual-key code 
                    // for the keystroke in the vkeys structure. 
 
                    hwndCtl = GetDlgItem(hwndDlg, IDD_KEYSTROKES); 
                    nCurSel = (int) SendMessage(hwndCtl, 
                        CB_GETCURSEL, 0, 0); 
                    SendMessage(hwndCtl, CB_GETLBTEXT, 
                        nCurSel, (LONG) (LPSTR) szKeyStroke); 
                    for (i = 0; i < MAXKEYS; i++) 
                    { 
                        if(lstrcmp(vkeys[i].pKeyString, szKeyStroke) 
                            == 0) 
                        { 
                            lstrcpy(szKeyStroke, vkeys[i].pKeyName); 
                            break; 
                        } 
                    } 
 
                    // Concatenate the keystroke text to the 
                    // "Ctl+","Alt+", or "Shft+" string. 
 
                    lstrcat(szAccelText, szKeyStroke); 
 
                    // Determine the position in the menu of the 
                    // selected menu item. Menu items in the 
                    // "Character" menu have positions 0,2,3, and 4. 
 
                    if (lstrcmp(szItem, "Regular") == 0) 
                        uItemPos = 0; 
                    else if (lstrcmp(szItem, "Bold") == 0) 
                        uItemPos = 2; 
                    else if (lstrcmp(szItem, "Italic") == 0) 
                        uItemPos = 3; 
                    else if (lstrcmp(szItem, "Underline") == 0) 
                        uItemPos = 4; 
 
                    // Get the string that corresponds to the 
                    // selected item. 
 
                    GetMenuString(hmenu, uItemPos, szItem, 
                        sizeof(szItem), MF_BYPOSITION); 
 
                    // Append the new accelerator text to the 
                    // menu-item text. 
 
                    for (pch = szItem; *pch != '\t'; pch++); 
                        ++pch; 
 
                    for (pch2 = szAccelText; *pch2 != '\0'; pch2++) 
                        *pch++ = *pch2; 
                    *pch = '\0'; 
 
                    // Modify the menu item to reflect the new 
                    // accelerator text. 
 
                    idItem = GetMenuItemID(hmenu, uItemPos); 
                    ModifyMenu(hmenu, idItem, MF_BYCOMMAND | 
                        MF_STRING, idItem, szItem); 
 
                    // Reset the selection flags. 
 
                    fItemSelected = FALSE; 
                    fKeySelected = FALSE; 
 
                    // Save the current accelerator table. 
 
                    haccelOld = haccel; 
 
                    // Count the number of entries in the current 
                    // table, allocate a buffer for the table, and 
                    // then copy the table into the buffer. 
 
                    cAccelerators = CopyAcceleratorTable( 
                        haccelOld, NULL, 0); 
                    lpaccelNew = (LPACCEL) LocalAlloc(LPTR, 
                        cAccelerators * sizeof(ACCEL)); 
 
                    if (lpaccelNew != NULL) 
                    {
                        CopyAcceleratorTable(haccel, lpaccelNew, 
                            cAccelerators); 
                    }
 
                    // Find the accelerator that the user modified 
                    // and change its flags and virtual-key code 
                    // as appropriate. 
 
                    for (i = 0; (lpaccelNew[i].cmd == 
                                (WORD) idItem) 
                            && (i < (UINT) cAccelerators); i++) 
                    { 
                        lpaccelNew[i].fVirt = fAccelFlags; 
                        lpaccelNew[i].key = wVKCode; 
                    } 
 
                    // Create the new accelerator table, and 
                    // destroy the old one. 
 
                    DestroyAcceleratorTable(haccelOld); 
                    haccel = CreateAcceleratorTable(lpaccelNew, 
                        cAccelerators); 
 
                    // Destroy the dialog box. 
 
                    EndDialog(hwndDlg, TRUE); 
                    return 0; 
 
                case IDCANCEL: 
                    EndDialog(hwndDlg, TRUE); 
                    return TRUE; 
 
                default: 
                    break; 
            } 
        default: 
            break; 
    } 
    return FALSE; 
} 
 

Index