Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Программа и интерфейс
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 14.07.2010, 14:58
Аватар для SCrat.ORS
SCrat.ORS SCrat.ORS вне форума
Активный
 
Регистрация: 20.02.2007
Адрес: Мой адрес не дом и не улица, мой адрес 0x7С00
Сообщения: 208
Версия Delphi: 2006
Репутация: 884
По умолчанию Рисуем Меню своими руками на WinApi

Вопрос, как отрисовать меню с нуля?
Проблема в том, что помимо стандартного отрисования иконок меню, изврашенских рамок для выделения и прочего столкнулся вот с чем:
Если отрисовать полностью фон всего меню то иконки, чеки, текст и даже сепараторы не отрисовываюся ... беда...

Код:
...
function WindowProc(Window: HWND; aMessage, wParam,
  lParam: LongInt): LongInt; stdcall;
Begin
case AMessage of
...
  WM_DRAWITEM: 
...
               //Рисуем фон меню
             drawMenuWnd(lpdis.hDC);   

drawMenuWnd(lpdis.hDC) <- Функция полностью перересовывает фон меню, но она как бы закрашивает все остальное, если убрать эту строчку, то всё отрисовывается но на стандарном фоне.
Ранее рассматривали пересовку меню, но там фон не трогали...

menu.zip
__________________
Програмистами не рождаются, ими становятся!
Ответить с цитированием
  #2  
Старый 14.07.2010, 16:22
Аватар для SCrat.ORS
SCrat.ORS SCrat.ORS вне форума
Активный
 
Регистрация: 20.02.2007
Адрес: Мой адрес не дом и не улица, мой адрес 0x7С00
Сообщения: 208
Версия Delphi: 2006
Репутация: 884
По умолчанию

Всем спасибо за ответы =) разобрался с этим...
Просто не нужно рисовать весь фон, достаточно только 3-х пиксельной рамки, а все остальное зарисовывается невыделенными пунктами меню и сепараторами.

Теперь возник другой вопрос...

Почему вылетает RunTime Error 216?
Код:
...
AppendMenu(PopupMenu1, MF_SEPARATOR or MF_OWNERDRAW, 0, nil);
...

А Без MF_OWNERDRAW работает нормально.
Код:
...
AppendMenu(PopupMenu1, MF_SEPARATOR , 0, nil);
...

Ну и собсно проблема -Как Сепаратору присвоить стиль MF_OWNERDRAW для перерисовки и Как его перерисовать вручную?
__________________
Програмистами не рождаются, ими становятся!

Последний раз редактировалось SCrat.ORS, 14.07.2010 в 16:36.
Ответить с цитированием
  #3  
Старый 14.07.2010, 19:05
Аватар для SCrat.ORS
SCrat.ORS SCrat.ORS вне форума
Активный
 
Регистрация: 20.02.2007
Адрес: Мой адрес не дом и не улица, мой адрес 0x7С00
Сообщения: 208
Версия Delphi: 2006
Репутация: 884
По умолчанию

Код:
AppendMenu(PopupMenu1, MF_SEPARATOR or MF_OWNERDRAW, 0, '');
Вот .. убрал nil Ошибка исчезла... как же отрисовать Сепаратор теперь в WM_DRAWITEM?
ЗЫ : Как весело,.. сам спрашиваю, сам отвечаю спасибо всем за помощь ...
__________________
Програмистами не рождаются, ими становятся!
Ответить с цитированием
  #4  
Старый 14.07.2010, 20:27
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

BOOL WINAPI AppendMenu(
__in HMENU hMenu,
__in UINT uFlags,
__in UINT_PTR uIDNewItem,
__in_opt LPCTSTR lpNewItem
);

lpNewItem [in, optional]
LPCTSTR
The content of the new menu item. The interpretation of lpNewItem depends on whether the uFlags parameter includes the following values.

Value Meaning
MF_BITMAP
0x00000004L Contains a bitmap handle.

MF_OWNERDRAW
0x00000100L Contains an application-supplied value that can be used to maintain additional data related to the menu item. The value is in the itemData member of the structure pointed to by the lParam parameter of the WM_MEASUREITEM or WM_DRAWITEM message sent when the menu is created or its appearance is updated.

MF_STRING
0x00000000L Contains a pointer to a null-terminated string.


а для сепаратора используйт флаг MF_SEPARATOR вместо MF_OWNERDRAW
Ответить с цитированием
  #5  
Старый 14.07.2010, 21:58
Аватар для SCrat.ORS
SCrat.ORS SCrat.ORS вне форума
Активный
 
Регистрация: 20.02.2007
Адрес: Мой адрес не дом и не улица, мой адрес 0x7С00
Сообщения: 208
Версия Delphi: 2006
Репутация: 884
По умолчанию

Цитата:
Сообщение от NumLock
а для сепаратора используйт флаг MF_SEPARATOR вместо MF_OWNERDRAW

MF_SEPARATOR - Это флаг Сепаратора, a флаг MF_OWNERDRAW - позволяет вручную отрисовать элемент меню в сообщении WM_DRAWITEM, и в моём случае необходимо использование обоих флагов
Код:
MF_SEPARATOR or MF_OWNERDRAW
Но с этим я уже разобрался теперь мне нужно понять как отрисовать вручную сепаратор в WM_DRAWITEM, Как выделенный пункт меню отрисовывать - понятно, Не выделенный тоже понятно, CHECK тоже понятно... Иконки понятно, НО вот как отрисовать сам Сепаратор?
__________________
Програмистами не рождаются, ими становятся!
Ответить с цитированием
  #6  
Старый 14.07.2010, 23:06
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

ну если очень хочется, то можно:
Код:
BOOL DrawEdge(
    HDC hdc,	// handle to device context
    LPRECT qrc,	// pointer to rectangle coordinates
    UINT edge,	// type of inner and outer edge to draw
    UINT grfFlags	// type of border
   );	
к примеру
Ответить с цитированием
  #7  
Старый 14.07.2010, 23:40
Аватар для SCrat.ORS
SCrat.ORS SCrat.ORS вне форума
Активный
 
Регистрация: 20.02.2007
Адрес: Мой адрес не дом и не улица, мой адрес 0x7С00
Сообщения: 208
Версия Delphi: 2006
Репутация: 884
По умолчанию

Цитата:
Сообщение от NumLock
ну если очень хочется, то можно:
Код:
BOOL DrawEdge(
    HDC hdc,	// handle to device context
    LPRECT qrc,	// pointer to rectangle coordinates
    UINT edge,	// type of inner and outer edge to draw
    UINT grfFlags	// type of border
   );	
к примеру


Код:
...  
WM_DRAWITEM:
      begin

        case PDRAWITEMSTRUCT(lParam).CtlType of
          ODT_MENU :
            begin
             lpdis := Pointer(LParam);
             item := Pointer(lpdis.ItemData);

             Arrow:=LoadBitmap(0,Pchar(ArrowNum));
             h2DC := CreateDC('DISPLAY', nil, nil, nil);
             h1DC := CreateCompatibleDC(h2DC);
             SetBkMode(h1DC, TRANSPARENT);
             SelectObject(h1DC, Arrow);
             GetObject(Arrow,SizeOf(GetArrow),@GetArrow);
             CheckWidth:=GetArrow.bmWidth;

            //Рисуем Рамку меню
              drawMenuWnd(lpdis.hDC);


if (lpdis.itemState and ODS_SELECTED = ODS_SELECTED) then begin
 //- тут узнаём что рисуется Выделенный пункт меню и отрисовываем его
FillRect(lpdis.hDC,lpdis.rcItem, GetSysColorBrush(COLOR_HIGHLIGHT); //к примеру
 DrawIconEx(бла,бла,бла); // Рисуем иконку, текс и прочие шалости веделенного пункта меню в lpdis.rcItem - Rect этого пункта меню.
... 
end Else begin
//Тут узнаем о не выделенных пунктах меню ну и отрисовывем их как хотим. lpdis.rcItem - Rect'ы этИХ менюх
...
end; 
//Это всё опозналось, прекрасно, пробуем опознать сепаратор.

 mii.cbSize := sizeof(mii); //Структура Информации о Пункте меню
            mii.fMask:=MIIM_STATE or MIIM_TYPE or MIIM_ID or MIIM_DATA or MIIM_SUBMENU;
            mii.cbSize:=sizeof(MENUITEMINFO);
            GetMenuItemInfo(PopupMenu1, lpdis.itemID, true, &mii); //Получаем информацию о текущем пункте меню (lpdis.itemID)
             if (mii.fType = MFT_SEPARATOR) then begin //Смотрим - сепаратор или нет, если да то отрисовываем его.

            FillRect(lpdis.hDC,lpdis.rcItem, GetSysColorBrush(COLOR_WINDOWTEXT));

             end;  


         end;
...
Как рисовать это понятно, но мне не понятно другое
Вот вродебы должно отрисовать, но нет,.. if mii.fType = MFT_SEPARATOR - не даёт координаты сепаратора на менюхе lpdis.rcItem - остаётся темеже что и на выделенном меню...
Вот мне и надо узнать что рисуется Сепаратор, и получить его TRECT...
__________________
Програмистами не рождаются, ими становятся!

Последний раз редактировалось SCrat.ORS, 15.07.2010 в 00:00.
Ответить с цитированием
  #8  
Старый 15.07.2010, 10:07
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

fType - Menu item type. This member can be one or more of these values:
...
MFT_OWNERDRAW
MFT_SEPARATOR
...
поэтому if (mii.fType = MFT_SEPARATOR) then нужно, имхо, изменить на if (mii.fType and MFT_SEPARATOR)>0 then
ну и:
BOOL WINAPI GetMenuItemRect(
HWND hWnd,
HMENU hMenu,
UINT uItem,
LPRECT lprcItem
);
Ответить с цитированием
  #9  
Старый 15.07.2010, 17:23
Аватар для SCrat.ORS
SCrat.ORS SCrat.ORS вне форума
Активный
 
Регистрация: 20.02.2007
Адрес: Мой адрес не дом и не улица, мой адрес 0x7С00
Сообщения: 208
Версия Delphi: 2006
Репутация: 884
По умолчанию

О пасиба .. =) Отобразилось ... тока почмуто не все сепараторы =D, ну да ладно это уже мелочи ... дальше разбирусь
__________________
Програмистами не рождаются, ими становятся!
Ответить с цитированием
  #10  
Старый 15.07.2010, 20:57
Аватар для SCrat.ORS
SCrat.ORS SCrat.ORS вне форума
Активный
 
Регистрация: 20.02.2007
Адрес: Мой адрес не дом и не улица, мой адрес 0x7С00
Сообщения: 208
Версия Delphi: 2006
Репутация: 884
Вопрос

Блин нефига не понимаю... отобразлось 2 сепаратора из 4-х... флаги у всех одинаковые, ... непонимаю...
Вот теперь реально Хелп ми,...
menu.ZIP
__________________
Програмистами не рождаются, ими становятся!

Последний раз редактировалось SCrat.ORS, 16.07.2010 в 01:24.
Ответить с цитированием
  #11  
Старый 18.07.2010, 14:21
Аватар для SCrat.ORS
SCrat.ORS SCrat.ORS вне форума
Активный
 
Регистрация: 20.02.2007
Адрес: Мой адрес не дом и не улица, мой адрес 0x7С00
Сообщения: 208
Версия Delphi: 2006
Репутация: 884
Счастье

Ответа не дождался,.. пришлось полностью переписывать рисовалку меню,... но ничего, много нового узнал. Теперь всё работает =). Если кому интересно, пишите, расскажу.
__________________
Програмистами не рождаются, ими становятся!
Ответить с цитированием
  #12  
Старый 10.12.2010, 09:45
Agasfer2010 Agasfer2010 вне форума
Прохожий
 
Регистрация: 13.05.2010
Сообщения: 25
Репутация: 10
По умолчанию

Цитата:
Сообщение от SCrat.ORS
Ответа не дождался,.. пришлось полностью переписывать рисовалку меню,... но ничего, много нового узнал. Теперь всё работает =). Если кому интересно, пишите, расскажу.
Приветствую! Интересно, пишу, расскажи)
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 16:57.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter