В принципе, я в одной из своих программ делаю так:
| Код | procedure DoWork (Path :String); const faSpecial = FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_SYSTEM or $00000008 // FILE_ATTRIBUTE_VOLUMEID or FILE_ATTRIBUTE_DIRECTORY or FILE_ATTRIBUTE_TEMPORARY; SHGetFileInfoFlags = (SHGFI_SYSICONINDEX or SHGFI_SMALLICON {or SHGFI_ICON}); var MenuInfo :TMenuInfo; MenuItemInfo :TMenuItemInfo; miId :Integer; FindData :TWin32FindData; FindHandle :tHandle; Error :Boolean; MousePos :tPoint; Res :Integer; FileInfo :TSHFileInfo; begin hW := CreateMyMenuCallbackWnd; hM := CreatePopupMenu(); if (hM = 0) or (hW = 0) then ShowError else begin
with MenuInfo do begin cbSize := SizeOf(TMenuInfo); cyMax := 0; fMask := MIM_STYLE {or MIM_MENUDATA}; dwStyle := MNS_AUTODISMISS or MNS_CHECKORBMP or MNS_DRAGDROP {or MNS_MODELESS} {or MNS_NOTIFYBYPOS}; // MIM_STYLE //dwMenuData := SHGetFileInfo('', 0, FileInfo, SizeOf(TSHFileInfo), SHGetFileInfoFlags); // MIM_MENUDATA //hbrBack :=; // MIM_BACKGROUND //dwContextHelpID :=; // MIM_HELPID end; SetMenuInfo(hM,MenuInfo);
FindHandle := Windows.FindFirstFile(PChar(Path), FindData); if (FindHandle = INVALID_HANDLE_VALUE) then ShowError else begin Path := ExtractFilePath(Path); Error := False; miId := -1; repeat // цикл по всем файлам if (FindData.dwFileAttributes and faSpecial) = 0 then begin // файл включаемый в меню Inc(miId); // посчитаем его, и сохраним :) SetLength(Files,miId+1); Files[miId] := Path+FindData.cFileName; // получим параметры его иконки hIL := SHGetFileInfo(PChar(Files[miId]), 0, FileInfo, SizeOf(TSHFileInfo), SHGetFileInfoFlags); // заполним структуру описания итема меню with MenuItemInfo do begin cbSize := SizeOf(MENUITEMINFO); fMask := 0 or MIIM_STRING or MIIM_ID or MIIM_BITMAP or MIIM_DATA {or MIIM_FTYPE}; dwTypeData := FindData.cFileName; // MIIM_STRING cch := strlen(dwTypeData); // ... wID := miId; // MIIM_ID hbmpItem := Cardinal(HBMMENU_CALLBACK); // MIIM_BITMAP dwItemData := FileInfo.iIcon; // MIIM_DATA //fType := MFT_OWNERDRAW; // MIIM_FTYPE end; // добавим итем к меню if not InsertMenuItem(hM,$FFFFFFFF,True,MenuItemInfo) then begin ShowError; Error := True; Break; end; end; until not Windows.FindNextFile(FindHandle, FindData); Windows.FindClose(FindHandle);
if not Error then begin GetCursorPos(MousePos); Res := Cardinal( TrackPopupMenuEx(hM, TPM_LEFTALIGN //or TPM_LEFTBUTTON //or TPM_RIGHTBUTTON or TPM_RETURNCMD //or TPM_NONOTIFY ,MousePos.x,MousePos.y, hW, nil) ); if (Res = 0) and (GetLastError<>NO_ERROR) then ShowError else begin SelectedItem := Res; EBox(PChar({Files[SelectedItem]} IntToStr(SelectedItem) )); end; end;
end;
end; DestroyMenu(hM); DestroyWindow(hW); end; | |