Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
f58d80d1
Commit
f58d80d1
authored
Jun 15, 2000
by
David Lassonde
Committed by
Alexandre Julliard
Jun 15, 2000
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented the More Windows... menu item for MDI.
parent
a4b73d43
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
314 additions
and
10 deletions
+314
-10
mdi.h
include/mdi.h
+6
-0
sysres_En.rc
resources/sysres_En.rc
+15
-0
user32.rc
resources/user32.rc
+1
-0
mdi.c
windows/mdi.c
+292
-10
No files found.
include/mdi.h
View file @
f58d80d1
...
...
@@ -20,6 +20,12 @@
#define WM_MDICALCCHILDSCROLL 0x10AC
/* this is exactly what Windows uses */
/* "More Windows..." definitions */
#define MDI_MOREWINDOWSLIMIT 9
/* after this number of windows, a "More Windows..."
option will appear under the Windows menu */
#define MDI_IDC_LISTBOX 100
#define MDI_IDS_MOREWINDOWS 13
extern
LRESULT
WINAPI
MDIClientWndProc
(
HWND
hwnd
,
UINT
message
,
WPARAM
wParam
,
LPARAM
lParam
);
...
...
resources/sysres_En.rc
View file @
f58d80d1
...
...
@@ -46,3 +46,18 @@ BEGIN
PUSHBUTTON "&No", 7, 304, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
END
MDI_MOREWINDOWS DIALOG FIXED IMPURE 20, 20, 232, 122
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Select Window"
FONT 8, "MS Shell Dlg"
BEGIN
LISTBOX MDI_IDC_LISTBOX, 5, 7, 222, 90, WS_VSCROLL | WS_HSCROLL /* defined in mdi.h */
DEFPUSHBUTTON "OK", IDOK, 75, 100, 35, 14
PUSHBUTTON "Cancel", IDCANCEL, 120, 100, 35, 14
END
STRINGTABLE DISCARDABLE
{
MDI_IDS_MOREWINDOWS "&More Windows..." /* defined in mdi.h */
}
resources/user32.rc
View file @
f58d80d1
...
...
@@ -7,6 +7,7 @@
#include "winuser.h"
#include "winnls.h"
#include "dlgs.h"
#include "mdi.h"
/*
* Everything that does not depend on language,
...
...
windows/mdi.c
View file @
f58d80d1
...
...
@@ -6,11 +6,64 @@
* This file contains routines to support MDI (Multiple Document
* Interface) features .
*
* Notes: Fairly complete implementation. Any volunteers for
* "More windows..." stuff?
*
* Notes: Fairly complete implementation.
* Also, Excel and WinWord do _not_ use MDI so if you're trying
* to fix them look elsewhere.
*
* Notes on how the "More Windows..." is implemented:
*
* When we have more than 9 opened windows, a "More Windows..."
* option appears in the "Windows" menu. Each child window has
* a WND* associated with it, accesible via the children list of
* the parent window. This WND* has a wIDmenu member, which reflects
* the position of the child in the window list. For example, with
* 9 child windows, we could have the following pattern:
*
*
*
* Name of the child window pWndChild->wIDmenu
* Doc1 5000
* Doc2 5001
* Doc3 5002
* Doc4 5003
* Doc5 5004
* Doc6 5005
* Doc7 5006
* Doc8 5007
* Doc9 5008
*
*
* The "Windows" menu, as the "More windows..." dialog, are constructed
* in this order. If we add a child, we would have the following list:
*
*
* Name of the child window pWndChild->wIDmenu
* Doc1 5000
* Doc2 5001
* Doc3 5002
* Doc4 5003
* Doc5 5004
* Doc6 5005
* Doc7 5006
* Doc8 5007
* Doc9 5008
* Doc10 5009
*
* But only 5000 to 5008 would be displayed in the "Windows" menu. We want
* the last created child to be in the menu, so we swap the last child with
* the 9th... Doc9 will be accessible via the "More Windows..." option.
*
* Doc1 5000
* Doc2 5001
* Doc3 5002
* Doc4 5003
* Doc5 5004
* Doc6 5005
* Doc7 5006
* Doc8 5007
* Doc9 5009
* Doc10 5008
*
*/
#include <stdlib.h>
...
...
@@ -30,6 +83,7 @@
#include "struct32.h"
#include "tweak.h"
#include "debugtools.h"
#include "dlgs.h"
DEFAULT_DEBUG_CHANNEL
(
mdi
);
...
...
@@ -45,6 +99,8 @@ static BOOL MDI_RestoreFrameMenu(WND *, HWND);
static
LONG
MDI_ChildActivate
(
WND
*
,
HWND
);
static
HWND
MDI_MoreWindowsDialog
(
WND
*
);
static
void
MDI_SwapMenuItems
(
WND
*
,
UINT
,
UINT
);
/* -------- Miscellaneous service functions ----------
*
* MDI_GetChildByID
...
...
@@ -134,15 +190,28 @@ static BOOL MDI_MenuDeleteItem(WND* clientWnd, HWND hWndChild )
/* set correct id */
tmpWnd
->
wIDmenu
--
;
n
=
sprintf
(
buffer
,
"%d "
,
index
-
clientInfo
->
idFirstChild
);
n
=
sprintf
(
buffer
,
"
&
%d "
,
index
-
clientInfo
->
idFirstChild
);
if
(
tmpWnd
->
text
)
lstrcpynA
(
buffer
+
n
,
tmpWnd
->
text
,
sizeof
(
buffer
)
-
n
);
/* change menu */
/* change menu if the current child is to be shown in the
* "Windows" menu
*/
if
(
index
<=
clientInfo
->
idFirstChild
+
MDI_MOREWINDOWSLIMIT
)
ModifyMenuA
(
clientInfo
->
hWindowMenu
,
index
,
MF_BYCOMMAND
|
MF_STRING
,
index
-
1
,
buffer
);
WIN_ReleaseWndPtr
(
tmpWnd
);
}
/* We must restore the "More Windows..." option if there is enough child
*/
if
(
clientInfo
->
nActiveChildren
-
1
>
MDI_MOREWINDOWSLIMIT
)
{
char
szTmp
[
50
];
LoadStringA
(
GetModuleHandleA
(
"USER32"
),
MDI_IDS_MOREWINDOWS
,
szTmp
,
50
);
AppendMenuA
(
clientInfo
->
hWindowMenu
,
MF_STRING
,
clientInfo
->
idFirstChild
+
MDI_MOREWINDOWSLIMIT
,
szTmp
);
}
retvalue
=
TRUE
;
END:
WIN_ReleaseWndPtr
(
wndPtr
);
...
...
@@ -248,9 +317,17 @@ static LRESULT MDISetMenu( HWND hwnd, HMENU hmenuFrame,
if
(
ci
->
nActiveChildren
)
{
INT
j
=
i
-
ci
->
nActiveChildren
+
1
;
INT
j
;
LPWSTR
buffer
=
NULL
;
MENUITEMINFOW
mii
;
INT
nbWindowsMenuItems
;
/* num of documents shown + "More Windows..." if present */
if
(
ci
->
nActiveChildren
<=
MDI_MOREWINDOWSLIMIT
)
nbWindowsMenuItems
=
ci
->
nActiveChildren
;
else
nbWindowsMenuItems
=
MDI_MOREWINDOWSLIMIT
+
1
;
j
=
i
-
nbWindowsMenuItems
+
1
;
for
(
;
i
>=
j
;
i
--
)
{
...
...
@@ -355,6 +432,7 @@ static HWND MDICreateChild( WND *w, MDICLIENTINFO *ci, HWND parent,
SendMessageA
(
w
->
hwndSelf
,
WM_SETREDRAW
,
TRUE
,
0L
);
}
if
(
ci
->
nActiveChildren
<=
MDI_MOREWINDOWSLIMIT
)
/* this menu is needed to set a check mark in MDI_ChildActivate */
if
(
ci
->
hWindowMenu
!=
0
)
AppendMenuA
(
ci
->
hWindowMenu
,
MF_STRING
,
wIDmenu
,
lpstrDef
);
...
...
@@ -405,7 +483,29 @@ static HWND MDICreateChild( WND *w, MDICLIENTINFO *ci, HWND parent,
/* All MDI child windows have the WS_EX_MDICHILD style */
wnd
->
dwExStyle
|=
WS_EX_MDICHILD
;
/* If we have more than 9 windows, we must insert the new one at the
* 9th position in order to see it in the "Windows" menu
*/
if
(
ci
->
nActiveChildren
>
MDI_MOREWINDOWSLIMIT
)
MDI_SwapMenuItems
(
wnd
->
parent
,
wnd
->
wIDmenu
,
ci
->
idFirstChild
+
MDI_MOREWINDOWSLIMIT
-
1
);
MDI_MenuModifyItem
(
w
,
hwnd
);
/* Have we hit the "More Windows..." limit? If so, we must
* add a "More Windows..." option
*/
if
(
ci
->
nActiveChildren
==
MDI_MOREWINDOWSLIMIT
+
1
)
{
char
szTmp
[
50
];
LoadStringA
(
GetModuleHandleA
(
"USER32"
),
MDI_IDS_MOREWINDOWS
,
szTmp
,
50
);
ModifyMenuA
(
ci
->
hWindowMenu
,
ci
->
idFirstChild
+
MDI_MOREWINDOWSLIMIT
,
MF_BYCOMMAND
|
MF_STRING
,
ci
->
idFirstChild
+
MDI_MOREWINDOWSLIMIT
,
szTmp
);
}
if
(
wnd
->
dwStyle
&
WS_MINIMIZE
&&
ci
->
hwndActiveChild
)
ShowWindow
(
hwnd
,
SW_SHOWMINNOACTIVE
);
else
...
...
@@ -540,6 +640,8 @@ static LRESULT MDIDestroyChild( WND *w_parent, MDICLIENTINFO *ci,
if
(
childPtr
)
{
MDI_MenuDeleteItem
(
w_parent
,
child
);
if
(
child
==
ci
->
hwndActiveChild
)
{
MDI_SwitchActiveChild
(
parent
,
child
,
TRUE
);
...
...
@@ -557,7 +659,6 @@ static LRESULT MDIDestroyChild( WND *w_parent, MDICLIENTINFO *ci,
MDI_ChildActivate
(
w_parent
,
0
);
}
}
MDI_MenuDeleteItem
(
w_parent
,
child
);
WIN_ReleaseWndPtr
(
childPtr
);
...
...
@@ -621,8 +722,16 @@ static LONG MDI_ChildActivate( WND *clientPtr, HWND hWndChild )
(
LPARAM
)
hWndChild
);
/* uncheck menu item */
if
(
clientInfo
->
hWindowMenu
)
{
WORD
wPrevID
=
wndPrev
->
wIDmenu
-
clientInfo
->
idFirstChild
;
if
(
wPrevID
<
MDI_MOREWINDOWSLIMIT
)
CheckMenuItem
(
clientInfo
->
hWindowMenu
,
wndPrev
->
wIDmenu
,
0
);
else
CheckMenuItem
(
clientInfo
->
hWindowMenu
,
clientInfo
->
idFirstChild
+
MDI_MOREWINDOWSLIMIT
-
1
,
0
);
}
}
/* set appearance */
...
...
@@ -650,9 +759,16 @@ static LONG MDI_ChildActivate( WND *clientPtr, HWND hWndChild )
/* check menu item */
if
(
clientInfo
->
hWindowMenu
)
CheckMenuItem
(
clientInfo
->
hWindowMenu
,
wndPtr
->
wIDmenu
,
MF_CHECKED
);
{
/* The window to be activated must be displayed in the "Windows" menu */
if
(
wndPtr
->
wIDmenu
>=
clientInfo
->
idFirstChild
+
MDI_MOREWINDOWSLIMIT
)
{
MDI_SwapMenuItems
(
wndPtr
->
parent
,
wndPtr
->
wIDmenu
,
clientInfo
->
idFirstChild
+
MDI_MOREWINDOWSLIMIT
-
1
);
MDI_MenuModifyItem
(
wndPtr
->
parent
,
wndPtr
->
hwndSelf
);
}
CheckMenuItem
(
clientInfo
->
hWindowMenu
,
wndPtr
->
wIDmenu
,
MF_CHECKED
);
}
/* bring active child to the top */
SetWindowPos
(
hWndChild
,
0
,
0
,
0
,
0
,
0
,
SWP_NOSIZE
|
SWP_NOMOVE
|
SWP_NOACTIVATE
);
...
...
@@ -1349,9 +1465,16 @@ LRESULT WINAPI DefFrameProc16( HWND16 hwnd, HWND16 hwndMDIClient,
else
{
wndPtr
=
WIN_FindWndPtr
(
hwndMDIClient
);
ci
=
(
MDICLIENTINFO
*
)
wndPtr
->
wExtra
;
if
(
wParam
-
ci
->
idFirstChild
==
MDI_MOREWINDOWSLIMIT
)
/* User chose "More Windows..." */
childHwnd
=
MDI_MoreWindowsDialog
(
wndPtr
);
else
/* User chose one of the windows listed in the "Windows" menu */
childHwnd
=
MDI_GetChildByID
(
wndPtr
,
wParam
);
WIN_ReleaseWndPtr
(
wndPtr
);
WIN_ReleaseWndPtr
(
wndPtr
);
if
(
childHwnd
)
SendMessage16
(
hwndMDIClient
,
WM_MDIACTIVATE
,
(
WPARAM16
)
childHwnd
,
0L
);
...
...
@@ -2170,3 +2293,162 @@ TileWindows (HWND hwndParent, UINT wFlags, const LPRECT lpRect,
return
0
;
}
/************************************************************************
* "More Windows..." functionality
*/
/* MDI_MoreWindowsDlgProc
*
* This function will process the messages sent to the "More Windows..."
* dialog.
* Return values: 0 = cancel pressed
* HWND = ok pressed or double-click in the list...
*
*/
static
BOOL
WINAPI
MDI_MoreWindowsDlgProc
(
HWND
hDlg
,
UINT
iMsg
,
WPARAM
wParam
,
LPARAM
lParam
)
{
switch
(
iMsg
)
{
case
WM_INITDIALOG
:
{
WND
*
pWnd
;
UINT
widest
=
0
;
UINT
length
;
UINT
i
;
WND
*
pParentWnd
=
(
WND
*
)
lParam
;
MDICLIENTINFO
*
ci
=
(
MDICLIENTINFO
*
)
pParentWnd
->
wExtra
;
HWND
hListBox
=
GetDlgItem
(
hDlg
,
MDI_IDC_LISTBOX
);
/* Fill the list, sorted by id... */
for
(
i
=
0
;
i
<
ci
->
nActiveChildren
;
i
++
)
{
/* Find the window with the current ID */
for
(
pWnd
=
WIN_LockWndPtr
(
pParentWnd
->
child
);
pWnd
;
WIN_UpdateWndPtr
(
&
pWnd
,
pWnd
->
next
))
if
(
pWnd
->
wIDmenu
==
ci
->
idFirstChild
+
i
)
break
;
SendMessageA
(
hListBox
,
LB_ADDSTRING
,
0
,
(
LPARAM
)
pWnd
->
text
);
SendMessageA
(
hListBox
,
LB_SETITEMDATA
,
i
,
(
LPARAM
)
pWnd
);
length
=
strlen
(
pWnd
->
text
);
WIN_ReleaseWndPtr
(
pWnd
);
if
(
length
>
widest
)
widest
=
length
;
}
/* Make sure the horizontal scrollbar scrolls ok */
SendMessageA
(
hListBox
,
LB_SETHORIZONTALEXTENT
,
widest
*
6
,
0
);
/* Set the current selection */
SendMessageA
(
hListBox
,
LB_SETCURSEL
,
MDI_MOREWINDOWSLIMIT
,
0
);
return
TRUE
;
}
case
WM_COMMAND
:
switch
(
LOWORD
(
wParam
))
{
case
IDOK
:
{
/* windows are sorted by menu ID, so we must return the
* window associated to the given id
*/
HWND
hListBox
=
GetDlgItem
(
hDlg
,
MDI_IDC_LISTBOX
);
UINT
index
=
SendMessageA
(
hListBox
,
LB_GETCURSEL
,
0
,
0
);
WND
*
pWnd
=
(
WND
*
)
SendMessageA
(
hListBox
,
LB_GETITEMDATA
,
index
,
0
);
EndDialog
(
hDlg
,
pWnd
->
hwndSelf
);
return
TRUE
;
}
case
IDCANCEL
:
EndDialog
(
hDlg
,
0
);
return
TRUE
;
default:
switch
(
HIWORD
(
wParam
))
{
case
LBN_DBLCLK
:
{
/* windows are sorted by menu ID, so we must return the
* window associated to the given id
*/
HWND
hListBox
=
GetDlgItem
(
hDlg
,
MDI_IDC_LISTBOX
);
UINT
index
=
SendMessageA
(
hListBox
,
LB_GETCURSEL
,
0
,
0
);
WND
*
pWnd
=
(
WND
*
)
SendMessageA
(
hListBox
,
LB_GETITEMDATA
,
index
,
0
);
EndDialog
(
hDlg
,
pWnd
->
hwndSelf
);
return
TRUE
;
}
}
break
;
}
break
;
}
return
FALSE
;
}
/*
*
* MDI_MoreWindowsDialog
*
* Prompts the user with a listbox containing the opened
* documents. The user can then choose a windows and click
* on OK to set the current window to the one selected, or
* CANCEL to cancel. The function returns a handle to the
* selected window.
*/
static
HWND
MDI_MoreWindowsDialog
(
WND
*
wndPtr
)
{
LPCVOID
template
;
HRSRC
hRes
;
HANDLE
hDlgTmpl
;
hRes
=
FindResourceA
(
GetModuleHandleA
(
"USER32"
),
"MDI_MOREWINDOWS"
,
RT_DIALOGA
);
if
(
hRes
==
0
)
return
0
;
hDlgTmpl
=
LoadResource
(
GetModuleHandleA
(
"USER32"
),
hRes
);
if
(
hDlgTmpl
==
0
)
return
0
;
template
=
LockResource
(
hDlgTmpl
);
if
(
template
==
0
)
return
0
;
return
(
HWND
)
DialogBoxIndirectParamA
(
GetModuleHandleA
(
"USER32"
),
(
LPDLGTEMPLATEA
)
template
,
wndPtr
->
hwndSelf
,
(
DLGPROC
)
MDI_MoreWindowsDlgProc
,
(
LPARAM
)
wndPtr
);
}
/*
*
* MDI_SwapMenuItems
*
* Will swap the menu IDs for the given 2 positions.
* pos1 and pos2 are menu IDs
*
*
*/
static
void
MDI_SwapMenuItems
(
WND
*
parentWnd
,
UINT
pos1
,
UINT
pos2
)
{
WND
*
pWnd
;
for
(
pWnd
=
WIN_LockWndPtr
(
parentWnd
->
child
);
pWnd
;
WIN_UpdateWndPtr
(
&
pWnd
,
pWnd
->
next
))
{
if
(
pWnd
->
wIDmenu
==
pos1
)
pWnd
->
wIDmenu
=
pos2
;
else
if
(
pWnd
->
wIDmenu
==
pos2
)
pWnd
->
wIDmenu
=
pos1
;
}
WIN_ReleaseWndPtr
(
pWnd
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment