Release 960428
Sun Apr 28 14:32:43 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [Makefile.in]
Subdir memory is now also compiled for Winelib, in order to get
the Win32 heap functions.
* [if1632/Makefile.in]
Renamed winprocs and winprocs32 to wprocs and wprocs32 to avoid
DLL names > 8 characters.
* [loader/builtin.c] (New file)
Grouped all built-in DLLs code in a single file.
* [memory/global.c]
Use the Win32 heap code instead of malloc() to allocate linear
memory. This will help test the heap code.
* [memory/local.c]
Fixed FreeSelector() to clear DS and ES correctly for huge blocks.
* [tools/build.c] [if1632/relay.c]
Removed 'id' directive in spec files. For relay debugging, the DLL
entry point is now computed from the CS:IP entry point address.
Added 'heap' directive to specifiy a local heap for the DLL. USER
and GDI heap are now created this way.
* [windows/class.c] [include/class.h]
Changed the class structure to use pointers instead of handles.
Changed Get/SetClassWord/Long to use a switch statement; this
allows changing the layout of the CLASS structure.
* [windows/win.c] [include/win.h]
Use a CLASS * instead of a handle for the window class.
Sat Apr 27 18:10:11 Martin von Loewis <loewis@informatik.hu-berlin.de>
* [if1632/kernel32.spec] [memory/global.c]
[win32/memory.c] [win32/process.c]
GetProcessAffinityMask,GlobalLock,IsBadReadPtr,IsBadWritePtr,
LocalLock,SetThreadAffinityMask: new relays.
* [win32/cursoricon32.c]
Return same handle if a cursor is loaded multiple times.
Sat Apr 27 15:13:37 1996 Bang Jun Young <bangjy@nownuri.nowcom.co.kr>
* [resources/sysres_Ko.rc]
Added support for Korean [Ko] language.
Fri Apr 26 00:49:05 1996 Huw D. M. Davies <h.davies1@physics.oxford.ac.uk>
* [objects/dc.c] [objects/font.c]
Fixed problem with SaveDC()/RestoreDC() and font cache 'used' count.
* [objects/metafile.c] [objects/dcvalues.c]
Fixed broken SetTextAlign() on metafiles.
* [objects/metafile.c]
Delete objects in handle table at end of PlayMetaFile().
Wed Apr 24 19:21:01 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [if1632/ver.spec] [misc/ver.c] [include/ver.h] (New files)
VER.DLL (partially) implemented (VerFindFile,VerInstallFile)
[If it doesn't work for you, use -dll -ver and report it to me]
* [if1632/user32.spec] [if1632/kernel32.spec] [if1632/shell.spec]
[if1632/shell32.spec] [misc/ole2nls.c] [windows/message.c]
[windows/graphics.c]
Simple win32 functions, where we can just use the win16 counterpart.
Misc. stubs.
* [misc/lstr.c]
Someone reported a _lstrlen(NULL). NULL is a valid argument. Fixed.
* [misc/registry.c]
Some alloclens were off by 1, one double fclose() fixed.
Requesting value 0 of a key with no values returns an error
(should we always return a made up value NULL? what does win3.1?)
Tue Apr 23 17:00:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>
* [misc/shell.c]
Implemented FindEnvironmentString(), DoEnvironmentSubst(),
ExtractIcon(), InternalExtractIcon() and ExtractAssociatedIcon().
* [misc/user.c]
Do extensive cleanup on application exit.
* [windows/hook.c] [windows/win.c] [windows/class.c]
Added miscellaneous cleanup routines.
* [controls/menu.c]
More efficient popup menu window handling.
Mon Apr 22 21:35:22 1996 Albrecht Kleine <kleine@ak.sax.de>
* [include/windows.h][objects/oembitmap.c][include/bitmaps/obm_trtype]
Added "TT-bitmap" for later usage in a ChooseFont() ownerdraw combobox.
diff --git a/controls/menu.c b/controls/menu.c
index 78e991d..eecb575 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -18,6 +18,7 @@
#include "windows.h"
#include "syscolor.h"
#include "sysmetrics.h"
+#include "task.h"
#include "win.h"
#include "menu.h"
#include "module.h"
@@ -65,6 +66,12 @@
static HBITMAP hStdCheck = 0;
static HBITMAP hStdMnArrow = 0;
+/* we _can_ use global popup window because there's no way 2 menues can
+ * be tracked at the same time.
+ */
+
+static WND* pTopPWnd = 0;
+static UINT uSubPWndLevel = 0;
/***********************************************************************
* MENU_Init
@@ -678,6 +685,23 @@
return lppop->Height;
}
+/***********************************************************************
+ * MENU_SwitchTPWndTo
+ */
+BOOL MENU_SwitchTPWndTo( HTASK hTask)
+{
+ /* This is supposed to be called when popup is hidden */
+
+ TDB* task = (TDB*)GlobalLock(hTask);
+
+ if( !task ) return 0;
+
+ /* if this task got as far as menu tracking it must have a queue */
+
+ pTopPWnd->hInstance = task->hInstance;
+ pTopPWnd->hmemTaskQ = task->hQueue;
+ return 1;
+}
/***********************************************************************
* MENU_ShowPopup
@@ -686,7 +710,9 @@
*/
static BOOL MENU_ShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, int x, int y)
{
- POPUPMENU *menu;
+ POPUPMENU *menu;
+ WND *wndPtr = NULL;
+ BOOL skip_init = 0;
if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ))) return FALSE;
if (menu->FocusedItem != NO_SELECTED_ITEM)
@@ -698,21 +724,47 @@
SendMessage( hwndOwner, WM_INITMENUPOPUP, (WPARAM)hmenu,
MAKELONG( id, (menu->wFlags & MF_SYSMENU) ? 1 : 0 ));
MENU_PopupMenuCalcSize( menu, hwndOwner );
- if (!menu->hWnd)
+
+ wndPtr = WIN_FindWndPtr( hwndOwner );
+ if (!wndPtr) return FALSE;
+
+ if (!pTopPWnd)
{
- WND *wndPtr = WIN_FindWndPtr( hwndOwner );
- if (!wndPtr) return FALSE;
- menu->hWnd = CreateWindow( POPUPMENU_CLASS_ATOM, (SEGPTR)0,
- WS_POPUP | WS_BORDER, x, y,
- menu->Width + 2*SYSMETRICS_CXBORDER,
- menu->Height + 2*SYSMETRICS_CYBORDER,
- 0, 0, wndPtr->hInstance, (SEGPTR)hmenu );
- if (!menu->hWnd) return FALSE;
+ pTopPWnd = WIN_FindWndPtr(CreateWindow( POPUPMENU_CLASS_ATOM, (SEGPTR)0,
+ WS_POPUP | WS_BORDER, x, y,
+ menu->Width + 2*SYSMETRICS_CXBORDER,
+ menu->Height + 2*SYSMETRICS_CYBORDER,
+ 0, 0, wndPtr->hInstance, (SEGPTR)hmenu ));
+ if (!pTopPWnd) return FALSE;
+ skip_init = TRUE;
}
- else SetWindowPos( menu->hWnd, 0, x, y,
- menu->Width + 2*SYSMETRICS_CXBORDER,
- menu->Height + 2*SYSMETRICS_CYBORDER,
- SWP_NOACTIVATE | SWP_NOZORDER );
+
+ if( uSubPWndLevel )
+ {
+ /* create new window for the submenu */
+ HWND hWnd = CreateWindow( POPUPMENU_CLASS_ATOM, (SEGPTR)0,
+ WS_POPUP | WS_BORDER, x, y,
+ menu->Width + 2*SYSMETRICS_CXBORDER,
+ menu->Height + 2*SYSMETRICS_CYBORDER,
+ menu->hWnd, 0, wndPtr->hInstance, (SEGPTR)hmenu );
+ if( !hWnd ) return FALSE;
+ menu->hWnd = hWnd;
+ }
+ else
+ {
+ if( !skip_init )
+ {
+ MENU_SwitchTPWndTo(GetCurrentTask());
+ SendMessage( pTopPWnd->hwndSelf, WM_USER, (WPARAM)hmenu, 0L);
+ }
+ menu->hWnd = pTopPWnd->hwndSelf;
+ }
+
+ uSubPWndLevel++;
+
+ SetWindowPos(menu->hWnd, 0, x, y, menu->Width + 2*SYSMETRICS_CXBORDER,
+ menu->Height + 2*SYSMETRICS_CYBORDER,
+ SWP_NOACTIVATE | SWP_NOZORDER );
/* Display the window */
@@ -1095,7 +1147,16 @@
}
submenu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hsubmenu );
MENU_HideSubPopups( hwndOwner, hsubmenu );
- if (submenu->hWnd) ShowWindow( submenu->hWnd, SW_HIDE );
+ if (submenu->hWnd == pTopPWnd->hwndSelf )
+ {
+ ShowWindow( submenu->hWnd, SW_HIDE );
+ uSubPWndLevel = 0;
+ }
+ else
+ {
+ DestroyWindow( submenu->hWnd );
+ submenu->hWnd = 0;
+ }
MENU_SelectItem( hwndOwner, hsubmenu, NO_SELECTED_ITEM );
}
@@ -1596,7 +1657,11 @@
USER_HEAP_FREE( hMsg );
ReleaseCapture();
MENU_HideSubPopups( hwnd, hmenu );
- if (menu->wFlags & MF_POPUP) ShowWindow( menu->hWnd, SW_HIDE );
+ if (menu->wFlags & MF_POPUP)
+ {
+ ShowWindow( menu->hWnd, SW_HIDE );
+ uSubPWndLevel = 0;
+ }
MENU_SelectItem( hwnd, hmenu, NO_SELECTED_ITEM );
SendMessage( hwnd, WM_MENUSELECT, 0, MAKELONG( 0xffff, 0 ) );
fEndMenuCalled = FALSE;
@@ -1743,6 +1808,25 @@
return 0;
}
+ case WM_DESTROY:
+ /* zero out global pointer in case system popup
+ * was destroyed by AppExit
+ */
+
+ if( hwnd == pTopPWnd->hwndSelf )
+ pTopPWnd = 0;
+ else
+ uSubPWndLevel--;
+ break;
+
+ case WM_USER:
+ if( wParam )
+#ifdef WINELIB32
+ SetWindowLong( hwnd, 0, (HMENU)wParam );
+#else
+ SetWindowWord( hwnd, 0, (HMENU)wParam );
+#endif
+ break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
@@ -2139,7 +2223,7 @@
lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
if (!lppop || (lppop->wMagic != MENU_MAGIC)) return FALSE;
lppop->wMagic = 0; /* Mark it as destroyed */
- if ((lppop->wFlags & MF_POPUP) && lppop->hWnd)
+ if ((lppop->wFlags & MF_POPUP) && lppop->hWnd && lppop->hWnd != pTopPWnd->hwndSelf )
DestroyWindow( lppop->hWnd );
if (lppop->hItems)