[CMAKE]
authorAmine Khaldi <amine.khaldi@reactos.org>
Sat, 26 Mar 2011 23:14:25 +0000 (23:14 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sat, 26 Mar 2011 23:14:25 +0000 (23:14 +0000)
- Sync with trunk r51165.

svn path=/branches/cmake-bringup/; revision=51166

249 files changed:
1  2 
base/applications/cacls/lang/da-DA.rc
base/applications/cacls/lang/es-ES.rc
base/applications/cacls/rsrc.rc
base/applications/games/winmine/lang/es-ES.rc
base/applications/games/winmine/lang/it-IT.rc
base/applications/network/ipconfig/ipconfig.rc
base/applications/network/ipconfig/lang/es-ES.rc
base/applications/network/ping/lang/it-IT.rc
base/applications/notepad/notepad.h
base/applications/paint/dialogs.h
base/applications/rapps/rapps/firefox2.txt
base/applications/rapps/rapps/firefox3.txt
base/applications/rapps/rapps/firefox36.txt
base/applications/rapps/rapps/openoffice2.4.txt
base/applications/rapps/rapps/seamonkey.txt
base/applications/rapps/rapps/sumatrapdf.txt
base/applications/rapps/rapps/thunderbird.txt
base/applications/rapps/rapps/winboard.txt
base/applications/rapps/winmain.c
base/applications/regedit/childwnd.c
base/applications/shutdown/lang/es-ES.rc
base/applications/shutdown/rsrc.rc
base/setup/reactos/lang/cs-CZ.rc
base/setup/reactos/lang/de-DE.rc
base/setup/reactos/lang/en-US.rc
base/setup/reactos/lang/fr-FR.rc
base/setup/reactos/lang/pl-PL.rc
base/setup/reactos/lang/sk-SK.rc
base/setup/reactos/resource.h
base/setup/usetup/partlist.c
base/shell/explorer/externals.h
base/shell/explorer/notifyhook/notifyhook.h
base/system/services/rpcserver.c
boot/freeldr/freeldr/arch/powerpc/compat.h
boot/freeldr/freeldr/arch/powerpc/prep.h
boot/freeldr/freeldr/include/arch/amd64/amd64.h
boot/freeldr/freeldr/include/arch/amd64/machpc.h
boot/freeldr/freeldr/include/machine.h
dll/cpl/desk/lang/bg-BG.rc
dll/cpl/desk/lang/cs-CZ.rc
dll/cpl/desk/lang/el-GR.rc
dll/cpl/desk/lang/fr-FR.rc
dll/cpl/desk/lang/hu-HU.rc
dll/cpl/desk/lang/id-ID.rc
dll/cpl/desk/lang/it-IT.rc
dll/cpl/desk/lang/nl-NL.rc
dll/cpl/desk/lang/no-NO.rc
dll/cpl/desk/lang/pl-PL.rc
dll/cpl/desk/lang/ro-RO.rc
dll/cpl/desk/lang/ru-RU.rc
dll/cpl/desk/lang/sk-SK.rc
dll/cpl/desk/lang/sv-SE.rc
dll/cpl/desk/lang/uk-UA.rc
dll/cpl/desk/lang/zh-CN.rc
dll/cpl/input/settings.c
dll/ntdll/CMakeLists.txt
dll/ntdll/include/ntdllp.h
dll/ntdll/ldr/ldrapi.c
dll/ntdll/ldr/ldrinit.c
dll/ntdll/ldr/ldrpe.c
dll/ntdll/ldr/ldrutils.c
dll/ntdll/ldr/startup.c
dll/ntdll/ldr/utils.c
dll/win32/devmgr/hwpage.c
dll/win32/gdi32/misc/misc.c
dll/win32/gdi32/objects/text.c
dll/win32/kernel32/misc/ldr.c
dll/win32/msi/CMakeLists.txt
dll/win32/msi/action.c
dll/win32/msi/appsearch.c
dll/win32/msi/assembly.c
dll/win32/msi/classes.c
dll/win32/msi/cond.tab.c
dll/win32/msi/cond.y
dll/win32/msi/create.c
dll/win32/msi/custom.c
dll/win32/msi/database.c
dll/win32/msi/dialog.c
dll/win32/msi/events.c
dll/win32/msi/files.c
dll/win32/msi/font.c
dll/win32/msi/format.c
dll/win32/msi/helpers.c
dll/win32/msi/insert.c
dll/win32/msi/install.c
dll/win32/msi/media.c
dll/win32/msi/msi.c
dll/win32/msi/msi.rc
dll/win32/msi/msi.spec
dll/win32/msi/msi_main.c
dll/win32/msi/msipriv.h
dll/win32/msi/msiquery.c
dll/win32/msi/msiserver.idl
dll/win32/msi/package.c
dll/win32/msi/record.c
dll/win32/msi/registry.c
dll/win32/msi/script.c
dll/win32/msi/source.c
dll/win32/msi/sql.tab.c
dll/win32/msi/sql.y
dll/win32/msi/string.c
dll/win32/msi/table.c
dll/win32/msi/where.c
dll/win32/shell32/clipboard.c
dll/win32/shell32/dialogs.c
dll/win32/shell32/lang/bg-BG.rc
dll/win32/shell32/lang/ca-ES.rc
dll/win32/shell32/lang/cs-CZ.rc
dll/win32/shell32/lang/da-DK.rc
dll/win32/shell32/lang/de-DE.rc
dll/win32/shell32/lang/el-GR.rc
dll/win32/shell32/lang/en-GB.rc
dll/win32/shell32/lang/en-US.rc
dll/win32/shell32/lang/es-ES.rc
dll/win32/shell32/lang/fi-FI.rc
dll/win32/shell32/lang/fr-FR.rc
dll/win32/shell32/lang/hu-HU.rc
dll/win32/shell32/lang/it-IT.rc
dll/win32/shell32/lang/ja-JP.rc
dll/win32/shell32/lang/ko-KR.rc
dll/win32/shell32/lang/nl-NL.rc
dll/win32/shell32/lang/no-NO.rc
dll/win32/shell32/lang/pl-PL.rc
dll/win32/shell32/lang/pt-BR.rc
dll/win32/shell32/lang/pt-PT.rc
dll/win32/shell32/lang/ro-RO.rc
dll/win32/shell32/lang/ru-RU.rc
dll/win32/shell32/lang/sk-SK.rc
dll/win32/shell32/lang/sl-SI.rc
dll/win32/shell32/lang/sv-SE.rc
dll/win32/shell32/lang/tr-TR.rc
dll/win32/shell32/lang/uk-UA.rc
dll/win32/shell32/lang/zh-CN.rc
dll/win32/shell32/lang/zh-TW.rc
dll/win32/shell32/she_ocmenu.c
dll/win32/shell32/shell32.spec
dll/win32/shell32/shresdef.h
dll/win32/shell32/undocshell.h
dll/win32/user32/controls/combo.c
dll/win32/user32/controls/edit.c
dll/win32/user32/controls/icontitle.c
dll/win32/user32/controls/regcontrol.c
dll/win32/user32/controls/scrollbar.c
dll/win32/user32/controls/static.c
dll/win32/user32/misc/desktop.c
dll/win32/user32/misc/display.c
dll/win32/user32/misc/winsta.c
dll/win32/user32/windows/menu.c
dll/win32/user32/windows/nonclient.c
dll/win32/user32/windows/window.c
drivers/base/kddll/kddll.h
drivers/filesystems/ext2/inc/protos.h
drivers/filesystems/fastfat_new/fastfat.h
drivers/network/lan/include/lan.h
drivers/network/ndis/include/miniport.h
drivers/network/ndis/ndis/config.c
drivers/network/tcpip/include/icmp.h
drivers/network/tcpip/include/interface.h
drivers/network/tcpip/include/lan.h
drivers/network/tcpip/include/lock.h
drivers/storage/classpnp/debug.h
drivers/storage/ide/uniata/inc/PostDbgMesg.h
drivers/usb/nt4compat/usbdriver/usb.h
drivers/usb/usbehci/physmem.h
drivers/video/displays/vga/vgavideo/vgavideo.h
drivers/video/miniport/vga/vgamp.h
drivers/video/videoprt/videoprt.c
drivers/wdm/audio/legacy/wdmaud/control.c
drivers/wdm/audio/legacy/wdmaud/wdmaud.h
include/crt/eh.h
include/crt/rtcapi.h
include/crt/xlocinfo.h
include/ddk/ntstrsafe.h
include/ndk/haltypes.h
include/psdk/commctrl.h
include/psdk/ntgdi.h
include/psdk/shlwapi_undoc.h
include/psdk/strsafe.h
include/psdk/uxtheme.h
include/psdk/ws2tcpip.h
include/reactos/drivers/directx/dxeng.h
include/reactos/libs/audiosrv/audiosrv.h
include/reactos/libs/ppcmmu/mmuutil.h
include/reactos/libs/sound/mmebuddy.h
include/reactos/libs/sound/time.h
include/reactos/win32k/ntuser.h
lib/drivers/oskittcp/include/oskittcp.h
lib/fslib/vfatlib/check/io.h
lib/ppcmmu/mmuobject.h
lib/rtl/actctx.c
lib/rtl/heap.c
lib/rtl/image.c
lib/sdk/crt/printf/streamout.c
lib/sdk/crt/stdio/file.c
ntoskrnl/ex/exintrin.c
ntoskrnl/ex/init.c
ntoskrnl/ex/win32k.c
ntoskrnl/fstub/translate.c
ntoskrnl/inbv/logo/1.bmp
ntoskrnl/include/internal/amd64/ke.h
ntoskrnl/include/internal/kd.h
ntoskrnl/include/ntoskrnl.h
ntoskrnl/kdbg/kdb.h
ntoskrnl/kdbg/kdb_cli.c
ntoskrnl/ke/freeldr.c
ntoskrnl/ke/i386/cpu.c
ntoskrnl/mm/ARM3/sysldr.c
ntoskrnl/ob/obhandle.c
ntoskrnl/ps/win32.c
subsystems/win32/csrss/win32csr/desktopbg.c
subsystems/win32/win32k/eng/device.c
subsystems/win32/win32k/eng/ldevobj.c
subsystems/win32/win32k/include/callback.h
subsystems/win32/win32k/include/cursoricon.h
subsystems/win32/win32k/include/dc.h
subsystems/win32/win32k/include/desktop.h
subsystems/win32/win32k/include/device.h
subsystems/win32/win32k/include/gdidebug.h
subsystems/win32/win32k/include/gdiobj.h
subsystems/win32/win32k/include/input.h
subsystems/win32/win32k/include/intgdi.h
subsystems/win32/win32k/include/ldevobj.h
subsystems/win32/win32k/include/monitor.h
subsystems/win32/win32k/include/msgqueue.h
subsystems/win32/win32k/include/palette.h
subsystems/win32/win32k/include/pdevobj.h
subsystems/win32/win32k/include/region.h
subsystems/win32/win32k/include/win32.h
subsystems/win32/win32k/include/winpos.h
subsystems/win32/win32k/include/winsta.h
subsystems/win32/win32k/main/dllmain.c
subsystems/win32/win32k/misc/registry.c
subsystems/win32/win32k/ntuser/class.c
subsystems/win32/win32k/ntuser/desktop.c
subsystems/win32/win32k/ntuser/display.c
subsystems/win32/win32k/ntuser/ntstubs.c
subsystems/win32/win32k/ntuser/object.c
subsystems/win32/win32k/ntuser/simplecall.c
subsystems/win32/win32k/ntuser/window.c
subsystems/win32/win32k/ntuser/winpos.c
subsystems/win32/win32k/ntuser/winsta.c
subsystems/win32/win32k/objects/cliprgn.c
subsystems/win32/win32k/objects/dcobjs.c
subsystems/win32/win32k/objects/fillshap.c
subsystems/win32/win32k/objects/freetype.c
subsystems/win32/win32k/objects/rect.c
subsystems/win32/win32k/objects/region.c
subsystems/win32/win32k/objects/stockobj.c
subsystems/win32/win32k/pch.h

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index aab01f1,0000000..dff520c
mode 100644,000000..100644
--- /dev/null
@@@ -1,60 -1,0 +1,63 @@@
 +
 +spec2def(ntdll.dll def/ntdll.spec)
 +
 +add_definitions(
 +    -D__NTDLL__
 +    -D_NTOSKRNL_
 +    -DCRTDLL)
 +
 +include_directories(
 +    BEFORE include
 +    ${REACTOS_SOURCE_DIR}/include/reactos/subsys)
 +
 +list(APPEND SOURCE
 +    csr/api.c
 +    csr/capture.c
 +    csr/connect.c
 +    dbg/dbgui.c
 +      ldr/actctx.c
++      ldr/ldrapi.c
 +      ldr/ldrinit.c
++      ldr/ldrpe.c
++      ldr/ldrutils.c
 +    ldr/startup.c
 +    ldr/utils.c
 +    rtl/libsupp.c
 +    rtl/version.c
 +    def/ntdll.rc
 +    ${CMAKE_CURRENT_BINARY_DIR}/ntdll.def)
 +    
 +if(ARCH MATCHES i386)
 +list(APPEND SOURCE dispatch/i386/dispatch.S)
 +elseif(ARCH MATCHES amd64)
 +list(APPEND SOURCE dispatch/amd64/stubs.c)
 +elseif(ARCH MATCHES arm)
 +list(APPEND SOURCE dispatch/arm/stubs_asm.s)
 +else()
 +list(APPEND SOURCE dispatch/dispatch.c)
 +endif(ARCH MATCHES i386)
 +
 +add_library(ntdll SHARED
 +    ${CMAKE_CURRENT_BINARY_DIR}/ntdll_ntdll.h.gch
 +    ${SOURCE})
 +
 +set_entrypoint(ntdll 0)
 +
 +if(MSVC)
 +target_link_libraries(ntdll rtl)
 +else()
 +target_link_libraries(ntdll -Wl,--whole-archive rtl -Wl,--no-whole-archive)
 +endif()
 +
 +target_link_libraries(ntdll
 +                      ntdllsys
 +                      libcntpr
 +                      ${PSEH_LIB})
 +
 +set_image_base(ntdll ${baseaddress_ntdll})
 +add_pch(ntdll ${CMAKE_CURRENT_SOURCE_DIR}/include/ntdll.h ${SOURCE})
 +add_dependencies(ntdll ntstatus asm)
 +
 +add_minicd_target(ntdll reactos/system32 ntdll.dll)
 +add_cab_target(ntdll 1)
 +add_importlib_target(def/ntdll.spec)
Simple merge
index 0000000,0a19351..0a19351
mode 000000,100644..100644
--- /dev/null
Simple merge
index 0000000,730d260..730d260
mode 000000,100644..100644
--- /dev/null
index 0000000,8c27837..8c27837
mode 000000,100644..100644
--- /dev/null
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 3057f0e,0000000..94cad13
mode 100644,000000..100644
--- /dev/null
@@@ -1,97 -1,0 +1,98 @@@
 +
 +include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
 +add_definitions(-D__WINESRC__ -DMSIRUNMODE=MSIRUNMODE_T)
 +
 +remove_definitions(-D_WIN32_WINNT=0x502)
 +add_definitions(-D_WIN32_WINNT=0x600)
 +
 +spec2def(msi.dll msi.spec)
 +
 +generate_idl_iids(msiserver.idl)
 +
 +list(APPEND SOURCE
 +    action.c
 +    alter.c
 +    appsearch.c
++      assembly.c
 +    automation.c
 +    classes.c
 +    cond.tab.c
 +    create.c
 +    custom.c
 +    database.c
 +    delete.c
 +    dialog.c
 +    distinct.c
 +    drop.c
 +    events.c
 +    files.c
 +    font.c
 +    format.c
 +    handle.c
 +    helpers.c
 +    insert.c
 +    install.c
 +    join.c
 +    media.c
 +    msi.c
 +    msi_main.c
 +    msiquery.c
 +    package.c
 +    preview.c
 +    record.c
 +    registry.c
 +    regsvr.c
 +    script.c
 +    select.c
 +    source.c
 +    sql.tab.c
 +    storages.c
 +    streams.c
 +    string.c
 +    suminfo.c
 +    table.c
 +    tokenize.c
 +    update.c
 +    upgrade.c
 +    where.c
 +    msi.rc
 +    ${CMAKE_CURRENT_BINARY_DIR}/msiserver_i.c
 +    ${CMAKE_CURRENT_BINARY_DIR}/msi_stubs.c
 +    ${CMAKE_CURRENT_BINARY_DIR}/msi.def)
 +
 +if(MSVC)
 +    set_source_files_properties(custom.c PROPERTIES COMPILE_FLAGS /FImsvchelper.h)
 +endif()
 +
 +add_library(msi SHARED ${SOURCE})
 +
 +add_idl_Headers(msi_idlheader msiserver.idl)
 +
 +add_typelib(msi_tlb msiserver.idl)
 +
 +set_module_type(msi win32dll)
 +
 +target_link_libraries(msi uuid ${PSEH_LIB} wine)
 +
 +add_dependencies(msi msi_idlheader msi_tlb)
 +
 +add_importlibs(msi
 +    advapi32
 +    cabinet
 +    comctl32
 +    gdi32
 +    odbccp32
 +    ole32
 +    oleaut32
 +    shell32
 +    shlwapi
 +    urlmon
 +    user32
 +    version
 +    wininet
 +    msvcrt
 +    kernel32
 +    ntdll)
 +
 +add_cab_target(msi 1)
 +add_importlib_target(msi.spec)
Simple merge
Simple merge
index 0000000,5199a31..5199a31
mode 000000,100644..100644
--- /dev/null
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index c9d0956,0000000..923139f
mode 100644,000000..100644
--- /dev/null
@@@ -1,505 -1,0 +1,505 @@@
- 61  stdcall -noname RunFileDlg(long long long str str long) RunFileDlg # Fixme
 +# Functions exported by the WinXP SP3 shell32.dll (6.0.2900.5686)
 +2   stdcall SHChangeNotifyRegister(long long long long long ptr)
 +3   stdcall SHDefExtractIconA(str long long ptr ptr long)
 +4   stdcall SHChangeNotifyDeregister(long)
 +5   stdcall -noname SHChangeNotifyUpdateEntryList(long long long long)
 +6   stdcall SHDefExtractIconW(wstr long long ptr ptr long)
 +7   stdcall -noname SHLookupIconIndexA(str long long)
 +8   stdcall -noname SHLookupIconIndexW(wstr long long)
 +9   stdcall PifMgr_OpenProperties(wstr wstr long long)
 +10  stdcall PifMgr_GetProperties(ptr wstr ptr long long)
 +11  stdcall PifMgr_SetProperties(ptr wstr ptr long long)
 +12  stdcall -noname SHStartNetConnectionDialogA(ptr str long)
 +13  stdcall PifMgr_CloseProperties(ptr long)
 +14  stdcall SHStartNetConnectionDialogW(ptr wstr long)
 +15  stdcall -noname ILGetDisplayName(ptr ptr)
 +16  stdcall ILFindLastID(ptr)
 +17  stdcall ILRemoveLastID(ptr)
 +18  stdcall ILClone(ptr)
 +19  stdcall ILCloneFirst(ptr)
 +20  stdcall -noname ILGlobalClone(ptr)
 +21  stdcall ILIsEqual(ptr ptr)
 +22  stdcall DAD_DragEnterEx2(ptr long long ptr)
 +23  stdcall ILIsParent(ptr ptr long)
 +24  stdcall ILFindChild(ptr ptr)
 +25  stdcall ILCombine(ptr ptr)
 +26  stdcall ILLoadFromStream(ptr ptr)
 +27  stdcall ILSaveToStream(ptr ptr)
 +28  stdcall SHILCreateFromPath(ptr ptr ptr) SHILCreateFromPathAW
 +29  stdcall -noname PathIsRoot(ptr) PathIsRootAW
 +30  stdcall -noname PathBuildRoot(ptr long) PathBuildRootAW
 +31  stdcall -noname PathFindExtension(wstr) PathFindExtensionW
 +32  stdcall -noname PathAddBackslash(wstr) PathAddBackslashW
 +33  stdcall -noname PathRemoveBlanks(wstr) PathRemoveBlanksW
 +34  stdcall -noname PathFindFileName(wstr) PathFindFileNameW
 +35  stdcall -noname PathRemoveFileSpec(ptr) PathRemoveFileSpecAW # Fixme
 +36  stdcall -noname PathAppend(ptr ptr) PathAppendAW # Fixme
 +37  stdcall -noname PathCombine(wstr wstr wstr) PathCombineW
 +38  stdcall -noname PathStripPath(wstr) PathStripPathW
 +39  stdcall -noname PathIsUNC(wstr) PathIsUNCW
 +40  stdcall -noname PathIsRelative(wstr) PathIsRelativeW
 +41  stdcall IsLFNDriveA(str)
 +42  stdcall IsLFNDriveW(wstr)
 +43  stdcall PathIsExe(ptr) PathIsExeAW
 +44  stdcall OpenAs_RunDLL(long long str long) OpenAs_RunDLLA
 +45  stdcall -noname PathFileExists(ptr) PathFileExistsAW # Fixme
 +46  stdcall -noname PathMatchSpec(wstr wstr) PathMatchSpecW
 +47  stdcall PathMakeUniqueName(ptr long ptr ptr ptr) PathMakeUniqueNameAW
 +48  stdcall -noname PathSetDlgItemPath(long long wstr) PathSetDlgItemPathW
 +49  stdcall PathQualify(ptr) PathQualifyAW
 +50  stdcall -noname PathStripToRoot(wstr) PathStripToRootW
 +51  stdcall PathResolve(str long long) PathResolveAW
 +52  stdcall -noname PathGetArgs(wstr) PathGetArgsW
 +53  stdcall -noname IsSuspendAllowed()
 +54  stdcall -noname LogoffWindowsDialog(ptr)
 +55  stdcall -noname PathQuoteSpaces(wstr) PathQuoteSpacesW
 +56  stdcall -noname PathUnquoteSpaces(wstr) PathUnquoteSpacesW
 +57  stdcall -noname PathGetDriveNumber(wstr) PathGetDriveNumberW
 +58  stdcall -noname ParseField(str long ptr long) ParseFieldAW # Fixme
 +59  stdcall RestartDialog(long wstr long)
 +60  stdcall -noname ExitWindowsDialog(long) # Fixme
- 63  stdcall GetFileNameFromBrowse(long long long long str str str)
++61  stdcall -noname RunFileDlg(long long long wstr wstr long) RunFileDlg # Fixme?
 +62  stdcall PickIconDlg(long long long long)
++63  stdcall GetFileNameFromBrowse(long long long long wstr wstr wstr)
 +64  stdcall DriveType(long)
 +65  stdcall -noname InvalidateDriveType(long)
 +66  stdcall IsNetDrive(long)
 +67  stdcall Shell_MergeMenus(long long long long long long)
 +68  stdcall SHGetSetSettings(ptr long long)
 +69  stdcall -noname SHGetNetResource(ptr long ptr long)
 +70  stdcall -noname SHCreateDefClassObject(long long long long long)
 +71  stdcall -noname Shell_GetImageLists(ptr ptr)
 +72  stdcall Shell_GetCachedImageIndex(ptr ptr long) Shell_GetCachedImageIndexAW
 +73  stdcall SHShellFolderView_Message(long long long)
 +74  stdcall SHCreateStdEnumFmtEtc(long ptr ptr)
 +75  stdcall PathYetAnotherMakeUniqueName(ptr wstr wstr wstr)
 +76  stdcall DragQueryInfo(ptr ptr)
 +77  stdcall SHMapPIDLToSystemImageListIndex(ptr ptr ptr)
 +78  stdcall -noname OleStrToStrN(str long wstr long) OleStrToStrNAW # Fixme
 +79  stdcall -noname StrToOleStrN(wstr long str long) StrToOleStrNAW # Fixme
 +80  stdcall SHOpenPropSheetW(wstr ptr long ptr ptr ptr wstr)
 +81  stdcall OpenAs_RunDLLA(long long str long)
 +82  stdcall -noname DDECreatePostNotify(ptr)
 +83  stdcall -noname CIDLData_CreateFromIDArray(ptr long ptr ptr)
 +84  stdcall SHIsBadInterfacePtr(ptr long) # Fixme
 +85  stdcall OpenRegStream(long str str long) shlwapi.SHOpenRegStreamA
 +86  stdcall -noname SHRegisterDragDrop(long ptr)
 +87  stdcall -noname SHRevokeDragDrop(long)
 +88  stdcall SHDoDragDrop(long ptr ptr long ptr)
 +89  stdcall SHCloneSpecialIDList(long long long)
 +90  stdcall SHFindFiles(ptr ptr)
 +91  stdcall SHFindComputer(ptr ptr)
 +92  stdcall PathGetShortPath(ptr) PathGetShortPathAW
 +93  stdcall -noname Win32CreateDirectory(wstr ptr) Win32CreateDirectoryW
 +94  stdcall -noname Win32RemoveDirectory(wstr) Win32RemoveDirectoryW
 +95  stdcall -noname SHLogILFromFSIL(ptr)
 +96  stdcall -noname StrRetToStrN(ptr long ptr ptr) StrRetToStrNAW # Fixme
 +97  stdcall -noname SHWaitForFileToOpen(long long long)
 +98  stdcall SHGetRealIDL(ptr ptr ptr)
 +99  stdcall -noname SetAppStartingCursor(long long) # Fixme
 +100 stdcall SHRestricted(long)
 +101 stdcall OpenAs_RunDLLW(long long wstr long)
 +102 stdcall SHCoCreateInstance(wstr ptr long ptr ptr)
 +103 stdcall SignalFileOpen(long)
 +104 stdcall Activate_RunDLL(long ptr ptr ptr)
 +105 stdcall AppCompat_RunDLLW(ptr ptr wstr long)
 +106 stdcall CheckEscapesA(str long)
 +107 stdcall CheckEscapesW(wstr long)
 +108 stdcall CommandLineToArgvW(wstr ptr)
 +109 stdcall Control_FillCache_RunDLL(long long long long) Control_FillCache_RunDLLA
 +110 stdcall Control_FillCache_RunDLLA(long long long long)
 +111 stdcall Control_FillCache_RunDLLW(long long long long)
 +112 stdcall Control_RunDLL(ptr ptr str long) Control_RunDLLA
 +113 stdcall Control_RunDLLA(ptr ptr str long)
 +114 stdcall Control_RunDLLAsUserW(ptr ptr wstr long)
 +115 stdcall Control_RunDLLW(ptr ptr wstr long)
 +@ stdcall -private DllCanUnloadNow()
 +@ stdcall -private DllGetClassObject(ptr ptr ptr)
 +118 stdcall DllGetVersion(ptr)
 +119 stdcall IsLFNDrive(ptr) IsLFNDriveAW
 +@ stdcall -private DllInstall(long wstr)
 +121 stdcall SHFlushClipboard()
 +122 stdcall -noname RunDLL_CallEntry16(long long long str long) # Fixme #name wrong?
 +123 stdcall -noname SHFreeUnusedLibraries()
 +@ stdcall -private DllRegisterServer()
 +@ stdcall -private DllUnregisterServer()
 +126 stdcall -noname SHOutOfMemoryMessageBox(long long long) # Fixme
 +127 stdcall -noname SHWinHelp(long long long long)
 +128 stdcall -noname SHDllGetClassObject(ptr ptr ptr) DllGetClassObject
 +129 stdcall DAD_AutoScroll(long ptr ptr)
 +130 stdcall -noname DAD_DragEnter(long)
 +131 stdcall DAD_DragEnterEx(long double)
 +132 stdcall DAD_DragLeave()
 +133 stdcall DoEnvironmentSubstA(str str)
 +134 stdcall DAD_DragMove(double)
 +135 stdcall DoEnvironmentSubstW(wstr wstr)
 +136 stdcall DAD_SetDragImage(long long)
 +137 stdcall DAD_ShowDragImage(long)
 +138 stdcall DragAcceptFiles(long long)
 +139 stdcall DragFinish(long)
 +140 stdcall DragQueryFile(long long ptr long) DragQueryFileA
 +141 stdcall DragQueryFileA(long long ptr long)
 +142 stdcall DragQueryFileAorW(ptr long wstr long long long)
 +143 stdcall DragQueryFileW(long long ptr long)
 +144 stdcall DragQueryPoint(long ptr)
 +145 stdcall -noname PathFindOnPath(wstr wstr) PathFindOnPathW
 +146 stdcall -noname RLBuildListOfPaths()
 +147 stdcall SHCLSIDFromString(long long) SHCLSIDFromStringAW
 +148 stdcall SHMapIDListToImageListIndexAsync(ptr ptr ptr long ptr ptr ptr ptr ptr)
 +149 stdcall SHFind_InitMenuPopup(long long long long)
 +150 stdcall DuplicateIcon(long long)
 +151 stdcall SHLoadOLE(long)
 +152 stdcall ILGetSize(ptr)
 +153 stdcall ILGetNext(ptr)
 +154 stdcall ILAppendID(long long long) ILAppend
 +155 stdcall ILFree(ptr)
 +156 stdcall -noname ILGlobalFree(ptr)
 +157 stdcall ILCreateFromPath(ptr) ILCreateFromPathAW
 +158 stdcall -noname PathGetExtension(wstr long long) SHPathGetExtensionW
 +159 stdcall -noname PathIsDirectory(wstr) PathIsDirectoryW
 +160 stdcall SHNetConnectionDialog(ptr wstr long) # Fixme
 +161 stdcall SHRunControlPanel(long long)
 +162 stdcall SHSimpleIDListFromPath(ptr) SHSimpleIDListFromPathAW # Fixme
 +163 stdcall -noname StrToOleStr(wstr str) StrToOleStrAW # Fixme
 +164 stdcall Win32DeleteFile(wstr) Win32DeleteFileW
 +165 stdcall SHCreateDirectory(long ptr)
 +166 stdcall CallCPLEntry16(long long long long long long)
 +167 stdcall SHAddFromPropSheetExtArray(long long long)
 +168 stdcall SHCreatePropSheetExtArray(long wstr long)
 +169 stdcall SHDestroyPropSheetExtArray(long)
 +170 stdcall SHReplaceFromPropSheetExtArray(long long long long)
 +171 stdcall PathCleanupSpec(ptr ptr)
 +172 stdcall -noname SHCreateLinks(long str ptr long ptr)
 +173 stdcall SHValidateUNC(long long long)
 +174 stdcall SHCreateShellFolderViewEx(ptr ptr)
 +175 stdcall -noname SHGetSpecialFolderPath(long long long long) SHGetSpecialFolderPathW
 +176 stdcall SHSetInstanceExplorer(long)
 +177 stdcall DAD_SetDragImageFromListView(ptr long long)
 +178 stdcall SHObjectProperties(long long wstr wstr)
 +179 stdcall SHGetNewLinkInfoA(str str ptr long long)
 +180 stdcall SHGetNewLinkInfoW(wstr wstr ptr long long)
 +181 stdcall -noname RegisterShellHook(long long)
 +182 varargs ShellMessageBoxA(long long str str long)
 +183 varargs ShellMessageBoxW(long long wstr wstr long)
 +184 stdcall -noname ArrangeWindows(long long long long long)
 +185 stdcall -noname SHHandleDiskFull(ptr long) # Fixme
 +186 stdcall -noname ILGetDisplayNameEx(ptr ptr ptr long)
 +187 stdcall -noname ILGetPseudoNameW(ptr ptr wstr long)
 +188 stdcall -noname ShellDDEInit(long)
 +189 stdcall ILCreateFromPathA(str)
 +190 stdcall ILCreateFromPathW(wstr)
 +191 stdcall SHUpdateImageA(str long long long)
 +192 stdcall SHUpdateImageW(wstr long long long)
 +193 stdcall SHHandleUpdateImage(ptr)
 +194 stdcall -noname SHCreatePropSheetExtArrayEx(long wstr long ptr)
 +195 stdcall SHFree(ptr)
 +196 stdcall SHAlloc(long)
 +197 stdcall -noname SHGlobalDefect(long)
 +198 stdcall -noname SHAbortInvokeCommand()
 +199 stdcall ExtractAssociatedIconA(long str ptr)
 +200 stdcall -noname SHCreateDesktop(ptr)
 +201 stdcall -noname SHDesktopMessageLoop(ptr)
 +202 stub -noname DDEHandleViewFolderNotify
 +203 stdcall -noname AddCommasW(long wstr)
 +204 stdcall -noname ShortSizeFormatW(double)
 +205 stdcall Printer_LoadIconsW(wstr ptr ptr)
 +206 stdcall ExtractAssociatedIconExA(long str long long)
 +207 stdcall ExtractAssociatedIconExW(long wstr long long)
 +208 stdcall ExtractAssociatedIconW(long wstr ptr)
 +209 stdcall -noname Int64ToString(double wstr long long ptr long) # Fixme
 +210 stdcall -noname LargeIntegerToString(ptr wstr long long ptr long) # Fixme
 +211 stdcall -noname Printers_GetPidl(ptr str) # Fixme
 +212 stdcall -noname Printers_AddPrinterPropPages(ptr ptr)
 +213 stdcall -noname Printers_RegisterWindowW(wstr long ptr ptr)
 +214 stdcall -noname Printers_UnregisterWindow(long long)
 +215 stdcall -noname SHStartNetConnectionDialog(long str long)
 +216 stdcall ExtractIconA(long str long)
 +217 stdcall ExtractIconEx(ptr long ptr ptr long) ExtractIconExA
 +218 stdcall ExtractIconExA(str long ptr ptr long)
 +219 stdcall ExtractIconExW(wstr long ptr ptr long)
 +220 stdcall ExtractIconResInfoA(ptr str long ptr ptr)
 +221 stdcall ExtractIconResInfoW(ptr wstr long ptr ptr)
 +222 stdcall ExtractIconW(long wstr long)
 +223 stdcall ExtractVersionResource16W(wstr ptr)
 +224 stdcall FindExeDlgProc(ptr long ptr ptr)
 +225 stdcall FindExecutableA(str str ptr)
 +226 stdcall FindExecutableW(wstr wstr ptr)
 +227 stdcall FreeIconList(long)
 +228 stdcall InternalExtractIconListA(ptr str ptr)
 +229 stdcall InternalExtractIconListW(ptr wstr ptr)
 +230 stdcall -noname FirstUserLogon(wstr wstr)
 +231 stdcall -noname SHSetFolderPathA(long ptr long str)
 +232 stdcall -noname SHSetFolderPathW(long ptr long wstr)
 +233 stdcall -noname SHGetUserPicturePathW(wstr long ptr)
 +234 stdcall -noname SHSetUserPicturePathW(wstr long ptr)
 +235 stdcall -noname SHOpenEffectiveToken(ptr)
 +236 stdcall -noname SHTestTokenPrivilegeW(ptr ptr)
 +237 stdcall -noname SHShouldShowWizards(ptr)
 +238 stdcall Options_RunDLL(ptr ptr str long)
 +239 stdcall PathIsSlowW(wstr long)
 +240 stdcall PathIsSlowA(str long)
 +241 stdcall -noname SHGetUserDisplayName(wstr ptr)
 +242 stdcall -noname SHGetProcessDword(long long)
 +243 stdcall -noname SHSetShellWindowEx(ptr ptr) user32.SetShellWindowEx
 +244 stdcall -noname SHInitRestricted(ptr ptr)
 +245 stdcall SHTestTokenMembership(ptr ptr)
 +246 stub -noname SHInvokePrivilegedFunctionW
 +247 stub -noname SHGetActiveConsoleSessionId
 +248 stdcall -noname SHGetUserSessionId(ptr) # Fixme
 +249 stdcall -noname PathParseIconLocation(wstr) PathParseIconLocationW
 +250 stdcall -noname PathRemoveExtension(wstr) PathRemoveExtensionW
 +251 stdcall -noname PathRemoveArgs(wstr) PathRemoveArgsW
 +252 stdcall -noname PathIsURL(wstr) shlwapi.PathIsURLW
 +253 stub -noname SHIsCurrentProcessConsoleSession
 +254 stub -noname DisconnectWindowsDialog
 +255 stdcall Options_RunDLLA(ptr ptr str long)
 +256 stdcall SHCreateShellFolderView(ptr ptr)
 +257 stdcall -noname SHGetShellFolderViewCB(ptr)
 +258 stdcall -noname LinkWindow_RegisterClass()
 +259 stdcall -noname LinkWindow_UnregisterClass()
 +260 stdcall Options_RunDLLW(ptr ptr wstr long)
 +261 stdcall PrintersGetCommand_RunDLL(ptr ptr wstr long)
 +262 stdcall PrintersGetCommand_RunDLLA(ptr ptr str long)
 +263 stdcall PrintersGetCommand_RunDLLW(ptr ptr wstr long)
 +264 stdcall RealShellExecuteA(ptr str str str str str str str long ptr)
 +265 stdcall RealShellExecuteExA(ptr str str str str str str str long ptr long)
 +266 stdcall RealShellExecuteExW(ptr str str str str str str str long ptr long)
 +267 stdcall RealShellExecuteW(ptr wstr wstr wstr wstr wstr wstr wstr long ptr)
 +268 stdcall RegenerateUserEnvironment(ptr long)
 +269 stdcall SHAddToRecentDocs(long ptr)
 +270 stdcall SHAppBarMessage(long ptr)
 +271 stdcall SHBindToParent(ptr ptr ptr ptr)
 +272 stdcall SHBrowseForFolder(ptr) SHBrowseForFolderA
 +273 stdcall SHBrowseForFolderA(ptr)
 +274 stdcall SHBrowseForFolderW(ptr)
 +275 stdcall SHChangeNotify(long long ptr ptr)
 +276 stdcall SHChangeNotifySuspendResume(long ptr long long)
 +277 stdcall SHCreateDirectoryExA(long str ptr)
 +278 stdcall SHCreateDirectoryExW(long wstr ptr)
 +279 stub SHCreateLocalServerRunDll
 +280 stdcall SHCreateProcessAsUserW(ptr)
 +281 stdcall SHCreateQueryCancelAutoPlayMoniker(ptr)
 +282 stdcall SHCreateShellItem(ptr ptr ptr ptr)
 +283 stdcall SHEmptyRecycleBinA(long str long)
 +284 stdcall SHEmptyRecycleBinW(long wstr long)
 +285 stub SHEnableServiceObject
 +286 stub SHEnumerateUnreadMailAccountsW
 +287 stdcall SHExtractIconsW(wstr long long long ptr ptr long long) user32.PrivateExtractIconsW
 +288 stdcall SHFileOperation(ptr) SHFileOperationA
 +289 stdcall SHFileOperationA(ptr)
 +290 stdcall SHFileOperationW(ptr)
 +291 stdcall SHFormatDrive(long long long long)
 +292 stdcall SHFreeNameMappings(ptr)
 +293 stdcall SHGetDataFromIDListA(ptr ptr long ptr long)
 +294 stdcall SHGetDataFromIDListW(ptr ptr long ptr long)
 +295 stdcall SHGetDesktopFolder(ptr)
 +296 stdcall SHGetDiskFreeSpaceA(str ptr ptr ptr) kernel32.GetDiskFreeSpaceExA
 +297 stdcall SHGetDiskFreeSpaceExA(str ptr ptr ptr) kernel32.GetDiskFreeSpaceExA
 +298 stdcall SHGetDiskFreeSpaceExW(wstr ptr ptr ptr) kernel32.GetDiskFreeSpaceExW
 +299 stdcall SHGetFileInfo(ptr long ptr long long) SHGetFileInfoA
 +300 stdcall SHGetFileInfoA(ptr long ptr long long)
 +301 stdcall SHGetFileInfoW(ptr long ptr long long)
 +302 stdcall SHGetFolderLocation(long long long long ptr)
 +303 stdcall SHGetFolderPathA(long long long long ptr)
 +304 stdcall SHGetFolderPathAndSubDirA(long long long long str ptr)
 +305 stdcall SHGetFolderPathAndSubDirW(long long long long wstr ptr)
 +306 stdcall SHGetFolderPathW(long long long long ptr)
 +307 stdcall SHGetIconOverlayIndexA(str long)
 +308 stdcall SHGetIconOverlayIndexW(wstr long)
 +309 stdcall SHGetInstanceExplorer(long)
 +310 stdcall SHGetMalloc(ptr)
 +311 stdcall SHGetNewLinkInfo(str str ptr long long) SHGetNewLinkInfoA
 +312 stdcall SHGetPathFromIDList(ptr ptr) SHGetPathFromIDListA
 +313 stdcall SHGetPathFromIDListA(ptr ptr)
 +314 stdcall SHGetPathFromIDListW(ptr ptr)
 +315 stdcall SHGetSettings(ptr long)
 +316 stdcall SHGetSpecialFolderLocation(long long ptr)
 +317 stdcall SHGetSpecialFolderPathA(long ptr long long)
 +318 stdcall SHGetSpecialFolderPathW(long ptr long long)
 +319 stdcall SHGetUnreadMailCountW (long wstr long ptr wstr long)
 +320 stdcall SHHelpShortcuts_RunDLL(long long long long) SHHelpShortcuts_RunDLLA
 +321 stdcall SHHelpShortcuts_RunDLLA(long long long long)
 +322 stdcall SHHelpShortcuts_RunDLLW(long long long long)
 +323 stdcall SHInvokePrinterCommandA(ptr long str str long)
 +324 stdcall SHInvokePrinterCommandW(ptr long wstr wstr long)
 +325 stdcall SHIsFileAvailableOffline(wstr ptr)
 +326 stdcall SHLoadInProc(long)
 +327 stdcall SHLoadNonloadedIconOverlayIdentifiers()
 +328 stdcall SHOpenFolderAndSelectItems(ptr long ptr long)
 +329 stdcall SHParseDisplayName(wstr ptr ptr long ptr)
 +330 stdcall SHPathPrepareForWriteA(long ptr str long)
 +331 stdcall SHPathPrepareForWriteW(long ptr wstr long)
 +332 stdcall SHQueryRecycleBinA(str ptr)
 +333 stdcall SHQueryRecycleBinW(wstr ptr)
 +334 stdcall SHSetLocalizedName(wstr wstr long)
 +335 stdcall SHSetUnreadMailCountW (wstr long wstr)
 +336 stdcall SHUpdateRecycleBinIcon()
 +337 stdcall SheChangeDirA(str)
 +338 stdcall SheChangeDirExA(str)
 +339 stdcall SheChangeDirExW(wstr)
 +340 stdcall SheChangeDirW(wstr)
 +341 stdcall SheConvertPathW(wstr wstr long)
 +342 stdcall SheFullPathA(str long str)
 +343 stdcall SheFullPathW(wstr long wstr)
 +344 stdcall SheGetCurDrive()
 +345 stdcall SheGetDirA(long long)
 +346 stdcall SheGetDirExW(wstr ptr wstr)
 +347 stdcall SheGetDirW(long long)
 +348 stdcall SheGetPathOffsetW(wstr)
 +349 stdcall SheRemoveQuotesA(str)
 +350 stdcall SheRemoveQuotesW(wstr)
 +351 stdcall SheSetCurDrive(long)
 +352 stdcall SheShortenPathA(str long)
 +353 stdcall SheShortenPathW(wstr long)
 +354 stdcall ShellAboutA(long str str long)
 +355 stdcall ShellAboutW(long wstr wstr long)
 +356 stdcall ShellExec_RunDLL(ptr ptr wstr long)
 +357 stdcall ShellExec_RunDLLA(ptr ptr str long)
 +358 stdcall ShellExec_RunDLLW(ptr ptr wstr long)
 +359 stdcall ShellExecuteA(long str str str str long)
 +360 stdcall ShellExecuteEx(long) ShellExecuteExA
 +361 stdcall ShellExecuteExA (long)
 +362 stdcall ShellExecuteExW (long)
 +363 stdcall ShellExecuteW(long wstr wstr wstr wstr long)
 +364 stdcall ShellHookProc(long ptr ptr)
 +365 stdcall Shell_NotifyIcon(long ptr) Shell_NotifyIconA
 +366 stdcall Shell_NotifyIconA(long ptr)
 +367 stdcall Shell_NotifyIconW(long ptr)
 +368 stdcall StrChrA(str long) shlwapi.StrChrA
 +369 stdcall StrChrIA(str long) shlwapi.StrChrIA
 +370 stdcall StrChrIW(wstr long) shlwapi.StrChrIW
 +371 stdcall StrChrW(wstr long) shlwapi.StrChrW
 +372 stdcall StrCmpNA(str str long) shlwapi.StrCmpNA
 +373 stdcall StrCmpNIA(str str long) shlwapi.StrCmpNIA
 +374 stdcall StrCmpNIW(wstr wstr long) shlwapi.StrCmpNIW
 +375 stdcall StrCmpNW(wstr wstr long) shlwapi.StrCmpNW
 +376 stdcall StrCpyNA (ptr str long) kernel32.lstrcpynA
 +377 stdcall StrCpyNW(wstr wstr long) shlwapi.StrCpyNW
 +378 stdcall StrNCmpA(str str long) shlwapi.StrCmpNA
 +379 stdcall StrNCmpIA(str str long) shlwapi.StrCmpNIA
 +380 stdcall StrNCmpIW(wstr wstr long) shlwapi.StrCmpNIW
 +381 stdcall StrNCmpW(wstr wstr long) shlwapi.StrCmpNW
 +382 stdcall StrNCpyA (ptr str long) kernel32.lstrcpynA
 +383 stdcall StrNCpyW(wstr wstr long) shlwapi.StrCpyNW
 +384 stdcall StrRChrA(str str long) shlwapi.StrRChrA
 +385 stdcall StrRChrIA(str str long) shlwapi.StrRChrIA
 +386 stdcall StrRChrIW(str str long) shlwapi.StrRChrIW
 +387 stdcall StrRChrW(wstr wstr long) shlwapi.StrRChrW
 +388 stdcall StrRStrA(str str str)
 +389 stdcall StrRStrIA(str str str) shlwapi.StrRStrIA
 +390 stdcall StrRStrIW(wstr wstr wstr) shlwapi.StrRStrIW
 +391 stdcall StrRStrW(wstr wstr wstr)
 +392 stdcall StrStrA(str str) shlwapi.StrStrA
 +393 stdcall StrStrIA(str str) shlwapi.StrStrIA
 +394 stdcall StrStrIW(wstr wstr) shlwapi.StrStrIW
 +395 stdcall StrStrW(wstr wstr) shlwapi.StrStrW
 +396 stdcall WOWShellExecute(ptr wstr wstr wstr wstr long ptr)
 +520 stdcall SHAllocShared(ptr long long)
 +521 stdcall SHLockShared(long long)
 +522 stdcall SHUnlockShared(ptr)
 +523 stdcall SHFreeShared(long long)
 +524 stdcall RealDriveType(long long)
 +525 stdcall -noname RealDriveTypeFlags(long long)
 +526 stdcall SHFlushSFCache()
 +640 stdcall -noname NTSHChangeNotifyRegister(long long long long long long)
 +641 stdcall -noname NTSHChangeNotifyDeregister(long)
 +643 stdcall -noname SHChangeNotifyReceive(long long ptr ptr)
 +644 stdcall SHChangeNotification_Lock(long long ptr ptr)
 +645 stdcall SHChangeNotification_Unlock(long)
 +646 stdcall -noname SHChangeRegistrationReceive(ptr long)
 +648 stdcall -noname SHWaitOp_Operate(ptr long)
 +650 stdcall -noname PathIsSameRoot(ptr ptr) PathIsSameRootAW # Fixme
 +651 stdcall -noname OldReadCabinetState(long long) ReadCabinetState
 +652 stdcall WriteCabinetState(long)
 +653 stdcall PathProcessCommand(long long long long) PathProcessCommandAW
 +654 stdcall ReadCabinetState(long long)
 +660 stdcall -noname FileIconInit(long)
 +680 stdcall IsUserAnAdmin()
 +681 stdcall -noname SHGetAppCompatFlags(long) shlwapi.SHGetAppCompatFlags
 +683 stub -noname SHStgOpenStorageW
 +684 stub -noname SHStgOpenStorageA
 +685 stub SHPropStgCreate
 +688 stub SHPropStgReadMultiple
 +689 stub SHPropStgWriteMultiple
 +690 stub -noname SHIsLegacyAnsiProperty
 +691 stub -noname SHFileSysBindToStorage
 +700 stdcall CDefFolderMenu_Create(ptr ptr long ptr ptr ptr ptr ptr ptr)
 +701 stdcall CDefFolderMenu_Create2(ptr ptr long ptr ptr ptr long ptr ptr)
 +702 stdcall -noname CDefFolderMenu_MergeMenu(ptr long long ptr)
 +703 stdcall -noname GUIDFromStringA(str ptr)
 +704 stdcall -noname GUIDFromStringW(wstr ptr)
 +707 stdcall -noname SHOpenPropSheetA(str ptr long ptr ptr ptr str)
 +708 stdcall -noname SHGetSetFolderCustomSettingsA(ptr str long)
 +709 stdcall SHGetSetFolderCustomSettingsW(ptr wstr long)
 +711 stdcall -noname CheckWinIniForAssocs()
 +712 stdcall -noname SHCopyMonikerToTemp(ptr wstr wstr long)
 +713 stdcall -noname PathIsTemporaryA(str)
 +714 stdcall -noname PathIsTemporaryW(wstr)
 +715 stdcall -noname SHCreatePropertyBag(ptr ptr)
 +716 stdcall SHMultiFileProperties(ptr long)
 +719 stdcall -noname SHParseDarwinIDFromCacheW(wstr wstr)
 +720 stdcall -noname MakeShellURLFromPathA(str str long)
 +721 stdcall -noname MakeShellURLFromPathW(wstr wstr long)
 +722 stub -noname SHCreateInstance
 +723 stdcall -noname SHCreateSessionKey(long ptr)
 +724 stdcall -noname SHIsTempDisplayMode()
 +725 stdcall -noname GetFileDescriptor(ptr long long wstr)
 +726 stdcall -noname CopyStreamUI(ptr ptr ptr)
 +727 stdcall SHGetImageList(long ptr ptr)
 +730 stdcall RestartDialogEx(long wstr long long)
 +731 stub -noname SHRegisterDarwinLink
 +732 stdcall -noname SHReValidateDarwinCache()
 +733 stdcall -noname CheckDiskSpace()
 +740 stub -noname SHCreateFileDataObject
 +743 stdcall SHCreateFileExtractIconW(wstr long ptr ptr)
 +744 stub -noname Create_IEnumUICommand
 +745 stub -noname Create_IUIElement
 +747 stdcall SHLimitInputEdit(ptr ptr)
 +748 stdcall -noname SHLimitInputCombo(ptr ptr)
 +749 stub SHGetShellStyleHInstance
 +750 stub SHGetAttributesFromDataObject
 +751 stub -noname SHSimulateDropOnClsid
 +752 stub -noname SHGetComputerDisplayNameW
 +753 stub -noname CheckStagingArea
 +754 stub -noname SHLimitInputEditWithFlags
 +755 stdcall -noname PathIsEqualOrSubFolder(wstr wstr)
 +756 stub -noname DeleteFileThumbnail
 +
 +# Functions exported by the WinVista shell32.dll
 +@ stdcall SHCreateDefaultContextMenu(ptr ptr ptr)
 +@ stdcall SHCreateDefaultExtractIcon(ptr ptr)
 +
 +# Discontinued in version 6.0. Until retired in WinVista and higher
 +@ stdcall FileMenu_DeleteAllItems(long)
 +@ stdcall FileMenu_DrawItem(long ptr)
 +@ stdcall FileMenu_FindSubMenuByPidl(long ptr)
 +@ stdcall FileMenu_GetLastSelectedItemPidls(long ptr ptr)
 +@ stdcall FileMenu_HandleMenuChar(long long)
 +@ stdcall FileMenu_InitMenuPopup(long)
 +@ stdcall FileMenu_InsertUsingPidl (long long ptr long long ptr)
 +@ stdcall FileMenu_Invalidate(long)
 +@ stdcall FileMenu_MeasureItem(long ptr)
 +@ stdcall FileMenu_ReplaceUsingPidl(long long ptr long ptr)
 +@ stdcall FileMenu_Create(long long long long long)
 +@ stdcall FileMenu_AppendItem(long ptr long long long long) FileMenu_AppendItemAW
 +@ stdcall FileMenu_TrackPopupMenuEx(long long long long long long)
 +@ stdcall FileMenu_DeleteItemByCmd(long long)
 +@ stdcall FileMenu_Destroy(long)
 +@ stdcall FileMenu_AbortInitMenu()
 +@ stdcall FileMenu_AppendFilesForPidl(long ptr long)
 +@ stdcall FileMenu_AddFilesForPidl(long long long ptr long long ptr)
 +@ stdcall FileMenu_DeleteItemByIndex(long long)
 +@ stdcall FileMenu_DeleteItemByFirstID(long long)
 +@ stdcall FileMenu_DeleteSeparator(long)
 +@ stdcall FileMenu_EnableItemByCmd(long long long)
 +@ stdcall FileMenu_GetItemExtent(long long)
 +
 +# 4.0 (NT) and higher. Until discontinued in 5.0
 +@ stdcall SHRegCloseKey(long)
 +@ stdcall SHRegOpenKeyA(long str long)
 +@ stdcall SHRegOpenKeyW(long wstr long)
 +@ stdcall SHRegQueryValueA(long str ptr ptr)
 +@ stdcall SHRegQueryValueExA(long str ptr ptr ptr ptr)
 +@ stdcall SHRegQueryValueW (long long long long)
 +@ stdcall SHRegQueryValueExW (long wstr ptr ptr ptr ptr)
 +@ stdcall SHRegDeleteKeyW(long wstr)
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index bbc24c7,0000000..405e780
mode 100644,000000..100644
--- /dev/null
@@@ -1,5233 -1,0 +1,5266 @@@
 +/*
 + * COPYRIGHT:       See COPYING in the top level directory
 + * PROJECT:         ReactOS user32.dll
 + * FILE:            user32/windows/menu.c
 + * PURPOSE:         Menus
 + *
 + * PROGRAMMERS:     Casper S. Hornstrup
 + *                  James Tabor
 + */
 +
 +/* INCLUDES ******************************************************************/
 +
 +#include <user32.h>
 +#include <wine/debug.h>
 +
 +LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
 +
 +WINE_DEFAULT_DEBUG_CHANNEL(menu);
 +
 +/* internal popup menu window messages */
 +
 +#define MM_SETMENUHANDLE      (WM_USER + 0)
 +#define MM_GETMENUHANDLE      (WM_USER + 1)
 +
 +/* internal flags for menu tracking */
 +
 +#define TF_ENDMENU              0x10000
 +#define TF_SUSPENDPOPUP         0x20000
 +#define TF_SKIPREMOVE           0x40000
 +
 +#define ITEM_PREV             -1
 +#define ITEM_NEXT              1
 +
 +/* Internal MenuTrackMenu() flags */
 +#define TPM_INTERNAL          0xF0000000
 +#define TPM_BUTTONDOWN                0x40000000              /* menu was clicked before tracking */
 +#define TPM_POPUPMENU           0x20000000              /* menu is a popup menu */
 +
 +
 +#define MENU_TYPE_MASK (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR)
 +
 +#define MENU_ITEM_TYPE(flags) ((flags) & MENU_TYPE_MASK)
 +
 +/* macro to test that flags do not indicate bitmap, ownerdraw or separator */
 +#define IS_STRING_ITEM(flags) (MF_STRING == MENU_ITEM_TYPE(flags))
 +#define IS_MAGIC_BITMAP(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1))
 +
 +#define IS_SYSTEM_MENU(MenuInfo)  \
 +      (0 == ((MenuInfo)->Flags & MF_POPUP) && 0 != ((MenuInfo)->Flags & MF_SYSMENU))
 +
 +#define IS_SYSTEM_POPUP(MenuInfo) \
 +      (0 != ((MenuInfo)->Flags & MF_POPUP) && 0 != ((MenuInfo)->Flags & MF_SYSMENU))
 +
 +#define IS_BITMAP_ITEM(flags) (MF_BITMAP == MENU_ITEM_TYPE(flags))
 +
 +/* Use global popup window because there's no way 2 menus can
 + * be tracked at the same time.  */
 +static HWND top_popup;
 +static HMENU top_popup_hmenu;
 +
 +/* Flag set by EndMenu() to force an exit from menu tracking */
 +static BOOL fEndMenu = FALSE;
 +
 +#define MENU_ITEM_HBMP_SPACE (5)
 +#define MENU_BAR_ITEMS_SPACE (12)
 +#define SEPARATOR_HEIGHT (5)
 +#define MENU_TAB_SPACE (8)
 +
 +typedef struct
 +{
 +  UINT  TrackFlags;
 +  HMENU CurrentMenu; /* current submenu (can be equal to hTopMenu)*/
 +  HMENU TopMenu;     /* initial menu */
 +  HWND  OwnerWnd;    /* where notifications are sent */
 +  POINT Pt;
 +} MTRACKER;
 +
 +
 +/*********************************************************************
 + * PopupMenu class descriptor
 + */
 +const struct builtin_class_descr POPUPMENU_builtin_class =
 +{
 +    WC_MENU,                     /* name */
 +    CS_SAVEBITS | CS_DBLCLKS,                  /* style  */
 +    (WNDPROC) NULL,                            /* FIXME - procA */
 +    (WNDPROC) PopupMenuWndProcW,               /* FIXME - procW */
 +    sizeof(MENUINFO *),                        /* extra */
 +    (LPCWSTR) IDC_ARROW,                       /* cursor */
 +    (HBRUSH)(COLOR_MENU + 1)                   /* brush */
 +};
 +
 +#ifndef GET_WORD
 +#define GET_WORD(ptr)  (*(WORD *)(ptr))
 +#endif
 +#ifndef GET_DWORD
 +#define GET_DWORD(ptr) (*(DWORD *)(ptr))
 +#endif
 +
 +HFONT hMenuFont = NULL;
 +HFONT hMenuFontBold = NULL;
 +
 +/* Dimension of the menu bitmaps */
 +static HBITMAP BmpSysMenu = NULL;
 +
 +static SIZE MenuCharSize;
 +
 +/***********************************************************************
 + *           MenuGetRosMenuInfo
 + *
 + * Get full information about menu
 + */
 +static BOOL FASTCALL
 +MenuGetRosMenuInfo(PROSMENUINFO MenuInfo, HMENU Menu)
 +{
 +  MenuInfo->cbSize = sizeof(ROSMENUINFO);
 +  MenuInfo->fMask = MIM_BACKGROUND | MIM_HELPID | MIM_MAXHEIGHT | MIM_MENUDATA | MIM_STYLE;
 +
 +  return NtUserMenuInfo(Menu, MenuInfo, FALSE);
 +}
 +
 +/***********************************************************************
 + *           MenuSetRosMenuInfo
 + *
 + * Set full information about menu
 + */
 +static BOOL FASTCALL
 +MenuSetRosMenuInfo(PROSMENUINFO MenuInfo)
 +{
 +  MenuInfo->cbSize = sizeof(ROSMENUINFO);
 +  MenuInfo->fMask = MIM_BACKGROUND | MIM_HELPID | MIM_MAXHEIGHT | MIM_MENUDATA | MIM_STYLE;
 +
 +  return NtUserMenuInfo(MenuInfo->Self, MenuInfo, TRUE);
 +}
 +
 +/***********************************************************************
 + *           MenuInitRosMenuItemInfo
 + *
 + * Initialize a buffer for use with MenuGet/SetRosMenuItemInfo
 + */
 +static VOID FASTCALL
 +MenuInitRosMenuItemInfo(PROSMENUITEMINFO ItemInfo)
 +{
 +  ZeroMemory(ItemInfo, sizeof(ROSMENUITEMINFO));
 +  ItemInfo->cbSize = sizeof(ROSMENUITEMINFO);
 +}
 +
 +/***********************************************************************
 + *           MenuGetRosMenuItemInfo
 + *
 + * Get full information about a menu item
 + */
 +static BOOL FASTCALL
 +MenuGetRosMenuItemInfo(HMENU Menu, UINT Index, PROSMENUITEMINFO ItemInfo)
 +{
 +  UINT Save_Mask = ItemInfo->fMask; /* Save the org mask bits. */
 +
 +  if (ItemInfo->dwTypeData != NULL)
 +    {
 +      HeapFree(GetProcessHeap(), 0, ItemInfo->dwTypeData);
 +    }
 +
 +
 +  ItemInfo->fMask = MIIM_BITMAP | MIIM_CHECKMARKS | MIIM_DATA | MIIM_FTYPE
 +             | MIIM_ID | MIIM_STATE | MIIM_STRING | MIIM_SUBMENU | MIIM_TYPE;
 +  ItemInfo->dwTypeData = NULL;
 +
 +  if (! NtUserMenuItemInfo(Menu, Index, TRUE, ItemInfo, FALSE))
 +    {
 +      ItemInfo->fType = 0;
 +      return FALSE;
 +    }
 +
 +  if (MENU_ITEM_TYPE(ItemInfo->fType) == MF_STRING)
 +    {
 +      ItemInfo->cch++;
 +      ItemInfo->dwTypeData = HeapAlloc(GetProcessHeap(), 0,
 +                                       ItemInfo->cch * sizeof(WCHAR));
 +      if (NULL == ItemInfo->dwTypeData)
 +        {
 +          return FALSE;
 +        }
 +
 +      if (! NtUserMenuItemInfo(Menu, Index, TRUE, ItemInfo, FALSE))
 +        {
 +          ItemInfo->fType = 0;
 +          return FALSE;
 +        }
 +      ItemInfo->dwTypeData[ItemInfo->cch - 1] = UNICODE_NULL;
 +    }
 +  ItemInfo->fMask =  Save_Mask;
 +  return TRUE;
 +}
 +
 +/***********************************************************************
 + *           MenuSetRosMenuItemInfo
 + *
 + * Set selected information about a menu item, need to set the mask bits.
 + */
 +static BOOL FASTCALL
 +MenuSetRosMenuItemInfo(HMENU Menu, UINT Index, PROSMENUITEMINFO ItemInfo)
 +{
 +  BOOL Ret;
 +
 +  if (MENU_ITEM_TYPE(ItemInfo->fType) == MF_STRING &&
 +      ItemInfo->dwTypeData != NULL)
 +  {
 +    ItemInfo->cch = strlenW(ItemInfo->dwTypeData);
 +  }
 +  Ret = NtUserMenuItemInfo(Menu, Index, TRUE, ItemInfo, TRUE);
 +
 +  return Ret;
 +}
 +
 +/***********************************************************************
 + *           MenuCleanupRosMenuItemInfo
 + *
 + * Cleanup after use of MenuGet/SetRosMenuItemInfo
 + */
 +static VOID FASTCALL
 +MenuCleanupRosMenuItemInfo(PROSMENUITEMINFO ItemInfo)
 +{
 +  if (ItemInfo->dwTypeData != NULL)
 +    {
 +      HeapFree(GetProcessHeap(), 0, ItemInfo->dwTypeData);
 +      ItemInfo->dwTypeData = NULL;
 +    }
 +}
 +
 +/***********************************************************************
 + *           MenuGetAllRosMenuItemInfo
 + *
 + * Get full information about all menu items
 + */
 +static INT FASTCALL
 +MenuGetAllRosMenuItemInfo(HMENU Menu, PROSMENUITEMINFO *ItemInfo)
 +{
 +  DWORD BufSize;
 +
 +  BufSize = NtUserBuildMenuItemList(Menu, (VOID *) 1, 0, 0);
 +  if (BufSize == (DWORD) -1 || BufSize == 0)
 +    {
 +      return -1;
 +    }
 +  *ItemInfo = HeapAlloc(GetProcessHeap(), 0, BufSize);
 +  if (NULL == *ItemInfo)
 +    {
 +      return -1;
 +    }
 +
 +  return NtUserBuildMenuItemList(Menu, *ItemInfo, BufSize, 0);
 +}
 +
 +/***********************************************************************
 + *           MenuCleanupAllRosMenuItemInfo
 + *
 + * Cleanup after use of MenuGetAllRosMenuItemInfo
 + */
 +static VOID FASTCALL
 +MenuCleanupAllRosMenuItemInfo(PROSMENUITEMINFO ItemInfo)
 +{
 +  HeapFree(GetProcessHeap(), 0, ItemInfo);
 +}
 +
 +/***********************************************************************
 + *           MenuInitSysMenuPopup
 + *
 + * Grey the appropriate items in System menu.
 + */
 +void FASTCALL MenuInitSysMenuPopup(HMENU hmenu, DWORD style, DWORD clsStyle, LONG HitTest )
 +{
 +    BOOL gray;
 +    UINT DefItem;
 +    #if 0
 +    MENUITEMINFOW mii;
 +    #endif
 +
 +    gray = !(style & WS_THICKFRAME) || (style & (WS_MAXIMIZE | WS_MINIMIZE));
 +    EnableMenuItem( hmenu, SC_SIZE, (gray ? MF_GRAYED : MF_ENABLED) );
 +    gray = ((style & WS_MAXIMIZE) != 0);
 +    EnableMenuItem( hmenu, SC_MOVE, (gray ? MF_GRAYED : MF_ENABLED) );
 +    gray = !(style & WS_MINIMIZEBOX) || (style & WS_MINIMIZE);
 +    EnableMenuItem( hmenu, SC_MINIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
 +    gray = !(style & WS_MAXIMIZEBOX) || (style & WS_MAXIMIZE);
 +    EnableMenuItem( hmenu, SC_MAXIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
 +    gray = !(style & (WS_MAXIMIZE | WS_MINIMIZE));
 +    EnableMenuItem( hmenu, SC_RESTORE, (gray ? MF_GRAYED : MF_ENABLED) );
 +    gray = (clsStyle & CS_NOCLOSE) != 0;
 +
 +    /* The menu item must keep its state if it's disabled */
 +    if(gray)
 +        EnableMenuItem( hmenu, SC_CLOSE, MF_GRAYED);
 +
 +    /* Set default menu item */
 +    if(style & WS_MINIMIZE) DefItem = SC_RESTORE;
 +    else if(HitTest == HTCAPTION) DefItem = ((style & (WS_MAXIMIZE | WS_MINIMIZE)) ? SC_RESTORE : SC_MAXIMIZE);
 +    else DefItem = SC_CLOSE;
 +#if 0
 +    mii.cbSize = sizeof(MENUITEMINFOW);
 +    mii.fMask |= MIIM_STATE;
 +    if((DefItem != SC_CLOSE) && GetMenuItemInfoW(hmenu, DefItem, FALSE, &mii) &&
 +       (mii.fState & (MFS_GRAYED | MFS_DISABLED))) DefItem = SC_CLOSE;
 +#endif
 +    SetMenuDefaultItem(hmenu, DefItem, MF_BYCOMMAND);
 +}
 +
 +/******************************************************************************
 + *
 + *   UINT MenuGetStartOfNextColumn(
 + *     PROSMENUINFO MenuInfo)
 + *
 + *****************************************************************************/
 +static UINT MenuGetStartOfNextColumn(
 +    PROSMENUINFO MenuInfo)
 +{
 +    PROSMENUITEMINFO MenuItems;
 +    UINT i;
 +
 +    i = MenuInfo->FocusedItem;
 +    if ( i == NO_SELECTED_ITEM )
 +        return i;
 +
 +    if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &MenuItems) <= 0)
 +        return NO_SELECTED_ITEM;
 +
 +    for (i++ ; i < MenuInfo->MenuItemCount; i++)
 +        if (0 != (MenuItems[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK)))
 +            return i;
 +
 +    return NO_SELECTED_ITEM;
 +}
 +
 +/******************************************************************************
 + *
 + *   UINT MenuGetStartOfPrevColumn(
 + *     PROSMENUINFO MenuInfo)
 + *
 + *****************************************************************************/
 +
 +static UINT FASTCALL MenuGetStartOfPrevColumn(
 +    PROSMENUINFO MenuInfo)
 +{
 +    PROSMENUITEMINFO MenuItems;
 +    UINT i;
 +
 +    if (!MenuInfo->FocusedItem || MenuInfo->FocusedItem == NO_SELECTED_ITEM)
 +        return NO_SELECTED_ITEM;
 +
 +    if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &MenuItems) <= 0)
 +        return NO_SELECTED_ITEM;
 +
 +    /* Find the start of the column */
 +    for (i = MenuInfo->FocusedItem;
 +         0 != i && 0 == (MenuItems[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK));
 +         --i)
 +    {
 +        ; /* empty */
 +    }
 +
 +    if (i == 0)
 +    {
 +        MenuCleanupAllRosMenuItemInfo(MenuItems);
 +        return NO_SELECTED_ITEM;
 +    }
 +
 +    for (--i; 0 != i; --i)
 +        if (MenuItems[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK))
 +            break;
 +
 +    MenuCleanupAllRosMenuItemInfo(MenuItems);
 +    TRACE("ret %d.\n", i );
 +
 +    return i;
 +}
 +
 +/***********************************************************************
 + *           MenuFindSubMenu
 + *
 + * Find a Sub menu. Return the position of the submenu, and modifies
 + * *hmenu in case it is found in another sub-menu.
 + * If the submenu cannot be found, NO_SELECTED_ITEM is returned.
 + */
 +static UINT FASTCALL MenuFindSubMenu(HMENU *hmenu, HMENU hSubTarget )
 +{
 +    ROSMENUINFO menu;
 +    UINT i;
 +    ROSMENUITEMINFO item;
 +    if (((*hmenu)==(HMENU)0xffff) ||
 +          (!MenuGetRosMenuInfo(&menu, *hmenu)))
 +        return NO_SELECTED_ITEM;
 +
 +    MenuInitRosMenuItemInfo(&item);
 +    for (i = 0; i < menu.MenuItemCount; i++) {
 +        if (! MenuGetRosMenuItemInfo(menu.Self, i, &item))
 +        {
 +            MenuCleanupRosMenuItemInfo(&item);
 +            return NO_SELECTED_ITEM;
 +        }
 +        if (!(item.fType & MF_POPUP)) continue;
 +        if (item.hSubMenu == hSubTarget) {
 +            MenuCleanupRosMenuItemInfo(&item);
 +            return i;
 +        }
 +        else  {
 +            HMENU hsubmenu = item.hSubMenu;
 +            UINT pos = MenuFindSubMenu(&hsubmenu, hSubTarget );
 +            if (pos != NO_SELECTED_ITEM) {
 +                *hmenu = hsubmenu;
 +                return pos;
 +           }
 +        }
 +    }
 +    MenuCleanupRosMenuItemInfo(&item);
 +    return NO_SELECTED_ITEM;
 +}
 +
 +/***********************************************************************
 + *           MenuLoadBitmaps
 + *
 + * Load the arrow bitmap. We can't do this from MenuInit since user32
 + * can also be used (and thus initialized) from text-mode.
 + */
 +static void FASTCALL
 +MenuLoadBitmaps(VOID)
 +{
 +  /* Load system buttons bitmaps */
 +  if (NULL == BmpSysMenu)
 +    {
 +      BmpSysMenu = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE));
 +    }
 +}
 +
 +/***********************************************************************
 + *           MenuDrawPopupGlyph
 + *
 + * Draws popup magic glyphs (can be found in system menu).
 + */
 +static void FASTCALL
 +MenuDrawPopupGlyph(HDC dc, LPRECT r, INT_PTR popupMagic, BOOL inactive, BOOL hilite)
 +{
 +  LOGFONTW lf;
 +  HFONT hFont, hOldFont;
 +  COLORREF clrsave;
 +  INT bkmode;
 +  TCHAR symbol;
 +  switch (popupMagic)
 +  {
 +  case (INT_PTR) HBMMENU_POPUP_RESTORE:
 +    symbol = '2';
 +    break;
 +  case (INT_PTR) HBMMENU_POPUP_MINIMIZE:
 +    symbol = '0';
 +    break;
 +  case (INT_PTR) HBMMENU_POPUP_MAXIMIZE:
 +    symbol = '1';
 +    break;
 +  case (INT_PTR) HBMMENU_POPUP_CLOSE:
 +    symbol = 'r';
 +    break;
 +  default:
 +    ERR("Invalid popup magic bitmap %d\n", (int)popupMagic);
 +    return;
 +  }
 +  ZeroMemory(&lf, sizeof(LOGFONTW));
 +  InflateRect(r, -2, -2);
 +  lf.lfHeight = r->bottom - r->top;
 +  lf.lfWidth = 0;
 +  lf.lfWeight = FW_NORMAL;
 +  lf.lfCharSet = DEFAULT_CHARSET;
 +  lstrcpy(lf.lfFaceName, TEXT("Marlett"));
 +  hFont = CreateFontIndirect(&lf);
 +  /* save font and text color */
 +  hOldFont = SelectObject(dc, hFont);
 +  clrsave = GetTextColor(dc);
 +  bkmode = GetBkMode(dc);
 +  /* set color and drawing mode */
 +  SetBkMode(dc, TRANSPARENT);
 +  if (inactive)
 +  {
 +    /* draw shadow */
 +    if (!hilite)
 +    {
 +      SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT));
 +      TextOut(dc, r->left + 1, r->top + 1, &symbol, 1);
 +    }
 +  }
 +  SetTextColor(dc, GetSysColor(inactive ? COLOR_GRAYTEXT : (hilite ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT)));
 +  /* draw selected symbol */
 +  TextOut(dc, r->left, r->top, &symbol, 1);
 +  /* restore previous settings */
 +  SetTextColor(dc, clrsave);
 +  SelectObject(dc, hOldFont);
 +  SetBkMode(dc, bkmode);
 +  DeleteObject(hFont);
 +}
 +
 +/***********************************************************************
 + *           MenuFindItemByKey
 + *
 + * Find the menu item selected by a key press.
 + * Return item id, -1 if none, -2 if we should close the menu.
 + */
 +static UINT FASTCALL MenuFindItemByKey(HWND WndOwner, PROSMENUINFO MenuInfo,
 +                  WCHAR Key, BOOL ForceMenuChar)
 +{
 +  ROSMENUINFO SysMenuInfo;
 +  PROSMENUITEMINFO Items, ItemInfo;
 +  LRESULT MenuChar;
 +  UINT i;
 +
 +  TRACE("\tlooking for '%c' (0x%02x) in [%p]\n", (char) Key, Key, MenuInfo);
 +
 +  if (NULL == MenuInfo || ! IsMenu(MenuInfo->Self))
 +    {
 +      if (MenuGetRosMenuInfo(&SysMenuInfo, GetSystemMenu(WndOwner, FALSE)))
 +        {
 +          MenuInfo = &SysMenuInfo;
 +        }
 +      else
 +        {
 +          MenuInfo = NULL;
 +        }
 +    }
 +
 +  if (NULL != MenuInfo)
 +    {
 +      if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &Items) <= 0)
 +        {
 +          return -1;
 +        }
 +      if (! ForceMenuChar)
 +        {
 +          Key = toupperW(Key);
 +          ItemInfo = Items;
 +          for (i = 0; i < MenuInfo->MenuItemCount; i++, ItemInfo++)
 +            {
 +              if ((ItemInfo->lpstr) && NULL != ItemInfo->dwTypeData)
 +                {
 +                  WCHAR *p = (WCHAR *) ItemInfo->dwTypeData - 2;
 +                  do
 +                    {
 +                      p = strchrW(p + 2, '&');
 +                  }
 +                  while (NULL != p && L'&' == p[1]);
 +                  if (NULL != p && (toupperW(p[1]) == Key))
 +                    {
 +                      return i;
 +                    }
 +                }
 +            }
 +        }
 +
 +      MenuChar = SendMessageW(WndOwner, WM_MENUCHAR,
 +                              MAKEWPARAM(Key, MenuInfo->Flags), (LPARAM) MenuInfo->Self);
 +      if (2 == HIWORD(MenuChar))
 +        {
 +          return LOWORD(MenuChar);
 +        }
 +      if (1 == HIWORD(MenuChar))
 +        {
 +          return (UINT) (-2);
 +        }
 +    }
 +
 +  return (UINT)(-1);
 +}
 +
 +/***********************************************************************
 + *           MenuGetBitmapItemSize
 + *
 + * Get the size of a bitmap item.
 + */
 +static void FASTCALL MenuGetBitmapItemSize(PROSMENUITEMINFO lpitem, SIZE *size, HWND WndOwner)
 +{
 +    BITMAP bm;
 +    HBITMAP bmp = lpitem->hbmpItem;
 +
 +    size->cx = size->cy = 0;
 +
 +    /* check if there is a magic menu item associated with this item */
 +    if (IS_MAGIC_BITMAP(bmp))
 +    {
 +      switch((INT_PTR) bmp)
 +        {
 +            case (INT_PTR)HBMMENU_CALLBACK:
 +            {
 +                MEASUREITEMSTRUCT measItem;
 +                measItem.CtlType = ODT_MENU;
 +                measItem.CtlID = 0;
 +                measItem.itemID = lpitem->wID;
 +                measItem.itemWidth = lpitem->Rect.right - lpitem->Rect.left;
 +                measItem.itemHeight = lpitem->Rect.bottom - lpitem->Rect.top;
 +                measItem.itemData = lpitem->dwItemData;
 +                SendMessageW( WndOwner, WM_MEASUREITEM, lpitem->wID, (LPARAM)&measItem);
 +                size->cx = measItem.itemWidth;
 +                size->cy = measItem.itemHeight;
 +                return;
 +            }
 +            break;
 +
 +          case (INT_PTR) HBMMENU_SYSTEM:
 +            if (0 != lpitem->dwItemData)
 +              {
 +                bmp = (HBITMAP) lpitem->dwItemData;
 +                break;
 +              }
 +            /* fall through */
 +          case (INT_PTR) HBMMENU_MBAR_RESTORE:
 +          case (INT_PTR) HBMMENU_MBAR_MINIMIZE:
 +          case (INT_PTR) HBMMENU_MBAR_CLOSE:
 +          case (INT_PTR) HBMMENU_MBAR_MINIMIZE_D:
 +          case (INT_PTR) HBMMENU_MBAR_CLOSE_D:
 +          case (INT_PTR) HBMMENU_POPUP_CLOSE:
 +          case (INT_PTR) HBMMENU_POPUP_RESTORE:
 +          case (INT_PTR) HBMMENU_POPUP_MAXIMIZE:
 +          case (INT_PTR) HBMMENU_POPUP_MINIMIZE:
 +            /* FIXME: Why we need to subtract these magic values? */
 +            /* to make them smaller than the menu bar? */
 +            size->cx = GetSystemMetrics(SM_CXSIZE) - 2;
 +            size->cy = GetSystemMetrics(SM_CYSIZE) - 4;
 +            return;
 +        }
 +    }
 +
 +    if (GetObjectW(bmp, sizeof(BITMAP), &bm))
 +    {
 +        size->cx = bm.bmWidth;
 +        size->cy = bm.bmHeight;
 +    }
 +}
 +
 +/***********************************************************************
 + *           MenuDrawBitmapItem
 + *
 + * Draw a bitmap item.
 + */
 +static void FASTCALL MenuDrawBitmapItem(HDC hdc, PROSMENUITEMINFO lpitem, const RECT *rect,
 +                    HMENU hmenu, HWND WndOwner, UINT odaction, BOOL MenuBar)
 +{
 +    BITMAP bm;
 +    DWORD rop;
 +    HDC hdcMem;
 +    HBITMAP bmp;
 +    int w = rect->right - rect->left;
 +    int h = rect->bottom - rect->top;
 +    int bmp_xoffset = 0;
 +    int left, top;
 +    HBITMAP hbmToDraw = lpitem->hbmpItem;
 +    bmp = hbmToDraw;
 +
 +    /* Check if there is a magic menu item associated with this item */
 +    if (IS_MAGIC_BITMAP(hbmToDraw))
 +    {
 +        UINT flags = 0;
 +        RECT r;
 +
 +      r = *rect;
 +      switch ((INT_PTR)hbmToDraw)
 +        {
 +        case (INT_PTR)HBMMENU_SYSTEM:
 +            if (lpitem->dwTypeData)
 +            {
 +                bmp = (HBITMAP)lpitem->dwTypeData;
 +                if (!GetObjectW( bmp, sizeof(bm), &bm )) return;
 +            }
 +            else
 +            {
 +                if (!BmpSysMenu) BmpSysMenu = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE));
 +                bmp = BmpSysMenu;
 +                if (! GetObjectW(bmp, sizeof(bm), &bm)) return;
 +                /* only use right half of the bitmap */
 +                bmp_xoffset = bm.bmWidth / 2;
 +                bm.bmWidth -= bmp_xoffset;
 +            }
 +            goto got_bitmap;
 +        case (INT_PTR)HBMMENU_MBAR_RESTORE:
 +            flags = DFCS_CAPTIONRESTORE;
 +            break;
 +        case (INT_PTR)HBMMENU_MBAR_MINIMIZE:
 +            r.right += 1;
 +            flags = DFCS_CAPTIONMIN;
 +            break;
 +        case (INT_PTR)HBMMENU_MBAR_MINIMIZE_D:
 +            r.right += 1;
 +            flags = DFCS_CAPTIONMIN | DFCS_INACTIVE;
 +            break;
 +        case (INT_PTR)HBMMENU_MBAR_CLOSE:
 +            flags = DFCS_CAPTIONCLOSE;
 +            break;
 +        case (INT_PTR)HBMMENU_MBAR_CLOSE_D:
 +            flags = DFCS_CAPTIONCLOSE | DFCS_INACTIVE;
 +            break;
 +        case (INT_PTR)HBMMENU_CALLBACK:
 +            {
 +                DRAWITEMSTRUCT drawItem;
 +                POINT origorg;
 +                drawItem.CtlType = ODT_MENU;
 +                drawItem.CtlID = 0;
 +                drawItem.itemID = lpitem->wID;
 +                drawItem.itemAction = odaction;
 +                drawItem.itemState = (lpitem->fState & MF_CHECKED)?ODS_CHECKED:0;
 +                drawItem.itemState |= (lpitem->fState & MF_DEFAULT)?ODS_DEFAULT:0;
 +                drawItem.itemState |= (lpitem->fState & MF_DISABLED)?ODS_DISABLED:0;
 +                drawItem.itemState |= (lpitem->fState & MF_GRAYED)?ODS_GRAYED|ODS_DISABLED:0;
 +                drawItem.itemState |= (lpitem->fState & MF_HILITE)?ODS_SELECTED:0;
 +                drawItem.hwndItem = (HWND)hmenu;
 +                drawItem.hDC = hdc;
 +                drawItem.rcItem = *rect;
 +                drawItem.itemData = lpitem->dwItemData;
 +                /* some applications make this assumption on the DC's origin */
 +                SetViewportOrgEx( hdc, lpitem->Rect.left, lpitem->Rect.top, &origorg);
 +                OffsetRect( &drawItem.rcItem, - lpitem->Rect.left, - lpitem->Rect.top);
 +                SendMessageW( WndOwner, WM_DRAWITEM, 0, (LPARAM)&drawItem);
 +                SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
 +                return;
 +            }
 +            break;
 +
 +          case (INT_PTR) HBMMENU_POPUP_CLOSE:
 +          case (INT_PTR) HBMMENU_POPUP_RESTORE:
 +          case (INT_PTR) HBMMENU_POPUP_MAXIMIZE:
 +          case (INT_PTR) HBMMENU_POPUP_MINIMIZE:
 +            MenuDrawPopupGlyph(hdc, &r, (INT_PTR)hbmToDraw, lpitem->fState & MF_GRAYED, lpitem->fState & MF_HILITE);
 +            return;
 +        }
 +      InflateRect(&r, -1, -1);
 +      if (0 != (lpitem->fState & MF_HILITE))
 +      {
 +          flags |= DFCS_PUSHED;
 +      }
 +      DrawFrameControl(hdc, &r, DFC_CAPTION, flags);
 +      return;
 +    }
 +
 +    if (!bmp || !GetObjectW( bmp, sizeof(bm), &bm )) return;
 +
 + got_bitmap:
 +    hdcMem = CreateCompatibleDC( hdc );
 +    SelectObject( hdcMem, bmp );
 +
 +    /* handle fontsize > bitmap_height */
 +    top = (h>bm.bmHeight) ? rect->top+(h-bm.bmHeight)/2 : rect->top;
 +    left=rect->left;
 +    rop=((lpitem->fState & MF_HILITE) && !IS_MAGIC_BITMAP(hbmToDraw)) ? NOTSRCCOPY : SRCCOPY;
 +    if ((lpitem->fState & MF_HILITE) && lpitem->hbmpItem)
 +        SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
 +    BitBlt( hdc, left, top, w, h, hdcMem, bmp_xoffset, 0, rop );
 +    DeleteDC( hdcMem );
 +}
 +
 +/***********************************************************************
 + *           MenuCalcItemSize
 + *
 + * Calculate the size of the menu item and store it in lpitem->rect.
 + */
 +static void FASTCALL MenuCalcItemSize( HDC hdc, PROSMENUITEMINFO lpitem, PROSMENUINFO MenuInfo, HWND hwndOwner,
 +                 INT orgX, INT orgY, BOOL menuBar)
 +{
 +    WCHAR *p;
 +    UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK );
 +    INT itemheight = 0;
 +
 +    TRACE("dc=%x owner=%x (%d,%d)\n", hdc, hwndOwner, orgX, orgY);
 +
 +    MenuCharSize.cx = GdiGetCharDimensions( hdc, NULL, &MenuCharSize.cy );
 +
 +    SetRect( &lpitem->Rect, orgX, orgY, orgX, orgY );
 +
 +    if (lpitem->fType & MF_OWNERDRAW)
 +    {
 +        MEASUREITEMSTRUCT mis;
 +        mis.CtlType    = ODT_MENU;
 +        mis.CtlID      = 0;
 +        mis.itemID     = lpitem->wID;
 +        mis.itemData   = lpitem->dwItemData;
 +        mis.itemHeight = HIWORD( GetDialogBaseUnits());
 +        mis.itemWidth  = 0;
 +        SendMessageW( hwndOwner, WM_MEASUREITEM, 0, (LPARAM)&mis );
 +        /* Tests reveal that Windows ( Win95 thru WinXP) adds twice the average
 +         * width of a menufont character to the width of an owner-drawn menu.
 +         */
 +        lpitem->Rect.right += mis.itemWidth + 2 * MenuCharSize.cx;
 +
 +        if (menuBar) {
 +            /* under at least win95 you seem to be given a standard
 +               height for the menu and the height value is ignored */
 +            lpitem->Rect.bottom += GetSystemMetrics(SM_CYMENUSIZE);
 +        } else
 +            lpitem->Rect.bottom += mis.itemHeight;
 +
 +        TRACE("id=%04lx size=%dx%d\n",
 +                lpitem->wID, mis.itemWidth, mis.itemHeight);
 +        return;
 +    }
 +
 +    if (lpitem->fType & MF_SEPARATOR)
 +    {
 +        lpitem->Rect.bottom += SEPARATOR_HEIGHT;
 +        if( !menuBar)
 +            lpitem->Rect.right += check_bitmap_width +  MenuCharSize.cx;
 +        return;
 +    }
 +
 +    lpitem->dxTab = 0;
 +
 +    if (lpitem->hbmpItem)
 +    {
 +        SIZE size;
 +
 +        if (!menuBar) {
 +            MenuGetBitmapItemSize(lpitem, &size, hwndOwner );
 +            /* Keep the size of the bitmap in callback mode to be able
 +             * to draw it correctly */
 +            lpitem->Rect.right = lpitem->Rect.left + size.cx;
 +            if (MenuInfo->maxBmpSize.cx < abs(size.cx) +  MENU_ITEM_HBMP_SPACE ||
 +                MenuInfo->maxBmpSize.cy < abs(size.cy))
 +            {
 +                MenuInfo->maxBmpSize.cx = abs(size.cx) + MENU_ITEM_HBMP_SPACE;
 +                MenuInfo->maxBmpSize.cy = abs(size.cy);
 +            }
 +            MenuSetRosMenuInfo(MenuInfo);
 +            itemheight = size.cy + 2;
 +
 +            if( !(MenuInfo->dwStyle & MNS_NOCHECK))
 +                lpitem->Rect.right += 2 * check_bitmap_width;
 +            lpitem->Rect.right += 4 + MenuCharSize.cx;
 +            lpitem->dxTab = lpitem->Rect.right;
 +            lpitem->Rect.right += check_bitmap_width;
 +        } else /* hbmpItem & MenuBar */ {
 +            MenuGetBitmapItemSize(lpitem, &size, hwndOwner );
 +            lpitem->Rect.right  += size.cx;
 +            if( lpitem->lpstr) lpitem->Rect.right  += 2;
 +            itemheight = size.cy;
 +
 +            /* Special case: Minimize button doesn't have a space behind it. */
 +            if (lpitem->hbmpItem == (HBITMAP)HBMMENU_MBAR_MINIMIZE ||
 +                lpitem->hbmpItem == (HBITMAP)HBMMENU_MBAR_MINIMIZE_D)
 +            lpitem->Rect.right -= 1;
 +        }
 +    }
 +    else if (!menuBar) {
 +        if( !(MenuInfo->dwStyle & MNS_NOCHECK))
 +             lpitem->Rect.right += check_bitmap_width;
 +        lpitem->Rect.right += 4 + MenuCharSize.cx;
 +        lpitem->dxTab = lpitem->Rect.right;
 +        lpitem->Rect.right += check_bitmap_width;
 +    }
 +
 +    /* it must be a text item - unless it's the system menu */
 +    if (!(lpitem->fType & MF_SYSMENU) && lpitem->lpstr) {
 +        HFONT hfontOld = NULL;
 +        RECT rc = lpitem->Rect;
 +        LONG txtheight, txtwidth;
 +
 +        if ( lpitem->fState & MFS_DEFAULT ) {
 +            hfontOld = SelectObject( hdc, hMenuFontBold );
 +        }
 +        if (menuBar) {
 +            txtheight = DrawTextW( hdc, lpitem->dwTypeData, -1, &rc,
 +                    DT_SINGLELINE|DT_CALCRECT);
 +            lpitem->Rect.right  += rc.right - rc.left;
 +            itemheight = max( max( itemheight, txtheight),
 +                    GetSystemMetrics( SM_CYMENU) - 1);
 +            lpitem->Rect.right +=  2 * MenuCharSize.cx;
 +        } else {
 +            if ((p = strchrW( lpitem->dwTypeData, '\t' )) != NULL) {
 +                RECT tmprc = rc;
 +                LONG tmpheight;
 +                int n = (int)( p - lpitem->dwTypeData);
 +                /* Item contains a tab (only meaningful in popup menus) */
 +                /* get text size before the tab */
 +                txtheight = DrawTextW( hdc, lpitem->dwTypeData, n, &rc,
 +                        DT_SINGLELINE|DT_CALCRECT);
 +                txtwidth = rc.right - rc.left;
 +                p += 1; /* advance past the Tab */
 +                /* get text size after the tab */
 +                tmpheight = DrawTextW( hdc, p, -1, &tmprc,
 +                        DT_SINGLELINE|DT_CALCRECT);
 +                lpitem->dxTab += txtwidth;
 +                txtheight = max( txtheight, tmpheight);
 +                txtwidth += MenuCharSize.cx + /* space for the tab */
 +                    tmprc.right - tmprc.left; /* space for the short cut */
 +            } else {
 +                txtheight = DrawTextW( hdc, lpitem->dwTypeData, -1, &rc,
 +                        DT_SINGLELINE|DT_CALCRECT);
 +                txtwidth = rc.right - rc.left;
 +                lpitem->dxTab += txtwidth;
 +            }
 +            lpitem->Rect.right  += 2 + txtwidth;
 +            itemheight = max( itemheight,
 +                                  max( txtheight + 2, MenuCharSize.cy + 4));
 +        }
 +        if (hfontOld) SelectObject (hdc, hfontOld);
 +    } else if( menuBar) {
 +        itemheight = max( itemheight, GetSystemMetrics(SM_CYMENU)-1);
 +    }
 +    lpitem->Rect.bottom += itemheight;
 +    TRACE("(%ld,%ld)-(%ld,%ld)\n", lpitem->Rect.left, lpitem->Rect.top, lpitem->Rect.right, lpitem->Rect.bottom);
 +}
 +
 +/***********************************************************************
 + *           MenuPopupMenuCalcSize
 + *
 + * Calculate the size of a popup menu.
 + */
 +static void FASTCALL MenuPopupMenuCalcSize(PROSMENUINFO MenuInfo, HWND WndOwner)
 +{
 +    ROSMENUITEMINFO lpitem;
 +    HDC hdc;
 +    int start, i;
 +    int orgX, orgY, maxX, maxTab, maxTabWidth;
 +
 +    MenuInfo->Width = MenuInfo->Height = 0;
 +    if (MenuInfo->MenuItemCount == 0)
 +    {
 +        MenuSetRosMenuInfo(MenuInfo);
 +        return;
 +    }
 +
 +    hdc = GetDC(NULL);
 +    SelectObject( hdc, hMenuFont );
 +
 +    start = 0;
 +    maxX = 2 + 1;
 +
 +    MenuInfo->maxBmpSize.cx = 0;
 +    MenuInfo->maxBmpSize.cy = 0;
 +
 +    MenuInitRosMenuItemInfo(&lpitem);
 +    while (start < MenuInfo->MenuItemCount)
 +    {
 +      orgX = maxX;
 +      orgY = 2;
 +
 +      maxTab = maxTabWidth = 0;
 +
 +      /* Parse items until column break or end of menu */
 +      for (i = start; i < MenuInfo->MenuItemCount; i++)
 +      {
 +          if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i, &lpitem))
 +          {
 +              MenuCleanupRosMenuItemInfo(&lpitem);
 +              MenuSetRosMenuInfo(MenuInfo);
 +              return;
 +          }
 +          if (i != start &&
 +               (lpitem.fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
 +
 +          MenuCalcItemSize(hdc, &lpitem, MenuInfo, WndOwner, orgX, orgY, FALSE);
 +          if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &lpitem))
 +          {
 +              MenuCleanupRosMenuItemInfo(&lpitem);
 +              MenuSetRosMenuInfo(MenuInfo);
 +              return;
 +          }
 +// Not sure here,, The patch from wine removes this.
 +//        if ((lpitem.fType & MF_MENUBARBREAK) != 0)
 +//        {
 +//              OrgX++;
 +//        }
 +          maxX = max(maxX, lpitem.Rect.right);
 +          orgY = lpitem.Rect.bottom;
 +          if ((lpitem.lpstr) && lpitem.dxTab )
 +            {
 +              maxTab = max( maxTab, lpitem.dxTab );
 +              maxTabWidth = max(maxTabWidth, lpitem.Rect.right - lpitem.dxTab);
 +          }
 +        }
 +
 +        /* Finish the column (set all items to the largest width found) */
 +        maxX = max( maxX, maxTab + maxTabWidth );
 +        while (start < i)
 +        {
 +            if (MenuGetRosMenuItemInfo(MenuInfo->Self, start, &lpitem))
 +            {
 +                lpitem.Rect.right = maxX;
 +                if ((lpitem.lpstr) && 0 != lpitem.dxTab)
 +                {
 +                    lpitem.dxTab = maxTab;
 +                }
 +                MenuSetRosMenuItemInfo(MenuInfo->Self, start, &lpitem);
 +            }
 +            start++;
 +          }
 +        MenuInfo->Height = max(MenuInfo->Height, orgY);
 +    }
 +
 +    MenuInfo->Width  = maxX;
 +
 +    /* space for 3d border */
 +    MenuInfo->Height += 2;
 +    MenuInfo->Width += 2;
 +
 +    MenuCleanupRosMenuItemInfo(&lpitem);
 +    MenuSetRosMenuInfo(MenuInfo);
 +    ReleaseDC( 0, hdc );
 +}
 +
 +/***********************************************************************
 + *           MenuMenuBarCalcSize
 + *
 + * FIXME: Word 6 implements its own MDI and its own 'close window' bitmap
 + * height is off by 1 pixel which causes lengthy window relocations when
 + * active document window is maximized/restored.
 + *
 + * Calculate the size of the menu bar.
 + */
 +static void FASTCALL MenuMenuBarCalcSize( HDC hdc, LPRECT lprect,
 +                                          PROSMENUINFO MenuInfo, HWND hwndOwner )
 +{
 +    ROSMENUITEMINFO ItemInfo;
 +    int start, i, orgX, orgY, maxY, helpPos;
 +
 +    if ((lprect == NULL) || (MenuInfo == NULL)) return;
 +    if (MenuInfo->MenuItemCount == 0) return;
 +    TRACE("left=%ld top=%ld right=%ld bottom=%ld\n", lprect->left, lprect->top, lprect->right, lprect->bottom);
 +    MenuInfo->Width = lprect->right - lprect->left;
 +    MenuInfo->Height = 0;
 +    maxY = lprect->top + 1;
 +    start = 0;
 +    helpPos = -1;
 +
 +    MenuInfo->maxBmpSize.cx = 0;
 +    MenuInfo->maxBmpSize.cy = 0;
 +
 +    MenuInitRosMenuItemInfo(&ItemInfo);
 +    while (start < MenuInfo->MenuItemCount)
 +    {
 +        if (! MenuGetRosMenuItemInfo(MenuInfo->Self, start, &ItemInfo))
 +        {
 +            MenuCleanupRosMenuItemInfo(&ItemInfo);
 +            return;
 +        }
 +        orgX = lprect->left;
 +        orgY = maxY;
 +
 +        /* Parse items until line break or end of menu */
 +        for (i = start; i < MenuInfo->MenuItemCount; i++)
 +          {
 +            if ((helpPos == -1) && (ItemInfo.fType & MF_RIGHTJUSTIFY)) helpPos = i;
 +            if ((i != start) &&
 +               (ItemInfo.fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
 +
 +            TRACE("calling MENU_CalcItemSize org=(%d, %d)\n", orgX, orgY);
 +            MenuCalcItemSize(hdc, &ItemInfo, MenuInfo, hwndOwner, orgX, orgY, TRUE);
 +            if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo))
 +            {
 +                MenuCleanupRosMenuItemInfo(&ItemInfo);
 +                return;
 +            }
 +
 +            if (ItemInfo.Rect.right > lprect->right)
 +            {
 +                if (i != start) break;
 +                else ItemInfo.Rect.right = lprect->right;
 +            }
 +            maxY = max( maxY, ItemInfo.Rect.bottom );
 +            orgX = ItemInfo.Rect.right;
 +            if (i + 1 < MenuInfo->MenuItemCount)
 +            {
 +                if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i + 1, &ItemInfo))
 +                {
 +                    MenuCleanupRosMenuItemInfo(&ItemInfo);
 +                    return;
 +                }
 +            }
 +      }
 +
 +/* FIXME: Is this really needed? */ /*NO! it is not needed, why make the
 +HBMMENU_MBAR_CLOSE, MINIMIZE & RESTORE, look the same size as the menu bar! */
 +#if 0
 +        /* Finish the line (set all items to the largest height found) */
 +        while (start < i)
 +        {
 +            if (MenuGetRosMenuItemInfo(MenuInfo->Self, start, &ItemInfo))
 +            {
 +                ItemInfo.Rect.bottom = maxY;
 +                MenuSetRosMenuItemInfo(MenuInfo->Self, start, &ItemInfo);
 +            }
 +            start++;
 +        }
 +#else
 +        start = i; /* This works! */
 +#endif
 +    }
 +
 +    lprect->bottom = maxY;
 +    MenuInfo->Height = lprect->bottom - lprect->top;
 +    MenuSetRosMenuInfo(MenuInfo);
 +
 +    if (helpPos != -1)
 +    {
 +      /* Flush right all items between the MF_RIGHTJUSTIFY and */
 +      /* the last item (if several lines, only move the last line) */
 +      if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->MenuItemCount - 1, &ItemInfo))
 +      {
 +          MenuCleanupRosMenuItemInfo(&ItemInfo);
 +          return;
 +      }
 +      orgY = ItemInfo.Rect.top;
 +      orgX = lprect->right;
 +      for (i = MenuInfo->MenuItemCount - 1; helpPos <= i; i--)
 +        {
 +          if (i < helpPos)
 +          {
 +              break;                          /* done */
 +          }
 +          if (ItemInfo.Rect.top != orgY)
 +          {
 +              break;                          /* Other line */
 +          }
 +          if (orgX <= ItemInfo.Rect.right)
 +          {
 +              break;                          /* Too far right already */
 +          }
 +          ItemInfo.Rect.left += orgX - ItemInfo.Rect.right;
 +          ItemInfo.Rect.right = orgX;
 +          orgX = ItemInfo.Rect.left;
 +          MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo);
 +          if (helpPos + 1 <= i &&
 +              ! MenuGetRosMenuItemInfo(MenuInfo->Self, i - 1, &ItemInfo))
 +            {
 +                MenuCleanupRosMenuItemInfo(&ItemInfo);
 +                return;
 +            }
 +        }
 +    }
 +
 +    MenuCleanupRosMenuItemInfo(&ItemInfo);
 +}
 +
 +/***********************************************************************
 + *           MenuDrawMenuItem
 + *
 + * Draw a single menu item.
 + */
 +static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND WndOwner, HDC hdc,
 +                 PROSMENUITEMINFO lpitem, UINT Height, BOOL menuBar, UINT odaction)
 +{
 +    RECT rect;
 +    PWCHAR Text;
 +    BOOL flat_menu = FALSE;
 +    int bkgnd;
 +    PWND Wnd = ValidateHwnd(hWnd);
 +
 +    if (!Wnd)
 +      return;
 +
 +    if (lpitem->fType & MF_SYSMENU)
 +    {
 +        if ( (Wnd->style & WS_MINIMIZE))
 +        {
 +          UserGetInsideRectNC(Wnd, &rect);
 +          UserDrawSysMenuButton(hWnd, hdc, &rect,
 +                                lpitem->fState & (MF_HILITE | MF_MOUSESELECT));
 +          }
 +        return;
 +    }
 +
 +    SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0);
 +    bkgnd = (menuBar && flat_menu) ? COLOR_MENUBAR : COLOR_MENU;
 +
 +    /* Setup colors */
 +
 +    if (lpitem->fState & MF_HILITE)
 +    {
 +        if(menuBar && !flat_menu) {
 +            SetTextColor(hdc, GetSysColor(COLOR_MENUTEXT));
 +            SetBkColor(hdc, GetSysColor(COLOR_MENU));
 +        } else {
 +            if (lpitem->fState & MF_GRAYED)
 +                SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
 +            else
 +                SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
 +            SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
 +        }
 +    }
 +    else
 +    {
 +        if (lpitem->fState & MF_GRAYED)
 +            SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) );
 +        else
 +            SetTextColor( hdc, GetSysColor( COLOR_MENUTEXT ) );
 +        SetBkColor( hdc, GetSysColor( bkgnd ) );
 +    }
 +
 +    rect = lpitem->Rect;
 +
 +    if (lpitem->fType & MF_OWNERDRAW)
 +    {
 +        /*
 +        ** Experimentation under Windows reveals that an owner-drawn
 +        ** menu is given the rectangle which includes the space it requested
 +        ** in its response to WM_MEASUREITEM _plus_ width for a checkmark
 +        ** and a popup-menu arrow.  This is the value of lpitem->rect.
 +        ** Windows will leave all drawing to the application except for
 +        ** the popup-menu arrow.  Windows always draws that itself, after
 +        ** the menu owner has finished drawing.
 +        */
 +        DRAWITEMSTRUCT dis;
 +
 +        dis.CtlType   = ODT_MENU;
 +        dis.CtlID     = 0;
 +        dis.itemID    = lpitem->wID;
 +        dis.itemData  = (DWORD)lpitem->dwItemData;
 +        dis.itemState = 0;
 +        if (lpitem->fState & MF_CHECKED) dis.itemState |= ODS_CHECKED;
 +        if (lpitem->fState & MF_GRAYED)  dis.itemState |= ODS_GRAYED | ODS_DISABLED;
 +        if (lpitem->fState & MF_HILITE)  dis.itemState |= ODS_SELECTED;
 +        dis.itemAction = odaction; /* ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; */
 +        dis.hwndItem   = (HWND) MenuInfo->Self;
 +        dis.hDC        = hdc;
 +        dis.rcItem     = rect;
 +        TRACE("Ownerdraw: owner=%p itemID=%d, itemState=%d, itemAction=%d, "
 +              "hwndItem=%p, hdc=%p, rcItem={%ld,%ld,%ld,%ld}\n", hWnd,
 +              dis.itemID, dis.itemState, dis.itemAction, dis.hwndItem,
 +              dis.hDC, dis.rcItem.left, dis.rcItem.top, dis.rcItem.right,
 +              dis.rcItem.bottom);
 +        SendMessageW(WndOwner, WM_DRAWITEM, 0, (LPARAM) &dis);
 +        /* Draw the popup-menu arrow */
 +        if (lpitem->fType & MF_POPUP)
 +        {
 +            RECT rectTemp;
 +            CopyRect(&rectTemp, &rect);
 +            rectTemp.left = rectTemp.right - GetSystemMetrics(SM_CXMENUCHECK);
 +            DrawFrameControl(hdc, &rectTemp, DFC_MENU, DFCS_MENUARROW);
 +        }
 +        return;
 +    }
 +
 +    if (menuBar && (lpitem->fType & MF_SEPARATOR)) return;
 +
 +    if (lpitem->fState & MF_HILITE)
 +    {
 +        if (flat_menu)
 +        {
 +            InflateRect (&rect, -1, -1);
 +            FillRect(hdc, &rect, GetSysColorBrush(COLOR_MENUHILIGHT));
 +            InflateRect (&rect, 1, 1);
 +            FrameRect(hdc, &rect, GetSysColorBrush(COLOR_HIGHLIGHT));
 +        }
 +        else
 +        {
 +            if(menuBar)
 +                DrawEdge(hdc, &rect, BDR_SUNKENOUTER, BF_RECT);
 +            else
 +                FillRect(hdc, &rect, GetSysColorBrush(COLOR_HIGHLIGHT));
 +        }
 +    }
 +    else
 +        FillRect( hdc, &rect, GetSysColorBrush(bkgnd) );
 +
 +    SetBkMode( hdc, TRANSPARENT );
 +
 +    /* vertical separator */
 +    if (!menuBar && (lpitem->fType & MF_MENUBARBREAK))
 +    {
 +        HPEN oldPen;
 +        RECT rc = rect;
 +
 +        rc.left -= 3;
 +        rc.top = 3;
 +        rc.bottom = Height - 3;
 +        if (flat_menu)
 +        {
 +            oldPen = SelectObject( hdc, GetStockObject(DC_PEN) );
 +            SetDCPenColor(hdc, GetSysColor(COLOR_BTNSHADOW));
 +            MoveToEx( hdc, rc.left, rc.top, NULL );
 +            LineTo( hdc, rc.left, rc.bottom );
 +            SelectObject( hdc, oldPen );
 +        }
 +        else
 +            DrawEdge (hdc, &rc, EDGE_ETCHED, BF_LEFT);
 +    }
 +
 +    /* horizontal separator */
 +    if (lpitem->fType & MF_SEPARATOR)
 +    {
 +        HPEN oldPen;
 +        RECT rc = rect;
 +
 +        rc.left++;
 +        rc.right--;
 +        rc.top += SEPARATOR_HEIGHT / 2;
 +        if (flat_menu)
 +        {
 +            oldPen = SelectObject( hdc, GetStockObject(DC_PEN) );
 +            SetDCPenColor( hdc, GetSysColor(COLOR_BTNSHADOW));
 +            MoveToEx( hdc, rc.left, rc.top, NULL );
 +            LineTo( hdc, rc.right, rc.top );
 +            SelectObject( hdc, oldPen );
 +        }
 +        else
 +            DrawEdge (hdc, &rc, EDGE_ETCHED, BF_TOP);
 +        return;
 +    }
 +
 +#if 0
 +    /* helper lines for debugging */
 +    /* This is a very good test tool when hacking menus! (JT) 07/16/2006 */
 +    FrameRect(hdc, &rect, GetStockObject(BLACK_BRUSH));
 +    SelectObject(hdc, GetStockObject(DC_PEN));
 +    SetDCPenColor(hdc, GetSysColor(COLOR_WINDOWFRAME));
 +    MoveToEx(hdc, rect.left, (rect.top + rect.bottom) / 2, NULL);
 +    LineTo(hdc, rect.right, (rect.top + rect.bottom) / 2);
 +#endif
 +
 +    if (!menuBar)
 +    {
 +        HBITMAP bm;
 +        INT y = rect.top + rect.bottom;
 +        RECT rc = rect;
 +        int checked = FALSE;
 +        UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK );
 +        UINT check_bitmap_height = GetSystemMetrics( SM_CYMENUCHECK );
 +        /* Draw the check mark
 +         *
 +         * FIXME:
 +         * Custom checkmark bitmaps are monochrome but not always 1bpp.
 +         */
 +        if( !(MenuInfo->dwStyle & MNS_NOCHECK)) {
 +            bm = (lpitem->fState & MF_CHECKED) ? lpitem->hbmpChecked :
 +                lpitem->hbmpUnchecked;
 +            if (bm)  /* we have a custom bitmap */
 +            {
 +                HDC hdcMem = CreateCompatibleDC( hdc );
 +
 +                SelectObject( hdcMem, bm );
 +                BitBlt( hdc, rc.left, (y - check_bitmap_height) / 2,
 +                        check_bitmap_width, check_bitmap_height,
 +                        hdcMem, 0, 0, SRCCOPY );
 +                DeleteDC( hdcMem );
 +                checked = TRUE;
 +            }
 +            else if (lpitem->fState & MF_CHECKED) /* standard bitmaps */
 +            {
 +                RECT r;
 +                CopyRect(&r, &rect);
 +                r.right = r.left + GetSystemMetrics(SM_CXMENUCHECK);
 +                DrawFrameControl( hdc, &r, DFC_MENU,
 +                                 (lpitem->fType & MFT_RADIOCHECK) ?
 +                                 DFCS_MENUBULLET : DFCS_MENUCHECK);
 +                checked = TRUE;
 +            }
 +        }
 +        if ( lpitem->hbmpItem )
 +        {
 +            RECT bmpRect;
 +            CopyRect(&bmpRect, &rect);
 +            if (!(MenuInfo->dwStyle & MNS_CHECKORBMP) && !(MenuInfo->dwStyle & MNS_NOCHECK))
 +                bmpRect.left += check_bitmap_width + 2;
 +            if (!(checked && (MenuInfo->dwStyle & MNS_CHECKORBMP)))
 +            {
 +                bmpRect.right = bmpRect.left + MenuInfo->maxBmpSize.cx;
 +                MenuDrawBitmapItem(hdc, lpitem, &bmpRect, MenuInfo->Self, WndOwner, odaction, menuBar);
 +            }
 +        }
 +        /* Draw the popup-menu arrow */
 +        if (lpitem->fType & MF_POPUP)
 +        {
 +            RECT rectTemp;
 +            CopyRect(&rectTemp, &rect);
 +            rectTemp.left = rectTemp.right - GetSystemMetrics(SM_CXMENUCHECK);
 +            DrawFrameControl(hdc, &rectTemp, DFC_MENU, DFCS_MENUARROW);
 +        }
 +        rect.left += 4;
 +        if( !(MenuInfo->dwStyle & MNS_NOCHECK))
 +            rect.left += check_bitmap_width;
 +        rect.right -= check_bitmap_width;
 +    }
 +    else if( lpitem->hbmpItem)
 +    { /* Draw the bitmap */
 +        MenuDrawBitmapItem(hdc, lpitem, &rect, MenuInfo->Self, WndOwner, odaction, menuBar);
 +    }
 +
 +    /* process text if present */
 +    if (lpitem->lpstr)
 +    {
 +        register int i = 0;
 +        HFONT hfontOld = 0;
 +
 +        UINT uFormat = menuBar ? DT_CENTER | DT_VCENTER | DT_SINGLELINE
 +                       : DT_LEFT | DT_VCENTER | DT_SINGLELINE;
 +
 +        if(MenuInfo->dwStyle & MNS_CHECKORBMP)
 +             rect.left += max(0, MenuInfo->maxBmpSize.cx - GetSystemMetrics(SM_CXMENUCHECK));
 +        else
 +             rect.left += MenuInfo->maxBmpSize.cx;
 +
 +        if ( lpitem->fState & MFS_DEFAULT )
 +        {
 +            hfontOld = SelectObject(hdc, hMenuFontBold);
 +        }
 +
 +        if (menuBar) {
 +            rect.left += MENU_BAR_ITEMS_SPACE / 2;
 +            rect.right -= MENU_BAR_ITEMS_SPACE / 2;
 +        }
 +
 +        Text = (PWCHAR) lpitem->dwTypeData;
 +        if(Text)
 +        {
 +            for (i = 0; L'\0' != Text[i]; i++)
 +                if (Text[i] == L'\t' || Text[i] == L'\b')
 +                    break;
 +        }
 +
 +        if(lpitem->fState & MF_GRAYED)
 +        {
 +            if (!(lpitem->fState & MF_HILITE) )
 +            {
 +                ++rect.left; ++rect.top; ++rect.right; ++rect.bottom;
 +                SetTextColor(hdc, RGB(0xff, 0xff, 0xff));
 +                DrawTextW( hdc, Text, i, &rect, uFormat );
 +                --rect.left; --rect.top; --rect.right; --rect.bottom;
 +              }
 +            SetTextColor(hdc, RGB(0x80, 0x80, 0x80));
 +        }
 +
 +        DrawTextW( hdc, Text, i, &rect, uFormat);
 +
 +        /* paint the shortcut text */
 +        if (!menuBar && L'\0' != Text[i])  /* There's a tab or flush-right char */
 +        {
 +            if (L'\t' == Text[i])
 +            {
 +                rect.left = lpitem->dxTab;
 +                uFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
 +            }
 +            else
 +            {
 +                rect.right = lpitem->dxTab;
 +                uFormat = DT_RIGHT | DT_VCENTER | DT_SINGLELINE;
 +            }
 +
 +            if (lpitem->fState & MF_GRAYED)
 +            {
 +                if (!(lpitem->fState & MF_HILITE) )
 +                {
 +                    ++rect.left; ++rect.top; ++rect.right; ++rect.bottom;
 +                    SetTextColor(hdc, RGB(0xff, 0xff, 0xff));
 +                    DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat);
 +                    --rect.left; --rect.top; --rect.right; --rect.bottom;
 +                }
 +                SetTextColor(hdc, RGB(0x80, 0x80, 0x80));
 +              }
 +          DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat );
 +        }
 +
 +        if (hfontOld)
 +          SelectObject (hdc, hfontOld);
 +    }
 +}
 +
 +/***********************************************************************
 + *           MenuDrawPopupMenu
 + *
 + * Paint a popup menu.
 + */
 +static void FASTCALL MenuDrawPopupMenu(HWND hwnd, HDC hdc, HMENU hmenu )
 +{
 +    HBRUSH hPrevBrush = 0;
 +    RECT rect;
 +
 +    TRACE("wnd=%p dc=%p menu=%p\n", hwnd, hdc, hmenu);
 +
 +    GetClientRect( hwnd, &rect );
 +
 +    if((hPrevBrush = SelectObject( hdc, GetSysColorBrush(COLOR_MENU) ))
 +        && (SelectObject( hdc, hMenuFont)))
 +    {
 +        HPEN hPrevPen;
 +
 +        Rectangle( hdc, rect.left, rect.top, rect.right, rect.bottom );
 +
 +        hPrevPen = SelectObject( hdc, GetStockObject( NULL_PEN ) );
 +        if ( hPrevPen )
 +        {
 +            BOOL flat_menu = FALSE;
 +            ROSMENUINFO MenuInfo;
 +            ROSMENUITEMINFO ItemInfo;
 +
 +            SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0);
 +            if (flat_menu)
 +               FrameRect(hdc, &rect, GetSysColorBrush(COLOR_BTNSHADOW));
 +            else
 +               DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT);
 +
 +            /* draw menu items */
 +            if (MenuGetRosMenuInfo(&MenuInfo, hmenu) && MenuInfo.MenuItemCount)
 +            {
 +                UINT u;
 +
 +                              MenuInitRosMenuItemInfo(&ItemInfo);
 +
 +                for (u = 0; u < MenuInfo.MenuItemCount; u++)
 +                {
 +                    if (MenuGetRosMenuItemInfo(MenuInfo.Self, u, &ItemInfo))
 +                    {
 +                        MenuDrawMenuItem(hwnd, &MenuInfo, MenuInfo.WndOwner, hdc, &ItemInfo,
 +                        MenuInfo.Height, FALSE, ODA_DRAWENTIRE);
 +                    }
 +                }
 +
 +                MenuCleanupRosMenuItemInfo(&ItemInfo);
 +            }
 +         } else
 +         {
 +             SelectObject( hdc, hPrevBrush );
 +         }
 +    }
 +}
 +
 +/***********************************************************************
 + *           MenuDrawMenuBar
 + *
 + * Paint a menu bar. Returns the height of the menu bar.
 + * called from [windows/nonclient.c]
 + */
 +UINT MenuDrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd,
 +                         BOOL suppress_draw)
 +{
 +    ROSMENUINFO lppop;
 +    HFONT hfontOld = 0;
 +    HMENU hMenu = GetMenu(hwnd);
 +
 +    if (! MenuGetRosMenuInfo(&lppop, hMenu) || lprect == NULL)
 +    {
 +        return GetSystemMetrics(SM_CYMENU);
 +    }
 +
 +    if (suppress_draw)
 +    {
 +        hfontOld = SelectObject(hDC, hMenuFont);
 +
 +        MenuMenuBarCalcSize(hDC, lprect, &lppop, hwnd);
 +
 +        lprect->bottom = lprect->top + lppop.Height;
 +
 +        if (hfontOld) SelectObject( hDC, hfontOld);
 +        return lppop.Height;
 +    }
 +      else
 +        return DrawMenuBarTemp(hwnd, hDC, lprect, hMenu, NULL);
 +}
 +
 +/***********************************************************************
 + *           MenuShowPopup
 + *
 + * Display a popup menu.
 + */
 +static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT flags,
 +                              INT x, INT y, INT xanchor, INT yanchor )
 +{
 +    ROSMENUINFO MenuInfo;
 +    ROSMENUITEMINFO ItemInfo;
 +    UINT width, height;
 +    POINT pt;
 +    HMONITOR monitor;
 +    MONITORINFO info;
 +
 +    TRACE("owner=%p hmenu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n",
 +          hwndOwner, hmenu, id, x, y, xanchor, yanchor);
 +
 +    if (! MenuGetRosMenuInfo(&MenuInfo, hmenu)) return FALSE;
 +    if (MenuInfo.FocusedItem != NO_SELECTED_ITEM)
 +    {
 +        MenuInitRosMenuItemInfo(&ItemInfo);
 +        if (MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo))
 +        {
 +            ItemInfo.fMask |= MIIM_STATE;
 +            ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT);
 +            MenuSetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo);
 +        }
 +        MenuCleanupRosMenuItemInfo(&ItemInfo);
 +        MenuInfo.FocusedItem = NO_SELECTED_ITEM;
 +    }
 +
 +    /* store the owner for DrawItem */
 +    MenuInfo.WndOwner = hwndOwner;
 +    MenuSetRosMenuInfo(&MenuInfo);
 +
 +    MenuPopupMenuCalcSize(&MenuInfo, hwndOwner);
 +
 +    /* adjust popup menu pos so that it fits within the desktop */
 +
 +    width = MenuInfo.Width + GetSystemMetrics(SM_CXBORDER);
 +    height = MenuInfo.Height + GetSystemMetrics(SM_CYBORDER);
 +
 +    /* FIXME: should use item rect */
 +    pt.x = x;
 +    pt.y = y;
 +    monitor = MonitorFromPoint( pt, MONITOR_DEFAULTTONEAREST );
 +    info.cbSize = sizeof(info);
 +    GetMonitorInfoW( monitor, &info );
 +
 +    if( flags & TPM_RIGHTALIGN ) x -= width;
 +    if( flags & TPM_CENTERALIGN ) x -= width / 2;
 +
 +    if( flags & TPM_BOTTOMALIGN ) y -= height;
 +    if( flags & TPM_VCENTERALIGN ) y -= height / 2;
 +
 +    if( x + width > info.rcMonitor.right)
 +    {
 +        if( xanchor && x >= width - xanchor )
 +            x -= width - xanchor;
 +
 +        if( x + width > info.rcMonitor.right)
 +            x = info.rcMonitor.right - width;
 +    }
 +    if( x < info.rcMonitor.left ) x = info.rcMonitor.left;
 +
 +    if( y + height > info.rcMonitor.bottom)
 +    {
 +        if( yanchor && y >= height + yanchor )
 +            y -= height + yanchor;
 +
 +        if( y + height > info.rcMonitor.bottom)
 +            y = info.rcMonitor.bottom - height;
 +    }
 +    if( y < info.rcMonitor.top ) y = info.rcMonitor.top;
 +
 +    /* NOTE: In Windows, top menu popup is not owned. */
 +    MenuInfo.Wnd = CreateWindowExW( 0, WC_MENU, NULL,
 +                                  WS_POPUP, x, y, width, height,
 +                                  hwndOwner, 0, (HINSTANCE) GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE),
 +                                 (LPVOID) MenuInfo.Self);
 +    if ( !MenuInfo.Wnd || ! MenuSetRosMenuInfo(&MenuInfo)) return FALSE;
 +    if (!top_popup) {
 +        top_popup = MenuInfo.Wnd;
 +        top_popup_hmenu = hmenu;
 +    }
 +
 +    IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPSTART, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
 +
 +    /* Display the window */
 +
 +    SetWindowPos( MenuInfo.Wnd, HWND_TOPMOST, 0, 0, 0, 0,
 +                  SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
 +    UpdateWindow( MenuInfo.Wnd );
 +    return TRUE;
 +}
 +
 +
 +/***********************************************************************
 + *           MenuSelectItem
 + */
 +static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIndex,
 +                                    BOOL sendMenuSelect, HMENU topmenu)
 +{
 +    ROSMENUITEMINFO ItemInfo;
 +    ROSMENUINFO TopMenuInfo;
 +    HDC hdc;
 +
 +    TRACE("owner=%p menu=%p index=0x%04x select=0x%04x\n", hwndOwner, hmenu, wIndex, sendMenuSelect);
 +
 +     if (!hmenu || !hmenu->MenuItemCount || !hmenu->Wnd) return;
 +    if (hmenu->FocusedItem == wIndex) return;
 +    if (hmenu->Flags & MF_POPUP) hdc = GetDC(hmenu->Wnd);
 +    else hdc = GetDCEx(hmenu->Wnd, 0, DCX_CACHE | DCX_WINDOW);
 +    if (!top_popup) {
 +        top_popup = hmenu->Wnd;
 +        top_popup_hmenu = hmenu->Self;
 +    }
 +
 +    SelectObject( hdc, hMenuFont );
 +
 +    MenuInitRosMenuItemInfo(&ItemInfo);
 +
 +     /* Clear previous highlighted item */
 +    if (hmenu->FocusedItem != NO_SELECTED_ITEM)
 +    {
 +        if (MenuGetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo))
 +        {
 +            ItemInfo.fMask |= MIIM_STATE;
 +            ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT);
 +            MenuSetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo);
 +        }
 +        MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc, &ItemInfo,
 +                       hmenu->Height, ! (hmenu->Flags & MF_POPUP),
 +                       ODA_SELECT);
 +    }
 +
 +    /* Highlight new item (if any) */
 +    hmenu->FocusedItem = wIndex;
 +    MenuSetRosMenuInfo(hmenu);
 +    if (hmenu->FocusedItem != NO_SELECTED_ITEM)
 +    {
 +        if (MenuGetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo))
 +        {
 +            if (!(ItemInfo.fType & MF_SEPARATOR))
 +            {
 +                ItemInfo.fMask |= MIIM_STATE;
 +                ItemInfo.fState |= MF_HILITE;
 +                MenuSetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo);
 +                MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc,
 +                               &ItemInfo, hmenu->Height, ! (hmenu->Flags & MF_POPUP),
 +                               ODA_SELECT);
 +            }
 +            if (sendMenuSelect)
 +            {
 +                SendMessageW(hwndOwner, WM_MENUSELECT,
 +                           MAKELONG(ItemInfo.fType & MF_POPUP ? wIndex : ItemInfo.wID,
 +                                    ItemInfo.fType | ItemInfo.fState | MF_MOUSESELECT |
 +                                    (hmenu->Flags & MF_SYSMENU)), (LPARAM) hmenu->Self);
 +            }
 +        }
 +    }
 +    else if (sendMenuSelect) {
 +        if(topmenu) {
 +            int pos;
 +            pos = MenuFindSubMenu(&topmenu, hmenu->Self);
 +            if (pos != NO_SELECTED_ITEM)
 +            {
 +                if (MenuGetRosMenuInfo(&TopMenuInfo, topmenu)
 +                    && MenuGetRosMenuItemInfo(topmenu, pos, &ItemInfo))
 +                {
 +                    SendMessageW(hwndOwner, WM_MENUSELECT,
 +                               MAKELONG(Pos, ItemInfo.fType | ItemInfo.fState
 +                                             | MF_MOUSESELECT
 +                                             | (TopMenuInfo.Flags & MF_SYSMENU)),
 +                               (LPARAM) topmenu);
 +                }
 +            }
 +        }
 +    }
 +    MenuCleanupRosMenuItemInfo(&ItemInfo);
 +    ReleaseDC(hmenu->Wnd, hdc);
 +}
 +
 +/***********************************************************************
 + *           MenuMoveSelection
 + *
 + * Moves currently selected item according to the Offset parameter.
 + * If there is no selection then it should select the last item if
 + * Offset is ITEM_PREV or the first item if Offset is ITEM_NEXT.
 + */
 +static void FASTCALL
 +MenuMoveSelection(HWND WndOwner, PROSMENUINFO MenuInfo, INT Offset)
 +{
 +  INT i;
 +  ROSMENUITEMINFO ItemInfo;
 +  INT OrigPos;
 +
 +  TRACE("hwnd=%x menu=%x off=0x%04x\n", WndOwner, MenuInfo, Offset);
 +
 +  /* Prevent looping */
 +  if (0 == MenuInfo->MenuItemCount || 0 == Offset)
 +    return;
 +  else if (Offset < -1)
 +    Offset = -1;
 +  else if (Offset > 1)
 +    Offset = 1;
 +
 +  MenuInitRosMenuItemInfo(&ItemInfo);
 +
 +  OrigPos = MenuInfo->FocusedItem;
 +  if (OrigPos == NO_SELECTED_ITEM) /* NO_SELECTED_ITEM is not -1 ! */
 +    {
 +       OrigPos = 0;
 +       i = -1;
 +    }
 +  else
 +    {
 +      i = MenuInfo->FocusedItem;
 +    }
 +
 +  do
 +    {
 +      /* Step */
 +      i += Offset;
 +      /* Clip and wrap around */
 +      if (i < 0)
 +        {
 +          i = MenuInfo->MenuItemCount - 1;
 +        }
 +      else if (i >= MenuInfo->MenuItemCount)
 +        {
 +          i = 0;
 +        }
 +      /* If this is a good candidate; */
 +      if (MenuGetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo) &&
 +          0 == (ItemInfo.fType & MF_SEPARATOR))
 +        {
 +          MenuSelectItem(WndOwner, MenuInfo, i, TRUE, NULL);
 +          MenuCleanupRosMenuItemInfo(&ItemInfo);
 +          return;
 +        }
 +    } while (i != OrigPos);
 +
 +  /* Not found */
 +  MenuCleanupRosMenuItemInfo(&ItemInfo);
 +}
 +
++//
++// This breaks some test results. Should handle A2U if called!
++//
 +LRESULT WINAPI PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam)
 +{
 +  TRACE("YES! hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam);
++#ifdef __REACTOS__
++  PWND pWnd;
++
++  pWnd = ValidateHwnd(Wnd);
++  if (pWnd)
++  {
++     if (!pWnd->fnid)
++     {
++        NtUserSetWindowFNID(Wnd, FNID_MENU);
++     }
++  }    
++#endif    
 +
 +  switch(Message)
 +    {
 +    case WM_CREATE:
 +      {
 +        CREATESTRUCTA *cs = (CREATESTRUCTA *) lParam;
 +        SetWindowLongPtrA(Wnd, 0, (LONG_PTR)cs->lpCreateParams);
 +        return 0;
 +      }
 +
 +    case WM_MOUSEACTIVATE:  /* We don't want to be activated */
 +      return MA_NOACTIVATE;
 +
 +    case WM_PAINT:
 +      {
 +        PAINTSTRUCT ps;
 +        BeginPaint(Wnd, &ps);
 +        MenuDrawPopupMenu(Wnd, ps.hdc, (HMENU)GetWindowLongPtrA(Wnd, 0));
 +        EndPaint(Wnd, &ps);
 +        return 0;
 +      }
 +
 +    case WM_PRINTCLIENT:
 +      {
 +        MenuDrawPopupMenu( Wnd, (HDC)wParam,
 +                                (HMENU)GetWindowLongPtrW( Wnd, 0 ) );
 +        return 0;
 +      }
 +
 +    case WM_ERASEBKGND:
 +      return 1;
 +
 +    case WM_DESTROY:
 +      /* zero out global pointer in case resident popup window was destroyed. */
 +      if (Wnd == top_popup)
 +        {
 +          top_popup = NULL;
 +          top_popup_hmenu = NULL;
 +        }
++#ifdef __REACTOS__
++      NtUserSetWindowFNID(Wnd, FNID_DESTROY);
++#endif
 +      break;
 +
 +    case WM_SHOWWINDOW:
 +      if (0 != wParam)
 +        {
 +          if (0 == GetWindowLongPtrA(Wnd, 0))
 +            {
 +              OutputDebugStringA("no menu to display\n");
 +            }
 +        }
 +      else
 +        {
 +          SetWindowLongPtrA(Wnd, 0, 0);
 +        }
 +      break;
 +
 +    case MM_SETMENUHANDLE:
 +      SetWindowLongPtrA(Wnd, 0, wParam);
 +      break;
 +
 +    case MM_GETMENUHANDLE:
 +    case MN_GETHMENU:
 +      return GetWindowLongPtrA(Wnd, 0);
 +
 +    default:
 +      return DefWindowProcA(Wnd, Message, wParam, lParam);
 +    }
 +  return 0;
 +}
 +
 +LRESULT WINAPI
 +PopupMenuWndProcW(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam)
 +{
 +  TRACE("hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam);
++#ifdef __REACTOS__ // Do this now, remove after Server side is fixed.
++  PWND pWnd;
++
++  pWnd = ValidateHwnd(Wnd);
++  if (pWnd)
++  {
++     if (!pWnd->fnid)
++     {
++        NtUserSetWindowFNID(Wnd, FNID_MENU);
++     }
++  }    
++#endif    
 +
 +  switch(Message)
 +    {
 +    case WM_CREATE:
 +      {
 +        CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam;
 +        SetWindowLongPtrW(Wnd, 0, (LONG_PTR)cs->lpCreateParams);
 +        return 0;
 +      }
 +
 +    case WM_MOUSEACTIVATE:  /* We don't want to be activated */
 +      return MA_NOACTIVATE;
 +
 +    case WM_PAINT:
 +      {
 +        PAINTSTRUCT ps;
 +        BeginPaint(Wnd, &ps);
 +        MenuDrawPopupMenu(Wnd, ps.hdc, (HMENU)GetWindowLongPtrW(Wnd, 0));
 +        EndPaint(Wnd, &ps);
 +        return 0;
 +      }
 +
 +    case WM_PRINTCLIENT:
 +      {
 +         MenuDrawPopupMenu( Wnd, (HDC)wParam,
 +                                (HMENU)GetWindowLongPtrW( Wnd, 0 ) );
 +         return 0;
 +      }
 +
 +    case WM_ERASEBKGND:
 +      return 1;
 +
 +    case WM_DESTROY:
 +      /* zero out global pointer in case resident popup window was destroyed. */
 +      if (Wnd == top_popup)
 +        {
 +          top_popup = NULL;
 +          top_popup_hmenu = NULL;
 +        }
++#ifdef __REACTOS__
++      NtUserSetWindowFNID(Wnd, FNID_DESTROY);
++#endif
 +      break;
 +
 +    case WM_SHOWWINDOW:
 +      if (0 != wParam)
 +        {
 +          if (0 == GetWindowLongPtrW(Wnd, 0))
 +            {
 +              OutputDebugStringA("no menu to display\n");
 +            }
 +        }
 +      else
 +        {
 +          SetWindowLongPtrW(Wnd, 0, 0);
 +        }
 +      break;
 +
 +    case MM_SETMENUHANDLE:
 +      SetWindowLongPtrW(Wnd, 0, wParam);
 +      break;
 +
 +    case MM_GETMENUHANDLE:
 +    case MN_GETHMENU:
 +      return GetWindowLongPtrW(Wnd, 0);
 +
 +    default:
 +      return DefWindowProcW(Wnd, Message, wParam, lParam);
 +    }
 +
 +  return 0;
 +}
 +
 +/**********************************************************************
 + *         MENU_ParseResource
 + *
 + * Parse a standard menu resource and add items to the menu.
 + * Return a pointer to the end of the resource.
 + *
 + * NOTE: flags is equivalent to the mtOption field
 + */
 +static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
 +{
 +    WORD flags, id = 0;
 +    HMENU hSubMenu;
 +    LPCSTR str;
 +    BOOL end = FALSE;
 +
 +    do
 +    {
 +        flags = GET_WORD(res);
 +
 +        /* remove MF_END flag before passing it to AppendMenu()! */
 +        end = (flags & MF_END);
 +        if(end) flags ^= MF_END;
 +
 +        res += sizeof(WORD);
 +        if(!(flags & MF_POPUP))
 +        {
 +            id = GET_WORD(res);
 +            res += sizeof(WORD);
 +        }
 +        str = res;
 +        if(!unicode)
 +            res += strlen(str) + 1;
 +        else
 +            res += (strlenW((LPCWSTR)str) + 1) * sizeof(WCHAR);
 +        if (flags & MF_POPUP)
 +        {
 +            hSubMenu = CreatePopupMenu();
 +            if(!hSubMenu) return NULL;
 +            if(!(res = MENU_ParseResource(res, hSubMenu, unicode)))
 +                return NULL;
 +            if(!unicode)
 +                AppendMenuA(hMenu, flags, (UINT)hSubMenu, str);
 +            else
 +                AppendMenuW(hMenu, flags, (UINT)hSubMenu, (LPCWSTR)str);
 +        }
 +        else  /* Not a popup */
 +        {
 +            if(!unicode)
 +            {
 +                if (*str == 0)
 +                    flags = MF_SEPARATOR;
 +            }
 +            else
 +            {
 +                if (*(LPCWSTR)str == 0)
 +                    flags = MF_SEPARATOR;
 +            }
 +
 +            if (flags & MF_SEPARATOR)
 +            {
 +                if (!(flags & (MF_GRAYED | MF_DISABLED)))
 +                    flags |= MF_GRAYED | MF_DISABLED;
 +            }
 +
 +            if(!unicode)
 +                AppendMenuA(hMenu, flags, id, *str ? str : NULL);
 +            else
 +                AppendMenuW(hMenu, flags, id,
 +                    *(LPCWSTR)str ? (LPCWSTR)str : NULL);
 +        }
 +    } while(!end);
 +    return res;
 +}
 +
 +
 +/**********************************************************************
 + *         MENUEX_ParseResource
 + *
 + * Parse an extended menu resource and add items to the menu.
 + * Return a pointer to the end of the resource.
 + */
 +static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu)
 +{
 +    WORD resinfo;
 +    do {
 +        MENUITEMINFOW mii;
 +
 +        mii.cbSize = sizeof(mii);
 +        mii.fMask = MIIM_STATE | MIIM_ID | MIIM_FTYPE;
 +        mii.fType = GET_DWORD(res);
 +        res += sizeof(DWORD);
 +        mii.fState = GET_DWORD(res);
 +        res += sizeof(DWORD);
 +        mii.wID = GET_DWORD(res);
 +        res += sizeof(DWORD);
 +        resinfo = GET_WORD(res);
 +        res += sizeof(WORD);
 +        /* Align the text on a word boundary.  */
 +        res += (~((UINT_PTR)res - 1)) & 1;
 +        mii.dwTypeData = (LPWSTR) res;
 +        res += (1 + strlenW(mii.dwTypeData)) * sizeof(WCHAR);
 +        /* Align the following fields on a dword boundary.  */
 +        res += (~((UINT_PTR)res - 1)) & 3;
 +
 +        TRACE("Menu item: [%08x,%08x,%04x,%04x,%S]\n",
 +              mii.fType, mii.fState, mii.wID, resinfo, mii.dwTypeData);
 +
 +              if (resinfo & 1) { /* Pop-up? */
 +            /* DWORD helpid = GET_DWORD(res); FIXME: use this.  */
 +            res += sizeof(DWORD);
 +            mii.hSubMenu = CreatePopupMenu();
 +            if (!mii.hSubMenu)
 +                return NULL;
 +            if (!(res = MENUEX_ParseResource(res, mii.hSubMenu))) {
 +                DestroyMenu(mii.hSubMenu);
 +                return NULL;
 +            }
 +            mii.fMask |= MIIM_SUBMENU;
 +            mii.fType |= MF_POPUP;
 +            mii.wID = (UINT) mii.hSubMenu;
 +        }
 +        else if(!*mii.dwTypeData && !(mii.fType & MF_SEPARATOR))
 +        {
 +            mii.fType |= MF_SEPARATOR;
 +        }
 +        InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii);
 +    } while (!(resinfo & MF_END));
 +    return res;
 +}
 +
 +NTSTATUS WINAPI
 +User32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength)
 +{
 +  HMENU hmenu = LoadMenuW(User32Instance, L"SYSMENU");
 +  LRESULT Result = (LRESULT)hmenu;
 +  MENUINFO menuinfo = {0};
 +  MENUITEMINFOW info = {0};
 +
 +  // removing space for checkboxes from menu
 +  menuinfo.cbSize = sizeof(menuinfo);
 +  menuinfo.fMask = MIM_STYLE;
 +  GetMenuInfo(hmenu, &menuinfo);
 +  menuinfo.dwStyle |= MNS_NOCHECK;
 +  SetMenuInfo(hmenu, &menuinfo);
 +
 +  // adding bitmaps to menu items
 +  info.cbSize = sizeof(info);
 +  info.fMask |= MIIM_BITMAP;
 +  info.hbmpItem = HBMMENU_POPUP_MINIMIZE;
 +  SetMenuItemInfoW(hmenu, SC_MINIMIZE, FALSE, &info);
 +  info.hbmpItem = HBMMENU_POPUP_RESTORE;
 +  SetMenuItemInfoW(hmenu, SC_RESTORE, FALSE, &info);
 +  info.hbmpItem = HBMMENU_POPUP_MAXIMIZE;
 +  SetMenuItemInfoW(hmenu, SC_MAXIMIZE, FALSE, &info);
 +  info.hbmpItem = HBMMENU_POPUP_CLOSE;
 +  SetMenuItemInfoW(hmenu, SC_CLOSE, FALSE, &info);
 +
 +  return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
 +}
 +
 +
 +BOOL
 +MenuInit(VOID)
 +{
 +  NONCLIENTMETRICSW ncm;
 +
 +  /* get the menu font */
 +  if(!hMenuFont || !hMenuFontBold)
 +  {
 +    ncm.cbSize = sizeof(ncm);
 +    if(!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0))
 +    {
 +      DbgPrint("MenuInit(): SystemParametersInfoW(SPI_GETNONCLIENTMETRICS) failed!\n");
 +      return FALSE;
 +    }
 +
 +    hMenuFont = CreateFontIndirectW(&ncm.lfMenuFont);
 +    if(hMenuFont == NULL)
 +    {
 +      DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFont) failed!\n");
 +      return FALSE;
 +    }
 +
 +    ncm.lfMenuFont.lfWeight = max(ncm.lfMenuFont.lfWeight + 300, 1000);
 +    hMenuFontBold = CreateFontIndirectW(&ncm.lfMenuFont);
 +    if(hMenuFontBold == NULL)
 +    {
 +      DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFontBold) failed!\n");
 +      DeleteObject(hMenuFont);
 +      hMenuFont = NULL;
 +      return FALSE;
 +    }
 +  }
 +
 +  return TRUE;
 +}
 +
 +VOID
 +MenuCleanup(VOID)
 +{
 +  if (hMenuFont)
 +  {
 +    DeleteObject(hMenuFont);
 +    hMenuFont = NULL;
 +  }
 +
 +  if (hMenuFontBold)
 +  {
 +    DeleteObject(hMenuFontBold);
 +    hMenuFontBold = NULL;
 +  }
 +}
 +
 +/***********************************************************************
 + *           DrawMenuBarTemp   (USER32.@)
 + *
 + * UNDOCUMENTED !!
 + *
 + * called by W98SE desk.cpl Control Panel Applet
 + *
 + * Not 100% sure about the param names, but close.
 + *
 + * @implemented
 + */
 +DWORD WINAPI
 +DrawMenuBarTemp(HWND Wnd, HDC DC, LPRECT Rect, HMENU Menu, HFONT Font)
 +{
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUITEMINFO ItemInfo;
 +  UINT i;
 +  HFONT FontOld = NULL;
 +  BOOL flat_menu = FALSE;
 +
 +  SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0);
 +
 +  if (NULL == Menu)
 +    {
 +      Menu = GetMenu(Wnd);
 +    }
 +
 +  if (NULL == Font)
 +    {
 +      Font = hMenuFont;
 +    }
 +
 +  if (NULL == Rect || ! MenuGetRosMenuInfo(&MenuInfo, Menu))
 +    {
 +      return GetSystemMetrics(SM_CYMENU);
 +    }
 +
 +  TRACE("(%x, %x, %p, %x, %x)\n", Wnd, DC, Rect, Menu, Font);
 +
 +  FontOld = SelectObject(DC, Font);
 +
 +  if (0 == MenuInfo.Height)
 +    {
 +      MenuMenuBarCalcSize(DC, Rect, &MenuInfo, Wnd);
 +    }
 +
 +  Rect->bottom = Rect->top + MenuInfo.Height;
 +
 +  FillRect(DC, Rect, GetSysColorBrush(flat_menu ? COLOR_MENUBAR : COLOR_MENU));
 +
 +  SelectObject(DC, GetStockObject(DC_PEN));
 +  SetDCPenColor(DC, GetSysColor(COLOR_3DFACE));
 +  MoveToEx(DC, Rect->left, Rect->bottom - 1, NULL);
 +  LineTo(DC, Rect->right, Rect->bottom - 1);
 +
 +  if (0 == MenuInfo.MenuItemCount)
 +    {
 +      SelectObject(DC, FontOld);
 +      return GetSystemMetrics(SM_CYMENU);
 +    }
 +
 +  MenuInitRosMenuItemInfo(&ItemInfo);
 +  for (i = 0; i < MenuInfo.MenuItemCount; i++)
 +    {
 +      if (MenuGetRosMenuItemInfo(MenuInfo.Self, i, &ItemInfo))
 +        {
 +          MenuDrawMenuItem(Wnd, &MenuInfo, Wnd, DC, &ItemInfo,
 +                           MenuInfo.Height, TRUE, ODA_DRAWENTIRE);
 +        }
 +    }
 +  MenuCleanupRosMenuItemInfo(&ItemInfo);
 +
 +  SelectObject(DC, FontOld);
 +
 +  return MenuInfo.Height;
 +}
 +
 +/***********************************************************************
 + *           MenuShowSubPopup
 + *
 + * Display the sub-menu of the selected item of this menu.
 + * Return the handle of the submenu, or menu if no submenu to display.
 + */
 +static HMENU FASTCALL
 +MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Flags)
 +{
 +  extern void FASTCALL NcGetSysPopupPos(HWND Wnd, RECT *Rect);
 +  RECT Rect;
 +  ROSMENUITEMINFO ItemInfo;
 +  ROSMENUINFO SubMenuInfo;
 +  HDC Dc;
 +  HMENU Ret;
 +
 +  TRACE("owner=%x menu=%p 0x%04x\n", WndOwner, MenuInfo, SelectFirst);
 +
 +  if (NO_SELECTED_ITEM == MenuInfo->FocusedItem)
 +    {
 +      return MenuInfo->Self;
 +    }
 +
 +  MenuInitRosMenuItemInfo(&ItemInfo);
 +  if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo))
 +    {
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +      return MenuInfo->Self;
 +    }
 +  if (0 == (ItemInfo.fType & MF_POPUP) || 0 != (ItemInfo.fState & (MF_GRAYED | MF_DISABLED)))
 +    {
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +      return MenuInfo->Self;
 +    }
 +
 +  /* message must be sent before using item,
 +     because nearly everything may be changed by the application ! */
 +
 +  /* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
 +  if (0 == (Flags & TPM_NONOTIFY))
 +    {
 +      SendMessageW(WndOwner, WM_INITMENUPOPUP, (WPARAM) ItemInfo.hSubMenu,
 +                   MAKELONG(MenuInfo->FocusedItem, IS_SYSTEM_MENU(MenuInfo)));
 +    }
 +
 +  if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo))
 +    {
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +      return MenuInfo->Self;
 +    }
 +  Rect = ItemInfo.Rect;
 +
 +  /* correct item if modified as a reaction to WM_INITMENUPOPUP message */
 +  if (0 == (ItemInfo.fState & MF_HILITE))
 +    {
 +      if (0 != (MenuInfo->Flags & MF_POPUP))
 +        {
 +          Dc = GetDC(MenuInfo->Wnd);
 +        }
 +      else
 +        {
 +          Dc = GetDCEx(MenuInfo->Wnd, 0, DCX_CACHE | DCX_WINDOW);
 +        }
 +
 +      SelectObject(Dc, hMenuFont);
 +      ItemInfo.fMask |= MIIM_STATE;
 +      ItemInfo.fState |= MF_HILITE;
 +      MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
 +      MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc, &ItemInfo, MenuInfo->Height,
 +                       ! (MenuInfo->Flags & MF_POPUP), ODA_DRAWENTIRE);
 +      ReleaseDC(MenuInfo->Wnd, Dc);
 +    }
 +
 +  if (0 == ItemInfo.Rect.top && 0 == ItemInfo.Rect.left
 +      && 0 == ItemInfo.Rect.bottom && 0 == ItemInfo.Rect.right)
 +    {
 +      ItemInfo.Rect = Rect;
 +    }
 +
 +  ItemInfo.fMask |= MIIM_STATE;
 +  ItemInfo.fState |= MF_MOUSESELECT;
 +  MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
 +
 +  if (IS_SYSTEM_MENU(MenuInfo))
 +    {
 +      MenuInitSysMenuPopup(ItemInfo.hSubMenu, GetWindowLongPtrW(MenuInfo->Wnd, GWL_STYLE),
 +                           GetClassLongPtrW(MenuInfo->Wnd, GCL_STYLE), HTSYSMENU);
 +
 +      NcGetSysPopupPos(MenuInfo->Wnd, &Rect);
 +      Rect.top = Rect.bottom;
 +      Rect.right = GetSystemMetrics(SM_CXSIZE);
 +      Rect.bottom = GetSystemMetrics(SM_CYSIZE);
 +    }
 +  else
 +    {
 +      GetWindowRect(MenuInfo->Wnd, &Rect);
 +      if (0 != (MenuInfo->Flags & MF_POPUP))
 +      {
 +          Rect.left += ItemInfo.Rect.right - GetSystemMetrics(SM_CXBORDER);
 +          Rect.top += ItemInfo.Rect.top - 3;
 +          Rect.right = ItemInfo.Rect.left - ItemInfo.Rect.right + GetSystemMetrics(SM_CXBORDER);
 +          Rect.bottom = ItemInfo.Rect.top - ItemInfo.Rect.bottom - 3 - 2
 +                                                    - GetSystemMetrics(SM_CYBORDER);
 +        }
 +      else
 +        {
 +          Rect.left += ItemInfo.Rect.left;
 +          Rect.top += ItemInfo.Rect.bottom;
 +          Rect.right = ItemInfo.Rect.right - ItemInfo.Rect.left;
 +          Rect.bottom = ItemInfo.Rect.bottom - ItemInfo.Rect.top;
 +        }
 +    }
 +
 +  MenuShowPopup(WndOwner, ItemInfo.hSubMenu, MenuInfo->FocusedItem, Flags,
 +                Rect.left, Rect.top, Rect.right, Rect.bottom );
 +  if (SelectFirst && MenuGetRosMenuInfo(&SubMenuInfo, ItemInfo.hSubMenu))
 +    {
 +      MenuMoveSelection(WndOwner, &SubMenuInfo, ITEM_NEXT);
 +    }
 +
 +  Ret = ItemInfo.hSubMenu;
 +  MenuCleanupRosMenuItemInfo(&ItemInfo);
 +
 +  return Ret;
 +}
 +
 +/**********************************************************************
 + *         MENU_EndMenu
 + *
 + * Calls EndMenu() if the hwnd parameter belongs to the menu owner
 + *
 + * Does the (menu stuff) of the default window handling of WM_CANCELMODE
 + */
 +void MENU_EndMenu( HWND hwnd )
 +{
 +    ROSMENUINFO MenuInfo;
 +    BOOL Ret = FALSE;
 +    if (top_popup_hmenu)
 +       Ret = MenuGetRosMenuInfo(&MenuInfo, top_popup_hmenu);
 +    if (Ret && hwnd == MenuInfo.WndOwner) EndMenu();
 +}
 +
 +/***********************************************************************
 + *           MenuHideSubPopups
 + *
 + * Hide the sub-popup menus of this menu.
 + */
 +static void FASTCALL
 +MenuHideSubPopups(HWND WndOwner, PROSMENUINFO MenuInfo,
 +                               BOOL SendMenuSelect, UINT wFlags)
 +{
 +  ROSMENUINFO SubMenuInfo;
 +  ROSMENUITEMINFO ItemInfo;
 +
 +  TRACE("owner=%x menu=%x 0x%04x\n", WndOwner, MenuInfo, SendMenuSelect);
 +
 +  if (NULL != MenuInfo && NULL != top_popup && NO_SELECTED_ITEM != MenuInfo->FocusedItem)
 +  {
 +      MenuInitRosMenuItemInfo(&ItemInfo);
 +      ItemInfo.fMask |= MIIM_FTYPE | MIIM_STATE;
 +      if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo)
 +          || 0 == (ItemInfo.fType & MF_POPUP)
 +          || 0 == (ItemInfo.fState & MF_MOUSESELECT))
 +      {
 +          MenuCleanupRosMenuItemInfo(&ItemInfo);
 +          return;
 +      }
 +      ItemInfo.fState &= ~MF_MOUSESELECT;
 +      ItemInfo.fMask |= MIIM_STATE;
 +      MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
 +      if (MenuGetRosMenuInfo(&SubMenuInfo, ItemInfo.hSubMenu))
 +      {
 +          MenuHideSubPopups(WndOwner, &SubMenuInfo, FALSE, wFlags);
 +          MenuSelectItem(WndOwner, &SubMenuInfo, NO_SELECTED_ITEM, SendMenuSelect, NULL);
 +          DestroyWindow(SubMenuInfo.Wnd);
 +          SubMenuInfo.Wnd = NULL;
 +          MenuSetRosMenuInfo(&SubMenuInfo);
 +
 +          if (!(wFlags & TPM_NONOTIFY))
 +             SendMessageW( WndOwner, WM_UNINITMENUPOPUP, (WPARAM)ItemInfo.hSubMenu,
 +                                 MAKELPARAM(0, IS_SYSTEM_MENU(&SubMenuInfo)) );
 +      }
 +  }
 +}
 +
 +/***********************************************************************
 + *           MenuSwitchTracking
 + *
 + * Helper function for menu navigation routines.
 + */
 +static void FASTCALL
 +MenuSwitchTracking(MTRACKER* Mt, PROSMENUINFO PtMenuInfo, UINT Index, UINT wFlags)
 +{
 +  ROSMENUINFO TopMenuInfo;
 +
 +  TRACE("%x menu=%x 0x%04x\n", Mt, PtMenuInfo->Self, Index);
 +
 +  if (MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu) &&
 +      Mt->TopMenu != PtMenuInfo->Self &&
 +      0 == ((PtMenuInfo->Flags | TopMenuInfo.Flags) & MF_POPUP))
 +    {
 +      /* both are top level menus (system and menu-bar) */
 +      MenuHideSubPopups(Mt->OwnerWnd, &TopMenuInfo, FALSE, wFlags);
 +      MenuSelectItem(Mt->OwnerWnd, &TopMenuInfo, NO_SELECTED_ITEM, FALSE, NULL);
 +      Mt->TopMenu = PtMenuInfo->Self;
 +    }
 +  else
 +    {
 +      MenuHideSubPopups(Mt->OwnerWnd, PtMenuInfo, FALSE, wFlags);
 +    }
 +
 +  MenuSelectItem(Mt->OwnerWnd, PtMenuInfo, Index, TRUE, NULL);
 +}
 +
 +/***********************************************************************
 + *           MenuExecFocusedItem
 + *
 + * Execute a menu item (for instance when user pressed Enter).
 + * Return the wID of the executed item. Otherwise, -1 indicating
 + * that no menu item was executed, -2 if a popup is shown;
 + * Have to receive the flags for the TrackPopupMenu options to avoid
 + * sending unwanted message.
 + *
 + */
 +static INT FASTCALL
 +MenuExecFocusedItem(MTRACKER *Mt, PROSMENUINFO MenuInfo, UINT Flags)
 +{
 +  ROSMENUITEMINFO ItemInfo;
 +  UINT wID;
 +
 +  TRACE("%p menu=%p\n", Mt, MenuInfo);
 +
 +  if (0 == MenuInfo->MenuItemCount || NO_SELECTED_ITEM == MenuInfo->FocusedItem)
 +    {
 +      return -1;
 +    }
 +
 +  MenuInitRosMenuItemInfo(&ItemInfo);
 +  if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo))
 +    {
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +      return -1;
 +    }
 +
 +  TRACE("%p %08x %p\n", MenuInfo, ItemInfo.wID, ItemInfo.hSubMenu);
 +
 +  if (0 == (ItemInfo.fType & MF_POPUP))
 +    {
 +      if (0 == (ItemInfo.fState & (MF_GRAYED | MF_DISABLED))
 +          && 0 == (ItemInfo.fType & MF_SEPARATOR))
 +        {
 +          /* If TPM_RETURNCMD is set you return the id, but
 +            do not send a message to the owner */
 +          if (0 == (Flags & TPM_RETURNCMD))
 +          {
 +              if (0 != (MenuInfo->Flags & MF_SYSMENU))
 +                {
 +                  PostMessageW(Mt->OwnerWnd, WM_SYSCOMMAND, ItemInfo.wID,
 +                               MAKELPARAM((SHORT) Mt->Pt.x, (SHORT) Mt->Pt.y));
 +                }
 +              else
 +                {
 +                  if (MenuInfo->dwStyle & MNS_NOTIFYBYPOS)
 +                      PostMessageW(Mt->OwnerWnd, WM_MENUCOMMAND,
 +                                                 MenuInfo->FocusedItem,
 +                                                       (LPARAM)MenuInfo->Self);
 +                  else
 +                    PostMessageW(Mt->OwnerWnd, WM_COMMAND, ItemInfo.wID, 0);
 +                }
 +            }
 +          wID = ItemInfo.wID;
 +          MenuCleanupRosMenuItemInfo(&ItemInfo);
 +        return wID;
 +        }
 +    }
 +  else
 +    {
 +      Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, MenuInfo, TRUE, Flags);
 +      return -2;
 +    }
 +
 +  return -1;
 +}
 +
 +/***********************************************************************
 + *           MenuButtonDown
 + *
 + * Return TRUE if we can go on with menu tracking.
 + */
 +static BOOL FASTCALL
 +MenuButtonDown(MTRACKER* Mt, HMENU PtMenu, UINT Flags)
 +{
 +  int Index;
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUITEMINFO Item;
 +
 +  TRACE("%x PtMenu=%p\n", Mt, PtMenu);
 +
 +  if (NULL != PtMenu)
 +    {
 +      if (! MenuGetRosMenuInfo(&MenuInfo, PtMenu))
 +        {
 +          return FALSE;
 +        }
 +      if (IS_SYSTEM_MENU(&MenuInfo))
 +        {
 +          Index = 0;
 +        }
 +      else
 +        {
 +          Index = NtUserMenuItemFromPoint(Mt->OwnerWnd, PtMenu, Mt->Pt.x, Mt->Pt.y);
 +        }
 +      MenuInitRosMenuItemInfo(&Item);
 +      if (NO_SELECTED_ITEM == Index || ! MenuGetRosMenuItemInfo(PtMenu, Index, &Item))
 +        {
 +          MenuCleanupRosMenuItemInfo(&Item);
 +          return FALSE;
 +        }
 +
 +      if (!(Item.fType & MF_SEPARATOR) &&
 +          !(Item.fState & (MFS_DISABLED | MFS_GRAYED)) )
 +      {
 +          if (MenuInfo.FocusedItem != Index)
 +            {
 +              MenuSwitchTracking(Mt, &MenuInfo, Index, Flags);
 +            }
 +
 +          /* If the popup menu is not already "popped" */
 +          if (0 == (Item.fState & MF_MOUSESELECT))
 +            {
 +              Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &MenuInfo, FALSE, Flags);
 +            }
 +        }
 +
 +      MenuCleanupRosMenuItemInfo(&Item);
 +
 +      return TRUE;
 +    }
 +
 +  /* else the click was on the menu bar, finish the tracking */
 +
 +  return FALSE;
 +}
 +
 +/***********************************************************************
 + *           MenuButtonUp
 + *
 + * Return the value of MenuExecFocusedItem if
 + * the selected item was not a popup. Else open the popup.
 + * A -1 return value indicates that we go on with menu tracking.
 + *
 + */
 +static INT FASTCALL
 +MenuButtonUp(MTRACKER *Mt, HMENU PtMenu, UINT Flags)
 +{
 +  UINT Id;
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUITEMINFO ItemInfo;
 +
 +  TRACE("%p hmenu=%x\n", Mt, PtMenu);
 +
 +  if (NULL != PtMenu)
 +    {
 +      Id = 0;
 +      if (! MenuGetRosMenuInfo(&MenuInfo, PtMenu))
 +        {
 +          return -1;
 +        }
 +
 +      if (! IS_SYSTEM_MENU(&MenuInfo))
 +        {
 +          Id = NtUserMenuItemFromPoint(Mt->OwnerWnd, MenuInfo.Self, Mt->Pt.x, Mt->Pt.y);
 +        }
 +      MenuInitRosMenuItemInfo(&ItemInfo);
 +      if (0 <= Id && MenuGetRosMenuItemInfo(MenuInfo.Self, Id, &ItemInfo) &&
 +          MenuInfo.FocusedItem == Id)
 +        {
 +          if (0 == (ItemInfo.fType & MF_POPUP))
 +            {
 +              INT ExecutedMenuId = MenuExecFocusedItem(Mt, &MenuInfo, Flags);
 +              MenuCleanupRosMenuItemInfo(&ItemInfo);
 +              return (ExecutedMenuId < 0) ? -1 : ExecutedMenuId;
 +            }
 +          MenuCleanupRosMenuItemInfo(&ItemInfo);
 +
 +          /* If we are dealing with the top-level menu            */
 +          /* and this is a click on an already "popped" item:     */
 +          /* Stop the menu tracking and close the opened submenus */
 +          if (Mt->TopMenu == MenuInfo.Self && MenuInfo.TimeToHide)
 +            {
 +              MenuCleanupRosMenuItemInfo(&ItemInfo);
 +              return 0;
 +            }
 +        }
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +      MenuInfo.TimeToHide = TRUE;
 +      MenuSetRosMenuInfo(&MenuInfo);
 +    }
 +
 +  return -1;
 +}
 +
 +/***********************************************************************
 + *           MenuPtMenu
 + *
 + * Walks menu chain trying to find a menu pt maps to.
 + */
 +static HMENU FASTCALL
 +MenuPtMenu(HMENU Menu, POINT Pt)
 +{
 +  extern LRESULT DefWndNCHitTest(HWND hWnd, POINT Point);
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUITEMINFO ItemInfo;
 +  HMENU Ret = NULL;
 +  INT Ht;
 +
 +  if (! MenuGetRosMenuInfo(&MenuInfo, Menu))
 +    {
 +      return NULL;
 +    }
 +
 +  /* try subpopup first (if any) */
 +  if (NO_SELECTED_ITEM != MenuInfo.FocusedItem)
 +    {
 +      MenuInitRosMenuItemInfo(&ItemInfo);
 +      if (MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo) &&
 +          0 != (ItemInfo.fType & MF_POPUP) &&
 +          0 != (ItemInfo.fState & MF_MOUSESELECT))
 +        {
 +          Ret = MenuPtMenu(ItemInfo.hSubMenu, Pt);
 +          if (NULL != Ret)
 +            {
 +              MenuCleanupRosMenuItemInfo(&ItemInfo);
 +              return Ret;
 +            }
 +        }
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +    }
 +
 +  /* check the current window (avoiding WM_HITTEST) */
 +  Ht = DefWndNCHitTest(MenuInfo.Wnd, Pt);
 +  if (0 != (MenuInfo.Flags & MF_POPUP))
 +    {
 +      if (HTNOWHERE != Ht && HTERROR != Ht)
 +        {
 +          Ret = Menu;
 +        }
 +    }
 +  else if (HTSYSMENU == Ht)
 +    {
 +      Ret = NtUserGetSystemMenu(MenuInfo.Wnd, FALSE);
 +    }
 +  else if (HTMENU == Ht)
 +    {
 +      Ret = GetMenu(MenuInfo.Wnd);
 +    }
 +
 +  return Ret;
 +}
 +
 +/***********************************************************************
 + *           MenuMouseMove
 + *
 + * Return TRUE if we can go on with menu tracking.
 + */
 +static BOOL FASTCALL
 +MenuMouseMove(MTRACKER *Mt, HMENU PtMenu, UINT Flags)
 +{
 +  UINT Index;
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUITEMINFO ItemInfo;
 +
 +  if (NULL != PtMenu)
 +    {
 +      if (! MenuGetRosMenuInfo(&MenuInfo, PtMenu))
 +        {
 +          return TRUE;
 +        }
 +      if (IS_SYSTEM_MENU(&MenuInfo))
 +        {
 +          Index = 0;
 +        }
 +      else
 +        {
 +          Index = NtUserMenuItemFromPoint(Mt->OwnerWnd, PtMenu, Mt->Pt.x, Mt->Pt.y);
 +        }
 +    }
 +  else
 +    {
 +      Index = NO_SELECTED_ITEM;
 +    }
 +
 +  if (NO_SELECTED_ITEM == Index)
 +    {
 +      if (Mt->CurrentMenu == MenuInfo.Self ||
 +          MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu))
 +        {
 +          MenuSelectItem(Mt->OwnerWnd, &MenuInfo, NO_SELECTED_ITEM,
 +                         TRUE, Mt->TopMenu);
 +        }
 +    }
 +  else if (MenuInfo.FocusedItem != Index)
 +    {
 +      MenuInitRosMenuItemInfo(&ItemInfo);
 +      if (MenuGetRosMenuItemInfo(MenuInfo.Self, Index, &ItemInfo) &&
 +           !(ItemInfo.fType & MF_SEPARATOR))
 +      {
 +          MenuSwitchTracking(Mt, &MenuInfo, Index, Flags);
 +        if (!(ItemInfo.fState & (MFS_DISABLED | MFS_GRAYED)))
 +              Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &MenuInfo, FALSE, Flags);
 +      }
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +    }
 +
 +  return TRUE;
 +}
 +
 +/***********************************************************************
 + *           MenuGetSubPopup
 + *
 + * Return the handle of the selected sub-popup menu (if any).
 + */
 +static HMENU FASTCALL
 +MenuGetSubPopup(HMENU Menu)
 +{
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUITEMINFO ItemInfo;
 +
 +  if (! MenuGetRosMenuInfo(&MenuInfo, Menu)
 +      || NO_SELECTED_ITEM == MenuInfo.FocusedItem)
 +    {
 +      return NULL;
 +    }
 +
 +  MenuInitRosMenuItemInfo(&ItemInfo);
 +  if (! MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo))
 +    {
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +      return NULL;
 +    }
 +  if (0 != (ItemInfo.fType & MF_POPUP) && 0 != (ItemInfo.fState & MF_MOUSESELECT))
 +    {
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +      return ItemInfo.hSubMenu;
 +    }
 +
 +  MenuCleanupRosMenuItemInfo(&ItemInfo);
 +  return NULL;
 +}
 +
 +/***********************************************************************
 + *           MenuDoNextMenu
 + *
 + * NOTE: WM_NEXTMENU documented in Win32 is a bit different.
 + */
 +static LRESULT FASTCALL
 +MenuDoNextMenu(MTRACKER* Mt, UINT Vk, UINT wFlags)
 +{
 +  ROSMENUINFO TopMenuInfo;
 +  ROSMENUINFO MenuInfo;
 +
 +  if (! MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu))
 +    {
 +      return (LRESULT) FALSE;
 +    }
 +
 +  if ((VK_LEFT == Vk && 0 == TopMenuInfo.FocusedItem)
 +      || (VK_RIGHT == Vk && TopMenuInfo.FocusedItem == TopMenuInfo.MenuItemCount - 1))
 +    {
 +      MDINEXTMENU NextMenu;
 +      HMENU NewMenu;
 +      HWND NewWnd;
 +      UINT Id = 0;
 +
 +      NextMenu.hmenuIn = (IS_SYSTEM_MENU(&TopMenuInfo)) ? GetSubMenu(Mt->TopMenu, 0) : Mt->TopMenu;
 +      NextMenu.hmenuNext = NULL;
 +      NextMenu.hwndNext = NULL;
 +      SendMessageW(Mt->OwnerWnd, WM_NEXTMENU, Vk, (LPARAM) &NextMenu);
 +
 +      TRACE("%p [%p] -> %p [%p]\n",
 +             Mt->CurrentMenu, Mt->OwnerWnd, NextMenu.hmenuNext, NextMenu.hwndNext );
 +
 +      if (NULL == NextMenu.hmenuNext || NULL == NextMenu.hwndNext)
 +        {
 +          DWORD Style = GetWindowLongPtrW(Mt->OwnerWnd, GWL_STYLE);
 +          NewWnd = Mt->OwnerWnd;
 +          if (IS_SYSTEM_MENU(&TopMenuInfo))
 +            {
 +              /* switch to the menu bar */
 +
 +              if (0 != (Style & WS_CHILD)
 +                  || NULL == (NewMenu = GetMenu(NewWnd)))
 +                {
 +                  return FALSE;
 +                }
 +
 +              if (VK_LEFT == Vk)
 +                {
 +                  if (! MenuGetRosMenuInfo(&MenuInfo, NewMenu))
 +                    {
 +                      return FALSE;
 +                    }
 +                  Id = MenuInfo.MenuItemCount - 1;
 +                }
 +            }
 +          else if (0 != (Style & WS_SYSMENU))
 +            {
 +              /* switch to the system menu */
 +              NewMenu = NtUserGetSystemMenu(NewWnd, FALSE);
 +            }
 +          else
 +            {
 +              return FALSE;
 +            }
 +        }
 +      else    /* application returned a new menu to switch to */
 +        {
 +          NewMenu = NextMenu.hmenuNext;
 +          NewWnd = NextMenu.hwndNext;
 +
 +          if (IsMenu(NewMenu) && IsWindow(NewWnd))
 +            {
 +              DWORD Style = GetWindowLongPtrW(NewWnd, GWL_STYLE);
 +
 +              if (0 != (Style & WS_SYSMENU)
 +                  && GetSystemMenu(NewWnd, FALSE) == NewMenu)
 +                {
 +                  /* get the real system menu */
 +                  NewMenu = NtUserGetSystemMenu(NewWnd, FALSE);
 +                }
 +              else if (0 != (Style & WS_CHILD) || GetMenu(NewWnd) != NewMenu)
 +                {
 +                  /* FIXME: Not sure what to do here;
 +                   * perhaps try to track NewMenu as a popup? */
 +
 +                  WARN(" -- got confused.\n");
 +                  return FALSE;
 +                }
 +            }
 +          else
 +            {
 +              return FALSE;
 +            }
 +        }
 +
 +      if (NewMenu != Mt->TopMenu)
 +        {
 +          MenuSelectItem(Mt->OwnerWnd, &TopMenuInfo, NO_SELECTED_ITEM,
 +                         FALSE, 0 );
 +          if (Mt->CurrentMenu != Mt->TopMenu)
 +            {
 +              MenuHideSubPopups(Mt->OwnerWnd, &TopMenuInfo, FALSE, wFlags);
 +            }
 +        }
 +
 +      if (NewWnd != Mt->OwnerWnd)
 +        {
 +          Mt->OwnerWnd = NewWnd;
 +          SetCapture(Mt->OwnerWnd);
 +          (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, Mt->OwnerWnd);
 +        }
 +
 +      Mt->TopMenu = Mt->CurrentMenu = NewMenu; /* all subpopups are hidden */
 +      if (MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu))
 +        {
 +          MenuSelectItem(Mt->OwnerWnd, &TopMenuInfo, Id, TRUE, 0);
 +        }
 +
 +      return TRUE;
 +    }
 +
 +  return FALSE;
 +}
 +
 +/***********************************************************************
 + *           MenuSuspendPopup
 + *
 + * The idea is not to show the popup if the next input message is
 + * going to hide it anyway.
 + */
 +static BOOL FASTCALL
 +MenuSuspendPopup(MTRACKER* Mt, UINT Message)
 +{
 +  MSG Msg;
 +
 +  Msg.hwnd = Mt->OwnerWnd;
 +
 +  PeekMessageW(&Msg, 0, 0, 0, PM_NOYIELD | PM_REMOVE);
 +  Mt->TrackFlags |= TF_SKIPREMOVE;
 +
 +  switch (Message)
 +    {
 +      case WM_KEYDOWN:
 +        PeekMessageW(&Msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE);
 +        if (WM_KEYUP == Msg.message || WM_PAINT == Msg.message)
 +          {
 +            PeekMessageW(&Msg, 0, 0, 0, PM_NOYIELD | PM_REMOVE);
 +            PeekMessageW(&Msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE);
 +            if (WM_KEYDOWN == Msg.message
 +                && (VK_LEFT == Msg.wParam || VK_RIGHT == Msg.wParam))
 +              {
 +                Mt->TrackFlags |= TF_SUSPENDPOPUP;
 +                return TRUE;
 +              }
 +          }
 +        break;
 +    }
 +
 +  /* failures go through this */
 +  Mt->TrackFlags &= ~TF_SUSPENDPOPUP;
 +
 +  return FALSE;
 +}
 +
 +/***********************************************************************
 + *           MenuKeyEscape
 + *
 + * Handle a VK_ESCAPE key event in a menu.
 + */
 +static BOOL FASTCALL
 +MenuKeyEscape(MTRACKER *Mt, UINT Flags)
 +{
 +  BOOL EndMenu = TRUE;
 +  ROSMENUINFO MenuInfo;
 +  HMENU MenuTmp, MenuPrev;
 +
 +  if (Mt->CurrentMenu != Mt->TopMenu)
 +    {
 +      if (MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu)
 +          && 0 != (MenuInfo.Flags & MF_POPUP))
 +        {
 +          MenuPrev = MenuTmp = Mt->TopMenu;
 +
 +          /* close topmost popup */
 +          while (MenuTmp != Mt->CurrentMenu)
 +            {
 +              MenuPrev = MenuTmp;
 +              MenuTmp = MenuGetSubPopup(MenuPrev);
 +            }
 +
 +          if (MenuGetRosMenuInfo(&MenuInfo, MenuPrev))
 +            {
 +              MenuHideSubPopups(Mt->OwnerWnd, &MenuInfo, TRUE, Flags);
 +            }
 +          Mt->CurrentMenu = MenuPrev;
 +          EndMenu = FALSE;
 +        }
 +    }
 +
 +  return EndMenu;
 +}
 +
 +/***********************************************************************
 + *           MenuKeyLeft
 + *
 + * Handle a VK_LEFT key event in a menu.
 + */
 +static void FASTCALL
 +MenuKeyLeft(MTRACKER* Mt, UINT Flags)
 +{
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUINFO TopMenuInfo;
 +  ROSMENUINFO PrevMenuInfo;
 +  HMENU MenuTmp, MenuPrev;
 +  UINT PrevCol;
 +
 +  MenuPrev = MenuTmp = Mt->TopMenu;
 +
 +  if (! MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu))
 +    {
 +      return;
 +    }
 +
 +  /* Try to move 1 column left (if possible) */
 +  if (NO_SELECTED_ITEM != (PrevCol = MenuGetStartOfPrevColumn(&MenuInfo)))
 +    {
 +      if (MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu))
 +        {
 +          MenuSelectItem(Mt->OwnerWnd, &MenuInfo, PrevCol, TRUE, 0);
 +        }
 +      return;
 +    }
 +
 +  /* close topmost popup */
 +  while (MenuTmp != Mt->CurrentMenu)
 +    {
 +      MenuPrev = MenuTmp;
 +      MenuTmp = MenuGetSubPopup(MenuPrev);
 +    }
 +
 +  if (! MenuGetRosMenuInfo(&PrevMenuInfo, MenuPrev))
 +    {
 +      return;
 +    }
 +  MenuHideSubPopups(Mt->OwnerWnd, &PrevMenuInfo, TRUE, Flags);
 +  Mt->CurrentMenu = MenuPrev;
 +
 +  if (! MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu))
 +    {
 +      return;
 +    }
 +  if ((MenuPrev == Mt->TopMenu) && 0 == (TopMenuInfo.Flags & MF_POPUP))
 +    {
 +      /* move menu bar selection if no more popups are left */
 +
 +      if (! MenuDoNextMenu(Mt, VK_LEFT, Flags))
 +        {
 +          MenuMoveSelection(Mt->OwnerWnd, &TopMenuInfo, ITEM_PREV);
 +        }
 +
 +      if (MenuPrev != MenuTmp || 0 != (Mt->TrackFlags & TF_SUSPENDPOPUP))
 +        {
 +          /* A sublevel menu was displayed - display the next one
 +           * unless there is another displacement coming up */
 +
 +          if (! MenuSuspendPopup(Mt, WM_KEYDOWN)
 +              && MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu))
 +            {
 +              Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &TopMenuInfo,
 +                                                 TRUE, Flags);
 +            }
 +        }
 +    }
 +}
 +
 +/***********************************************************************
 + *           MenuKeyRight
 + *
 + * Handle a VK_RIGHT key event in a menu.
 + */
 +static void FASTCALL MenuKeyRight(MTRACKER *Mt, UINT Flags)
 +{
 +    HMENU hmenutmp;
 +    ROSMENUINFO MenuInfo;
 +    ROSMENUINFO CurrentMenuInfo;
 +    UINT NextCol;
 +
 +    TRACE("MenuKeyRight called, cur %p, top %p.\n",
 +         Mt->CurrentMenu, Mt->TopMenu);
 +
 +    if (! MenuGetRosMenuInfo(&MenuInfo, Mt->TopMenu)) return;
 +    if ((MenuInfo.Flags & MF_POPUP) || (Mt->CurrentMenu != Mt->TopMenu))
 +    {
 +      /* If already displaying a popup, try to display sub-popup */
 +
 +      hmenutmp = Mt->CurrentMenu;
 +      if (MenuGetRosMenuInfo(&CurrentMenuInfo, Mt->CurrentMenu))
 +        {
 +          Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &CurrentMenuInfo, TRUE, Flags);
 +        }
 +
 +      /* if subpopup was displayed then we are done */
 +      if (hmenutmp != Mt->CurrentMenu) return;
 +    }
 +
 +  if (! MenuGetRosMenuInfo(&CurrentMenuInfo, Mt->CurrentMenu))
 +    {
 +      return;
 +    }
 +
 +  /* Check to see if there's another column */
 +  if (NO_SELECTED_ITEM != (NextCol = MenuGetStartOfNextColumn(&CurrentMenuInfo)))
 +    {
 +      TRACE("Going to %d.\n", NextCol);
 +      if (MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu))
 +        {
 +          MenuSelectItem(Mt->OwnerWnd, &MenuInfo, NextCol, TRUE, 0);
 +        }
 +      return;
 +    }
 +
 +  if (0 == (MenuInfo.Flags & MF_POPUP))       /* menu bar tracking */
 +    {
 +      if (Mt->CurrentMenu != Mt->TopMenu)
 +        {
 +          MenuHideSubPopups(Mt->OwnerWnd, &MenuInfo, FALSE, Flags);
 +          hmenutmp = Mt->CurrentMenu = Mt->TopMenu;
 +        }
 +      else
 +        {
 +          hmenutmp = NULL;
 +        }
 +
 +      /* try to move to the next item */
 +      if ( !MenuDoNextMenu(Mt, VK_RIGHT, Flags))
 +          MenuMoveSelection(Mt->OwnerWnd, &MenuInfo, ITEM_NEXT);
 +
 +      if ( hmenutmp || Mt->TrackFlags & TF_SUSPENDPOPUP )
 +        {
 +          if (! MenuSuspendPopup(Mt, WM_KEYDOWN)
 +              && MenuGetRosMenuInfo(&MenuInfo, Mt->TopMenu))
 +            {
 +              Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &MenuInfo,
 +                                                 TRUE, Flags);
 +            }
 +        }
 +    }
 +}
 +
 +/***********************************************************************
 + *           MenuTrackMenu
 + *
 + * Menu tracking code.
 + */
 +static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
 +                            HWND hwnd, const RECT *lprect )
 +{
 +    MSG msg;
 +    ROSMENUINFO MenuInfo;
 +    ROSMENUITEMINFO ItemInfo;
 +    BOOL fRemove;
 +    INT executedMenuId = -1;
 +    MTRACKER mt;
 +    BOOL enterIdleSent = FALSE;
 +
 +    mt.TrackFlags = 0;
 +    mt.CurrentMenu = hmenu;
 +    mt.TopMenu = hmenu;
 +    mt.OwnerWnd = hwnd;
 +    mt.Pt.x = x;
 +    mt.Pt.y = y;
 +
 +    TRACE("hmenu=%p flags=0x%08x (%d,%d) hwnd=%x (%ld,%ld)-(%ld,%ld)\n",
 +         hmenu, wFlags, x, y, hwnd, lprect ? lprect->left : 0, lprect ? lprect->top : 0,
 +         lprect ? lprect->right : 0, lprect ? lprect->bottom : 0);
 +
 +    if (!IsMenu(hmenu))
 +    {
 +        WARN("Invalid menu handle %p\n", hmenu);
 +        SetLastError( ERROR_INVALID_MENU_HANDLE );
 +        return FALSE;
 +    }
 +
 +    fEndMenu = FALSE;
 +    if (! MenuGetRosMenuInfo(&MenuInfo, hmenu))
 +    {
 +        return FALSE;
 +    }
 +
 +    if (wFlags & TPM_BUTTONDOWN)
 +    {
 +        /* Get the result in order to start the tracking or not */
 +        fRemove = MenuButtonDown( &mt, hmenu, wFlags );
 +        fEndMenu = !fRemove;
 +    }
 +
 +    SetCapture(mt.OwnerWnd);
 +    (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, mt.OwnerWnd);
 +
 +    FIXME("MenuTrackMenu 1\n");
 +    while (! fEndMenu)
 +    {
 +        PVOID menu = ValidateHandle(mt.CurrentMenu, VALIDATE_TYPE_MENU);
 +        if (!menu) /* sometimes happens if I do a window manager close */
 +           break;
 +
 +        /* we have to keep the message in the queue until it's
 +         * clear that menu loop is not over yet. */
 +
 +        for (;;)
 +        {
 +            if (PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE ))
 +            {
 +                if (!CallMsgFilterW( &msg, MSGF_MENU )) break;
 +                /* remove the message from the queue */
 +                PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
 +            }
 +            else
 +            {
 +                if (!enterIdleSent)
 +                {
 +                  HWND win = MenuInfo.Flags & MF_POPUP ? MenuInfo.Wnd : NULL;
 +                  enterIdleSent = TRUE;
 +                  SendMessageW( mt.OwnerWnd, WM_ENTERIDLE, MSGF_MENU, (LPARAM) win);
 +                }
 +                WaitMessage();
 +            }
 +            //FIXME("MenuTrackMenu loop 1\n");
 +        }
 +
 +        /* check if EndMenu() tried to cancel us, by posting this message */
 +        if (msg.message == WM_CANCELMODE)
 +        {
 +            /* we are now out of the loop */
 +            fEndMenu = TRUE;
 +
 +            /* remove the message from the queue */
 +            PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
 +
 +            /* break out of internal loop, ala ESCAPE */
 +            break;
 +        }
 +
 +        TranslateMessage( &msg );
 +        mt.Pt = msg.pt;
 +
 +        if ( (msg.hwnd == MenuInfo.Wnd) || (msg.message!=WM_TIMER) )
 +            enterIdleSent=FALSE;
 +
 +        fRemove = FALSE;
 +        if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST))
 +        {
 +            /*
 +             * Use the mouse coordinates in lParam instead of those in the MSG
 +             * struct to properly handle synthetic messages. They are already
 +             * in screen coordinates.
 +             */
 +            mt.Pt.x = (short)LOWORD(msg.lParam);
 +            mt.Pt.y = (short)HIWORD(msg.lParam);
 +
 +            /* Find a menu for this mouse event */
 +            hmenu = MenuPtMenu(mt.TopMenu, mt.Pt);
 +
 +            switch(msg.message)
 +            {
 +                /* no WM_NC... messages in captured state */
 +
 +                case WM_RBUTTONDBLCLK:
 +                case WM_RBUTTONDOWN:
 +                     if (!(wFlags & TPM_RIGHTBUTTON)) break;
 +                    /* fall through */
 +                case WM_LBUTTONDBLCLK:
 +                case WM_LBUTTONDOWN:
 +                    /* If the message belongs to the menu, removes it from the queue */
 +                    /* Else, end menu tracking */
 +                    fRemove = MenuButtonDown(&mt, hmenu, wFlags);
 +                    fEndMenu = !fRemove;
 +                    break;
 +
 +                case WM_RBUTTONUP:
 +                    if (!(wFlags & TPM_RIGHTBUTTON)) break;
 +                    /* fall through */
 +                case WM_LBUTTONUP:
 +                    /* Check if a menu was selected by the mouse */
 +                    if (hmenu)
 +                    {
 +                        executedMenuId = MenuButtonUp( &mt, hmenu, wFlags);
 +                        TRACE("executedMenuId %d\n", executedMenuId);
 +
 +                    /* End the loop if executedMenuId is an item ID */
 +                    /* or if the job was done (executedMenuId = 0). */
 +                        fEndMenu = fRemove = (executedMenuId != -1);
 +                    }
 +                    /* No menu was selected by the mouse */
 +                    /* if the function was called by TrackPopupMenu, continue
 +                       with the menu tracking. If not, stop it */
 +                    else
 +                        fEndMenu = ((wFlags & TPM_POPUPMENU) ? FALSE : TRUE);
 +
 +                    break;
 +
 +                case WM_MOUSEMOVE:
 +                    /* the selected menu item must be changed every time */
 +                    /* the mouse moves. */
 +
 +                    if (hmenu)
 +                        fEndMenu |= !MenuMouseMove( &mt, hmenu, wFlags );
 +
 +              } /* switch(msg.message) - mouse */
 +          }
 +        else if ((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST))
 +        {
 +            fRemove = TRUE;  /* Keyboard messages are always removed */
 +            switch(msg.message)
 +            {
 +                case WM_KEYDOWN:
 +                case WM_SYSKEYDOWN:
 +                switch(msg.wParam)
 +                {
 +                    case VK_MENU:
 +                    case VK_F10:
 +                        fEndMenu = TRUE;
 +                         break;
 +
 +                    case VK_HOME:
 +                    case VK_END:
 +                        if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu))
 +                        {
 +                            MenuSelectItem(mt.OwnerWnd, &MenuInfo,
 +                                    NO_SELECTED_ITEM, FALSE, 0 );
 +                            MenuMoveSelection(mt.OwnerWnd, &MenuInfo,
 +                                              VK_HOME == msg.wParam ? ITEM_NEXT : ITEM_PREV);
 +                        }
 +                        break;
 +
 +                    case VK_UP:
 +                    case VK_DOWN: /* If on menu bar, pull-down the menu */
 +                        if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu))
 +                        {
 +                            if (!(MenuInfo.Flags & MF_POPUP))
 +                            {
 +                                if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu))
 +                                    mt.CurrentMenu = MenuShowSubPopup(mt.OwnerWnd, &MenuInfo, TRUE, wFlags);
 +                            }
 +                            else      /* otherwise try to move selection */
 +                                MenuMoveSelection(mt.OwnerWnd, &MenuInfo,
 +                                       (msg.wParam == VK_UP)? ITEM_PREV : ITEM_NEXT );
 +                        }
 +                        break;
 +
 +                    case VK_LEFT:
 +                        MenuKeyLeft( &mt, wFlags );
 +                        break;
 +
 +                    case VK_RIGHT:
 +                        MenuKeyRight( &mt, wFlags );
 +                        break;
 +
 +                    case VK_ESCAPE:
 +                        fEndMenu = MenuKeyEscape(&mt, wFlags);
 +                        break;
 +
 +                    case VK_F1:
 +                    {
 +                        HELPINFO hi;
 +                        hi.cbSize = sizeof(HELPINFO);
 +                        hi.iContextType = HELPINFO_MENUITEM;
 +                        if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu))
 +                        {
 +                            if (MenuInfo.FocusedItem == NO_SELECTED_ITEM)
 +                                hi.iCtrlId = 0;
 +                            else
 +                            {
 +                                MenuInitRosMenuItemInfo(&ItemInfo);
 +                                if (MenuGetRosMenuItemInfo(MenuInfo.Self,
 +                                                           MenuInfo.FocusedItem,
 +                                                           &ItemInfo))
 +                                {
 +                                    hi.iCtrlId = ItemInfo.wID;
 +                                }
 +                                else
 +                                {
 +                                    hi.iCtrlId = 0;
 +                                }
 +                                MenuCleanupRosMenuItemInfo(&ItemInfo);
 +                            }
 +                        }
 +                        hi.hItemHandle = hmenu;
 +                        hi.dwContextId = MenuInfo.dwContextHelpID;
 +                        hi.MousePos = msg.pt;
 +                        SendMessageW(hwnd, WM_HELP, 0, (LPARAM)&hi);
 +                        break;
 +                    }
 +
 +                    default:
 +                        break;
 +                }
 +                break;  /* WM_KEYDOWN */
 +
 +                case WM_CHAR:
 +                case WM_SYSCHAR:
 +                {
 +                    UINT pos;
 +
 +                    if (! MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu)) break;
 +                    if (msg.wParam == L'\r' || msg.wParam == L' ')
 +                    {
 +                        executedMenuId = MenuExecFocusedItem(&mt, &MenuInfo, wFlags);
 +                        fEndMenu = (executedMenuId != -2);
 +                        break;
 +                    }
 +
 +                    /* Hack to avoid control chars. */
 +                    /* We will find a better way real soon... */
 +                    if (msg.wParam < 32) break;
 +
 +                    pos = MenuFindItemByKey(mt.OwnerWnd, &MenuInfo,
 +                                          LOWORD(msg.wParam), FALSE);
 +                    if (pos == (UINT)-2) fEndMenu = TRUE;
 +                    else if (pos == (UINT)-1) MessageBeep(0);
 +                    else
 +                    {
 +                        MenuSelectItem(mt.OwnerWnd, &MenuInfo, pos,
 +                            TRUE, 0);
 +                        executedMenuId = MenuExecFocusedItem(&mt, &MenuInfo, wFlags);
 +                        fEndMenu = (executedMenuId != -2);
 +                    }
 +                }
 +                break;
 +            }  /* switch(msg.message) - kbd */
 +        }
 +        else
 +        {
 +            PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
 +            DispatchMessageW( &msg );
 +            //FIXME("MenuTrackMenu loop 2\n");
 +            continue;
 +        }
 +
 +        if (!fEndMenu) fRemove = TRUE;
 +
 +        /* finally remove message from the queue */
 +
 +        if (fRemove && !(mt.TrackFlags & TF_SKIPREMOVE) )
 +            PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
 +        else mt.TrackFlags &= ~TF_SKIPREMOVE;
 +        //FIXME("MenuTrackMenu loop 3\n");
 +    }
 +    FIXME("MenuTrackMenu 2\n");
 +
 +    (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, NULL);
 +    SetCapture(NULL);  /* release the capture */
 +
 +    /* If dropdown is still painted and the close box is clicked on
 +       then the menu will be destroyed as part of the DispatchMessage above.
 +       This will then invalidate the menu handle in mt.hTopMenu. We should
 +       check for this first.  */
 +    if( IsMenu( mt.TopMenu ) )
 +    {
 +        if (IsWindow(mt.OwnerWnd))
 +        {
 +            if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu))
 +            {
 +                MenuHideSubPopups(mt.OwnerWnd, &MenuInfo, FALSE, wFlags);
 +
 +                if (MenuInfo.Flags & MF_POPUP)
 +                {
 +                    IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
 +                    DestroyWindow(MenuInfo.Wnd);
 +                    MenuInfo.Wnd = NULL;
 +
 +                    if (!(MenuInfo.Flags & TPM_NONOTIFY))
 +                      SendMessageW( mt.OwnerWnd, WM_UNINITMENUPOPUP, (WPARAM)mt.TopMenu,
 +                                 MAKELPARAM(0, IS_SYSTEM_MENU(&MenuInfo)) );
 +
 +                }
 +                MenuSelectItem( mt.OwnerWnd, &MenuInfo, NO_SELECTED_ITEM, FALSE, 0 );
 +            }
 +
 +            SendMessageW( mt.OwnerWnd, WM_MENUSELECT, MAKEWPARAM(0, 0xffff), 0 );
 +        }
 +
 +        /* Reset the variable for hiding menu */
 +        if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu))
 +        {
 +            MenuInfo.TimeToHide = FALSE;
 +            MenuSetRosMenuInfo(&MenuInfo);
 +        }
 +    }
 +
 +    /* The return value is only used by TrackPopupMenu */
 +    if (!(wFlags & TPM_RETURNCMD)) return TRUE;
 +    if (executedMenuId == -1) executedMenuId = 0;
 +    return executedMenuId;
 +}
 +
 +/***********************************************************************
 + *           MenuInitTracking
 + */
 +static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags)
 +{
 +    ROSMENUINFO MenuInfo;
 +
 +    TRACE("hwnd=%p hmenu=%p\n", hWnd, hMenu);
 +
 +    HideCaret(0);
 +
 +    MenuGetRosMenuInfo(&MenuInfo, hMenu);
 +    /* This makes the menus of applications built with Delphi work.
 +     * It also enables menus to be displayed in more than one window,
 +     * but there are some bugs left that need to be fixed in this case.
 +     */
 +    if(MenuInfo.Self == hMenu)
 +    {
 +        MenuInfo.Wnd = hWnd;
 +        MenuSetRosMenuInfo(&MenuInfo);
 +    }
 +
 +    /* Send WM_ENTERMENULOOP and WM_INITMENU message only if TPM_NONOTIFY flag is not specified */
 +    if (!(wFlags & TPM_NONOTIFY))
 +       SendMessageW( hWnd, WM_ENTERMENULOOP, bPopup, 0 );
 +
 +    SendMessageW( hWnd, WM_SETCURSOR, (WPARAM)hWnd, HTCAPTION );
 +
 +    if (!(wFlags & TPM_NONOTIFY))
 +    {
 +       SendMessageW( hWnd, WM_INITMENU, (WPARAM)hMenu, 0 );
 +       /* If an app changed/recreated menu bar entries in WM_INITMENU
 +        * menu sizes will be recalculated once the menu created/shown.
 +        */
 +
 +       if (!MenuInfo.Height)
 +       {
 +          /* app changed/recreated menu bar entries in WM_INITMENU
 +             Recalculate menu sizes else clicks will not work */
 +             SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
 +                       SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
 +
 +       }
 +    }
 +
 +    IntNotifyWinEvent( EVENT_SYSTEM_MENUSTART,
 +                       hWnd,
 +                       MenuInfo.Flags & MF_SYSMENU ? OBJID_SYSMENU : OBJID_MENU,
 +                       CHILDID_SELF, 0);
 +    return TRUE;
 +}
 +/***********************************************************************
 + *           MenuExitTracking
 + */
 +static BOOL FASTCALL MenuExitTracking(HWND hWnd, BOOL bPopup)
 +{
 +    TRACE("hwnd=%p\n", hWnd);
 +
 +    IntNotifyWinEvent( EVENT_SYSTEM_MENUEND, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
 +    SendMessageW( hWnd, WM_EXITMENULOOP, bPopup, 0 );
 +    ShowCaret(0);
 +    top_popup = 0;
 +    top_popup_hmenu = NULL;
 +    return TRUE;
 +}
 +
 +/***********************************************************************
 + *           MenuTrackMouseMenuBar
 + *
 + * Menu-bar tracking upon a mouse event. Called from NC_HandleSysCommand().
 + */
 +VOID MenuTrackMouseMenuBar( HWND hWnd, ULONG ht, POINT pt)
 +{
 +    HMENU hMenu = (ht == HTSYSMENU) ? NtUserGetSystemMenu( hWnd, FALSE) : GetMenu(hWnd);
 +    UINT wFlags = TPM_BUTTONDOWN | TPM_LEFTALIGN | TPM_LEFTBUTTON;
 +
 +    TRACE("wnd=%p ht=0x%04x (%ld,%ld)\n", hWnd, ht, pt.x, pt.y);
 +
 +    if (IsMenu(hMenu))
 +    {
 +        /* map point to parent client coordinates */
 +        HWND Parent = GetAncestor(hWnd, GA_PARENT );
 +        if (Parent != GetDesktopWindow())
 +        {
 +            ScreenToClient(Parent, &pt);
 +        }
 +
 +        MenuInitTracking(hWnd, hMenu, FALSE, wFlags);
 +        MenuTrackMenu(hMenu, wFlags, pt.x, pt.y, hWnd, NULL);
 +        MenuExitTracking(hWnd, FALSE);
 +    }
 +}
 +
 +
 +/***********************************************************************
 + *           MenuTrackKbdMenuBar
 + *
 + * Menu-bar tracking upon a keyboard event. Called from NC_HandleSysCommand().
 + */
 +VOID MenuTrackKbdMenuBar(HWND hwnd, UINT wParam, WCHAR wChar)
 +{
 +    UINT uItem = NO_SELECTED_ITEM;
 +    HMENU hTrackMenu;
 +    ROSMENUINFO MenuInfo;
 +    UINT wFlags = TPM_LEFTALIGN | TPM_LEFTBUTTON;
 +
 +    TRACE("hwnd %p wParam 0x%04x wChar 0x%04x\n", hwnd, wParam, wChar);
 +
 +    /* find window that has a menu */
 +
 +    while (!((GetWindowLongPtrW( hwnd, GWL_STYLE ) &
 +                                         (WS_CHILD | WS_POPUP)) != WS_CHILD))
 +        if (!(hwnd = GetAncestor( hwnd, GA_PARENT ))) return;
 +
 +    /* check if we have to track a system menu */
 +
 +    hTrackMenu = GetMenu( hwnd );
 +    if (!hTrackMenu || IsIconic(hwnd) || wChar == ' ' )
 +    {
 +        if (!(GetWindowLongPtrW( hwnd, GWL_STYLE ) & WS_SYSMENU)) return;
 +        hTrackMenu = NtUserGetSystemMenu(hwnd, FALSE);
 +        uItem = 0;
 +        wParam |= HTSYSMENU; /* prevent item lookup */
 +    }
 +
 +    if (!IsMenu( hTrackMenu )) return;
 +
 +    MenuInitTracking( hwnd, hTrackMenu, FALSE, wFlags );
 +
 +    if (! MenuGetRosMenuInfo(&MenuInfo, hTrackMenu))
 +    {
 +      goto track_menu;
 +    }
 +
 +    if( wChar && wChar != ' ' )
 +    {
 +        uItem = MenuFindItemByKey( hwnd, &MenuInfo, wChar, (wParam & HTSYSMENU) );
 +        if ( uItem >= (UINT)(-2) )
 +        {
 +            if( uItem == (UINT)(-1) ) MessageBeep(0);
 +            /* schedule end of menu tracking */
 +            wFlags |= TF_ENDMENU;
 +            goto track_menu;
 +        }
 +    }
 +
 +    MenuSelectItem( hwnd, &MenuInfo, uItem, TRUE, 0 );
 +
 +    if (wParam & HTSYSMENU)
 +    {
 +        /* prevent sysmenu activation for managed windows on Alt down/up */
 +//        if (GetPropA( hwnd, "__wine_x11_managed" ))
 +            wFlags |= TF_ENDMENU; /* schedule end of menu tracking */
 +    }
 +    else
 +    {
 +        if( uItem == NO_SELECTED_ITEM )
 +            MenuMoveSelection( hwnd, &MenuInfo, ITEM_NEXT );
 +        else
 +            PostMessageW( hwnd, WM_KEYDOWN, VK_DOWN, 0L );
 +    }
 +
 +track_menu:
 +    MenuTrackMenu( hTrackMenu, wFlags, 0, 0, hwnd, NULL );
 +    MenuExitTracking( hwnd, FALSE );
 +
 +}
 +
 +/**********************************************************************
 + *           TrackPopupMenuEx   (USER32.@)
 + */
 +BOOL WINAPI TrackPopupMenuEx( HMENU Menu, UINT Flags, int x, int y,
 +                              HWND Wnd, LPTPMPARAMS Tpm)
 +{
 +    BOOL ret = FALSE;
 +    ROSMENUINFO MenuInfo;
 +
 +    if (!IsMenu(Menu))
 +    {
 +      SetLastError( ERROR_INVALID_MENU_HANDLE );
 +      return FALSE;
 +    }
 +
 +    MenuGetRosMenuInfo(&MenuInfo, Menu);
 +    if (IsWindow(MenuInfo.Wnd))
 +    {
 +        SetLastError( ERROR_POPUP_ALREADY_ACTIVE );
 +        return FALSE;
 +    }
 +
 +    MenuInitTracking(Wnd, Menu, TRUE, Flags);
 +
 +    /* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
 +    if (!(Flags & TPM_NONOTIFY))
 +        SendMessageW(Wnd, WM_INITMENUPOPUP, (WPARAM) Menu, 0);
 +
 +    if (MenuShowPopup(Wnd, Menu, 0, Flags, x, y, 0, 0 ))
 +       ret = MenuTrackMenu(Menu, Flags | TPM_POPUPMENU, 0, 0, Wnd,
 +                           Tpm ? &Tpm->rcExclude : NULL);
 +    MenuExitTracking(Wnd, TRUE);
 +    return ret;
 +}
 +
 +/**********************************************************************
 + *           TrackPopupMenu     (USER32.@)
 + */
 +BOOL WINAPI TrackPopupMenu( HMENU Menu, UINT Flags, int x, int y,
 +                            int Reserved, HWND Wnd, CONST RECT *Rect)
 +{
 +    return TrackPopupMenuEx( Menu, Flags, x, y, Wnd, NULL);
 +}
 +
 +/*
 + *  From MSDN:
 + *  The MFT_BITMAP, MFT_SEPARATOR, and MFT_STRING values cannot be combined
 + *  with one another. Also MFT_OWNERDRAW. Set fMask to MIIM_TYPE to use fType.
 + *
 + *  Windows 2K/XP: fType is used only if fMask has a value of MIIM_FTYPE.
 + *
 + *  MIIM_TYPE: Retrieves or sets the fType and dwTypeData members. Windows
 + *  2K/XP: MIIM_TYPE is replaced by  MIIM_BITMAP, MIIM_FTYPE, and MIIM_STRING.
 + *  MFT_STRING is replaced by MIIM_STRING.
 + *  (So, I guess we should use MIIM_STRING only for strings?)
 + *
 + *  MIIM_FTYPE: Windows 2K/Windows XP: Retrieves or sets the fType member.
 + *
 + *  Based on wine, SetMenuItemInfo_common:
 + *  1) set MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP any one with MIIM_TYPE,
 + *     it will result in a error.
 + *  2) set menu mask to MIIM_FTYPE and MFT_BITMAP ftype it will result in a error.
 + *     These conditions are addressed in Win32k IntSetMenuItemInfo.
 + *
 + */
 +static
 +BOOL
 +FASTCALL
 +MenuSetItemData(
 +  LPMENUITEMINFOW mii,
 +  UINT Flags,
 +  UINT_PTR IDNewItem,
 +  LPCWSTR NewItem,
 +  BOOL Unicode)
 +{
 +/*
 + * Let us assume MIIM_FTYPE is set and building a new menu item structure.
 + */
 +  if(Flags & MF_BITMAP)
 +  {
 +     mii->fMask |= MIIM_BITMAP;   /* Use the new way of seting hbmpItem.*/
 +     mii->hbmpItem = (HBITMAP) NewItem;
 +
 +     if (Flags & MF_HELP)
 +     {
 +         /* increase ident */
 +         mii->fType |= MF_HELP;
 +     }
 +  }
 +  else if(Flags & MF_OWNERDRAW)
 +  {
 +    mii->fType |= MFT_OWNERDRAW;
 +    mii->fMask |= MIIM_DATA;
 +    mii->dwItemData = (DWORD_PTR) NewItem;
 +  }
 +  else if (Flags & MF_SEPARATOR)
 +  {
 +    mii->fType |= MFT_SEPARATOR;
 +    if (!(Flags & (MF_GRAYED|MF_DISABLED)))
 +      Flags |= MF_GRAYED|MF_DISABLED;
 +  }
 +  else /* Default action MF_STRING. */
 +  {
 +    /* Item beginning with a backspace is a help item */
 +    if (NewItem != NULL)
 +    {
 +       if (Unicode)
 +       {
 +          if (*NewItem == '\b')
 +          {
 +             mii->fType |= MF_HELP;
 +             NewItem++;
 +          }
 +       }
 +       else
 +       {
 +          LPCSTR NewItemA = (LPCSTR) NewItem;
 +          if (*NewItemA == '\b')
 +          {
 +             mii->fType |= MF_HELP;
 +             NewItemA++;
 +             NewItem = (LPCWSTR) NewItemA;
 +          }
 +       }
 +
 +       if (Flags & MF_HELP)
 +         mii->fType |= MF_HELP;
 +       mii->fMask |= MIIM_STRING;
 +       mii->fType |= MFT_STRING; /* Zero */
 +       mii->dwTypeData = (LPWSTR)NewItem;
 +       if (Unicode)
 +         mii->cch = (NULL == NewItem ? 0 : strlenW(NewItem));
 +       else
 +         mii->cch = (NULL == NewItem ? 0 : strlen((LPCSTR)NewItem));
 +    }
 +    else
 +    {
 +      mii->fType |= MFT_SEPARATOR;
 +      if (!(Flags & (MF_GRAYED|MF_DISABLED)))
 +        Flags |= MF_GRAYED|MF_DISABLED;
 +    }
 +  }
 +
 +  if(Flags & MF_RIGHTJUSTIFY) /* Same as MF_HELP */
 +  {
 +    mii->fType |= MFT_RIGHTJUSTIFY;
 +  }
 +
 +  if(Flags & MF_MENUBREAK)
 +  {
 +    mii->fType |= MFT_MENUBREAK;
 +  }
 +  else if(Flags & MF_MENUBARBREAK)
 +  {
 +    mii->fType |= MFT_MENUBARBREAK;
 +  }
 +
 +  if(Flags & MF_GRAYED || Flags & MF_DISABLED)
 +  {
 +    if (Flags & MF_GRAYED)
 +      mii->fState |= MF_GRAYED;
 +
 +    if (Flags & MF_DISABLED)
 +      mii->fState |= MF_DISABLED;
 +
 +    mii->fMask |= MIIM_STATE;
 +  }
 +  else if (Flags & MF_HILITE)
 +  {
 +    mii->fState |= MF_HILITE;
 +    mii->fMask |= MIIM_STATE;
 +  }
 +  else /* default state */
 +  {
 +    mii->fState |= MFS_ENABLED;
 +    mii->fMask |= MIIM_STATE;
 +  }
 +
 +  if(Flags & MF_POPUP)
 +  {
 +    mii->fType |= MF_POPUP;
 +    mii->fMask |= MIIM_SUBMENU;
 +    mii->hSubMenu = (HMENU)IDNewItem;
 +  }
 +  else
 +  {
 +    mii->fMask |= MIIM_ID;
 +    mii->wID = (UINT)IDNewItem;
 +  }
 +  return TRUE;
 +}
 +
 +NTSTATUS WINAPI
 +User32CallLoadMenuFromKernel(PVOID Arguments, ULONG ArgumentLength)
 +{
 +  PLOADMENU_CALLBACK_ARGUMENTS Common;
 +  LRESULT Result;
 +
 +  Common = (PLOADMENU_CALLBACK_ARGUMENTS) Arguments;
 +
 +  Result = (LRESULT)LoadMenuW( Common->hModule,
 +                               IS_INTRESOURCE(Common->MenuName[0]) ?
 +                                  MAKEINTRESOURCE(Common->MenuName[0]) :
 +                                        (LPCWSTR)&Common->MenuName);
 +
 +  return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS);
 +}
 +
 +
 +/* FUNCTIONS *****************************************************************/
 +
 +/*static BOOL
 +MenuIsStringItem(ULONG TypeData)
 +{
 +  return(MF_STRING == MENU_ITEM_TYPE(ItemInfo->fType));
 +}*/
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +AppendMenuA(HMENU hMenu,
 +          UINT uFlags,
 +          UINT_PTR uIDNewItem,
 +          LPCSTR lpNewItem)
 +{
 +  return(InsertMenuA(hMenu, -1, uFlags | MF_BYPOSITION, uIDNewItem,
 +                   lpNewItem));
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +AppendMenuW(HMENU hMenu,
 +          UINT uFlags,
 +          UINT_PTR uIDNewItem,
 +          LPCWSTR lpNewItem)
 +{
 +  return(InsertMenuW(hMenu, -1, uFlags | MF_BYPOSITION, uIDNewItem,
 +                   lpNewItem));
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +DWORD WINAPI
 +CheckMenuItem(HMENU hmenu,
 +            UINT uIDCheckItem,
 +            UINT uCheck)
 +{
 +  return NtUserCheckMenuItem(hmenu, uIDCheckItem, uCheck);
 +}
 +
 +static
 +BOOL
 +MenuCheckMenuRadioItem(HMENU hMenu, UINT idFirst, UINT idLast, UINT idCheck, UINT uFlags, BOOL bCheck, PUINT pChecked, PUINT pUnchecked, PUINT pMenuChanged)
 +{
 +  UINT ItemCount, i;
 +  PROSMENUITEMINFO Items = NULL;
 +  UINT cChecked, cUnchecked;
 +  BOOL bRet = TRUE;
 +  //ROSMENUINFO mi;
 +
 +  if(idFirst > idLast)
 +      return FALSE;
 +
 +  ItemCount = GetMenuItemCount(hMenu);
 +
 +  //mi.cbSize = sizeof(ROSMENUINFO);
 +  //if(!NtUserMenuInfo(hmenu, &mi, FALSE)) return ret;
 +
 +
 +  if(MenuGetAllRosMenuItemInfo(hMenu, &Items) <= 0)
 +  {
 +    ERR("MenuGetAllRosMenuItemInfo failed\n");
 +    return FALSE;
 +  }
 +
 +  cChecked = cUnchecked = 0;
 +
 +  for (i = 0 ; i < ItemCount; i++)
 +  {
 +    BOOL check = FALSE;
 +    if (0 != (Items[i].fType & MF_MENUBARBREAK)) continue;
 +    if (0 != (Items[i].fType & MF_SEPARATOR)) continue;
 +
 +    if ((Items[i].fType & MF_POPUP) && (uFlags == MF_BYCOMMAND))
 +    {
 +      MenuCheckMenuRadioItem(Items[i].hSubMenu, idFirst, idLast, idCheck, uFlags, bCheck, pChecked, pUnchecked, pMenuChanged);
 +      continue;
 +    }
 +    if (uFlags & MF_BYPOSITION)
 +    {
 +      if (i < idFirst || i > idLast)
 +        continue;
 +
 +      if (i == idCheck)
 +      {
 +        cChecked++;
 +        check = TRUE;
 +      }
 +      else
 +      {
 +        cUnchecked++;
 +      }
 +    }
 +      else
 +      {
 +        if (Items[i].wID < idFirst || Items[i].wID > idLast)
 +          continue;
 +
 +        if (Items[i].wID == idCheck)
 +        {
 +          cChecked++;
 +          check = TRUE;
 +        }
 +        else
 +        {
 +          cUnchecked++;
 +        }
 +      }
 +
 +      if (!bCheck)
 +        continue;
 +
 +      Items[i].fMask = MIIM_STATE | MIIM_FTYPE;
 +      if (check)
 +      {
 +        Items[i].fType |= MFT_RADIOCHECK;
 +        Items[i].fState |= MFS_CHECKED;
 +      }
 +      else
 +      {
 +        Items[i].fState &= ~MFS_CHECKED;
 +      }
 +
 +      if(!MenuSetRosMenuItemInfo(hMenu, i ,&Items[i]))
 +      {
 +        ERR("MenuSetRosMenuItemInfo failed\n");
 +        bRet = FALSE;
 +        break;
 +      }
 +  }
 +  HeapFree(GetProcessHeap(), 0, Items);
 +
 +  *pChecked += cChecked;
 +  *pUnchecked += cUnchecked;
 +
 +  if (cChecked || cUnchecked)
 +    (*pMenuChanged)++;
 +
 +  return bRet;
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +CheckMenuRadioItem(HMENU hmenu,
 +                 UINT idFirst,
 +                 UINT idLast,
 +                 UINT idCheck,
 +                 UINT uFlags)
 +{
 +  UINT cChecked = 0;
 +  UINT cUnchecked = 0;
 +  UINT cMenuChanged = 0;
 +
 +  if (!MenuCheckMenuRadioItem(hmenu, idFirst, idLast, idCheck, uFlags, FALSE, &cChecked, &cUnchecked, &cMenuChanged))
 +    return FALSE;
 +
 +  if (cMenuChanged > 1)
 +    return FALSE;
 +
 +  cMenuChanged = 0;
 +  cChecked = 0;
 +  cUnchecked = 0;
 +
 +  if (!MenuCheckMenuRadioItem(hmenu, idFirst, idLast, idCheck, uFlags, TRUE, &cChecked, &cUnchecked, &cMenuChanged))
 +    return FALSE;
 +
 +  return (cChecked != 0);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +HMENU WINAPI
 +CreateMenu(VOID)
 +{
 +  MenuLoadBitmaps();
 +  return (HMENU)NtUserCallNoParam(NOPARAM_ROUTINE_CREATEMENU);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +HMENU WINAPI
 +CreatePopupMenu(VOID)
 +{
 +  MenuLoadBitmaps();
 +  return (HMENU)NtUserCallNoParam(NOPARAM_ROUTINE_CREATEMENUPOPUP);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +DrawMenuBar(HWND hWnd)
 +{
 +//  return (BOOL)NtUserCallHwndLock(hWnd, HWNDLOCK_ROUTINE_DRAWMENUBAR);
 +  ROSMENUINFO MenuInfo;
 +  HMENU hMenu;
 +  hMenu = GetMenu(hWnd);
 +  if (!hMenu)
 +     return FALSE;
 +  MenuGetRosMenuInfo(&MenuInfo, hMenu);
 +  MenuInfo.Height = 0; // make sure to recalc size
 +  MenuSetRosMenuInfo(&MenuInfo);
 +  
 +  SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
 +                  SWP_NOZORDER | SWP_FRAMECHANGED );
 +  return TRUE;
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +EnableMenuItem(HMENU hMenu,
 +             UINT uIDEnableItem,
 +             UINT uEnable)
 +{
 +  return NtUserEnableMenuItem(hMenu, uIDEnableItem, uEnable);
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +EndMenu(VOID)
 +{
 +  GUITHREADINFO guii;
 +  guii.cbSize = sizeof(GUITHREADINFO);
 +  if(GetGUIThreadInfo(GetCurrentThreadId(), &guii) && guii.hwndMenuOwner)
 +  {
 +    if (!fEndMenu &&
 +         top_popup &&
 +         guii.hwndMenuOwner != top_popup )
 +    {
 +       ERR("Capture GUI pti hWnd does not match top_popup!\n");
 +    }
 +  }
 +
 +  /* if we are in the menu code, and it is active */
 +  if (!fEndMenu && top_popup)
 +  {
 +      /* terminate the menu handling code */
 +      fEndMenu = TRUE;
 +
 +      /* needs to be posted to wakeup the internal menu handler */
 +      /* which will now terminate the menu, in the event that */
 +      /* the main window was minimized, or lost focus, so we */
 +      /* don't end up with an orphaned menu */
 +      PostMessageW( top_popup, WM_CANCELMODE, 0, 0);
 +  }
 +  return TRUE;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +HMENU WINAPI
 +GetMenu(HWND hWnd)
 +{
 +       PWND Wnd = ValidateHwnd(hWnd);
 +
 +       if (!Wnd)
 +               return NULL;
 +
 +       return UlongToHandle(Wnd->IDMenu);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +LONG WINAPI
 +GetMenuCheckMarkDimensions(VOID)
 +{
 +  return(MAKELONG(GetSystemMetrics(SM_CXMENUCHECK),
 +                GetSystemMetrics(SM_CYMENUCHECK)));
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +UINT WINAPI
 +GetMenuDefaultItem(HMENU hMenu,
 +                 UINT fByPos,
 +                 UINT gmdiFlags)
 +{
 +  return NtUserGetMenuDefaultItem(hMenu, fByPos, gmdiFlags);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +GetMenuInfo(HMENU hmenu,
 +          LPMENUINFO lpcmi)
 +{
 +  ROSMENUINFO mi;
 +  BOOL res = FALSE;
 +
 +  if(!lpcmi || (lpcmi->cbSize != sizeof(MENUINFO)))
 +    return FALSE;
 +
 +  RtlZeroMemory(&mi, sizeof(MENUINFO));
 +  mi.cbSize = sizeof(MENUINFO);
 +  mi.fMask = lpcmi->fMask;
 +
 +  res = NtUserMenuInfo(hmenu, &mi, FALSE);
 +
 +  memcpy(lpcmi, &mi, sizeof(MENUINFO));
 +  return res;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +int WINAPI
 +GetMenuItemCount(HMENU Menu)
 +{
 +  ROSMENUINFO MenuInfo;
 +
 +  return MenuGetRosMenuInfo(&MenuInfo, Menu) ? MenuInfo.MenuItemCount : 0;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +UINT WINAPI
 +GetMenuItemID(HMENU hMenu,
 +            int nPos)
 +{
 +  ROSMENUITEMINFO mii;
 +
 +  mii.cbSize = sizeof(MENUITEMINFOW);
 +  mii.fMask = MIIM_ID | MIIM_SUBMENU;
 +
 +  if (! NtUserMenuItemInfo(hMenu, nPos, MF_BYPOSITION, &mii, FALSE))
 +    {
 +      return -1;
 +    }
 +
 +  if (NULL != mii.hSubMenu)
 +    {
 +      return -1;
 +    }
 +  if (0 == mii.wID)
 +    {
 +      return -1;
 +    }
 +
 +  return mii.wID;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +GetMenuItemInfoA(
 +   HMENU Menu,
 +   UINT Item,
 +   BOOL ByPosition,
 +   LPMENUITEMINFOA mii)
 +{
 +   MENUITEMINFOW miiW;
 +   LPSTR AnsiBuffer;
 +   INT Count;
 +
 +   if (mii->cbSize != sizeof(MENUITEMINFOA) &&
 +       mii->cbSize != sizeof(MENUITEMINFOA) - sizeof(HBITMAP))
 +   {
 +      SetLastError(ERROR_INVALID_PARAMETER);
 +      return FALSE;
 +   }
 +
 +   if(!(mii->fMask & (MIIM_TYPE | MIIM_STRING)))
 +   {
 +      /* No text requested, just pass on */
 +      return NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO) mii, FALSE);
 +   }
 +
 +   AnsiBuffer = mii->dwTypeData;
 +   Count = miiW.cch = mii->cch;
 +   RtlCopyMemory(&miiW, mii, mii->cbSize);
 +   miiW.dwTypeData = 0;
 +
 +   if (AnsiBuffer)
 +   {
 +      miiW.dwTypeData = RtlAllocateHeap(GetProcessHeap(), 0,
 +                                        miiW.cch * sizeof(WCHAR));
 +      if (miiW.dwTypeData == NULL) return FALSE;
 +      miiW.dwTypeData[0] = 0;
 +   }
 +
 +   if (!NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO)&miiW, FALSE))
 +   {
 +      if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData);
 +      return FALSE;
 +   }
 +
 +   RtlCopyMemory(mii, &miiW, miiW.cbSize);
 +
 +   if (!AnsiBuffer || !Count)
 +   {
 +      if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData);
 +      mii->dwTypeData = AnsiBuffer;
 +      mii->cch = miiW.cch;
 +      return TRUE;
 +   }
 +
 +   if ((miiW.fMask & MIIM_STRING) || (IS_STRING_ITEM(miiW.fType)))
 +   {
 +      if (miiW.cch)
 +      {
 +         if (!WideCharToMultiByte(CP_ACP, 0, miiW.dwTypeData, miiW.cch, AnsiBuffer, mii->cch, NULL, NULL))
 +         {
 +            AnsiBuffer[0] = 0;
 +         }
 +         if (Count > miiW.cch)
 +         {
 +            AnsiBuffer[miiW.cch] = 0;
 +         }
 +         mii->cch = mii->cch;
 +      }
 +   }
 +   else
 +   {
 +      AnsiBuffer[0] = 0;
 +   }
 +
 +   RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData);
 +   mii->dwTypeData = AnsiBuffer;
 +
 +   return TRUE;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +GetMenuItemInfoW(
 +   HMENU Menu,
 +   UINT Item,
 +   BOOL ByPosition,
 +   LPMENUITEMINFOW mii)
 +{
 +   MENUITEMINFOW miiW;
 +   LPWSTR String;
 +   INT Count;
 +
 +   if (mii->cbSize != sizeof(MENUITEMINFOW) &&
 +       mii->cbSize != sizeof(MENUITEMINFOW) - sizeof(HBITMAP))
 +   {
 +      SetLastError(ERROR_INVALID_PARAMETER);
 +      return FALSE;
 +   }
 +
 +   if(!(mii->fMask & (MIIM_TYPE | MIIM_STRING)))
 +   {
 +      /* No text requested, just pass on */
 +      return NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO) mii, FALSE);
 +   }
 +
 +   String = mii->dwTypeData;
 +   Count = mii->cch;
 +   RtlCopyMemory(&miiW, mii, mii->cbSize);
 +   miiW.dwTypeData = 0;
 +
 +   if (String)
 +   {
 +      miiW.dwTypeData = RtlAllocateHeap(GetProcessHeap(), 0,
 +                                        miiW.cch * sizeof(WCHAR));
 +      if (miiW.dwTypeData == NULL) return FALSE;
 +      miiW.dwTypeData[0] = 0;
 +   }
 +
 +   if (!NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO) &miiW, FALSE))
 +   {
 +      if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData);
 +      return FALSE;
 +   }
 +
 +   RtlCopyMemory(mii, &miiW, miiW.cbSize); // Okay to over write user data.
 +
 +   if (!String || !Count)
 +   {
 +      if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData);
 +      mii->dwTypeData = String; // may not be zero.
 +      mii->cch = miiW.cch;
 +      return TRUE;
 +   }
 +
 +   if ((miiW.fMask & MIIM_STRING) || (IS_STRING_ITEM(miiW.fType)))
 +   {
 +      lstrcpynW( String, miiW.dwTypeData, Count );
 +   }
 +
 +   RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData);
 +   mii->dwTypeData = String;
 +   mii->cch = strlenW(String);
 +   return TRUE;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +UINT
 +WINAPI
 +GetMenuState(
 +  HMENU hMenu,
 +  UINT uId,
 +  UINT uFlags)
 +{
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUITEMINFO mii;
 +  memset( &mii, 0, sizeof(mii) );
 +  mii.cbSize = sizeof(MENUITEMINFOW);
 +  mii.fMask = MIIM_STATE | MIIM_FTYPE | MIIM_SUBMENU;
 +
 +  SetLastError(0);
 +  if(NtUserMenuItemInfo(hMenu, uId, uFlags, &mii, FALSE))
 +    {
 +      UINT nSubItems = 0;
 +      if(mii.hSubMenu)
 +        {
 +          if (! MenuGetRosMenuInfo(&MenuInfo, mii.hSubMenu))
 +            {
 +              return (UINT) -1;
 +            }
 +          nSubItems = MenuInfo.MenuItemCount;
 +
 +          /* FIXME - ported from wine, does that work (0xff)? */
 +          if(GetLastError() != ERROR_INVALID_MENU_HANDLE)
 +            return (nSubItems << 8) | ((mii.fState | mii.fType) & 0xff);
 +
 +          return (UINT)-1; /* Invalid submenu */
 +        }
 +
 +      /* FIXME - ported from wine, does that work? */
 +      return (mii.fType | mii.fState);
 +    }
 +
 +  return (UINT)-1;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +int
 +WINAPI
 +GetMenuStringA(
 +  HMENU hMenu,
 +  UINT uIDItem,
 +  LPSTR lpString,
 +  int nMaxCount,
 +  UINT uFlag)
 +{
 +  MENUITEMINFOA mii;
 +  memset( &mii, 0, sizeof(mii) );
 +  mii.dwTypeData = lpString;
 +  mii.fMask = MIIM_STRING | MIIM_FTYPE;
 +  mii.fType = MFT_STRING;
 +  mii.cbSize = sizeof(MENUITEMINFOA);
 +  mii.cch = nMaxCount;
 +
 +  if(!(GetMenuItemInfoA( hMenu, uIDItem, (BOOL)(MF_BYPOSITION & uFlag),&mii)))
 +     return 0;
 +  else
 +     return mii.cch;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +int
 +WINAPI
 +GetMenuStringW(
 +  HMENU hMenu,
 +  UINT uIDItem,
 +  LPWSTR lpString,
 +  int nMaxCount,
 +  UINT uFlag)
 +{
 +  MENUITEMINFOW miiW;
 +  memset( &miiW, 0, sizeof(miiW) );
 +  miiW.dwTypeData = lpString;
 +  miiW.fMask = MIIM_STRING | MIIM_FTYPE;
 +  miiW.fType = MFT_STRING;
 +  miiW.cbSize = sizeof(MENUITEMINFOW);
 +  miiW.cch = nMaxCount;
 +
 +  if(!(GetMenuItemInfoW( hMenu, uIDItem, (BOOL)(MF_BYPOSITION & uFlag),&miiW)))
 +     return 0;
 +  else
 +     return miiW.cch;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +HMENU
 +WINAPI
 +GetSubMenu(
 +  HMENU hMenu,
 +  int nPos)
 +{
 +  ROSMENUITEMINFO mi;
 +
 +  mi.cbSize = sizeof(MENUITEMINFOW);
 +  mi.fMask = MIIM_SUBMENU;
 +
 +  if (NtUserMenuItemInfo(hMenu, (UINT)nPos, MF_BYPOSITION, &mi, FALSE))
 +    {
 +      return IsMenu(mi.hSubMenu) ? mi.hSubMenu : NULL;
 +    }
 +
 +  return NULL;
 +}
 +
 +/*
 + * @implemented
 + */
 +HMENU
 +WINAPI
 +GetSystemMenu(
 +  HWND hWnd,
 +  BOOL bRevert)
 +{
 +  HMENU TopMenu;
 +
 +  TopMenu = NtUserGetSystemMenu(hWnd, bRevert);
 +
 +  return NULL == TopMenu ? NULL : GetSubMenu(TopMenu, 0);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +InsertMenuA(
 +  HMENU hMenu,
 +  UINT uPosition,
 +  UINT uFlags,
 +  UINT_PTR uIDNewItem,
 +  LPCSTR lpNewItem)
 +{
 +  MENUITEMINFOA mii;
 +  memset( &mii, 0, sizeof(mii) );
 +  mii.cbSize = sizeof(MENUITEMINFOA);
 +  mii.fMask = MIIM_FTYPE;
 +
 +  MenuSetItemData((LPMENUITEMINFOW) &mii,
 +                 uFlags,
 +                 uIDNewItem,
 +                (LPCWSTR) lpNewItem,
 +                 FALSE);
 +
 +  return InsertMenuItemA(hMenu, uPosition, (BOOL)((MF_BYPOSITION & uFlags) > 0), &mii);
 +}
 +
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +InsertMenuItemA(
 +  HMENU hMenu,
 +  UINT uItem,
 +  BOOL fByPosition,
 +  LPCMENUITEMINFOA lpmii)
 +{
 +  MENUITEMINFOW mi;
 +  UNICODE_STRING MenuText;
 +  BOOL res = FALSE;
 +  BOOL CleanHeap = FALSE;
 +  NTSTATUS Status;
 +
 +  if((lpmii->cbSize == sizeof(MENUITEMINFOA)) ||
 +     (lpmii->cbSize == sizeof(MENUITEMINFOA) - sizeof(HBITMAP)))
 +  {
 +    RtlCopyMemory ( &mi, lpmii, lpmii->cbSize );
 +
 +    if( lpmii->cbSize != sizeof( MENUITEMINFOW))
 +    {
 +       mi.cbSize = sizeof( MENUITEMINFOW);
 +       mi.hbmpItem = NULL;
 +    }
 +    /* copy the text string */
 +    if (((mi.fMask & MIIM_STRING) ||
 +        ((mi.fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(mi.fType) == MF_STRING)))
 +          && mi.dwTypeData != NULL)
 +    {
 +      Status = RtlCreateUnicodeStringFromAsciiz(&MenuText, (LPSTR)mi.dwTypeData);
 +      if (!NT_SUCCESS (Status))
 +      {
 +        SetLastError (RtlNtStatusToDosError(Status));
 +        return FALSE;
 +      }
 +      mi.dwTypeData = MenuText.Buffer;
 +      mi.cch = MenuText.Length / sizeof(WCHAR);
 +      CleanHeap = TRUE;
 +    }
 +    res = NtUserThunkedMenuItemInfo(hMenu, uItem, fByPosition, TRUE, &mi, NULL);
 +
 +    if ( CleanHeap ) RtlFreeUnicodeString ( &MenuText );
 +  }
 +  return res;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +InsertMenuItemW(
 +  HMENU hMenu,
 +  UINT uItem,
 +  BOOL fByPosition,
 +  LPCMENUITEMINFOW lpmii)
 +{
 +  MENUITEMINFOW mi;
 +  UNICODE_STRING MenuText;
 +  BOOL res = FALSE;
 +
 +  /* while we could just pass 'lpmii' to win32k, we make a copy so that
 +     if a bad user passes bad data, we crash his process instead of the
 +     entire kernel */
 +
 +  if((lpmii->cbSize == sizeof(MENUITEMINFOW)) ||
 +     (lpmii->cbSize == sizeof(MENUITEMINFOW) - sizeof(HBITMAP)))
 +  {
 +    RtlCopyMemory(&mi, lpmii, lpmii->cbSize);
 +
 +    if( lpmii->cbSize != sizeof( MENUITEMINFOW))
 +    {
 +       mi.cbSize = sizeof( MENUITEMINFOW);
 +       mi.hbmpItem = NULL;
 +    }
 +    /* copy the text string */
 +    if (((mi.fMask & MIIM_STRING) ||
 +        ((mi.fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(mi.fType) == MF_STRING)))
 +          && mi.dwTypeData != NULL)
 +    {
 +      RtlInitUnicodeString(&MenuText, (PWSTR)lpmii->dwTypeData);
 +      mi.dwTypeData = MenuText.Buffer;
 +      mi.cch = MenuText.Length / sizeof(WCHAR);
 +    }
 +    res = NtUserThunkedMenuItemInfo(hMenu, uItem, fByPosition, TRUE, &mi, NULL);
 +  }
 +  return res;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +InsertMenuW(
 +  HMENU hMenu,
 +  UINT uPosition,
 +  UINT uFlags,
 +  UINT_PTR uIDNewItem,
 +  LPCWSTR lpNewItem)
 +{
 +  MENUITEMINFOW mii;
 +  memset( &mii, 0, sizeof(mii) );
 +  mii.cbSize = sizeof(MENUITEMINFOW);
 +  mii.fMask = MIIM_FTYPE;
 +
 +  MenuSetItemData( &mii,
 +                 uFlags,
 +                 uIDNewItem,
 +                 lpNewItem,
 +                 TRUE);
 +
 +  return InsertMenuItemW(hMenu, uPosition, (BOOL)((MF_BYPOSITION & uFlags) > 0), &mii);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +IsMenu(
 +  HMENU Menu)
 +{
 +  if (ValidateHandle(Menu, VALIDATE_TYPE_MENU)) return TRUE;
 +  return FALSE;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +HMENU WINAPI
 +LoadMenuA(HINSTANCE hInstance,
 +        LPCSTR lpMenuName)
 +{
 +  HANDLE Resource = FindResourceA(hInstance, lpMenuName, MAKEINTRESOURCEA(4));
 +  if (Resource == NULL)
 +    {
 +      return(NULL);
 +    }
 +  return(LoadMenuIndirectA((PVOID)LoadResource(hInstance, Resource)));
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +HMENU WINAPI
 +LoadMenuIndirectA(CONST MENUTEMPLATE *lpMenuTemplate)
 +{
 +  return(LoadMenuIndirectW(lpMenuTemplate));
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +HMENU WINAPI
 +LoadMenuIndirectW(CONST MENUTEMPLATE *lpMenuTemplate)
 +{
 +  HMENU hMenu;
 +  WORD version, offset;
 +  LPCSTR p = (LPCSTR)lpMenuTemplate;
 +
 +  version = GET_WORD(p);
 +  p += sizeof(WORD);
 +
 +  switch (version)
 +  {
 +    case 0: /* standard format is version of 0 */
 +      offset = GET_WORD(p);
 +      p += sizeof(WORD) + offset;
 +      if (!(hMenu = CreateMenu())) return 0;
 +      if (!MENU_ParseResource(p, hMenu, TRUE))
 +      {
 +        DestroyMenu(hMenu);
 +        return 0;
 +      }
 +      return hMenu;
 +    case 1: /* extended format is version of 1 */
 +      offset = GET_WORD(p);
 +      p += sizeof(WORD) + offset;
 +      if (!(hMenu = CreateMenu())) return 0;
 +      if (!MENUEX_ParseResource(p, hMenu))
 +      {
 +        DestroyMenu( hMenu );
 +        return 0;
 +      }
 +      return hMenu;
 +    default:
 +      DbgPrint("LoadMenuIndirectW(): version %d not supported.\n", version);
 +      return 0;
 +  }
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +HMENU WINAPI
 +LoadMenuW(HINSTANCE hInstance,
 +        LPCWSTR lpMenuName)
 +{
 +  HANDLE Resource = FindResourceW(hInstance, lpMenuName, RT_MENU);
 +  if (Resource == NULL)
 +    {
 +      return(NULL);
 +    }
 +  return(LoadMenuIndirectW((PVOID)LoadResource(hInstance, Resource)));
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +int
 +WINAPI
 +MenuItemFromPoint(
 +  HWND hWnd,
 +  HMENU hMenu,
 +  POINT ptScreen)
 +{
 +  return NtUserMenuItemFromPoint(hWnd, hMenu, ptScreen.x, ptScreen.y);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +ModifyMenuA(
 +  HMENU hMnu,
 +  UINT uPosition,
 +  UINT uFlags,
 +  UINT_PTR uIDNewItem,
 +  LPCSTR lpNewItem)
 +{
 +  ROSMENUINFO mi;
 +  ROSMENUITEMINFO rmii;
 +  MENUITEMINFOA mii;
 +  memset( &mii, 0, sizeof(mii) );
 +  mii.cbSize = sizeof(MENUITEMINFOA);
 +  mii.fMask = MIIM_FTYPE;
 +
 +  if (!MenuGetRosMenuInfo( &mi, hMnu )) return FALSE;
 +
 +  mi.Height = 0;
 +
 +  if (!MenuSetRosMenuInfo( &mi )) return FALSE;
 +
 +  MenuInitRosMenuItemInfo( &rmii );
 +
 +  if(!MenuGetRosMenuItemInfo( hMnu, uPosition, &rmii)) return FALSE;
 +
 +  if ((rmii.fType & MF_POPUP) && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem))
 +    NtUserDestroyMenu( rmii.hSubMenu );   /* ModifyMenu() spec */
 +
 +  MenuCleanupRosMenuItemInfo( &rmii );
 +
 +  MenuSetItemData((LPMENUITEMINFOW) &mii,
 +                 uFlags,
 +                 uIDNewItem,
 +                (LPCWSTR) lpNewItem,
 +                 FALSE);
 +
 +  return SetMenuItemInfoA( hMnu,
 +                           uPosition,
 +                          (BOOL)(MF_BYPOSITION & uFlags),
 +                           &mii);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +ModifyMenuW(
 +  HMENU hMnu,
 +  UINT uPosition,
 +  UINT uFlags,
 +  UINT_PTR uIDNewItem,
 +  LPCWSTR lpNewItem)
 +{
 +  ROSMENUINFO mi;
 +  ROSMENUITEMINFO rmii;
 +  MENUITEMINFOW mii;
 +  memset ( &mii, 0, sizeof(mii) );
 +  mii.cbSize = sizeof(MENUITEMINFOW);
 +  mii.fMask = MIIM_FTYPE;
 +
 +  if (!MenuGetRosMenuInfo( &mi, hMnu )) return FALSE;
 +
 +  mi.Height = 0; // Force size recalculation.
 +
 +  if (!MenuSetRosMenuInfo( &mi )) return FALSE;
 +
 +  MenuInitRosMenuItemInfo( &rmii );
 +
 +  if(!MenuGetRosMenuItemInfo( hMnu, uPosition, &rmii)) return FALSE;
 +
 +  if ((rmii.fType & MF_POPUP) && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem))
 +    NtUserDestroyMenu( rmii.hSubMenu );   /* ModifyMenu() spec */
 +
 +  MenuCleanupRosMenuItemInfo( &rmii );
 +
 +  /* Init new data for this menu item */
 +  MenuSetItemData( &mii,
 +                 uFlags,
 +                 uIDNewItem,
 +                 lpNewItem,
 +                 TRUE);
 +
 +  /* Now, make Win32k IntSetMenuItemInfo handle the changes to this menu item. */
 +  return SetMenuItemInfoW( hMnu,
 +                           uPosition,
 +                           (BOOL)(MF_BYPOSITION & uFlags),
 +                           &mii);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +SetMenu(HWND hWnd,
 +      HMENU hMenu)
 +{
 +  return NtUserSetMenu(hWnd, hMenu, TRUE);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +SetMenuInfo(
 +  HMENU hmenu,
 +  LPCMENUINFO lpcmi)
 +{
 +  ROSMENUINFO mi;
 +  BOOL res = FALSE;
 +
 +  if (!lpcmi || (lpcmi->cbSize != sizeof(MENUINFO)))
 +  {
 +    SetLastError(ERROR_INVALID_PARAMETER);
 +    return res;
 +  }
 +
 +  memcpy(&mi, lpcmi, sizeof(MENUINFO));
 +  return NtUserMenuInfo(hmenu, &mi, TRUE);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +SetMenuItemBitmaps(
 +  HMENU hMenu,
 +  UINT uPosition,
 +  UINT uFlags,
 +  HBITMAP hBitmapUnchecked,
 +  HBITMAP hBitmapChecked)
 +{
 +  ROSMENUITEMINFO uItem;
 +  memset ( &uItem, 0, sizeof(uItem) );
 +  uItem.fMask = MIIM_STATE | MIIM_BITMAP;
 +
 +  if(!(NtUserMenuItemInfo(hMenu, uPosition,
 +                 (BOOL)(MF_BYPOSITION & uFlags), &uItem, FALSE))) return FALSE;
 +
 +  if (!hBitmapChecked && !hBitmapUnchecked)
 +  {
 +    uItem.fState &= ~MF_USECHECKBITMAPS;
 +  }
 +  else  /* Install new bitmaps */
 +  {
 +    uItem.hbmpChecked = hBitmapChecked;
 +    uItem.hbmpUnchecked = hBitmapUnchecked;
 +    uItem.fState |= MF_USECHECKBITMAPS;
 +  }
 + return NtUserMenuItemInfo(hMenu, uPosition,
 +                                 (BOOL)(MF_BYPOSITION & uFlags), &uItem, TRUE);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +SetMenuItemInfoA(
 +  HMENU hMenu,
 +  UINT uItem,
 +  BOOL fByPosition,
 +  LPCMENUITEMINFOA lpmii)
 +{
 +  MENUITEMINFOW MenuItemInfoW;
 +  UNICODE_STRING UnicodeString;
 +  NTSTATUS Status;
 +  ULONG Result = FALSE;
 +
 +  RtlCopyMemory(&MenuItemInfoW, lpmii, min(lpmii->cbSize, sizeof(MENUITEMINFOW)));
 +
 +  if( lpmii->cbSize != sizeof( MENUITEMINFOW))
 +  {
 +     MenuItemInfoW.cbSize = sizeof( MENUITEMINFOW);
 +     MenuItemInfoW.hbmpItem = NULL;
 +  }
 +/*
 + *  MIIM_STRING              == good
 + *  MIIM_TYPE & MFT_STRING   == good
 + *  MIIM_STRING & MFT_STRING == good
 + *  MIIM_STRING & MFT_OWNERSRAW == good
 + */
 +  if (((MenuItemInfoW.fMask & MIIM_STRING) ||
 +      ((MenuItemInfoW.fMask & MIIM_TYPE) &&
 +                           (MENU_ITEM_TYPE(MenuItemInfoW.fType) == MF_STRING)))
 +        && MenuItemInfoW.dwTypeData != NULL)
 +  {
 +/* cch is ignored when the content of a menu item is set by calling SetMenuItemInfo. */
 +    Status = RtlCreateUnicodeStringFromAsciiz(&UnicodeString,
 +                                     (LPSTR)MenuItemInfoW.dwTypeData);
 +    if (!NT_SUCCESS (Status))
 +    {
 +      SetLastError (RtlNtStatusToDosError(Status));
 +      return FALSE;
 +    }
 +    MenuItemInfoW.dwTypeData = UnicodeString.Buffer;
 +    MenuItemInfoW.cch = UnicodeString.Length / sizeof(WCHAR);
 +  }
 +  else
 +  {
 +    UnicodeString.Buffer = NULL;
 +  }
 +
 +  Result = NtUserMenuItemInfo(hMenu, uItem, fByPosition,
 +                              (PROSMENUITEMINFO)&MenuItemInfoW, TRUE);
 +
 +  if (UnicodeString.Buffer != NULL)
 +  {
 +    RtlFreeUnicodeString(&UnicodeString);
 +  }
 +
 +  return Result;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +SetMenuItemInfoW(
 +  HMENU hMenu,
 +  UINT uItem,
 +  BOOL fByPosition,
 +  LPCMENUITEMINFOW lpmii)
 +{
 +  MENUITEMINFOW MenuItemInfoW;
 +  ULONG Result;
 +
 +  RtlCopyMemory(&MenuItemInfoW, lpmii, min(lpmii->cbSize, sizeof(MENUITEMINFOW)));
 +
 +  if( lpmii->cbSize != sizeof( MENUITEMINFOW))
 +  {
 +     MenuItemInfoW.cbSize = sizeof( MENUITEMINFOW);
 +     MenuItemInfoW.hbmpItem = NULL;
 +  }
 +
 +  if (((MenuItemInfoW.fMask & MIIM_STRING) ||
 +      ((MenuItemInfoW.fMask & MIIM_TYPE) &&
 +                           (MENU_ITEM_TYPE(MenuItemInfoW.fType) == MF_STRING)))
 +        && MenuItemInfoW.dwTypeData != NULL)
 +  {
 +     MenuItemInfoW.cch = strlenW(MenuItemInfoW.dwTypeData);
 +  }
 +  Result = NtUserMenuItemInfo(hMenu, uItem, fByPosition,
 +                            (PROSMENUITEMINFO)&MenuItemInfoW, TRUE);
 +
 +  return Result;
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +SetSystemMenu (
 +  HWND hwnd,
 +  HMENU hMenu)
 +{
 +  if(!hwnd)
 +  {
 +    SetLastError(ERROR_INVALID_WINDOW_HANDLE);
 +    return FALSE;
 +  }
 +  if(!hMenu)
 +  {
 +    SetLastError(ERROR_INVALID_MENU_HANDLE);
 +    return FALSE;
 +  }
 +  return NtUserSetSystemMenu(hwnd, hMenu);
 +}
 +
 +//
 +// Example for the Win32/User32 rewrite.
 +// Def = TrackPopupMenuEx@24=NtUserTrackPopupMenuEx@24
 +//
 +//
 +BOOL
 +WINAPI
 +NEWTrackPopupMenu(
 +  HMENU Menu,
 +  UINT Flags,
 +  int x,
 +  int y,
 +  int Reserved,
 +  HWND Wnd,
 +  CONST RECT *Rect)
 +{
 +  return NtUserTrackPopupMenuEx( Menu,
 +                                Flags,
 +                                    x,
 +                                    y,
 +                                  Wnd,
 +                                 NULL); // LPTPMPARAMS is null
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +DWORD
 +WINAPI
 +GetMenuContextHelpId(HMENU hmenu)
 +{
 +  ROSMENUINFO mi;
 +  mi.cbSize = sizeof(ROSMENUINFO);
 +  mi.fMask = MIM_HELPID;
 +
 +  if(NtUserMenuInfo(hmenu, &mi, FALSE))
 +  {
 +    return mi.dwContextHelpID;
 +  }
 +  return 0;
 +}
 +
 +/*
 + * @unimplemented
 + */
 +BOOL
 +WINAPI
 +MenuWindowProcA(
 +              HWND   hWnd,
 +              ULONG_PTR Result,
 +              UINT   Msg,
 +              WPARAM wParam,
 +              LPARAM lParam
 +              )
 +{
 +  if ( Msg < WM_USER)
 +  {
 +     LRESULT lResult;
 +     lResult = PopupMenuWndProcA(hWnd, Msg, wParam, lParam );
 +     if (Result)
 +     {
 +        Result = (ULONG_PTR)lResult;
 +        return TRUE;
 +     }
 +     return FALSE;
 +  }
 +  return NtUserMessageCall(hWnd, Msg, wParam, lParam, Result, FNID_MENU, TRUE);
 +
 +}
 +
 +/*
 + * @unimplemented
 + */
 +BOOL
 +WINAPI
 +MenuWindowProcW(
 +              HWND   hWnd,
 +              ULONG_PTR Result,
 +              UINT   Msg,
 +              WPARAM wParam,
 +              LPARAM lParam
 +              )
 +{
 +  if ( Msg < WM_USER)
 +  {
 +     LRESULT lResult;
 +     lResult = PopupMenuWndProcW(hWnd, Msg, wParam, lParam );
 +     if (Result)
 +     {
 +        Result = (ULONG_PTR)lResult;
 +        return TRUE;
 +     }
 +     return FALSE;
 +  }
 +  return NtUserMessageCall(hWnd, Msg, wParam, lParam, Result, FNID_MENU, FALSE);
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +ChangeMenuW(
 +    HMENU hMenu,
 +    UINT cmd,
 +    LPCWSTR lpszNewItem,
 +    UINT cmdInsert,
 +    UINT flags)
 +{
 +    /*
 +        FIXME: Word passes the item id in 'cmd' and 0 or 0xffff as cmdInsert
 +        for MF_DELETE. We should check the parameters for all others
 +        MF_* actions also (anybody got a doc on ChangeMenu?).
 +    */
 +
 +    switch(flags & (MF_APPEND | MF_DELETE | MF_CHANGE | MF_REMOVE | MF_INSERT))
 +    {
 +        case MF_APPEND :
 +            return AppendMenuW(hMenu, flags &~ MF_APPEND, cmdInsert, lpszNewItem);
 +
 +        case MF_DELETE :
 +            return DeleteMenu(hMenu, cmd, flags &~ MF_DELETE);
 +
 +        case MF_CHANGE :
 +            return ModifyMenuW(hMenu, cmd, flags &~ MF_CHANGE, cmdInsert, lpszNewItem);
 +
 +        case MF_REMOVE :
 +            return RemoveMenu(hMenu, flags & MF_BYPOSITION ? cmd : cmdInsert,
 +                                flags &~ MF_REMOVE);
 +
 +        default :   /* MF_INSERT */
 +            return InsertMenuW(hMenu, cmd, flags, cmdInsert, lpszNewItem);
 +    };
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +ChangeMenuA(
 +    HMENU hMenu,
 +    UINT cmd,
 +    LPCSTR lpszNewItem,
 +    UINT cmdInsert,
 +    UINT flags)
 +{
 +    /*
 +        FIXME: Word passes the item id in 'cmd' and 0 or 0xffff as cmdInsert
 +        for MF_DELETE. We should check the parameters for all others
 +        MF_* actions also (anybody got a doc on ChangeMenu?).
 +    */
 +
 +    switch(flags & (MF_APPEND | MF_DELETE | MF_CHANGE | MF_REMOVE | MF_INSERT))
 +    {
 +        case MF_APPEND :
 +            return AppendMenuA(hMenu, flags &~ MF_APPEND, cmdInsert, lpszNewItem);
 +
 +        case MF_DELETE :
 +            return DeleteMenu(hMenu, cmd, flags &~ MF_DELETE);
 +
 +        case MF_CHANGE :
 +            return ModifyMenuA(hMenu, cmd, flags &~ MF_CHANGE, cmdInsert, lpszNewItem);
 +
 +        case MF_REMOVE :
 +            return RemoveMenu(hMenu, flags & MF_BYPOSITION ? cmd : cmdInsert,
 +                                flags &~ MF_REMOVE);
 +
 +        default :   /* MF_INSERT */
 +            return InsertMenuA(hMenu, cmd, flags, cmdInsert, lpszNewItem);
 +    };
 +}
 +
 +
 +
 +
 +
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc lib/rtl/heap.c
Simple merge
diff --cc lib/rtl/image.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index d13c48d,05b139a..05b139a
Binary files differ
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge