Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как рисовать картинки в пунктах меню 
:(
    Опции темы
Nikfel
  Дата 16.7.2009, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 15.7.2009
Где: Kirov

Репутация: нет
Всего: нет



У меня лежит меню в ресурсах. Загружаю его так:

Код

SetMenu(hwin,LoadMenu(HInstance, 'MAINMENU'));


Я понял как обработать сообщение WM_MeasureItem и WM_DrawItem, просто надо сначала для пункта меню сделать так:
Код

var h,h1:HMenu;
begin
h :=GetMenu(hwin);
h1 :=GetSubMenu(h,0);
ModifyMenu(h1,0,mf_ByPosition or mf_OwnerDraw,1001,'');


Можно ли поставить (mf_ByPosition or mf_OwnerDraw) через SetWindowLong?
Тогда окно будет получать сообщения WM_MeasureItem и WM_DrawItem, но проблема в том как нарисовать на меню, а точнее никак не получается получить HDC для пункта меню, чтобы рисовать на нем. 

В интернете найти не смог, т.к. там все плохие варианты предлагают, а мне надо на чистом Winapi.

Может кто знает как осуществить такое? Заранее спасибо.
PM MAIL   Вверх
Romikgy
Дата 16.7.2009, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Nikfel @  16.7.2009,  15:33 Найти цитируемый пост)
там все плохие варианты предлагают

хочу сказать один секрет , все варианты в конце концов работаю через винапи ,
так что берем вариант и смотрим что он делает , и получаем ответ , правим под себя и получаем то что хотим....


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Nikfel
Дата 16.7.2009, 20:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 15.7.2009
Где: Kirov

Репутация: нет
Всего: нет



И как же тогда перевести вот этот код на чистый WinApi:
http://delphisite.ru/faq/kak-risovat-karti...-punktakh-menyu

В основном в интернете я натыкался на подобный код через:
Procedure WMDrawItem(var Msg:TWMDrawItem); message wm_DrawItem;
Procedure WMMeasureItem(var Msg:TWMMeasureItem); message wm_MeasureItem;

Но на чистом WinApi делается по другому.
PM MAIL   Вверх
kami
Дата 16.7.2009, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(Nikfel @  16.7.2009,  20:11 Найти цитируемый пост)
Но на чистом WinApi делается по другому.

По другому - это как?
там что, сообщения другие приходят?
Да, обработчик не будет классовым методом. Но это ничего не меняет.
PM MAIL WWW   Вверх
Nikfel
Дата 16.7.2009, 21:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 15.7.2009
Где: Kirov

Репутация: нет
Всего: нет



Код

var DIS:DRAWITEMSTRUCT;
...
WM_DrawItem:begin


Проблема в том как записать переменную DIS? Чтобы можно было получить DIS.HDC, чтобы рисовать на нем. Знаю что надо брать lParam, но как его записать в DIS?
PM MAIL   Вверх
Romikgy
Дата 16.7.2009, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Nikfel @  16.7.2009,  19:11 Найти цитируемый пост)
В основном в интернете я натыкался на подобный код через:
Procedure WMDrawItem(var Msg:TWMDrawItem); message wm_DrawItem;
Procedure WMMeasureItem(var Msg:TWMMeasureItem); message wm_MeasureItem;

цикл обработки сообщения есть ?
вот туда и пихаешь 
Код

wm_DrawItem:
begin

end;
wm_MeasureItem:
begin

end;



Добавлено через 2 минуты и 37 секунд
Код

WM_DRAWITEM:
      with PDrawItemStruct(Message.LParam)^ do
      begin
        for I := 0 to Count - 1 do
        begin
          MenuItem := TPopupMenu(Items[I]).FindItem(itemID, fkCommand);
          if MenuItem <> nil then
          begin
            Canvas := TControlCanvas.Create;
            with Canvas do
            try
              SaveIndex := SaveDC(hDC);
              try
                Handle := hDC;
                Font := Screen.MenuFont;
                DrawMenuItem(MenuItem, Canvas, rcItem, TOwnerDrawState(LongRec(itemState).Lo));
              finally
                Handle := 0;
                RestoreDC(hDC, SaveIndex);
              end;
            finally
              Canvas.Free;
            end;
            Exit;
          end;
        end;
      end;
    WM_MEASUREITEM:
      with PMeasureItemStruct(Message.LParam)^ do
      begin
        for I := 0 to Count - 1 do
        begin
          MenuItem := TPopupMenu(Items[I]).FindItem(itemID, fkCommand);
          if MenuItem <> nil then
          begin
            DC := GetWindowDC(Window);
            try
              Canvas := TControlCanvas.Create;
              with Canvas do
              try
                SaveIndex := SaveDC(DC);
                try
                  Handle := DC;
                  Font := Screen.MenuFont;
                  MenuItem.MeasureItem(Canvas, Integer(itemWidth),
                    Integer(itemHeight));
                finally
                  Handle := 0;
                  RestoreDC(DC, SaveIndex);
                end;
              finally
                Canvas.Free;
              end;
            finally
              ReleaseDC(Window, DC);
            end;
            Exit;
          end;
        end;
      end;

вот кусок из TPopupMenu


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Nikfel
Дата 16.7.2009, 22:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 15.7.2009
Где: Kirov

Репутация: нет
Всего: нет



Romikgy,  большое спасибо за пример кода, теперь становится понятнее как такое делать. Буду дальше разбираться что к чему.
PM MAIL   Вверх
Nikfel
Дата 19.7.2009, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 15.7.2009
Где: Kirov

Репутация: нет
Всего: нет



Вот еще что мне не понятно:
Как узнать и изменить ширину окна меню?
Как узнать высоту пункта меню и изменить её, т.е. может быть Separator или обычный пункт меню?
PM MAIL   Вверх
Nikfel
  Дата 19.7.2009, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 15.7.2009
Где: Kirov

Репутация: нет
Всего: нет



Разобрался как изменить ширину и высоту пункта меню.
Код

var mii:PMeasureItemStruct;
WM_MeasureItem:begin
    mii:=PMeasureItemStruct(LParam);
    mii.itemWidth:=150;
    mii.itemHeight:=32;
end;


Еще бы как-то узнать что пункт меню это separator и мне надо вывести текст(с заданным шрифтом) и получить ширину и высоту текста. 

Просто если не трудно то напишите какие для этого функции и процедуры нужно использовать?
PM MAIL   Вверх
Romikgy
Дата 20.7.2009, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Nikfel @  19.7.2009,  20:48 Найти цитируемый пост)
что пункт меню это separator 

Код

BOOL WINAPI GetMenuItemInfo(

    HMENU hMenu,    
    UINT uItem,    
    BOOL fByPosition,    
    LPMENUITEMINFO lpmii    
   );
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; 
 

fType

Menu item type. This member can be one or more of these values:

Value    Meaning
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.
MFT_MENUBARBREAK    Places the menu item on a new line (for a menu bar) or in a new column (for a drop-down menu, submenu, or shortcut menu). For a drop-down menu, submenu, or shortcut menu, a vertical line separates the new column from the old.
MFT_MENUBREAK    Places the menu item on a new line (for a menu bar) or in a new column (for a drop-down menu, submenu, or shortcut menu). For a drop-down menu, submenu, or shortcut menu, the columns are not separated by a vertical line.
MFT_OWNERDRAW    Assigns responsibility for drawing the menu item to the window that owns the menu. The window receives a WM_MEASUREITEM message before the menu is displayed for the first time, and a WM_DRAWITEM message whenever the appearance of the menu item must be updated. If this value is specified, the dwTypeData member contains an application-defined 32-bit value.
MFT_RADIOCHECK    Displays checked menu items using a radio-button mark instead of a check mark if the hbmpChecked member is NULL.
MFT_RIGHTJUSTIFY    Right-justifies the menu item and any subsequent items. This value is valid only if the menu item is in a menu bar.
MFT_SEPARATOR    Specifies that the menu item is a separator. A menu item separator appears as a horizontal dividing line. The dwTypeData and cch members are ignored. This value is valid only in a drop-down menu, submenu, or shortcut menu.
MFT_STRING    Displays the menu item using a text string. The dwTypeData member is the pointer to a null-terminated string, and the cch member is the length of the string.
 

The MFT_BITMAP, MFT_SEPARATOR, and MFT_STRING values cannot be combined with one another.


Цитата(Nikfel @  19.7.2009,  20:48 Найти цитируемый пост)
мне надо вывести текст(с заданным шрифтом) и получить ширину и высоту текста. 


Цитата(Romikgy @  16.7.2009,  20:08 Найти цитируемый пост)
 DC := GetWindowDC(Window);

+
Код

BOOL GetTextExtentPoint32(

    HDC hdc,    // handle of device context 
    LPCTSTR lpString,    // address of text string 
    int cbString,    // number of characters in string 
    LPSIZE lpSize    // address of structure for string size  
   );




--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Nikfel
  Дата 20.7.2009, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 15.7.2009
Где: Kirov

Репутация: нет
Всего: нет



Спасибо, буду дальше разбираться. Но вот еще что не ясно:

как закрасить всю область выпадающего меню, а не только перекрасить пункты меню? А вот как получить hdc всего выпадающего меню, а то у меня как-то не красиво получается по бокам белый фон.
PM MAIL   Вверх
Romikgy
Дата 20.7.2009, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



http://torry.net/pages.php?id=149
http://torry.net/pages.php?id=147
http://torry.net/pages.php?id=150
качай где FWS , там есть исходники , и разбирай как заменяют отрисовку стандартного меню своим!


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Nikfel
Дата 21.7.2009, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 15.7.2009
Где: Kirov

Репутация: нет
Всего: нет



Спасибо, буду разбираться.

А как на счет такого способа рисования по всему меню:

Код

WM_DrawItem:begin
   H0:=FindWindow('#32768',nil);//получаем хандле окна меню
   H1:=getwindowdc(H0);//получаем hdc всего меню
end;

PM MAIL   Вверх
Nikfel
  Дата 22.7.2009, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 15.7.2009
Где: Kirov

Репутация: нет
Всего: нет



Для рисования по всему меню лучше всего делать так:
Код

var dis:PDrawItemStruct;
WM_DRAWITEM:begin
dis:=PDrawItemStruct(LParam);
getwindowdc(WindowFromDC(dis.hDC)); //hdc всего меню
end;

Никак не могу разобраться с GetMenuItemInfo. Почему-то не работает вот это:
Код

function GetMenuIDName(itemID:integer):boolean;
var Buffer: array[0..50] of Char;
begin
MII.cbSize        := SizeOf(MENUITEMINFO);
MII.fMask         := MIIM_STRING or MIIM_TYPE;
MII.fType         := MFT_STRING or MFT_OWNERDRAW;
MII.dwTypeData    := buffer;
MII.cch           := 1023;
result:=false;
If GetMenuItemInfo(Menu,itemID,false,MII) then begin
result:=true;
ItemName:=mii.dwTypeData;
end;
end;


menu:=getsubmenu(getmenu(wnd),0);

Где тут ошибка? функция GetMenuItemInfo всегда возвращает False, а значит не работает.
PM MAIL   Вверх
Romikgy
Дата 22.7.2009, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Nikfel @  22.7.2009,  10:35 Найти цитируемый пост)
GetMenuItemInfo всегда возвращает False

обработай ошибку используя GetLastError 
и посмотри что не в поряде


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0566 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.