NBKEY3.C

From EDM2
Jump to: navigation, search
/*--------------------------------------------------------------------------------------*\
 * This procedure gets invoked from the dialog to forwards keystrokes (created within   *
 * the dialog itself, or passed on via the owner chain) to the notebook. The notebook   *
 * then has the chance to see if the keystroke matches with one of it accelerator keys. *
 * Usually this is done automatically via the owner chain, but the notebook control has *
 * some peculiar behaviour (design flaws) here.                                         *
 * This procedure is called when processing the WM_CHAR message in the "root" dialog's  *
 * window procedure.                                                                    *
 * Req:                                                                                 *
 *      pulRecursion .. We have to prevent recursive calling of the code via PM         *
 *                      messages to prevent looping                                     *
 *      hwndDialog .... Dialog where the notebook control is part of the client         *
 *      hwndNotebook .. Notebook control itself (part of the client)                    *
 *      pfnwpNotebook . Window procedure of notebook control                            *
 *      mp1 ........... Window procedure parameter 1                                    *
 *      mp2 ........... Window procedure parameter 2                                    *
 * Ret:                                                                                 *
 *      mresult........ Result of processing WM_CHAR                                    *
 * Ref:                                                                                 *
\*--------------------------------------------------------------------------------------*/
MRESULT DispatchKeyToNotebook(ULONG *pulRecursion, HWND hwndDialog, HWND hwndNotebook, PFNWP pfnwpNotebook,
    MPARAM  mp1, MPARAM mp2)
{

                                        /* We have to exclude VK_NEWLINE because this does not allow
                                           us to enter a newline into multi-line entryfields. On
                                           Laptop computers the CRLF key causes a VK_NEWLINE, and
                                           the ENTER key can only be accessed by SHIFT+CRLF (at least
                                           on my ThinkPad) */
if(SHORT2FROMMP(mp2)==VK_ENTER)
    {
#ifdef  DEBUG_DIALOG
    printf("Dialog: Dialog - Enter\n");
#endif  /* DEBUG_DIALOG */
    WinPostMsg(hwndDialog, WM_COMMAND,
        MPFROMSHORT(DID_OK), MPFROM2SHORT(CMDSRC_ACCELERATOR, FALSE));
    }
if(SHORT2FROMMP(mp2)==VK_ESC)
    {
#ifdef  DEBUG_DIALOG
    printf("Dialog: Dialog - ESC\n");
#endif  /* DEBUG_DIALOG */
    WinPostMsg(hwndDialog, WM_COMMAND,
        MPFROMSHORT(DID_CANCEL), MPFROM2SHORT(CMDSRC_ACCELERATOR, FALSE));
    }
                                        /* Prevent recursion and prevent message processing then */
if(*pulRecursion==TRUE)
    return((MRESULT)FALSE);
                                        /* Avoid recursion and process key */
*pulRecursion=TRUE;
if((SHORT1FROMMP(mp1) & KC_ALT) &&
    !(SHORT1FROMMP(mp1) & KC_VIRTUALKEY) &&
    !(SHORT1FROMMP(mp1) & KC_KEYUP))
    {
#ifdef  DEBUG_DIALOG
    printf("Dialog: Dialog - Got key (%02X)", (int)(char)(SHORT1FROMMP(mp2)));
    if(((char)SHORT1FROMMP(mp2)>=0x20) && ((char)SHORT1FROMMP(mp2)<0x7F))
        printf("(%c)", (char)(SHORT1FROMMP(mp2)));
    printf("\n");
#endif  /* DEBUG_DIALOG */
                                        /* Let's see if this is a shortcut key for our dialog the
                                           notebook is part of the client */
    if(!(BOOL)WinDefDlgProc(hwndDialog, WM_CHAR, mp1, mp2))
        {
                                        /* Notebook page on top */
        HWND    hwndNotebookPage;

#ifdef  DEBUG_DIALOG
        printf("Dialog: Dialog - we didn't handle it\n");
#endif  /* DEBUG_DIALOG */
        hwndNotebookPage=(HWND)WinSendMsg(hwndNotebook, BKM_QUERYPAGEWINDOWHWND,
                (MPARAM)WinSendMsg(hwndNotebook, BKM_QUERYPAGEID, NULL, MPFROM2SHORT(BKA_TOP, 0)),
                    NULL);
                                        /* Let's see if this is a shortcut key for the dialog that
                                           implements the current notebook page on top */
        if(!(BOOL)WinDefDlgProc(hwndNotebookPage, WM_CHAR, mp1, mp2))
            {
#ifdef  DEBUG_DIALOG
            printf("Dialog: Page - we didn't handle it\n");
#endif  /* DEBUG_DIALOG */
                                        /* Let's see if this is a notebook shortcut (with no ALT
                                           modifier) and activate the dialog page to give it the
                                           focus then */
            if((BOOL)(pfnwpNotebook)(hwndNotebook, WM_CHAR, MPFROM2SHORT(KC_CHAR, SHORT2FROMMP(mp1)), mp2))
                {
                SWP     swpPage;

#ifdef  DEBUG_DIALOG
                printf("Dialog: Notebook - we handled it\n");
#endif  /* DEBUG_DIALOG */
                memset(&swpPage, 0, sizeof(swpPage));
                swpPage.fl=SWP_ACTIVATE;
                swpPage.hwndInsertBehind=HWND_TOP;
                swpPage.hwnd=hwndNotebookPage;
                WinSetMultWindowPos(pHP->habPc2, &swpPage, 1);
                                        /* Now that a different notebook page is on top, get the new
                                           one to activate the control previously having the focus */
                hwndNotebookPage=(HWND)WinSendMsg(hwndNotebook, BKM_QUERYPAGEWINDOWHWND,
                        (MPARAM)WinSendMsg(hwndNotebook, BKM_QUERYPAGEID, NULL, MPFROM2SHORT(BKA_TOP, 0)),
                            NULL);
#ifdef  DEBUG_DIALOG
                printf("Dialog: Page - activating control %08X on page %08X\n",
                WinQueryWindowULong(hwndNotebookPage, QWL_HWNDFOCUSSAVE), hwndNotebookPage);
#endif  /* DEBUG_DIALOG */
                WinSetFocus(HWND_DESKTOP, WinQueryWindowULong(hwndNotebookPage, QWL_HWNDFOCUSSAVE));
                }
#ifdef  DEBUG_DIALOG
            else
                printf("Dialog: Notebook - we didn't handle it\n");
#endif  /* DEBUG_DIALOG */
            }
        }
    *pulRecursion=FALSE;
    return((MRESULT)TRUE);
    }
*pulRecursion=FALSE;
return((MRESULT)FALSE);
}