Автор: ShIvADeSt
Дата сообщения: 31.08.2008 05:54
Maks150988
Много косяков было, первое - если пункт меню не имеет текста (а это именно разделитель), то у тебя был выход из процедуры отрисовки пункта. Далее, ты пытался получить статус разделитель или не разделитель передавая в функцию GetMenuState ID иконки, но статус получал по позиции, а не по команде. Что конечно в корне не верно, плюс много мелких багов, когда ты рисуешь часть пункта, а потом поверх того, что уже отрисовал рисуешь что то другое. В общем вот рабочий код
[more]
Код:
function MainDlgFunc(hWnd : THandle; uMsg : UINT; wParam : wParam; lParam : lParam) : BOOL; stdcall;
var
lpmis : PMEASUREITEMSTRUCT;
lpdis : PDRAWITEMSTRUCT;
MenuIndex : Integer;
MenuRect : TRect;
MenuText : Array [0..MAX_PATH] of Char;
MenuUINT : UINT;
BrushNew : HBRUSH;
BrushOld : HBRUSH;
PenBrush : HPEN;
PixelInx : Integer;
SelTmp : HGDIOBJ;
ItemState : DWORD;
begin
Result := TRUE;
case uMsg of
WM_MEASUREITEM :
case PDRAWITEMSTRUCT(lParam).CtlType of
ODT_MENU :
begin
MenuDC := GetDC(0);
lpmis := Pointer(lParam);
lstrcpy(MenuName, SizeMenu[lpmis.itemID]);
SetRectEmpty(RectData);
if MenuName[0] <> #0 then
begin
MenuDC := GetDC(0);
DrawText(MenuDC, MenuName, lstrlen(MenuName), RectData, DT_SINGLELINE or DT_CALCRECT or DT_LEFT);
ReleaseDC(0, MenuDC);
end;
lpmis.itemWidth := RectData.Right;
if (PChar(lpmis.itemData) = nil) then
lpmis.itemHeight := 10
else
lpmis.itemHeight := 22;
end;
end;
WM_DRAWITEM :
begin
case PDRAWITEMSTRUCT(lParam).CtlType of
ODT_MENU :
begin
lpdis := Pointer(lParam);
lstrcpy(MenuText, SizeMenu[lpdis.itemID]);
CopyRect(RectData, lpdis.rcItem);
SetRect(MenuRect, lpdis.rcItem.Left, lpdis.rcItem.Top, lpdis.rcItem.Left + 18, lpdis.rcItem.Bottom-3);
Inc(RectData.Left, 28);
if (lpdis.itemState and ODS_SELECTED) <> 0 then
begin
BrushNew := CreateSolidBrush(RGB(200, 210, 240));
BrushOld := SelectObject(lpdis.hDC, BrushNew);
FillRect(lpdis.hDC, lpdis.rcItem, BrushNew);
PenBrush := CreatePen(PS_SOLID, 1, RGB(50, 105, 200));
SelectObject(lpdis.hDC, PenBrush);
Rectangle(lpdis.hDC, lpdis.rcItem.Left, lpdis.rcItem.Top, lpdis.rcItem.Right, lpdis.rcItem.Bottom);
DeleteObject(PenBrush);
SetBkColor(lpdis.hDC, RGB(200, 210, 240));
SelectObject(lpdis.hDC, BrushOld);
DeleteObject(BrushNew);
SetBkMode(lpdis.hDC, TRANSPARENT);
SetTextColor(lpdis.hDC, GetSysColor(COLOR_WINDOWTEXT));
end
else
begin
FillRect(lpdis.hDC, lpdis.rcItem, GetSysColorBrush(COLOR_MENU));
SetBkColor(lpdis.hDC, GetSysColor(COLOR_WINDOW));
SetBkMode(lpdis.hDC, TRANSPARENT);
SetTextColor(lpdis.hDC, GetSysColor(COLOR_WINDOWTEXT));
for PixelInx := 22 downto 0 do
begin
SetDCPenColor(lpdis.hDC, GetGradientColor(RGB(205, 255, 255), PixelInx * 2));
SelTmp := SelectObject(lpdis.hDC, GetStockObject(DC_PEN));
MoveToEx(lpdis.hDC, lpdis.rcItem.Left + PixelInx, lpdis.rcItem.Top - 4, nil);
LineTo(lpdis.hDC, lpdis.rcItem.Left + PixelInx, lpdis.rcItem.Bottom);
DeleteObject(SelTmp);
end;
end;
if (lpdis.itemState and ODS_FOCUS) <> 0 then
DrawFocusRect(lpdis.hDC, PDRAWITEMSTRUCT(lParam).rcItem);
if (lpdis.itemState and ODS_GRAYED) <> 0 then
begin
SetBkMode(lpdis.hDC, TRANSPARENT);
SetBkColor(lpdis.hDC, GetSysColor(COLOR_GRAYTEXT));
SetTextColor(lpdis.hDC, GetSysColor(COLOR_GRAYTEXT));
end;
ItemState := GetMenuState(GetMenu(hApp), lpdis.itemID, MF_BYCOMMAND );
if (ItemState and MF_SEPARATOR =MF_SEPARATOR) then
begin
SetDCPenColor(lpdis.hDC, GetGradientColor(RGB(0, 0, 0), 0));
MoveToEx(lpdis.hDC, 22 + 4,lpdis.rcItem.Top + ((lpdis.rcItem.Bottom -lpdis.rcItem.Top) div 2), nil);
LineTo(lpdis.hDC, lpdis.rcItem.Right-4, lpdis.rcItem.Top + ((lpdis.rcItem.Bottom -lpdis.rcItem.Top) div 2));
end
else
begin
SetDCPenColor(lpdis.hDC, GetGradientColor(RGB(160, 175, 190), 0));
MoveToEx(lpdis.hDC, 22 + 4, lpdis.rcItem.Bottom - 3, nil);
LineTo(lpdis.hDC, lpdis.rcItem.Right-4, lpdis.rcItem.Bottom - 3);
lpdis.rcItem.Left := lpdis.rcItem.Left + 3;
DrawIconEx(lpdis.hDC, lpdis.rcItem.Left, (lpdis.rcItem.Top + lpdis.rcItem.Bottom - 16) div 2, MenuIcons[lpdis.itemID], 0, 0, 0, 0, DI_NORMAL) ;
DrawText(lpdis.hDC, MenuText, lstrlen(MenuText), RectData, DT_SINGLELINE or DT_VCENTER or DT_LEFT);
end;
end;
end;
end;
WM_CLOSE :
begin
for MenuIndex := MinCntMenu to MaxCntMenu do
begin
if MenuIcons[MenuIndex] <> 0 then
DeleteObject(MenuIcons[MenuIndex]);
end;
PostQuitMessage(0);
end;
WM_INITDIALOG :
begin
hApp := hWnd;
SetMenu(hApp, LoadMenu(hInstance, MAKEINTRESOURCE(101)));
CreateImageListMenuItems;
for MenuUINT := MinCntMenu to MaxCntMenu do
begin
GetMenuString(GetMenu(hApp), MenuUINT, MenuName, SizeOf(MenuName), MF_BYCOMMAND);
lstrcpyn(SizeMenu[MenuUINT], MenuName, SizeOf(SizeMenu[MenuUINT]));
end;
end;
WM_COMMAND :
if HiWord(wParam) = BN_CLICKED then
case LoWord(wParam) of
51 : MessageBox(hApp, '', '', MB_OK);
end;
else
Result := FALSE;
end;
end;