![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Owner Draw Menu Item
Dima_dvp © (2003-11-01 01:25:00)
Уважаемые мастера, возникла необходимость вывести меню с иконками(у каждого пункта своя уникальная). Для этого по видимому следует использывать "ручную" прорисовку пунктов меню.
Не могу разобраться к какому окну всё-таки должны приходить сообщения WM_MEASUREITEM, WM_DRAWITEM если меню является Popup.
Код:
TLinkedItem = record
id: DWORD;
lpcPath: PChar;
lpcTitle: PChar;
hMenu: HMENU;
next: PLinkedItem;
end;
//**************************************************************
//ФУНКЦИЯ, СОХРАНЯЮЩАЯ НЕКИЙ СПИСОК В МЕНЮ
function TLinkedList.SaveToMenu(const hMenu: HMENU; const defaultIcon: HICON): DWORD;
var
Cursor: PLinkedItem;
MII: tagMenuItemInfo;
begin
//Устанавливаем курсор в начало
Cursor := FFirst;
//Очищаем меню
//КСТАТИ ТОЖЕ ВОПРОС КАК ЛУЧШЕ ОЧИСТИТЬ МЕНЮ?
while DeleteMenu(hMenu, 0, MF_BYPOSITION) do;
//Пока не достигнут конец спсика
while Cursor <> nil do begin
//Добавляем пункт
ZeroMemory(@MII, SizeOf(MII));
MII.cbSize := SizeOf(MII);
MII.fMask := MIIM_DATA or MIIM_TYPE or MIIM_ID or MIIM_BITMAP;
MII.fType := MFT_STRING;
MII.wID := Cursor^.id;
MII.dwItemData := Cursor^.id;
MII.dwTypeData := Cursor^.lpcTitle;
MII.hbmpItem := HBITMAP(HBMMENU_CALLBACK);
//MII.cch := lstrlen(Cursor^.lpcTitle);
if not InsertMenuItem(hMenu, 0, True, MII) then begin
//Result := GetLastError();
Result := 20;
Exit;
end;
Cursor := Cursor^.next;
//Устанавливаем иконку у этого пункта меню
end;
Result := 0;
end;
//**************************************************************
//ВИДИМО ОБРАБОТКА МЕНЮ ДОЛЖНА ВЫГЛЯДЕТЬ КАК-ТО ТАК, НО В КАКОЙ WndProc?
//Отрисовка пункта меню
WM_DRAWITEM: begin
//Если пришло от меню
if wParam = 0 then begin
DrawItem(PDRAWITEMSTRUCT(lParam));
Result := Integer(True);
end;
end;
//.......
WM_MEASUREITEM: begin
//Если пришло от меню
if wParam = 0 then begin
MeasureItem(PMEASUREITEMSTRUCT(lParam));
Result := Integer(True);
end;
end;
//*************************************************************
//А ВОТ ТАК СОЗДАВАЛОСЬ СОБСТВЕННО МЕНЮ
//Создаём меню
progMenu := CreatePopupMenu;
Подскажите пожалуста...
Заранее благодарен
Nick Denry (2003-11-01 16:33:00) [1]
2>[15]
А непонятно следкщее: Чем определяется окно, котому посылаются эти сообщения: С главным меню всё понятно потому что оно привязано к окну а всплывающие меню я же могу показать как реакцию на клик в любом окне.. Вот тут и возникает вопрос куда придут сообщения...
Окно определяется окном, а вот сообщеня придут в любом случае в оконную процедуру обработки сообщений...
andre (2003-11-01 14:39:00) [2]
А SetMenuItemBitMaps никак не пойдёт?
Dima_dvp (2003-11-01 14:35:00) [3]
Кажется разобрался, спсибо за помощь
Dima_dvp (2003-11-01 14:19:00) [4]
Справочку щас посмотрю..
А непонятно следкщее: Чем определяется окно, котому посылаются эти сообщения: С главным меню всё понятно потому что оно привязано к окну а всплывающие меню я же могу показать как реакцию на клик в любом окне.. Вот тут и возникает вопрос куда придут сообщения...
И ещё GetLastError возвращает ошибку 87 если я в MenuItemInfo ставлю MII.hbmpItem := HBITMAP(HBMMENU_CALLBACK); Впринципе в SDK этого поля вообще нету, а вот в книге у меня оно описано.
Меню заполняется только динамически и поэтому ресурсы использывать нельзя.
Привидите пример как вы используете SetMenuItemInfo в частности параметр MenuItemInfo
Спасибо за помощь
Nick Denry (2003-11-01 13:55:00) [5]
2>[12] - не понял вопроса - что не понятного?
Рекомендую : русская справка по WinApihttp://www.soobcha.ru/rushelp
Nick Denry (2003-11-01 13:51:00) [6]
2>[10]
Настоятельно рекомендую, если меню не изменяется динамически - грузить его из ресурса.
Ownerdraw я действительно устанавливал для каждого пункта отдельно - но использовал при этом функцию
Функция SetMenuItemInfo модуль Windows
Группа ссылок: Меню
Описание:
function SetMenuItemInfo(p1: HMENU; p2: UINT; p3: BOOL; const p4: TMenuItemInfo): BOOL;
Используется для получения информации о пункте меню.
Параметры:
p1: дискриптор меню, которое содержит пункт меню
p2: индентификатор (fByPosition=FALSE) или позиция (fByPosition=TRUE) пункта меню, для которого устанавливаем информацию
p3: Определяет содержание параметра p2
p4: указатель на структуру TMenuItemInfo, в которой содержится устанавливаемая информация
Возвращаемые значения
Если успешно то не ноль.
Если функция терпит неудачу - ноль. Чтобы получить расширенную информацию об ошибке, вызовите функцию GetLastError.
См. также: GetMenuItemInfo
Функция находится в файле user32.dll
Dima_dvp (2003-11-01 13:50:00) [7]
Но чем определяется окно, к которому придёт сообщение WM_DRAWITEM??? Тем, в чьей WindProc будет вызов TrackPopupMenu? Вообще не понятно это, а тем более когда меню выводиться по щелчку в трее...
Nick Denry (2003-11-01 13:46:00) [8]
[9]Нет. ТЫ ен прав - я в своем коде просто выделяю тот участок меню из главного, который мне нужен. (мое меню - из ресурса). Не важно как было созданно меню - оно в любом случае получает хендл - hMEnu:)
HMENU CreateMenu(VOID)
Parameters
This function has no parameters.
********************************
или
HMENU CreatePopupMenu(VOID).
Parameters
This function has no parameters
***************************************
и даже
HMENU LoadMenu(
HINSTANCE hInstance, // handle of application instance
LPCTSTR lpMenuName // menu name string or menu-resource identifier
);
дают одинаковый результат...
Dima_dvp (2003-11-01 13:45:00) [9]
//Добавляем пункт
ZeroMemory(@MII, SizeOf(MII));
MII.cbSize := SizeOf(MII);
MII.fMask := MIIM_DATA or MIIM_TYPE or MIIM_ID or MIIM_BITMAP;
MII.fType := MFT_STRING;
MII.wID := Cursor^.id; //неважно что такое Cursor
MII.dwItemData := Cursor^.id;
MII.dwTypeData := Cursor^.lpcTitle;
//включение нижеследуюшей строки приводит к ошибка при вставке пункта меню
MII.hbmpItem := HBITMAP(HBMMENU_CALLBACK);
//MII.cch := lstrlen(Cursor^.lpcTitle);
if not InsertMenuItem(hMenu, 0, True, MII) then begin
//Result := GetLastError();
Result := 20;
Exit;
end;
Что делать, чтобы меню было OwnerDraw и странно, что OwnerDraw устанавливается для каждого пункта меню отдельно.... или может этот пункт должен быть SubMenu обязательно и тогда будет OwnerDraw только вложенное мменю????
Разъясните плиз...
Dima_dvp (2003-11-01 13:38:00) [10]
Из вашего примера я почерпнул, что всплывающее меню должно быть создано как
SubMenu := GetSubMenu(menu,0);
а никак не
SubMenu := CreatePopupMenu;
я прав? Но мне совсем не нужно главное меню... Или с этим придётся смириться?
Nick Denry (2003-11-01 13:26:00) [11]
:)
Dima_dvp (2003-11-01 13:12:00) [12]
Спасибо..., но зачем орать-то, можно было просто сказать....
Nick Denry (2003-11-01 13:06:00) [13]
Заранеее пожалуиста... :))
Nick Denry (2003-11-01 12:48:00) [14]
куриные кубики Магги - просто как раз, два, три... ;-)
Nick Denry (2003-11-01 12:47:00) [15]
{
Nick Denry (2003-11-01 12:46:00) [16]var
menu_pstr : TpaintStruct;
menu,submenu : HMENU;
{menu pens&brushes ghtabrc "M"
Nick Denry (2003-11-01 12:45:00) [17]
WM_Syscdicon: {
Dima_dvp (2003-11-01 02:01:00) [18]
Да кстати если это важно, то отмечу что меню выводиться при клике по иконке в трее...