diff options
Diffstat (limited to 'Src/Winamp/menuv5.cpp')
-rw-r--r-- | Src/Winamp/menuv5.cpp | 653 |
1 files changed, 653 insertions, 0 deletions
diff --git a/Src/Winamp/menuv5.cpp b/Src/Winamp/menuv5.cpp new file mode 100644 index 00000000..350548d4 --- /dev/null +++ b/Src/Winamp/menuv5.cpp @@ -0,0 +1,653 @@ +/** (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; + } +} + + |