123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653 |
- /** (c) Nullsoft, Inc. C O N F I D E N T I A L
- ** Filename:
- ** Project:
- ** Description:
- ** Author:
- ** Created:
- **/
- #include "main.h"
- #include "menuv5.h"
- #include "../nu/AutoWide.h"
- #include "../Plugins/General/gen_ml/ml.h"
- #define TREE_LOCALMEDIA 1000
- #define TREE_PLAYLISTS 3001
- #define TREE_DEVICES 10000
- #define TREE_QUERIES 1000
- extern HINSTANCE language_pack_instance;
- void ensureInScreen(HMENU menu, int *x, int *y, int *flag, int width, int height);
- HMENU v5_top_menu = NULL;
- int MergeMenu(HMENU pMenuDestination, const HMENU pMenuAdd, int bTopLevel /*=false*/)
- {
- // Abstract:
- // Merges two menus.
- //
- // Parameters:
- // pMenuDestination - [in, retval] destination menu handle
- // pMenuAdd - [in] menu to merge
- // bTopLevel - [in] indicator for special top level behavior
- //
- // Return value:
- // <false> in case of error.
- //
- // Comments:
- // This function calles itself recursivley. If bTopLevel is set to true,
- // we append popups at top level or we insert before <Window> or <Help>.
- // get the number menu items in the menus
- int iMenuAddItemCount = GetMenuItemCount(pMenuAdd);
- int iMenuDestItemCount = GetMenuItemCount(pMenuDestination);
- int iLoop;
-
- // if there are no items return
- if( iMenuAddItemCount == 0 )
- return 1;
-
- // if we are not at top level and the destination menu is not empty
- // -> we append a seperator
- if( !bTopLevel && iMenuDestItemCount > 0 )
- AppendMenu(pMenuDestination, MF_SEPARATOR, 0, 0);
- // iterate through the top level of
- for( iLoop = 0; iLoop < iMenuAddItemCount; iLoop++ )
- {
- HMENU pSubMenu = 0;
- // get the menu string from the add menu
- wchar_t sMenuAddString[1024] = {0}; // hope it's enough
- GetMenuStringW(pMenuAdd, iLoop, sMenuAddString, 1024, MF_BYPOSITION);
- // try to get the submenu of the current menu item
- pSubMenu =GetSubMenu(pMenuAdd, iLoop);
- // check if we have a sub menu
- if (!pSubMenu)
- {
- // normal menu item
- // read the source and append at the destination
- UINT nState = GetMenuState(pMenuAdd, iLoop, MF_BYPOSITION);
- UINT nItemID = GetMenuItemID(pMenuAdd, iLoop);
-
- if(AppendMenuW(pMenuDestination, nState, nItemID, sMenuAddString))
- {
- // menu item added, don't forget to correct the item count
- iMenuDestItemCount++;
- }
- else
- {
- // MergeMenu: AppendMenu failed!
- return 0;
- }
- }
- else
- {
- HMENU NewPopupMenu=NULL;
- // create or insert a new popup menu item
-
- // default insert pos is like ap
- int iInsertPosDefault = -1;
-
- // if we are at top level merge into existing popups rather than
- // creating new ones
- if( bTopLevel )
- {
- //ASSERT( sMenuAddString != "&?" && sMenuAddString != "?" );
- //CString sAdd( sMenuAddString );
- //sAdd.Remove('&'); // for comparison of menu items supress '&'
- int bAdded = 0;
- int iLoop1=0;
- // try to find existing popup
- for( iLoop1 = 0; iLoop1 < iMenuDestItemCount; iLoop1++ )
- {
- // get the menu string from the destination menu
- wchar_t sDest[1024] = {0}; // hope it's enough
- GetMenuStringW(pMenuDestination, iLoop1, sDest, 1024, MF_BYPOSITION );
- //sDest.Remove( '&' ); // for a better compare (s.a.)
- //if( !lstrcmp(sAdd,sDest))
- {
- // we got a hit -> merge the two popups
- // try to get the submenu of the desired destination menu item
- HMENU pSubMenuDest = GetSubMenu(pMenuDestination, iLoop1 );
-
- if( pSubMenuDest )
- {
- // merge the popup recursivly and continue with outer for loop
- if( !MergeMenu( pSubMenuDest, pSubMenu, 0 ))
- return 0;
-
- bAdded = 1;
- break;
- }
- }
- // alternativ insert before <Window> or <Help>
- //if( iInsertPosDefault == -1 && ( sDest == "Window" || sDest == "?" || sDest == "Help" ))
- // iInsertPosDefault = iLoop1;
- }
-
- if( bAdded )
- {
- // menu added, so go on with loop over pMenuAdd's top level
- continue;
- }
- }
- // if the top level search did not find a position append the menu
- if( iInsertPosDefault == -1 )
- iInsertPosDefault = GetMenuItemCount(pMenuDestination);
-
- // create a new popup and insert before <Window> or <Help>
- NewPopupMenu = CreatePopupMenu();
- if( !NewPopupMenu)
- {
- // MergeMenu: CreatePopupMenu failed!
- return 0;
- }
-
- // merge the new popup recursivly
- if( !MergeMenu( NewPopupMenu, pSubMenu, 0 ))
- return 0;
-
- // insert the new popup menu into the destination menu
- HMENU hNewMenu = NewPopupMenu;
- {
- MENUITEMINFOW menuItem={sizeof(MENUITEMINFO),
- MIIM_TYPE|MIIM_SUBMENU,
- MFT_STRING,
- MFS_ENABLED,
- 0, //wID
- hNewMenu, // hSubMenu
- NULL, // hbmpChecked
- NULL, // hbmpUnchecked
- 0, // dwItemData
- sMenuAddString, // dwTypeData
- 0, // cch
- };
-
- if (InsertMenuItemW(pMenuDestination, iInsertPosDefault, TRUE, &menuItem))
- {
- // don't forget to correct the item count
- iMenuDestItemCount++;
- }
- else
- {
- // MergeMenu: InsertMenu failed!
- return 0;
- }
- }
- }
- }
-
- return 1;
- }
- int getMenuItemPos(HMENU menu, UINT command)
- {
- int i;
- for (i = 0;i < 256;i++)
- {
- MENUITEMINFO mii = {sizeof(mii), MIIM_ID, };
- if (!GetMenuItemInfo(menu, i, TRUE, &mii)) break;
- if (mii.wID == command) return i;
- }
- return -1;
- }
- extern int g_SkinTop, g_BookmarkTop;
- int V5_File_Menu(HWND hwnd, int x, int y, int width, int height)
- {
- int flag = TPM_LEFTALIGN;
- HMENU file_menu = GetSubMenu(v5_top_menu, 0);
- HMENU hMenu = GetSubMenu(file_menu, 3);
- MENUITEMINFOW i = {sizeof(i), };
- FILE *fp;
- int a = 34768;
- int offs = 3;
- int count = GetMenuItemCount(hMenu) + 1;
- i.fMask = MIIM_TYPE | MIIM_DATA | MIIM_ID;
- i.fType = MFT_STRING;
- i.wID = 34768;
- // remove all of the items we might have added - do by command for certainty
- while (count){
- if(!RemoveMenu(hMenu, a++, MF_BYCOMMAND)) break;
- count--;
- }
- fp = _wfopen(BOOKMARKFILE8, L"rt");
- if (fp)
- {
- while (1)
- {
- char ft[FILETITLE_SIZE] = {0}, fn[FILENAME_SIZE] = {0};
- fgets(fn, FILENAME_SIZE, fp);
- if (feof(fp)) break;
- fgets(ft, FILETITLE_SIZE, fp);
- if (feof(fp)) break;
- if (ft[0] && fn[0])
- {
- if (fn[lstrlenA(fn) - 1] == '\n') fn[lstrlenA(fn) - 1] = 0;
- if (ft[lstrlenA(ft) - 1] == '\n') ft[lstrlenA(ft) - 1] = 0;
- if (ft[0] && fn[0])
- {
- i.dwTypeData = AutoWideDup(ft, CP_UTF8);
- i.cch = lstrlenW(i.dwTypeData);
- RemoveMenu(hMenu, i.wID, MF_BYCOMMAND);
- InsertMenuItemW(hMenu, i.wID + offs - 34768, TRUE, &i);
- i.wID++;
- }
- }
- }
- fclose(fp);
- }
- g_BookmarkTop = i.wID;
- // put in a place holder item if there were no read bookmarks
- if (g_BookmarkTop == 34768)
- {
- i.dwTypeData = getStringW(IDS_NO_BOOKMARKS,NULL,0);
- i.cch = lstrlenW(i.dwTypeData);
- InsertMenuItemW(hMenu, i.wID + offs - 34768, TRUE, &i);
- EnableMenuItem(hMenu, i.wID, MF_BYCOMMAND | MF_GRAYED);
- }
- ensureInScreen(file_menu, &x, &y, &flag, width, height);
- DoTrackPopup(file_menu, flag, x, y, hwnd);
- return 1;
- }
- int V5_Play_Menu(HWND hwnd, int x, int y, int width, int height)
- {
- HMENU play_menu = GetSubMenu(v5_top_menu, 1);
- int flag = TPM_LEFTALIGN;
- ensureInScreen(play_menu, &x, &y, &flag, width, height);
- DoTrackPopup(play_menu, flag, x, y, hwnd);
- return 1;
- }
- int V5_Options_Menu(HWND hwnd, int x, int y, int width, int height)
- {
- int flag = TPM_LEFTALIGN;
- HMENU options_menu = GetSubMenu(v5_top_menu, 2);
- HMENU eqMenu = NULL;
- { // set options skin menu to the skin menu
- extern HMENU g_submenus_skins1;
- MENUITEMINFO mi = {sizeof(mi), MIIM_SUBMENU};
- mi.hSubMenu = g_submenus_skins1;
- SetMenuItemInfoW(options_menu, 0, TRUE, &mi);
- }
- eqMenu = GetSubMenu(options_menu, 2);
- CheckMenuItem(eqMenu, EQ_ENABLE, config_use_eq ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(options_menu, WINAMP_OPTIONS_DSIZE, config_dsize ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(options_menu, WINAMP_OPTIONS_AOT, config_aot ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(options_menu, WINAMP_OPTIONS_ELAPSED, config_timeleftmode ? MF_UNCHECKED : MF_CHECKED);
- CheckMenuItem(options_menu, WINAMP_OPTIONS_REMAINING, config_timeleftmode ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(options_menu, WINAMP_OPTIONS_PREFS, IsWindow(prefs_hwnd) ? MF_CHECKED : MF_UNCHECKED);
- ensureInScreen(options_menu, &x, &y, &flag, width, height);
- DoTrackPopup(options_menu, flag, x, y, hwnd);
- return 1;
- }
- int V5_Windows_Menu(HWND hwnd, int x, int y, int width, int height)
- {
- HMENU windows_menu = GetSubMenu(v5_top_menu, 3);
- int flag = TPM_LEFTALIGN;
- CheckMenuItem(windows_menu, WINAMP_OPTIONS_PLEDIT, config_pe_open ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(windows_menu, WINAMP_VISPLUGIN, vis_running() ? MF_CHECKED : MF_UNCHECKED);
- if (g_has_video_plugin) CheckMenuItem(windows_menu, WINAMP_OPTIONS_VIDEO, config_video_open ? MF_CHECKED : MF_UNCHECKED);
- ensureInScreen(windows_menu, &x, &y, &flag, width, height);
- DoTrackPopup(windows_menu, flag, x, y, hwnd);
- return 1;
- }
- int Help_Menu(HWND hwnd, int x, int y, int width, int height)
- {
- HMENU help_menu = GetSubMenu(v5_top_menu, 4);
- int flag = TPM_LEFTALIGN;
- MENUITEMINFOW i = {sizeof(i), };
- i.fMask = MIIM_TYPE;
- i.fType = MFT_STRING;
- i.dwTypeData = getStringW(IDS_WINAMP_MENUITEM, NULL, 0);
- i.cch = (UINT)wcslen(i.dwTypeData);
- SetMenuItemInfoW(help_menu, WINAMP_HELP_ABOUT, FALSE, &i);
- ensureInScreen(help_menu, &x, &y, &flag, width, height);
- DoTrackPopup(help_menu, flag, x, y, hwnd);
- return 1;
- }
- int V5_Help_Menu(HWND hwnd, int x, int y, int width, int height)
- {
- return Help_Menu(hwnd, x, y, width, height);
- }
- LRESULT sendMlIpc(int msg, WPARAM param);
- // TODO:: need to make this only show what's needed at the time ie it'll still show even if there's no ml_playlists
- // and properly show if there's no playlists
- int V5_PE_File_Menu(HWND hwnd, int x, int y, int width, int height)
- {
- int flag = TPM_LEFTALIGN;
- HMENU pefile_menu = GetSubMenu(v5_top_menu, 5);
- HMENU playlistsmenu = NULL;
- HMENU viewmenu = NULL;
- HWND mlwnd = (HWND)sendMlIpc(0, 0);
- int viewmenu_added = 0;
- g_open_ml_item_in_pe = 1;
- if (mlwnd)
- {
- mlGetTreeStruct mgts = { TREE_PLAYLISTS, 45000, -1 };
- playlistsmenu = (HMENU)SendMessageW(mlwnd, WM_ML_IPC, (WPARAM) & mgts, ML_IPC_GETTREE);
- if (playlistsmenu)
- {
- mlGetTreeStruct mgts = { TREE_QUERIES, 45000, -1 };
- viewmenu = (HMENU)SendMessageW(mlwnd, WM_ML_IPC, (WPARAM) & mgts, ML_IPC_GETTREE);
- if (GetMenuItemCount(playlistsmenu) == 0) InsertMenuW(playlistsmenu, 0, MF_BYPOSITION | MF_STRING | MF_GRAYED, 0, getStringW(IDS_ML_NO_PLAYLISTS,NULL,0));
- InsertMenuW(pefile_menu, 2, MF_BYPOSITION | MF_ENABLED | MF_POPUP, (UINT_PTR)playlistsmenu, getStringW(IDS_ML_OPEN_PLAYLIST,NULL,0));
- if (viewmenu && GetMenuItemCount(viewmenu) > 0)
- {
- viewmenu_added = 1;
- InsertMenuW(pefile_menu, 3, MF_BYPOSITION | MF_ENABLED | MF_POPUP, (UINT_PTR)viewmenu, getStringW(IDS_ML_OPEN_VIEW_RESULTS,NULL,0));
- }
- }
- }
- ModifyMenuW(pefile_menu, ID_PE_CLOSE, MF_BYCOMMAND | MF_STRING, ID_PE_CLOSE, config_pe_open ? getStringW(IDS_PE_CLOSE,NULL,0) : getStringW(IDS_PE_OPEN,NULL,0));
- ensureInScreen(pefile_menu, &x, &y, &flag, width, height);
- DoTrackPopup(pefile_menu, flag, x, y, hwnd);
- if (playlistsmenu)
- {
- if (viewmenu_added) RemoveMenu(pefile_menu, 3, MF_BYPOSITION);
- if (viewmenu) DestroyMenu(viewmenu);
- RemoveMenu(pefile_menu, 2, MF_BYPOSITION);
- DestroyMenu(playlistsmenu);
- }
- return 1;
- }
- int V5_PE_Playlist_Menu(HWND hwnd, int x, int y, int width, int height)
- {
- HMENU peplaylist_menu = GetSubMenu(v5_top_menu, 6);
- int flag = TPM_LEFTALIGN;
- ensureInScreen(peplaylist_menu, &x, &y, &flag, width, height);
- DoTrackPopup(peplaylist_menu, flag, x, y, hwnd);
- return 1;
- }
- int V5_PE_Sort_Menu(HWND hwnd, int x, int y, int width, int height)
- {
- HMENU pesort_menu = GetSubMenu(v5_top_menu, 7);
- int flag = TPM_LEFTALIGN;
- ensureInScreen(pesort_menu, &x, &y, &flag, width, height);
- DoTrackPopup(pesort_menu, flag, x, y, hwnd);
- return 1;
- }
- int V5_PE_Help_Menu(HWND hwnd, int x, int y, int width, int height)
- {
- return Help_Menu(hwnd, x, y, width, height);
- }
- int V5_ML_File_Menu(HWND hwnd, int x, int y, int width, int height)
- {
- int flag = TPM_LEFTALIGN;
- HMENU mlfile_menu = GetSubMenu(v5_top_menu, 8);
- HWND mlwnd = (HWND)sendMlIpc(0, 0);
- HWND mlplwnd = (HWND)SendMessageW(mlwnd, WM_ML_IPC, 0, ML_IPC_GETPLAYLISTWND);
- ModifyMenuW(mlfile_menu, 3, MF_BYPOSITION | (mlplwnd == NULL ? MF_GRAYED : 0), ID_MLFILE_SAVEPLAYLIST, getStringW(IDS_ML_EXPORT_PLAYLIST,NULL,0));
- {
- int visible = IsWindowVisible(mlwnd);
- int p = getMenuItemPos(mlfile_menu, ID_FILE_CLOSELIBRARY);
- if (p == -1) p = getMenuItemPos(mlfile_menu, ID_FILE_SHOWLIBRARY);
- ModifyMenuW(mlfile_menu, p, MF_BYPOSITION | MF_STRING, visible ? ID_FILE_CLOSELIBRARY : ID_FILE_SHOWLIBRARY, visible ? getStringW(IDS_ML_CLOSE_ML,NULL,0) : getStringW(IDS_ML_OPEN_ML,NULL,0));
- }
- ensureInScreen(mlfile_menu, &x, &y, &flag, width, height);
- DoTrackPopup(mlfile_menu, flag, x, y, hwnd);
- return 1;
- }
- int V5_ML_View_Menu(HWND hwnd, int x, int y, int width, int height)
- {
- int flag = TPM_LEFTALIGN;
- HMENU mlview_menu = GetSubMenu(v5_top_menu, 9), mediamenu = NULL;
- HWND mlwnd = (HWND)sendMlIpc(0, 0);
- if (mlwnd)
- {
- mlGetTreeStruct mgts = { 0, 45000, -1 };
- mediamenu = (HMENU)SendMessageW(mlwnd, WM_ML_IPC, (WPARAM) & mgts, ML_IPC_GETTREE);
- if (mediamenu)
- {
- MergeMenu(mediamenu, mlview_menu, 0);
- //InsertMenu(mediamenu, 0, MF_BYPOSITION | MF_STRING, ID_MLVIEW_MEDIA, "All &Media");
- //InsertMenu(mlview_menu, 1, MF_BYPOSITION | MF_ENABLED | MF_POPUP, (UINT)mediamenu, "&Local Media");
- }/*
- mgts.item_start = TREE_PLAYLISTS;
- playlistsmenu = (HMENU)SendMessageW(mlwnd, WM_ML_IPC, (int) & mgts, ML_IPC_GETTREE);
- if (playlistsmenu)
- {
- if (GetMenuItemCount(playlistsmenu) == 0) InsertMenu(playlistsmenu, 0, MF_BYPOSITION | MF_STRING | MF_GRAYED, 0, "No playlists");
- InsertMenu(mlview_menu, 2, MF_BYPOSITION | MF_ENABLED | MF_POPUP, (UINT)playlistsmenu, "&Playlists");
- }
- mgts.item_start = TREE_DEVICES;
- devicesmenu = (HMENU)SendMessageW(mlwnd, WM_ML_IPC, (int) & mgts, ML_IPC_GETTREE);
- if (devicesmenu)
- {
- if (GetMenuItemCount(devicesmenu) == 0) InsertMenu(devicesmenu, 0, MF_BYPOSITION | MF_STRING | MF_GRAYED, 0, "No devices");
- InsertMenu(mlview_menu, 3, MF_BYPOSITION | MF_ENABLED | MF_POPUP, (UINT)devicesmenu, "&Devices");
- }*/
- }
- g_open_ml_item_in_pe = 0;
- //ID_MLVIEW_PLAYLISTS
- //ID_MLVIEW_DEVICES
- ensureInScreen(mediamenu, &x, &y, &flag, width, height);
- DoTrackPopup(mediamenu, flag, x, y, hwnd);
- /*
- if (devicesmenu)
- {
- RemoveMenu(mlview_menu, 3, MF_BYPOSITION);
- DestroyMenu(devicesmenu);
- }
- if (playlistsmenu)
- {
- RemoveMenu(mlview_menu, 2, MF_BYPOSITION);
- DestroyMenu(playlistsmenu);
- }*/
- if (mediamenu)
- {
- //RemoveMenu(mlview_menu, 1, MF_BYPOSITION);
- DestroyMenu(mediamenu);
- }
- return 1;
- }
- int V5_ML_Help_Menu(HWND hwnd, int x, int y, int width, int height)
- {
- return Help_Menu(hwnd, x, y, width, height);
- }
- int V5_PE_ListOfPlaylists_Menu(int x, int y)
- {
- HMENU viewmenu = NULL;
- mlGetTreeStruct mgts = { TREE_PLAYLISTS, 55000, -1 };
- HWND mlwnd = (HWND)sendMlIpc(0, 0);
- HMENU playlistsmenu = (HMENU)SendMessageW(mlwnd, WM_ML_IPC, (WPARAM) & mgts, ML_IPC_GETTREE);
- if (playlistsmenu)
- {
- InsertMenuW(playlistsmenu, 0, MF_BYPOSITION | MF_STRING, ID_MANAGEPLAYLISTS, getStringW(IDS_ML_MANAGE_PLAYLISTS,NULL,0));
- {
- mlGetTreeStruct mgts = { TREE_QUERIES, 55000, -1 };
- viewmenu = (HMENU)SendMessageW(mlwnd, WM_ML_IPC, (WPARAM) &mgts, ML_IPC_GETTREE);
- }
- if (viewmenu && GetMenuItemCount(viewmenu) > 0)
- InsertMenuW(playlistsmenu, 1, MF_BYPOSITION | MF_ENABLED | MF_POPUP, (UINT_PTR)viewmenu, getStringW(IDS_ML_SMART_VIEW_RESULTS,NULL,0));
- InsertMenu(playlistsmenu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
- g_open_ml_item_in_pe = 1;
- DoTrackPopup(playlistsmenu, TPM_LEFTALIGN, x, y, hMainWindow);
- }
- DestroyMenu(playlistsmenu);
- DestroyMenu(viewmenu);
- return 1;
- }
- void getViewportFromPoint(POINT *pt, RECT *r)
- {
- if (!r || !pt) return ;
- {
- HMONITOR hm;
- hm = MonitorFromPoint(*pt, MONITOR_DEFAULTTONULL);
- if (hm)
- {
- MONITORINFOEXW mi;
- memset(&mi, 0, sizeof(mi));
- mi.cbSize = sizeof(mi);
- if (GetMonitorInfo(hm, &mi))
- {
- *r = mi.rcMonitor;
- return ;
- }
- }
- }
- }
- #undef GetSystemMetrics
- void ensureInScreen(HMENU menu, int *x, int *y, int *flag, int width, int height)
- {
- POINT pt = {*x, *y};
- int nitems = GetMenuItemCount(menu);
- int i;
- RECT mwr;
- RECT monitor;
- int rightdone = 0;
- int bottomdone = 0;
- int xedge = GetSystemMetrics(SM_CXEDGE);
- int yedge = GetSystemMetrics(SM_CYEDGE);
- int itemheight = GetSystemMetrics(SM_CYMENU);
- int checkmarkwidth = GetSystemMetrics(SM_CXMENUCHECK);
- int cury = *y + yedge + 1;
- GetWindowRect(hMainWindow, &mwr);
- getViewportFromPoint(&pt, &monitor);
- /*if (nitems*GetSystemMetrics(SM_CYMENU)+yedge*2+*y > monitor.bottom) {
- bottomdone = 1;
- *y -= height;
- *flag &= ~TPM_TOPALIGN;
- *flag |= TPM_BOTTOMALIGN;
- }*/
- for (i = 0;i < nitems;i++)
- {
- SIZE s={0};
- RECT item;
- MENUITEMINFOW info = {sizeof(info), MIIM_DATA | MIIM_TYPE | MIIM_STATE | MIIM_ID, MFT_STRING, };
- GetMenuItemRect(hMainWindow, menu, i, &item);
- item.left -= mwr.left;
- item.top -= mwr.top;
- item.right -= mwr.left;
- item.bottom -= mwr.top;
- if (item.top == 0 && item.left == 0)
- {
- // item has never been shown so MS wont give us the rect, I HATE THEM ! I HATE THEM SO MUCH ARRRG !
- // y
- item.top = cury;
- {
- GetMenuItemInfoW(menu, i, TRUE, &info);
- if (info.fType & MFT_SEPARATOR)
- cury += (itemheight - 1) >> 1;
- else
- {
- cury += itemheight - 2;
- //info.dwTypeData = (LPTSTR) MALLOC(++info.cch + 1);
- GetMenuItemInfoW(menu, i, TRUE, &info);
- //info.dwTypeData[info.cch] = 0;
- }
- }
- item.bottom = cury;
- // x
- if (info.dwTypeData)
- {
- LOGFONT m_lf;
- HFONT font = nullptr;
- HDC dc = nullptr;
- NONCLIENTMETRICS nm = {sizeof (NONCLIENTMETRICS), };
- memset((PVOID) &m_lf, 0, sizeof (LOGFONT));
- SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, nm.cbSize, &nm, 0);
- m_lf = nm.lfMenuFont;
- font = CreateFontIndirectW(&m_lf);
- dc = GetDC(hMainWindow);
- GetTextExtentPoint32(dc, info.dwTypeData, lstrlen(info.dwTypeData), &s);
- ReleaseDC(hMainWindow, dc);
- DeleteObject(font);
- //free(info.dwTypeData);
- }
- if (!(info.fType & MFT_SEPARATOR))
- {
- item.left = *x + xedge + 1;
- item.right = item.left + s.cx + checkmarkwidth * 2 + xedge + 1;
- }
- else
- {
- item.left = *x + xedge + 1;
- item.right = item.left + xedge + 1;
- }
- }
- else
- {
- item.left += *x;
- item.top += *y;
- item.right += *x;
- item.bottom += *y;
- item.right += xedge * 2 + 2; // to avoid last test
- cury = item.bottom;
- }
- if (!bottomdone && cury > monitor.bottom)
- {
- bottomdone = 1;
- *y -= height;
- *flag &= ~TPM_TOPALIGN;
- *flag |= TPM_BOTTOMALIGN;
- }
- if (!rightdone && item.right > monitor.right)
- {
- rightdone = 1;
- *x += width;
- *flag &= ~TPM_LEFTALIGN;
- *flag |= TPM_RIGHTALIGN;
- }
- if (rightdone && bottomdone) return ;
- }
- cury += yedge + 1;
- if (!bottomdone && cury > monitor.bottom)
- {
- //bottomdone = 1;
- *y -= height;
- *flag &= ~TPM_TOPALIGN;
- *flag |= TPM_BOTTOMALIGN;
- }
- }
|