Make the MDI Window menu refreshing Windows compatible
Dmitry Timoshkov
dmitry at baikal.ru
Fri Jan 30 10:08:09 CST 2004
Hello,
Windows simply finds the last separator in the Window menu and
uses it as a border in the process of Window menu refreshing.
Changelog:
Dmitry Timoshkov <dmitry at codeweavers.com>
Make the MDI Window menu refreshing Windows compatible.
Simplify MDI child visibility check.
--- cvs/hq/wine/windows/mdi.c 2004-01-27 15:31:30.000000000 +0800
+++ wine/windows/mdi.c 2004-01-30 23:43:21.000000000 +0800
@@ -121,7 +121,6 @@ typedef struct
HWND *child; /* array of tracked children */
HMENU hFrameMenu;
HMENU hWindowMenu;
- UINT add_pos; /* original number of items in the window menu */
UINT idFirstChild;
LPWSTR frameTitle;
UINT nTotalCreated;
@@ -312,7 +311,6 @@ static LRESULT MDISetMenu( HWND hwnd, HM
ci->nActiveChildren = 0;
MDI_RefreshMenu(ci);
- ci->add_pos = GetMenuItemCount(hmenuWindow);
ci->hWindowMenu = hmenuWindow;
/* Add items to the new Window menu */
@@ -320,10 +318,7 @@ static LRESULT MDISetMenu( HWND hwnd, HM
MDI_RefreshMenu(ci);
}
else
- {
ci->hWindowMenu = hmenuWindow;
- ci->add_pos = GetMenuItemCount(hmenuWindow);
- }
}
if (hmenuFrame)
@@ -360,7 +355,7 @@ static LRESULT MDISetMenu( HWND hwnd, HM
*/
static LRESULT MDI_RefreshMenu(MDICLIENTINFO *ci)
{
- UINT i, count, visible;
+ UINT i, count, visible, separator_pos;
WCHAR buf[MDI_MAXTITLELENGTH];
TRACE("children %u, window menu %p\n", ci->nActiveChildren, ci->hWindowMenu);
@@ -374,9 +369,26 @@ static LRESULT MDI_RefreshMenu(MDICLIENT
return 0;
}
+ /* Windows finds the last separator in the menu, removes all existing
+ * menu items after it, and then adds visible MDI children.
+ */
+ separator_pos = 0;
count = GetMenuItemCount(ci->hWindowMenu);
- for (i = ci->add_pos; i < count; i++)
- RemoveMenu(ci->hWindowMenu, ci->add_pos, MF_BYPOSITION);
+ for (i = 0; i < count; i++)
+ {
+ MENUITEMINFOW mii;
+
+ memset(&mii, 0, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_TYPE;
+ GetMenuItemInfoW(ci->hWindowMenu, i, TRUE, &mii);
+
+ if (mii.fType & MFT_SEPARATOR)
+ separator_pos = i;
+ }
+
+ for (i = separator_pos + 1; i < count; i++)
+ RemoveMenu(ci->hWindowMenu, separator_pos + 1, MF_BYPOSITION);
visible = 0;
for (i = 0; i < ci->nActiveChildren; i++)
@@ -390,9 +402,9 @@ static LRESULT MDI_RefreshMenu(MDICLIENT
break;
}
- if (IsWindowVisible(ci->child[i]))
+ if (GetWindowLongW(ci->child[i], GWL_STYLE) & WS_VISIBLE)
{
- if (!visible)
+ if (!visible && !separator_pos)
/* Visio expects that separator has id 0 */
AppendMenuW(ci->hWindowMenu, MF_SEPARATOR, 0, NULL);
@@ -404,12 +416,14 @@ static LRESULT MDI_RefreshMenu(MDICLIENT
buf[1] = '0' + visible;
buf[2] = ' ';
InternalGetWindowText(ci->child[i], buf + 3, sizeof(buf)/sizeof(WCHAR) - 3);
- TRACE("Adding %u %s\n", id, debugstr_w(buf));
+ TRACE("Adding %p, id %u %s\n", ci->child[i], id, debugstr_w(buf));
AppendMenuW(ci->hWindowMenu, MF_STRING, id, buf);
if (ci->child[i] == ci->hwndActiveChild)
CheckMenuItem(ci->hWindowMenu, id, MF_CHECKED);
}
+ else
+ TRACE("MDI child %p is not visible, skipping\n", ci->child[i]);
}
return (LRESULT)ci->hFrameMenu;
@@ -557,21 +571,10 @@ static LONG MDI_ChildActivate( HWND clie
/* deactivate prev. active child */
if(prevActiveWnd)
{
- SetWindowLongA( prevActiveWnd, GWL_STYLE,
- GetWindowLongA( prevActiveWnd, GWL_STYLE ) | WS_SYSMENU );
- SendMessageA( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
- SendMessageA( prevActiveWnd, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child);
- /* uncheck menu item */
- if( clientInfo->hWindowMenu )
- {
- UINT prevID = GetWindowLongA( prevActiveWnd, GWL_ID );
-
- if (prevID - clientInfo->idFirstChild < MDI_MOREWINDOWSLIMIT)
- CheckMenuItem( clientInfo->hWindowMenu, prevID, 0);
- else
- CheckMenuItem( clientInfo->hWindowMenu,
- clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT - 1, 0);
- }
+ SetWindowLongW( prevActiveWnd, GWL_STYLE,
+ GetWindowLongW( prevActiveWnd, GWL_STYLE ) | WS_SYSMENU );
+ SendMessageW( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
+ SendMessageW( prevActiveWnd, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child);
}
/* set appearance */
@@ -599,8 +602,6 @@ static LONG MDI_ChildActivate( HWND clie
clientInfo->hwndActiveChild = child;
- MDI_RefreshMenu(clientInfo);
-
/* check if we have any children left */
if( !child )
{
@@ -609,6 +610,8 @@ static LONG MDI_ChildActivate( HWND clie
return 0;
}
+ MDI_RefreshMenu(clientInfo);
+
/* bring active child to the top */
SetWindowPos( child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
@@ -1064,7 +1067,6 @@ static LRESULT MDIClientWndProc_common(
ci->frameTitle = NULL;
ci->mdiFlags = 0;
ci->hFrameMenu = GetMenu(cs->hwndParent);
- ci->add_pos = GetMenuItemCount(ci->hWindowMenu);
if (!hBmpClose) hBmpClose = CreateMDIMenuBitmap();
More information about the wine-patches
mailing list