![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как добавить иконку во всплывающее меню?
Piter © (2006-03-05 02:18:00)Не понимаю я... Что InsertMenuItem, что InsertMenu - у них есть флаги или MFT_BITMAP, или MFT_STRING. Последний параметр дата соответственно указывает на картинку или на строку.
А если я хочу и картинку, и строку? В общем, стандартный пункт всплывающего окна, когда слева иконка, а потом текст...
n0name (2006-03-06 10:08:00) [1]>>Видимо, n0name из MSDN цитировал
Apr 2005
Eraser (2006-03-05 19:41:00) [2]ага, не сразу заметил [13]... предыдущий пост не читать )
Eraser (2006-03-05 19:40:00) [3]
> Piter ©
почти оффтоп:
очень советую соотв. компонент из JEDI VCL, единственный который корректно работает после RecreateWindow.
Piter (2006-03-05 19:38:00) [4]Видимо, справка D еще во времена Win95 была составлена и не менялась. И там соответственно отсутствуют новвоведения, начиная с Win98...
Лоханулся.
Piter (2006-03-05 19:36:00) [5]begin...end © (05.03.06 17:49) [14]
извиняюсь, я просто не понял. У меня в справке по D отсутствует описание hbmpItem:
typedef struct tagMENUITEMINFO { UINT cbSize;
UINT fMask;
UINT fType;
UINT fState;
UINT wID;
HMENU hSubMenu;
HBITMAP hbmpChecked;
HBITMAP hbmpUnchecked;
DWORD dwItemData;
LPTSTR dwTypeData;
UINT cch;
} MENUITEMINFO, FAR *LPMENUITEMINFO;
Также как среди флагов fMask отсутствует MIIM_BITMAP.
Видимо, n0name из MSDN цитировал, а мне так навскидку показалось, что из справки WinApi по D, которую я и так читал, и там нету нужных мне вариантов работы :)
Сори.
n0name (2006-03-05 18:46:00) [6]
> P.S. Или может есть у кого простенький пример рисования
> пунктов меню на WinApi? В VCL не посылать, там замучаешься
> выдирать...
В общем писал для ListBox'a, но для Menu тоже пойдет после некоторых изменений.
function ListBoxOnDraw(hListBox: HWND; lParam, wParam: Integer): boolean;
var
DWI: PDrawItemStruct;
Text: PChar;
rcItem: TRect;
crOldTextColor: COLORREF;
crOldBkColor: COLORREF;
hBrush: THandle;
begin
result:=true;
DWI:=PDrawItemStruct(lParam);
if DWI^.CtlType<>ODT_LISTBOX then exit;
Text:=PChar(DWI^.itemData);
if Text=nil then exit;
crOldTextColor:=GetTextColor(DWI^.hDC);
crOldBkColor:=GetBkColor(DWI^.hDC);
if (DWI^.itemAction or ODA_SELECT=ODA_SELECT) and (DWI^.itemState and ODS_SELECTED=ODS_SELECTED) then
begin
SetTextColor(DWI^.hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
SetBkColor(DWI^.hDC, GetSysColor(COLOR_HIGHLIGHT));
FillRect(DWI^.hDC, DWI^.rcItem, GetSysColor(COLOR_HIGHLIGHT));
end
else
FillRect(DWI^.hDC, DWI^.rcItem, crOldBkColor);
if (DWI^.itemAction or ODA_FOCUS=ODA_FOCUS) and (DWI^.itemState and ODS_FOCUS=ODS_FOCUS) then
begin
hBrush:=CreateSolidBrush(RGB(0, 0, 0));
FrameRect(DWI^.hDC, DWI^.rcItem, hBrush);
DeleteObject(hBrush);
end;
rcItem:=DWI^.rcItem;
DrawText(DWI^.hDC, Text, length(Text), rcItem, DT_SINGLELINE or DT_VCENTER);
SetTextColor(DWI^.hDC, crOldTextColor);
SetBkColor(DWI^.hDC, crOldBkColor);
end;
function ListBoxOnMeasure(hListBox: HWND; lParam, wParam: Integer): boolean;
var
hDC: THandle;
MIS: PMEASUREITEMSTRUCT;
Text: PChar;
sz: TSize;
begin
result:=false;
MIS:=PMEASUREITEMSTRUCT(lParam);
if MIS^.CtlID<>ODT_LISTBOX then exit;
Text:=PChar(MIS^.itemData);
if Text=nil then exit;
hDC:=GetDC(hListBox);
GetTextExtentPoint32(hDC, Text, length(Text), sz);
ReleaseDC(hListBox, hDC);
MIS^.itemHeight:=sz.cy*2;
result:=true;
end;
>>begin...end © (05.03.06 17:49) [14]
Согласен, но лучше всегда предложить несколько вариантов реализации :))
begin...end (2006-03-05 17:49:00) [7]> Piter © (05.03.06 14:21) [7]
> может ты прояснишь тогда для ламеров о чем там ведется речь?
Это -- всегда пожалуйста.
Итак, читаем [1]. Оттуда следует, что для отображения битмапа в пункте меню нужно в структуре, описывающей его (которая используется, например, функцией InsertMenuItem), заполнить поле hbmpItem ( hbmpItem -- handle to the bitmap to be displayed-- цитата! ) и уведомить систему, что на это поле нужно обращать внимание при создании пункта, т.е. добавить в поле fMask значение MIIM_BITMAP ( it is used when the MIIM_BITMAP flag is set in the fMask member-- цитата! ).
Соответственно этому пишем код:
var
Item: TMenuItemInfo;
hBmp: HBITMAP;
begin
hBmp := LoadBitmap(0, PChar(OBM_CHECK)); // стандартный битмап
with Item do
begin
cbSize := sizeof(Item);
fMask := MIIM_STRING or MIIM_BITMAP;
dwTypeData := 'Check';
hbmpItem := hBmp;
end;
InsertMenuItem(PopupMenuHandle, 0, True, Item);
TrackPopupMenu(PopupMenuHandle, ...);
end
и получаем именно то, что и было нужно: в пункте меню отображается как строка, так и картинка. В этом примере в hbmpItem был помещён дескриптор стандартного битмапа, но ничего не мешает использовать и нестандартный.
Вывод: перед тем, как упрекать отвечающих в невнимательности, иногда лучше всё же разобраться в том, что именно они (отвечающие) советуют.
Piter (2006-03-05 17:23:00) [8]kaZaNoVa © (05.03.06 16:43) [12]
программка является COM-сервером, DLL. Там не совсем свое меню строится, там добавляются пункты к уже существующему меню по известному HMENU.
kaZaNoVa (2006-03-05 16:43:00) [9]Piter © (05.03.06 16:22) [11]
а чем VCL не устраивает? хочется программу поменьше размером?))
Piter (2006-03-05 16:22:00) [10]kaZaNoVa © (05.03.06 15:59) [10]
а что за задача то?
задача описана в сабже.
kaZaNoVa (2006-03-05 15:59:00) [11]Piter © (05.03.06 2:18)
а что за задача то? свой WinRAR пишешь?
Piter (2006-03-05 15:27:00) [12]n0name (05.03.06 14:52) [8]
Делай меню ownerdrraw и делай что хочешь.
это понятно, но рисовать вручную не хочется...
Имелось в виду - есть стандартный способ прилепить иконку?
P.S. Или может есть у кого простенький пример рисования пунктов меню на WinApi? В VCL не посылать, там замучаешься выдирать...
И еще почему не хочется связываться - судя по VCL, там столько условностей, учет какой Windows, немного разный код даже для Win98 и ME, какие-то условности...
n0name (2006-03-05 14:52:00) [13]HBMMENU_CALLBACK
A bitmap that is drawn by the window that owns the menu. The application must process the WM_MEASUREITEM and WM_DRAWITEM messages.
Делай меню ownerdrraw и делай что хочешь.
Piter (2006-03-05 14:21:00) [14]begin...end © (05.03.06 13:34) [4]
Вероятно, к тому, чтобы ты его всё-таки прочитал.
может ты прояснишь тогда для ламеров о чем там ведется речь?
n0name (05.03.06 7:38) [1]
MFT_BITMAP
Displays the menu item using a bitmap. The low-order word of the dwTypeData member is the bitmap handle, and the cch member is ignored
и вообще я писал проблему:
Piter © (05.03.06 2:18)
Последний параметр дата соответственно указывает на картинку или на строку.
А если я хочу и картинку, и строку?
Handle (05.03.06 13:39) [5]
Тогда зачем задаёшь такие вопросы?
Не понимаю я... Что InsertMenuItem, что InsertMenu
InsertMenuItem и InsertMenu - это WinApi функции.
Handle (2006-03-05 13:42:00) [15]
> Piter © (05.03.06 13:00) [3]
> это конференция WinApi, а не VCL.
Я всего лишь хотел тебе помочь.
Handle (2006-03-05 13:39:00) [16]
> Piter © (05.03.06 13:00) [3]
> это конференция WinApi, а не VCL.
Тогда зачем задаёшь такие вопросы?
Не понимаю я... Что InsertMenuItem, что InsertMenu
begin...end (2006-03-05 13:34:00) [17]> Piter © (05.03.06 13:00) [3]
> и к чему ты мне этот раздел справки процитировал?
Вероятно, к тому, чтобы ты его всё-таки прочитал.
Piter (2006-03-05 13:00:00) [18]Handle (05.03.06 11:47) [2]
NewItem := TMenuItem.Create(PopupMenu1);
NewItem.Caption := 'ТЕКСТ';
NewItem.Bitmap:= TheBitmap;
PopupMenu1.Items.Insert(0{номер строки в PopupMenu},NewItem);
это конференция WinApi, а не VCL.
n0name (05.03.06 7:38) [1]
и к чему ты мне этот раздел справки процитировал?
Ты мое сообщение читал?
Handle (2006-03-05 11:47:00) [19]
procedure TForm1.PopupMenu1Popup(Sender: TObject);
var
TheBitmap: TBitmap;
TheIcon: TIcon;
NewItem: TMenuItem;
begin
TheBitmap:= TBitmap.Create;
TheIcon:= TIcon.Create;
TheBitmap.Height := TheIcon.Height;
TheBitmap.Width := TheIcon.Width;
TheIcon.Handle := Image1.Picture.Icon.Handle;
TheBitmap.Canvas.Draw(0, 0, TheIcon);
NewItem := TMenuItem.Create(PopupMenu1);
NewItem.Caption := 'ТЕКСТ';
NewItem.Bitmap:= TheBitmap;
PopupMenu1.Items.Insert(0{номер строки в PopupMenu},NewItem);
end;
n0name (2006-03-05 07:38:00) [20]MFT_BITMAP
Displays the menu item using a bitmap. The low-order word of the dwTypeData member is the bitmap handle, and the cch member is ignored.
Windows 98/Me, Windows 2000/XP: MFT_BITMAP is replaced by MIIM_BITMAP and hbmpItem.
MIIM_BITMAP
Microsoft Windows 98/Windows Millennium Edition (Windows Me), Windows 2000/Windows XP: Retrieves or sets the hbmpItem member.
hbmpItem
Windows 98/Me, Windows 2000/XP: Handle to the bitmap to be displayed, or it can be one of the values in the following table. It is used when the MIIM_BITMAP flag is set in the fMask member.
HBMMENU_CALLBACK
A bitmap that is drawn by the window that owns the menu. The application must process the WM_MEASUREITEM and WM_DRAWITEM messages.
HBMMENU_MBAR_CLOSE
Close button for the menu bar.
HBMMENU_MBAR_CLOSE_D
Disabled close button for the menu bar.
HBMMENU_MBAR_MINIMIZE
Minimize button for the menu bar.
HBMMENU_MBAR_MINIMIZE_D
Disabled minimize button for the menu bar.
HBMMENU_MBAR_RESTORE
Restore button for the menu bar.
HBMMENU_POPUP_CLOSE
Close button for the submenu.
HBMMENU_POPUP_MAXIMIZE
Maximize button for the submenu.
HBMMENU_POPUP_MINIMIZE
Minimize button for the submenu.
HBMMENU_POPUP_RESTORE
Restore button for the submenu.
HBMMENU_SYSTEM
Windows icon or the icon of the window specified in dwItemData.