*/
/*
* PROJECT: ReactOS user32.dll
- * FILE: dll/win32/user32/windows/dialog.c
- * PURPOSE: Input
+ * FILE: win32ss/user/user32/windows/dialog.c
+ * PURPOSE: Dialog Manager
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* Thomas Weidenmueller (w3seek@users.sourceforge.net)
* Steven Edwards (Steven_Ed4153@yahoo.com)
* 09-05-2001 CSH Created
*/
-/* INCLUDES ******************************************************************/
-
#include <user32.h>
-#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(user32);
/* MACROS/DEFINITIONS ********************************************************/
#define DF_END 0x0001
-#define DF_OWNERENABLED 0x0002
#define DF_DIALOGACTIVE 0x4000 // ReactOS
#define DWLP_ROS_DIALOGINFO (DWLP_USER+sizeof(ULONG_PTR))
#define GETDLGINFO(hwnd) DIALOG_get_info(hwnd, FALSE)
#define SETDLGINFO(hwnd, info) SetWindowLongPtrW((hwnd), DWLP_ROS_DIALOGINFO, (LONG_PTR)(info))
#define GET_WORD(ptr) (*(WORD *)(ptr))
#define GET_DWORD(ptr) (*(DWORD *)(ptr))
+#define GET_LONG(ptr) (*(const LONG *)(ptr))
#define DLG_ISANSI 2
/* INTERNAL STRUCTS **********************************************************/
{
WC_DIALOG, /* name */
CS_SAVEBITS | CS_DBLCLKS, /* style */
- (WNDPROC) DefDlgProcA, /* procA */
- (WNDPROC) DefDlgProcW, /* procW */
+ DefDlgProcA, /* procA */
+ DefDlgProcW, /* procW */
DLGWINDOWEXTRA, /* extra */
(LPCWSTR) IDC_ARROW, /* cursor */
0 /* brush */
return dlgInfo;
}
-/***********************************************************************
- * DIALOG_EnableOwner
- *
- * Helper function for modal dialogs to enable again the
- * owner of the dialog box.
- */
-void DIALOG_EnableOwner( HWND hOwner )
-{
- /* Owner must be a top-level window */
- if (hOwner)
- hOwner = GetAncestor( hOwner, GA_ROOT );
- if (!hOwner) return;
- EnableWindow( hOwner, TRUE );
-}
-
-
-/***********************************************************************
- * DIALOG_DisableOwner
- *
- * Helper function for modal dialogs to disable the
- * owner of the dialog box. Returns TRUE if owner was enabled.
- */
-BOOL DIALOG_DisableOwner( HWND hOwner )
-{
- /* Owner must be a top-level window */
- if (hOwner)
- hOwner = GetAncestor( hOwner, GA_ROOT );
- if (!hOwner) return FALSE;
- if (IsWindowEnabled( hOwner ))
- {
- EnableWindow( hOwner, FALSE );
- return TRUE;
- }
- else
- return FALSE;
-}
-
/***********************************************************************
* DIALOG_GetControl32
*
if (dialogEx)
{
- /* id is a DWORD for DIALOGEX */
- info->id = GET_DWORD(p);
+ /* id is 4 bytes for DIALOGEX */
+ info->id = GET_LONG(p);
p += 2;
}
else
if (GET_WORD(p))
{
- info->data = p + 1;
+ info->data = p;
p += GET_WORD(p) / sizeof(WORD);
}
else info->data = NULL;
DIALOGINFO * dlgInfo;
MSG msg;
INT retval;
- HWND ownerMsg = GetAncestor( owner, GA_ROOT );
BOOL bFirstEmpty;
PWND pWnd;
if (!(GetWindowLongPtrW( hwnd, GWL_STYLE ) & DS_NOIDLEMSG))
{
/* No message present -> send ENTERIDLE and wait */
- if (ownerMsg) SendMessageW( ownerMsg, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)hwnd );
+ SendMessageW( owner, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)hwnd );
}
GetMessageW( &msg, 0, 0, 0 );
}
/*
* If the user is pressing Ctrl+C, send a WM_COPY message.
- * Guido Pola, Bug 5281, Is there another way to check if the Dialog it's a MessageBox?
+ * Guido Pola, CORE-4829, Is there another way to check if the Dialog is a MessageBox?
*/
- if( msg.message == WM_KEYDOWN &&
+ if (msg.message == WM_KEYDOWN &&
pWnd->state & WNDS_MSGBOX && // Yes!
- GetForegroundWindow() == hwnd )
+ GetForegroundWindow() == hwnd)
{
- if( msg.wParam == L'C' && GetKeyState(VK_CONTROL) < 0 )
- SendMessageW( hwnd, WM_COPY, 0, 0);
+ if (msg.wParam == L'C' && GetKeyState(VK_CONTROL) < 0)
+ SendMessageW(hwnd, WM_COPY, 0, 0);
}
-
+
if (!IsWindow( hwnd )) return 0;
if (!(dlgInfo->flags & DF_END) && !IsDialogMessageW( hwnd, &msg))
{
}
}
}
- if (dlgInfo->flags & DF_OWNERENABLED) DIALOG_EnableOwner( owner );
retval = dlgInfo->idResult;
DestroyWindow( hwnd );
return retval;
else
DEFDLG_SetFocus( infoPtr->hwndFocus );
- /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
- sometimes losing focus when receiving WM_SETFOCUS messages. */
+ infoPtr->hwndFocus = NULL;
}
/***********************************************************************
*/
static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
HWND owner, DLGPROC dlgProc, LPARAM param,
- BOOL unicode, BOOL modal )
+ BOOL unicode, HWND *modal_owner )
{
HWND hwnd;
RECT rect;
DLG_TEMPLATE template;
DIALOGINFO * dlgInfo = NULL;
DWORD units = GetDialogBaseUnits();
- BOOL ownerEnabled = TRUE;
+ HWND disabled_owner = NULL;
HMENU hMenu = 0;
HFONT hUserFont = 0;
UINT flags = 0;
/* Create dialog main window */
- rect.left = rect.top = 0;
- rect.right = MulDiv(template.cx, xBaseUnit, 4);
- rect.bottom = MulDiv(template.cy, yBaseUnit, 8);
-
+ SetRect(&rect, 0, 0, MulDiv(template.cx, xBaseUnit, 4), MulDiv(template.cy, yBaseUnit, 8));
if (template.style & DS_CONTROL)
template.style &= ~(WS_CAPTION|WS_SYSMENU);
template.style |= DS_3DLOOK;
{
pos.x += MulDiv(template.x, xBaseUnit, 4);
pos.y += MulDiv(template.y, yBaseUnit, 8);
- if (!(template.style & (WS_CHILD|DS_ABSALIGN))) ClientToScreen( owner, &pos );
+ //
+ // REACTOS : Need an owner to be passed!!!
+ //
+ if (!(template.style & (WS_CHILD|DS_ABSALIGN)) && owner ) ClientToScreen( owner, &pos );
}
if ( !(template.style & WS_CHILD) )
{
}
}
- if (modal)
+ if (modal_owner && owner)
{
- ownerEnabled = DIALOG_DisableOwner( owner );
- if (ownerEnabled) flags |= DF_OWNERENABLED;
+ HWND parent = NULL;
+ /*
+ * Owner needs to be top level window. We need to duplicate the logic from server,
+ * because we need to disable it before creating dialog window. Note that we do that
+ * even if dialog has WS_CHILD, but only for modal dialogs, which matched what
+ * Windows does.
+ */
+ while ((GetWindowLongW( owner, GWL_STYLE ) & (WS_POPUP|WS_CHILD)) == WS_CHILD)
+ {
+ parent = GetParent( owner );
+ if (!parent || parent == GetDesktopWindow()) break;
+ owner = parent;
+ }
+ ////// Wine'ie babies need to fix your code!!!! CORE-11633
+ if (!parent) parent = GetAncestor( owner, GA_ROOT );
+
+ if (parent)
+ {
+ owner = parent;
+
+ if (IsWindowEnabled( owner ))
+ {
+ disabled_owner = owner;
+ EnableWindow( disabled_owner, FALSE );
+ }
+ }
+ *modal_owner = owner;
}
if (unicode)
{
if (hUserFont) DeleteObject( hUserFont );
if (hMenu) DestroyMenu( hMenu );
- if (modal && (flags & DF_OWNERENABLED)) DIALOG_EnableOwner(owner);
+ if (disabled_owner) EnableWindow( disabled_owner, TRUE );
return 0;
}
{
if (hUserFont) DeleteObject( hUserFont );
if (hMenu) DestroyMenu( hMenu );
- if (modal && (flags & DF_OWNERENABLED)) DIALOG_EnableOwner(owner);
+ if (disabled_owner) EnableWindow( disabled_owner, TRUE );
return 0;
}
//
/* By returning TRUE, app has requested a default focus assignment.
* WM_INITDIALOG may have changed the tab order, so find the first
* tabstop control again. */
- dlgInfo->hwndFocus = GetNextDlgTabItem( hwnd, 0, FALSE );
- if (!dlgInfo->hwndFocus) dlgInfo->hwndFocus = GetNextDlgGroupItem( hwnd, 0, FALSE );
- if( dlgInfo->hwndFocus )
- SetFocus( dlgInfo->hwndFocus );
+ focus = GetNextDlgTabItem( hwnd, 0, FALSE );
+ if (!focus) focus = GetNextDlgGroupItem( hwnd, 0, FALSE );
+ if (focus)
+ {
+ if (SendMessageW( focus, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
+ SendMessageW( focus, EM_SETSEL, 0, MAXLONG );
+ SetFocus( focus );
+ }
+ else
+ {
+ if (!(template.style & WS_CHILD))
+ SetFocus( hwnd );
+ }
}
-//// ReactOS
- DEFDLG_SaveFocus( hwnd );
+//// ReactOS see 43396, Fixes setting focus on Open and Close dialogs to the FileName edit control in OpenOffice.
+//// This now breaks test_SaveRestoreFocus.
+ //DEFDLG_SaveFocus( hwnd );
////
}
//// ReactOS Rev 30613 & 30644
if (template.style & WS_VISIBLE && !(GetWindowLongPtrW( hwnd, GWL_STYLE ) & WS_VISIBLE))
{
ShowWindow( hwnd, SW_SHOWNORMAL ); /* SW_SHOW doesn't always work */
+ UpdateWindow( hwnd );
IntNotifyWinEvent(EVENT_SYSTEM_DIALOGSTART, hwnd, OBJID_WINDOW, CHILDID_SELF, 0);
}
return hwnd;
}
- if (modal && ownerEnabled) DIALOG_EnableOwner(owner);
+ if (disabled_owner) EnableWindow( disabled_owner, TRUE );
IntNotifyWinEvent(EVENT_SYSTEM_DIALOGEND, hwnd, OBJID_WINDOW, CHILDID_SELF, 0);
if( IsWindow(hwnd) )
{
return TRUE;
}
+#ifdef __REACTOS__
+static void DEFDLG_Reposition(HWND hwnd)
+{
+ HMONITOR hMon;
+ MONITORINFO mi = { sizeof(mi) };
+ RECT rc;
+ LONG cx, cy;
+
+ if (GetWindowLongW(hwnd, GWL_STYLE) & WS_CHILD)
+ return;
+ if (IsIconic(hwnd))
+ return;
+
+ hMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
+
+ if (!GetMonitorInfoW(hMon, &mi) || !GetWindowRect(hwnd, &rc))
+ return;
+
+ cx = rc.right - rc.left;
+ cy = rc.bottom - rc.top;
+
+ if (rc.right > mi.rcWork.right)
+ {
+ rc.right = mi.rcWork.right;
+ rc.left = rc.right - cx;
+ }
+ if (rc.bottom > mi.rcWork.bottom - 4)
+ {
+ rc.bottom = mi.rcWork.bottom - 4;
+ rc.top = rc.bottom - cy;
+ }
+
+ if (rc.left < mi.rcWork.left)
+ {
+ rc.left = mi.rcWork.left;
+ }
+ if (rc.top < mi.rcWork.top)
+ {
+ rc.top = mi.rcWork.top;
+ }
+
+ SetWindowPos(hwnd, NULL, rc.left, rc.top, 0, 0,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE |
+ SWP_NOZORDER);
+}
+#endif
/***********************************************************************
* DEFDLG_Proc
*
}
return 0;
+#ifdef __REACTOS__
+ case DM_REPOSITION:
+ DEFDLG_Reposition(hwnd);
+ return 0;
+#endif
case WM_NEXTDLGCTL:
if (dlgInfo)
{
HWND hwnd;
LPWSTR orig_spec = spec;
WCHAR any[] = {'*','.','*',0};
+ WCHAR star[] = {'*',0};
#define SENDMSG(msg,wparam,lparam) \
((attrib & DDL_POSTMSGS) ? PostMessageW( hwnd, msg, wparam, lparam ) \
TRACE("%p %s %d %d %04x\n", hDlg, debugstr_w(spec), idLBox, idStatic, attrib );
/* If the path exists and is a directory, chdir to it */
- if (!spec || !spec[0] || SetCurrentDirectoryW( spec )) spec = any;
+ if (!spec || !spec[0] || SetCurrentDirectoryW( spec )) spec = star;
else
{
WCHAR *p, *p2;
+
+ if (!strchrW(spec, '*') && !strchrW(spec, '?'))
+ {
+ SetLastError(ERROR_NO_WILDCARD_CHARACTERS);
+ return FALSE;
+ }
p = spec;
if ((p2 = strchrW( p, ':' ))) p = p2 + 1;
if ((p2 = strrchrW( p, '\\' ))) p = p2;
* Also wine has one more parameter identifying weather it should call
* the function with unicode or not
*/
- return DIALOG_CreateIndirect( hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit , Flags == DLG_ISANSI ? FALSE : TRUE, FALSE );
+ return DIALOG_CreateIndirect( hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit , Flags == DLG_ISANSI ? FALSE : TRUE, NULL );
}
BOOL result = FALSE;
/* Perform DIALOGINFO initialization if not done */
- if(!(dlgInfo = DIALOG_get_info( hDlg, TRUE ))) return 0;
+ if(!(dlgInfo = DIALOG_get_info( hDlg, TRUE ))) return 0; //// REACTOS : Always TRUE! See RealGetWindowClass.
SetWindowLongPtrW( hDlg, DWLP_MSGRESULT, 0 );
case WM_SETFOCUS:
case DM_SETDEFID:
case DM_GETDEFID:
+#ifdef __REACTOS__
+ case DM_REPOSITION:
+#endif
case WM_NEXTDLGCTL:
case WM_GETFONT:
case WM_CLOSE:
BOOL result = FALSE;
/* Perform DIALOGINFO initialization if not done */
- if(!(dlgInfo = DIALOG_get_info( hDlg, TRUE ))) return 0;
+ if(!(dlgInfo = DIALOG_get_info( hDlg, TRUE ))) return 0; //// REACTOS : Always TRUE! See RealGetWindowClass.
SetWindowLongPtrW( hDlg, DWLP_MSGRESULT, 0 );
case WM_SETFOCUS:
case DM_SETDEFID:
case DM_GETDEFID:
+#ifdef __REACTOS__
+ case DM_REPOSITION:
+#endif
case WM_NEXTDLGCTL:
case WM_GETFONT:
case WM_CLOSE:
* Also wine has one more parameter identifying weather it should call
* the function with unicode or not
*/
- HWND hWnd = DIALOG_CreateIndirect( hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam, Flags == DLG_ISANSI ? FALSE : TRUE, TRUE );
+ HWND hWnd = DIALOG_CreateIndirect( hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam, Flags == DLG_ISANSI ? FALSE : TRUE, &hWndParent );
if (hWnd) return DIALOG_DoDialogBox( hWnd, hWndParent );
return -1;
}
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
return 0;
}
- hwnd = DIALOG_CreateIndirect(hInstance, ptr, hWndParent, lpDialogFunc, dwInitParam, FALSE, TRUE);
+ hwnd = DIALOG_CreateIndirect(hInstance, ptr, hWndParent, lpDialogFunc, dwInitParam, FALSE, &hWndParent );
if (hwnd) return DIALOG_DoDialogBox(hwnd, hWndParent);
return -1;
}
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
return 0;
}
- hwnd = DIALOG_CreateIndirect(hInstance, ptr, hWndParent, lpDialogFunc, dwInitParam, TRUE, TRUE);
+ hwnd = DIALOG_CreateIndirect(hInstance, ptr, hWndParent, lpDialogFunc, dwInitParam, TRUE, &hWndParent );
if (hwnd) return DIALOG_DoDialogBox(hwnd, hWndParent);
return -1;
}
/*
- * @implemented Modified for ReactOS.
+ * @implemented Modified for ReactOS. Do not Port Sync!!!
*/
BOOL
WINAPI
HWND hwnd,
INT_PTR retval)
{
- BOOL wasEnabled = TRUE;
DIALOGINFO * dlgInfo;
HWND owner;
BOOL wasActive;
wasActive = (hwnd == GetActiveWindow());
dlgInfo->idResult = retval;
dlgInfo->flags |= DF_END;
- wasEnabled = (dlgInfo->flags & DF_OWNERENABLED);
- owner = GetWindow( hwnd, GW_OWNER );
- if (wasEnabled && owner)
- DIALOG_EnableOwner( owner );
+ if ((GetWindowLongW( hwnd, GWL_STYLE ) & (WS_POPUP|WS_CHILD)) == WS_CHILD)
+ {
+ owner = GetAncestor( hwnd, GA_PARENT);
+ }
+ else
+ owner = GetWindow( hwnd, GW_OWNER );
+
+ if (owner)
+ EnableWindow( owner, TRUE );
/* Windows sets the focus to the dialog itself in EndDialog */
if (wasActive && owner)
{
- /* If this dialog was given an owner then set the focus to that owner
- even when the owner is disabled (normally when a window closes any
- disabled windows cannot receive the focus). */
+ /* If this dialog was given an owner then set the focus to that owner. */
SetActiveWindow(owner);
}
else if (hwnd == GetActiveWindow()) // Check it again!
*/
retvalue = hCtl;
hwnd = hCtl;
- while (hwndNext = GetWindow (hwnd, GW_HWNDNEXT),
- 1)
+ while (1)
{
+ hwndNext = GetWindow (hwnd, GW_HWNDNEXT);
while (!hwndNext)
{
/* Climb out until there is a next sibling of the ancestor or we
{
INT dlgCode = 0;
+ if (!IsWindow( hDlg ))
+ return FALSE;
+
if (CallMsgFilterW( lpMsg, MSGF_DIALOGBOX )) return TRUE;
if (hDlg == GetDesktopWindow()) return FALSE;
WCHAR *buffer = HeapAlloc (GetProcessHeap(), 0, maxlen * sizeof(WCHAR));
if (buffer)
{
- INT length;
+ SIZE_T length;
SendMessageW (hwndNext, WM_GETTEXT, maxlen, (LPARAM) buffer);
length = strlenW (buffer);
HeapFree (GetProcessHeap(), 0, buffer);
if (!(dlgCode & DLGC_WANTARROWS))
{
BOOL fPrevious = (lpMsg->wParam == VK_LEFT || lpMsg->wParam == VK_UP);
- HWND hwndNext = GetNextDlgGroupItem (hDlg, GetFocus(), fPrevious );
- SendMessageW( hDlg, WM_NEXTDLGCTL, (WPARAM)hwndNext, 1 );
+ HWND hwndNext = GetNextDlgGroupItem( hDlg, lpMsg->hwnd, fPrevious );
+ if (hwndNext && SendMessageW( hwndNext, WM_GETDLGCODE, lpMsg->wParam, (LPARAM)lpMsg ) == (DLGC_BUTTON | DLGC_RADIOBUTTON))
+ {
+ SetFocus( hwndNext );
+ if ((GetWindowLongW( hwndNext, GWL_STYLE ) & BS_TYPEMASK) == BS_AUTORADIOBUTTON &&
+ SendMessageW( hwndNext, BM_GETCHECK, 0, 0 ) != BST_CHECKED)
+ SendMessageW( hwndNext, BM_CLICK, 1, 0 );
+ }
+ else
+ SendMessageW( hDlg, WM_NEXTDLGCTL, (WPARAM)hwndNext, 1 );
return TRUE;
}
break;
case VK_RETURN:
{
DWORD dw;
- if ((GetFocus() == lpMsg->hwnd) &&
- (SendMessageW (lpMsg->hwnd, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON))
+ HWND hwndFocus = GetFocus();
+ if (IsChild( hDlg, hwndFocus ) &&
+ (SendMessageW (hwndFocus, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON))
{
- SendMessageW (hDlg, WM_COMMAND, MAKEWPARAM (GetDlgCtrlID(lpMsg->hwnd),BN_CLICKED), (LPARAM)lpMsg->hwnd);
+ SendMessageW( hDlg, WM_COMMAND, MAKEWPARAM( GetDlgCtrlID( hwndFocus ), BN_CLICKED ), (LPARAM)hwndFocus );
}
else if (DC_HASDEFID == HIWORD(dw = SendMessageW (hDlg, DM_GETDEFID, 0, 0)))
{
else
{
SendMessageW( hDlg, WM_COMMAND, IDOK, (LPARAM)GetDlgItem( hDlg, IDOK ) );
-
}
}
return TRUE;