|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
Рисуем Меню своими руками на 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
|
||||
|
||||
Всем спасибо за ответы =) разобрался с этим...
Просто не нужно рисовать весь фон, достаточно только 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
|
||||
|
||||
Код:
AppendMenu(PopupMenu1, MF_SEPARATOR or MF_OWNERDRAW, 0, ''); ЗЫ : Как весело,.. сам спрашиваю, сам отвечаю спасибо всем за помощь ... Програмистами не рождаются, ими становятся! |
#4
|
||||
|
||||
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
|
||||
|
||||
Цитата:
MF_SEPARATOR - Это флаг Сепаратора, a флаг MF_OWNERDRAW - позволяет вручную отрисовать элемент меню в сообщении WM_DRAWITEM, и в моём случае необходимо использование обоих флагов Код:
MF_SEPARATOR or MF_OWNERDRAW Програмистами не рождаются, ими становятся! |
#6
|
||||
|
||||
ну если очень хочется, то можно:
Код:
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
|
||||
|
||||
Цитата:
Код:
... 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
|
||||
|
||||
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
|
||||
|
||||
О пасиба .. =) Отобразилось ... тока почмуто не все сепараторы =D, ну да ладно это уже мелочи ... дальше разбирусь
Програмистами не рождаются, ими становятся! |
#10
|
||||
|
||||
Блин нефига не понимаю... отобразлось 2 сепаратора из 4-х... флаги у всех одинаковые, ... непонимаю...
Вот теперь реально Хелп ми,... menu.ZIP Програмистами не рождаются, ими становятся! Последний раз редактировалось SCrat.ORS, 16.07.2010 в 01:24. |
#11
|
||||
|
||||
Ответа не дождался,.. пришлось полностью переписывать рисовалку меню,... но ничего, много нового узнал. Теперь всё работает =). Если кому интересно, пишите, расскажу.
Програмистами не рождаются, ими становятся! |
#12
|
|||
|
|||
Цитата:
|