First TAB correction to IsDialogMessage

Bill Medland billmedland at mercuryspeed.com
Mon Jan 5 16:02:11 CST 2004


Bill Medland (billmedland at mercuryspeed.com)
First correction to IsDialogMessage.  Add the EM_SETSEL and the
focus change on handling VK_TAB.

Index: windows/dialog.c
===================================================================
RCS file: /home/wine/wine/windows/dialog.c,v
retrieving revision 1.125
diff -u -r1.125 dialog.c
--- windows/dialog.c	10 Dec 2003 04:14:35 -0000	1.125
+++ windows/dialog.c	5 Jan 2004 21:56:25 -0000
@@ -1020,11 +1020,19 @@
 BOOL WINAPI IsDialogMessageW( HWND hwndDlg, LPMSG msg )
 {
     INT dlgCode = 0;
+    BOOL fIsDialog;
 
     if (CallMsgFilterW( msg, MSGF_DIALOGBOX )) return TRUE;
 
     hwndDlg = WIN_GetFullHandle( hwndDlg );
     if ((hwndDlg != msg->hwnd) && !IsChild( hwndDlg, msg->hwnd )) return FALSE;
+    {
+        WND *pWnd;
+        pWnd = WIN_FindWndPtr(hwndDlg);
+        if (!pWnd) return FALSE;
+        fIsDialog = (pWnd->flags & WIN_ISDIALOG);
+        WIN_ReleaseWndPtr(pWnd);
+    }
 
     hwndDlg = DIALOG_FindMsgDestination(hwndDlg);
 
@@ -1039,7 +1047,55 @@
         case VK_TAB:
             if (!(dlgCode & DLGC_WANTTAB))
             {
-                SendMessageW( hwndDlg, WM_NEXTDLGCTL, (GetKeyState(VK_SHIFT) & 0x8000), 0 );
+                /* I am not sure under which circumstances the TAB is handled
+                 * each way.  All I do know is that it does not always simply
+                 * send WM_NEXTDLGCTL.  (Personally I have never yet seen it
+                 * do so but I presume someone has)
+                 */
+                if (fIsDialog)
+                    SendMessageW( hwndDlg, WM_NEXTDLGCTL, (GetKeyState(VK_SHIFT) & 0x8000), 0 );
+                else
+                {
+                    /* It would appear that GetNextDlgTabItem can handle being
+                     * passed hwndDlg rather than NULL but that is undocumented
+                     * so let's do it properly
+                     */
+                    HWND hwndFocus = GetFocus();
+                    HWND hwndNext = GetNextDlgTabItem (hwndDlg, hwndFocus == hwndDlg ? NULL : hwndFocus, GetKeyState (VK_SHIFT) & 0x8000 );
+                    if (hwndNext)
+                    {
+                        /* I guess this should be very similar to the DEFDLG code */
+                        dlgCode = SendMessageW( hwndNext, WM_GETDLGCODE, msg->wParam, (LPARAM)msg );
+                        if (dlgCode & DLGC_HASSETSEL)
+                        {
+                            /* Actually I have only seen Windows do this 2*(1+l)
+                             * under the ANSI version, but I guess we need to
+                             * watch out for Double-word characters too
+                             */
+                            INT maxlen = 2 * (1 + SendMessageW (hwndNext, WM_GETTEXTLENGTH, 0, 0));
+                            WCHAR *buffer = HeapAlloc(GetProcessHeap(), 0, maxlen);
+                            if (buffer)
+                            {
+                                INT length;
+                                (void) SendMessageW (hwndNext, WM_GETTEXT, maxlen, buffer);
+                                length = strlenW (buffer);
+                                /* I expect this is wrong.  I expect it is
+                                 * supposed to be the number of actual
+                                 * characters, including allowing for
+                                 * multiword characters
+                                 */
+                                HeapFree (GetProcessHeap(), 0, buffer);
+                                (void) SendMessageW (hwndNext, EM_SETSEL, 0, length);
+                            }
+                        }
+                        SetFocus (hwndNext);
+                        /* And then there is some stuff associated with it
+                         * being a button, which we will fix later.
+                         */
+                    }
+                    else
+                        return FALSE;
+                }
                 return TRUE;
             }
             break;
@@ -1082,6 +1138,9 @@
         break;
 
     case WM_CHAR:
+        /* FIXME Under what circumstances does WM_GETDLGCODE get sent?
+         * It does NOT get sent in the test program I have
+         */
         dlgCode = SendMessageW( msg->hwnd, WM_GETDLGCODE, msg->wParam, (LPARAM)msg );
         if (dlgCode & (DLGC_WANTCHARS|DLGC_WANTMESSAGE)) break;
         if (msg->wParam == '\t' && (dlgCode & DLGC_WANTTAB)) break;
@@ -1344,6 +1403,12 @@
 
 /***********************************************************************
  *		GetNextDlgGroupItem (USER32.@)
+ *
+ * Corrections to MSDN documentation
+ *
+ * (Under Windows 2000 at least, where hwndDlg is not actually a dialog)
+ * 1. hwndCtrl can be hwndDlg in which case it behaves as for NULL
+ * 2. Prev of NULL or hwndDlg fails
  */
 HWND WINAPI GetNextDlgGroupItem( HWND hwndDlg, HWND hwndCtrl, BOOL fPrevious )
 {
@@ -1352,6 +1417,7 @@
     hwndDlg = WIN_GetFullHandle( hwndDlg );
     hwndCtrl = WIN_GetFullHandle( hwndCtrl );
 
+    if (hwndDlg == hwndCtrl) hwndCtrl = NULL;
     if(hwndCtrl)
     {
         /* if the hwndCtrl is the child of the control in the hwndDlg,

-- 
Bill Medland
mailto:billmedland at mercuryspeed.com
http://webhome.idirect.com/~kbmed




More information about the wine-patches mailing list