Create a menu using the contents of the directory

zhaozj2021-02-08  272

Purpose: To establish a menu according to the contents of the directory. The menu item is the file and subdirectory in the directory (displayed in a pop-up method).

Solution: Traverse the subdirectory, create a file path array. The ID of the menu item is an index of an array. When the user clicks on a menu item, read the file path from the array and perform the appropriate operation.

detail:

First, we need a menu. The newly established menu will be used as the submenu of this menu.

CMenu * pmenufavorites = new cmenu; pmenufavorites-> createPopupMenu ();

Then read the directory, create a menu

Buildfavoritesmenu (szpath, 0, pmenufavorites);

Finally, connect the menu to the already menu.

CMenu * pmenu = m_Menupopup.getsubmenu (0);

Pmenu-> modifymenu (m_imenuposition, mf_byposition | mf_popup | mf_string, (uint) (pMenufavorites-> getsafehmenu ()), _ t ("Dynamic Menu");

PMENUFAVORITES-> DETACH (); delete pmenufavorites;

Others are very simple, but it is very troublesome to build this menu.

State a variable to save the file path

CSTRINGARRAY M_ASTRFAVORITEURLS;

int CWorkBenchDlg :: BuildMenu (LPCTSTR pszPath, int nStartPos, CMenu * pMenu) {CString strPath (pszPath); // path to start from CString strPath2; // path to start from, with trailing backslash CString str; // menu item text Win32_find_data wfd; handle h; int npos; int Nendpos; int nnewendpos; int nlastdir; tchar buf [Internet_max_path_length]; cstringArray Astrfavorites; cstringArray astrdirs; cmenu * psubmenu;

// Make Sure The A Trailing Backslash IF (StrPath [StrPath.getLength () - 1]! =_T ('//')) StrPath =_T ('//); strpath2 = strpath; strpath = _t "*. *");

// now scan the directory, first for files and then for subdirectories // make a array of full pathnames h = FindFirstFile (strPath, & wfd);. If (h = INVALID_HANDLE_VALUE!) {NEndPos = nStartPos; do {if ((wfd .dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) == 0) {str = wfd.cFileName; // file name lstrcpy (buf, strPath2 str); // file full pathname if (str.Right (4) .CompareNoCase (_T (". URL")) == 0) {// an .url file is formatted just like an .ini file, so we can // use getprivateprofilestring () to get the information we want // Fill the Buf with Url :: getPrivateProfileString (_T ("Internetshstcut"), _T ("URL"), _T (""), buf, internet_max_path_length, str = str.Left (str.g ETLENGTH () - 4); // the name of url

} IF (str .right (4) .comparenocase (_t (")) == 0) {// Fill The Buf with link target cglobal :: resolveshortcut (Null, StrPath2 Str, BUF); str = STR .Left (Str.getLength () - 4);} // Todo: Add Other Format Process Here

// Here the .url file and the .lnk file have been processed, remove the extension. See http://support.microsoft.com/support/kb/articles/q130/6/98.asp. You can process the files in other formats and change the menu text.

// scan through the array and perform an insertion sort // to make sure the menu ends up in alphabetic order for (npos = nstartpos; npos appendmenu (mf_string | mf_enabled, 0xe00 npos, astrfavorites [npos]);} // Now That Weide Got Files, Check The subdirectories for more nLastdir = 0; h = findfirstfile (StrPath, & WFD); assert (h! = invalid_handle_value); do {if (wfd.dwfileAttributes & file_attribute_directory) { // ignore the current and perent Directory Entries IF (Wfd.cfileName, _T (")) == 0 || lstrcmp (wfd.cfilename, _t (". ")) == 0).

For (NPOS = 0; NPOS 0) Break;} psubmenu = new cmenu; psubmenu-> createPopupnupMenu ();

. // call this function recursively nNewEndPos = BuildFavoritesMenu (strPath2 wfd.cFileName, nEndPos, pSubMenu); if (! NNewEndPos = nEndPos) {// only intert a submenu if there are in fact files in the subdirectory nEndPos = nNewEndPos; pMenu -> InsertMenu (nPos, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT) pSubMenu-> m_hMenu, wfd.cFileName); pSubMenu-> Detach (); astrDirs.InsertAt (nPos, wfd.cFileName); nLastDir;} delete pSubMenu ;}} While (FindNextFile (H, & WFD)); FindClose (h);} Return Nendpos;} Ok, the menu is completed. Don't do things? No. Also write command processing functions.

AFX_MSG Void OnMenu (UINT NID)

{

Shellexecute (NULL, NULL, M_ASTRFAVORITEURLS [NID-0xE00], NULL, NULL, SW_SHOWDEFAULT);

}

And message mapping

......

//}} AFX_MSG_MAP ON_COMMAND_RANGE (0xE00, 0xFFF, OnMENU) end_MESSAGE_MAP ()

Here I use 0xE00 to 0xFFF as the range of the command ID, so there is up to 512 file menu items (enough? Not enough to write a lot of yourself). Because the ID of the usual command is greater than 327xx, it will not conflict with other menus (it may be conflict with the button ID, you pay attention to the resource ID range is OK).

Ok, compile, run, pass!

The only regret is no file icon. Since I am not very familiar with the operating system, I don't know how to get the icon of the file and draw it to the menu. Welcome seniors of all parties!

Tested under Windows ME and Visual C 6 SP5.

转载请注明原文地址:https://www.9cbs.com/read-1842.html

New Post(0)