Форум: "WinAPI";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
ВнизOwnerDraw PopupMenu и его рамка Найти похожие ветки
← →
DVM © (2004-03-10 18:48) [0]Увидел ниже вопрос про меню и решил задать в чем то похожий другой.
Возможно ли как-то перекрасить рамку Popup Menu в пределах одного приложения. Дело в том что сами Item-ы меню у меня отрисовываются через OwnerDraw, а вокруг них остается серый прямоугольник. Во время отрисовки Item - а, добраться до рамки не получается, т.к. вероятно область отсечения для окна меню установлена так, что рамка меню туда не попадает.
← →
DVM © (2004-03-10 18:48) [0]Увидел ниже вопрос про меню и решил задать в чем то похожий другой.
Возможно ли как-то перекрасить рамку Popup Menu в пределах одного приложения. Дело в том что сами Item-ы меню у меня отрисовываются через OwnerDraw, а вокруг них остается серый прямоугольник. Во время отрисовки Item - а, добраться до рамки не получается, т.к. вероятно область отсечения для окна меню установлена так, что рамка меню туда не попадает.
← →
Игорь Шевченко © (2004-03-10 23:16) [1]DVM © (10.03.04 18:48)
Рамка представляет из себя Window Frame для окна Popup-меню, и относится к неклиентской части того самого окна с классом #32768,
которое отображается для каждого Popup-меню.
Сдается мне, что лучше имитировать Popup-меню, например, ListBox"ом и уже его рисовать, как угодно.
Это, кстати, не так трудно. Впрочем, если вдруг увидишь нарисованное без рамки Popup- или MainMenu, определи класс окна, которое отображается в момент Popup"а - самому интересно, можно ли стандартными средствами отрисовать неклиентскую часть окна меню.
← →
Игорь Шевченко © (2004-03-10 23:16) [1]DVM © (10.03.04 18:48)
Рамка представляет из себя Window Frame для окна Popup-меню, и относится к неклиентской части того самого окна с классом #32768,
которое отображается для каждого Popup-меню.
Сдается мне, что лучше имитировать Popup-меню, например, ListBox"ом и уже его рисовать, как угодно.
Это, кстати, не так трудно. Впрочем, если вдруг увидишь нарисованное без рамки Popup- или MainMenu, определи класс окна, которое отображается в момент Popup"а - самому интересно, можно ли стандартными средствами отрисовать неклиентскую часть окна меню.
← →
Serge © (2004-03-11 09:23) [2]> Игорь Шевченко © "...можно ли стандартными средствами отрисовать неклиентскую часть окна меню"
Вроде как можно - реализованно в компоненте XPMenu при свойстве FlatMenu = true. Если он вам Нужен (в случае если Вы его не видели) могу его переслать, скажите только куда - на почту либо в "Кладовку" (хотя по моему его я оттуда и скачивал года три назад)
← →
Serge © (2004-03-11 09:23) [2]> Игорь Шевченко © "...можно ли стандартными средствами отрисовать неклиентскую часть окна меню"
Вроде как можно - реализованно в компоненте XPMenu при свойстве FlatMenu = true. Если он вам Нужен (в случае если Вы его не видели) могу его переслать, скажите только куда - на почту либо в "Кладовку" (хотя по моему его я оттуда и скачивал года три назад)
← →
Игорь Шевченко © (2004-03-11 09:57) [3]Serge © (11.03.04 09:23)
Кладовка за это время не один раз реорганизовывалась (иногда спонтанно), поэтому я не надеюсь там найти.
Если не затруднит, то на whitefranz@hotmail.com
← →
Игорь Шевченко © (2004-03-11 09:57) [3]Serge © (11.03.04 09:23)
Кладовка за это время не один раз реорганизовывалась (иногда спонтанно), поэтому я не надеюсь там найти.
Если не затруднит, то на whitefranz@hotmail.com
← →
serge © (2004-03-11 10:05) [4]Почему-же, не затруднит, уже скинул!
Надеюсь поможет.
P.S. А кладовка по моему и сейчас спонтанно реорганизовывается :)
← →
serge © (2004-03-11 10:05) [4]Почему-же, не затруднит, уже скинул!
Надеюсь поможет.
P.S. А кладовка по моему и сейчас спонтанно реорганизовывается :)
← →
Игорь Шевченко © (2004-03-11 10:34) [5]Как получить доступ к окну OwnerDraw меню:
В событии DrawItem надо использовать вызов функции
WindowFromDC, в качестве DC выступает ACanvas.Handle, передаваемый в обработчик события OnDrawItem.
А потом с окном можно делать все необходимые действия.
Как сделано в XPMenu:if not (csDesigning in ComponentState) then
begin
if (FFlatMenu) and (not FTopMenu) then
begin
hDcM := ACanvas.Handle;
hWndM := WindowFromDC(hDcM);
if hWndM <> FForm.Handle then
begin
DrawWindowBorder(hWndM, FMenu.IsRightToLeft);
end;
end;
end;
...
procedure TXPMenu.DrawWindowBorder(hWnd: HWND; IsRightToLeft: boolean);
var
WRect, CRect: TRect;
dCanvas: TCanvas;
begin
if hWnd <= 0 then
begin
exit;
end;
dCanvas := nil;
try
dCanvas := TCanvas.Create;
dCanvas.Handle := GetDc(0);
GetClientRect(hWnd, CRect);
GetWindowRect(hWnd, WRect);
ExcludeClipRect(dCanvas.Handle, CRect.Left, CRect.Top, CRect.Right,
CRect.Bottom);
dCanvas.Brush.Style := bsClear;
Dec(WRect.Right, 2);
Dec(WRect.Bottom, 2);
dCanvas.Pen.Color := FMenuBorderColor;
dCanvas.Rectangle(WRect.Left, WRect.Top, WRect.Right, WRect.Bottom);
if IsRightToLeft then
begin
dCanvas.Pen.Color := FFColor;
dCanvas.Rectangle(WRect.Left + 1, WRect.Top + 1, WRect.Right - 2,
WRect.Top + 3);
dCanvas.MoveTo(WRect.Left + 2, WRect.Top + 2);
dCanvas.LineTo(WRect.Left + 2, WRect.Bottom - 2);
dCanvas.Pen.Color := FFIconBackColor;
dCanvas.MoveTo(WRect.Right - 2, WRect.Top + 2);
dCanvas.LineTo(WRect.Right - 2, WRect.Bottom - 2);
dCanvas.MoveTo(WRect.Right - 2, WRect.Top + 2);
dCanvas.LineTo(WRect.Right - 1 - FIconWidth, WRect.Top + 2);
end
else
begin
if not FGradient then
begin
dCanvas.Pen.Color := FFColor;
dCanvas.Rectangle(WRect.Left + 1, WRect.Top + 1, WRect.Right - 2,
WRect.Top + 3);
dCanvas.Pen.Color := FFIconBackColor;
dCanvas.MoveTo(WRect.Left + 1, WRect.Top + 2);
dCanvas.LineTo(WRect.Left + 2 + FIconWidth, WRect.Top + 2);
end;
dCanvas.Pen.Color := FFIconBackColor;
dCanvas.MoveTo(WRect.Left + 1, WRect.Top + 1);
dCanvas.LineTo(WRect.Left + 1, WRect.Bottom - 2);
end;
Inc(WRect.Right, 2);
Inc(WRect.Bottom, 2);
dCanvas.Pen.Color := FMenuShadowColor;
dCanvas.Rectangle(WRect.Left +2, WRect.Bottom, WRect.Right, WRect.Bottom - 2);
dCanvas.Rectangle(WRect.Right - 2, WRect.Bottom, WRect.Right, WRect.Top + 2);
dCanvas.Pen.Color := FFIconBackColor;
dCanvas.Rectangle(WRect.Left, WRect.Bottom - 2, WRect.Left + 2, WRect.Bottom);
dCanvas.Rectangle(WRect.Right - 2, WRect.Top, WRect.Right, WRect.Top + 2);
finally
IntersectClipRect(dCanvas.Handle, WRect.Left, WRect.Top, WRect.Right, WRect.Bottom);
dCanvas.Free;
end;
end;
← →
Игорь Шевченко © (2004-03-11 10:34) [5]Как получить доступ к окну OwnerDraw меню:
В событии DrawItem надо использовать вызов функции
WindowFromDC, в качестве DC выступает ACanvas.Handle, передаваемый в обработчик события OnDrawItem.
А потом с окном можно делать все необходимые действия.
Как сделано в XPMenu:if not (csDesigning in ComponentState) then
begin
if (FFlatMenu) and (not FTopMenu) then
begin
hDcM := ACanvas.Handle;
hWndM := WindowFromDC(hDcM);
if hWndM <> FForm.Handle then
begin
DrawWindowBorder(hWndM, FMenu.IsRightToLeft);
end;
end;
end;
...
procedure TXPMenu.DrawWindowBorder(hWnd: HWND; IsRightToLeft: boolean);
var
WRect, CRect: TRect;
dCanvas: TCanvas;
begin
if hWnd <= 0 then
begin
exit;
end;
dCanvas := nil;
try
dCanvas := TCanvas.Create;
dCanvas.Handle := GetDc(0);
GetClientRect(hWnd, CRect);
GetWindowRect(hWnd, WRect);
ExcludeClipRect(dCanvas.Handle, CRect.Left, CRect.Top, CRect.Right,
CRect.Bottom);
dCanvas.Brush.Style := bsClear;
Dec(WRect.Right, 2);
Dec(WRect.Bottom, 2);
dCanvas.Pen.Color := FMenuBorderColor;
dCanvas.Rectangle(WRect.Left, WRect.Top, WRect.Right, WRect.Bottom);
if IsRightToLeft then
begin
dCanvas.Pen.Color := FFColor;
dCanvas.Rectangle(WRect.Left + 1, WRect.Top + 1, WRect.Right - 2,
WRect.Top + 3);
dCanvas.MoveTo(WRect.Left + 2, WRect.Top + 2);
dCanvas.LineTo(WRect.Left + 2, WRect.Bottom - 2);
dCanvas.Pen.Color := FFIconBackColor;
dCanvas.MoveTo(WRect.Right - 2, WRect.Top + 2);
dCanvas.LineTo(WRect.Right - 2, WRect.Bottom - 2);
dCanvas.MoveTo(WRect.Right - 2, WRect.Top + 2);
dCanvas.LineTo(WRect.Right - 1 - FIconWidth, WRect.Top + 2);
end
else
begin
if not FGradient then
begin
dCanvas.Pen.Color := FFColor;
dCanvas.Rectangle(WRect.Left + 1, WRect.Top + 1, WRect.Right - 2,
WRect.Top + 3);
dCanvas.Pen.Color := FFIconBackColor;
dCanvas.MoveTo(WRect.Left + 1, WRect.Top + 2);
dCanvas.LineTo(WRect.Left + 2 + FIconWidth, WRect.Top + 2);
end;
dCanvas.Pen.Color := FFIconBackColor;
dCanvas.MoveTo(WRect.Left + 1, WRect.Top + 1);
dCanvas.LineTo(WRect.Left + 1, WRect.Bottom - 2);
end;
Inc(WRect.Right, 2);
Inc(WRect.Bottom, 2);
dCanvas.Pen.Color := FMenuShadowColor;
dCanvas.Rectangle(WRect.Left +2, WRect.Bottom, WRect.Right, WRect.Bottom - 2);
dCanvas.Rectangle(WRect.Right - 2, WRect.Bottom, WRect.Right, WRect.Top + 2);
dCanvas.Pen.Color := FFIconBackColor;
dCanvas.Rectangle(WRect.Left, WRect.Bottom - 2, WRect.Left + 2, WRect.Bottom);
dCanvas.Rectangle(WRect.Right - 2, WRect.Top, WRect.Right, WRect.Top + 2);
finally
IntersectClipRect(dCanvas.Handle, WRect.Left, WRect.Top, WRect.Right, WRect.Bottom);
dCanvas.Free;
end;
end;
← →
serge © (2004-03-11 10:43) [6]Да, кстати - забыл сказать.
По исходникам - этого-же компонента делал то-же самое (рамку), так вот что у меня получалось - в Windows 2000 все тип-топ (рамочка и все такое), в XP, 2003 - даже при отключенных темах - ничего, меню отрисовывалось стандартным :(
← →
serge © (2004-03-11 10:43) [6]Да, кстати - забыл сказать.
По исходникам - этого-же компонента делал то-же самое (рамку), так вот что у меня получалось - в Windows 2000 все тип-топ (рамочка и все такое), в XP, 2003 - даже при отключенных темах - ничего, меню отрисовывалось стандартным :(
← →
DVM © (2004-03-11 18:31) [7]
> Игорь Шевченко © (11.03.04 10:34) [5]
Да, я уже и сам стал подумывать о примерно том же, попробую так сделать обязательно! О результатах сообщу.
← →
DVM © (2004-03-11 18:31) [7]
> Игорь Шевченко © (11.03.04 10:34) [5]
Да, я уже и сам стал подумывать о примерно том же, попробую так сделать обязательно! О результатах сообщу.
← →
DVM © (2004-03-11 22:57) [8]Попробовал, не то чтобы не получилось. Получилось, но не очень. Рамка меню рисуется только если по нему провести мышкой. Если меню просто показать TrackPopupMenu, то оно без рамки все равно. Тестировалось в WinXP. Вот тестовый код. Есть у кого какие соображения КАК ВСЕ ТАКИ ОТРИСОВАТЬ РАМКУ У МЕНЮ???
XP меню пробовал, вроде там тоже самое, но там работает.
program Test;
uses
Windows, Messages;
const
IDB_START = 10;
szMainWndClass: PChar = "MenuWndClass";
szMainWndName: PChar = "MenuDemo";
szButtonName: PChar = "Click";
var
wc: TWndClassEx;
hMainWnd: HWND;
Mesg: TMsg;
hBtn: HWND;
hMainMenu: HMENU;
type
PMenuItemData = ^TMenuItemData;
TMenuItemData = packed record
text: string;
end;
//------------------------------------------------------------------------------
function OnMeasureItem(wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
PMEASUREITEMSTRUCT (lParam).itemWidth := 200;
PMEASUREITEMSTRUCT (lParam).itemHeight:=18;
result:=1;
end;
//------------------------------------------------------------------------------
procedure DrawWindowBorder(Wnd: HWND; IsRightToLeft: boolean);
var
WRect, CRect: TRect;
dc: HDC;
br: HBRUSH;
begin
GetClientRect(Wnd, CRect);
GetWindowRect(Wnd, WRect);
DC := GetDc(0);
BR := CreateSolidBrush(rgb(255,0,0));
ExcludeClipRect(DC, wRect.Left+3, wRect.Top+3, wRect.Right-3, wRect.Bottom-3);
fillrect(dc, wRect, br);
IntersectClipRect(dc, WRect.Left, WRect.Top, WRect.Right, WRect.Bottom);
ReleaseDc(0, dc);
DeleteObject(br);
end;
//------------------------------------------------------------------------------
function OnDrawItem(wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
var
DC: HDC;
rc: TRect;
prevtx,prevbk:colorref;
lf:logfont;
buffnt:hfont;
prevfn:hfont;
br: HBRUSH;
txt:string;
hWndM: HWND;
begin
if (PDRAWITEMSTRUCT (LParam).CtlType = ODT_MENU) then
begin
DC := PDRAWITEMSTRUCT(LParam).hDC;
rc := PDRAWITEMSTRUCT (LParam).rcItem;
if (PDRAWITEMSTRUCT (LParam).itemState and ODS_SELECTED) = ODS_SELECTED then
begin
prevtx:=settextcolor (dc,GetSysColor(COLOR_HIGHLIGHTTEXT));
prevbk:=setbkcolor (dc,GetSysColor(COLOR_HIGHLIGHT));
Br:=CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
end
else
begin
prevtx:=settextcolor (dc,GetSysColor(COLOR_MENUTEXT));
prevbk:=setbkcolor (dc,(rgb(110,255,60)));
Br:=CreateSolidBrush((rgb(110,255,60)));
end;
FillRect(DC, rc, br);
DeleteObject(br);
zeromemory (@lf,sizeof (lf));
lf.lfHeight:=12;
lf.lfFaceName:="MS Sans Serif"+#0;
lf.lfCharSet:=DEFAULT_CHARSET;
lf.lfWeight:=FW_NORMAL;
buffnt:=createfontindirect (lf);
prevfn:=selectobject (dc,buffnt);
txt:=PMenuItemData(PDRAWITEMSTRUCT (LParam).itemData).text;
drawtextex(dc,pchar (txt),length (txt),rc,DT_END_ELLIPSIS or DT_LEFT or DT_MODIFYSTRING or DT_NOPREFIX or DT_VCENTER,NIL);
settextcolor (dc,prevtx);
selectobject (dc,prevfn);
setbkcolor (dc,prevbk);
deleteobject (buffnt);
hWndM := WindowFromDC(PDRAWITEMSTRUCT (LParam).hDC);
DrawWindowBorder(hWndM, true);
end;
Result:=1;
end;
//------------------------------------------------------------------------------
function OnCommand(wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
var
ctrlID: Word;
rc: TRect;
begin
ctrlID := loWord(wParam);
case ctrlID of
IDB_START:
begin
GetWindowRect(wnd, rc);
TrackPopupMenu(hMainMenu, TPM_VERNEGANIMATION, rc.Right, rc.Top, 0, Wnd, nil);
end
end;
result := 0;
end;
//------------------------------------------------------------------------------
procedure ClearMenuItemsData;
var
i: integer;
mii: TMenuItemInfo;
begin
for i := 0 to 10 do
begin
MII.cbSize := SizeOf(TMenuItemInfo);
MII.fMask := MIIM_DATA;
if (GetMenuItemInfo(hMainMenu, i, false, mii)<>false) then
begin
Dispose(PMenuItemData(mii.dwItemData));
end;
end;
end;
//------------------------------------------------------------------------------
function WindowProc(wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
case msg of
WM_MEASUREITEM: Result := OnMeasureItem(wnd, Msg, wParam, lParam);
WM_DRAWITEM: Result := OnDrawItem(wnd, Msg, wParam, lParam);
WM_COMMAND: Result := OnCommand(wnd, Msg, wParam, lParam);
WM_DESTROY:
begin
ClearMenuItemsData;
DestroyMenu(hMainMenu);
PostQuitMessage(0);
Result := 0;
exit;
end;
else
Result := DefWindowProc(Wnd, Msg, wParam, lParam);
end;
end;
//------------------------------------------------------------------------------
var
xPos, yPos, nWidth, nHeight: integer;
mii: TMenuItemInfo;
i: integer;
← →
DVM © (2004-03-11 22:57) [8]Попробовал, не то чтобы не получилось. Получилось, но не очень. Рамка меню рисуется только если по нему провести мышкой. Если меню просто показать TrackPopupMenu, то оно без рамки все равно. Тестировалось в WinXP. Вот тестовый код. Есть у кого какие соображения КАК ВСЕ ТАКИ ОТРИСОВАТЬ РАМКУ У МЕНЮ???
XP меню пробовал, вроде там тоже самое, но там работает.
program Test;
uses
Windows, Messages;
const
IDB_START = 10;
szMainWndClass: PChar = "MenuWndClass";
szMainWndName: PChar = "MenuDemo";
szButtonName: PChar = "Click";
var
wc: TWndClassEx;
hMainWnd: HWND;
Mesg: TMsg;
hBtn: HWND;
hMainMenu: HMENU;
type
PMenuItemData = ^TMenuItemData;
TMenuItemData = packed record
text: string;
end;
//------------------------------------------------------------------------------
function OnMeasureItem(wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
PMEASUREITEMSTRUCT (lParam).itemWidth := 200;
PMEASUREITEMSTRUCT (lParam).itemHeight:=18;
result:=1;
end;
//------------------------------------------------------------------------------
procedure DrawWindowBorder(Wnd: HWND; IsRightToLeft: boolean);
var
WRect, CRect: TRect;
dc: HDC;
br: HBRUSH;
begin
GetClientRect(Wnd, CRect);
GetWindowRect(Wnd, WRect);
DC := GetDc(0);
BR := CreateSolidBrush(rgb(255,0,0));
ExcludeClipRect(DC, wRect.Left+3, wRect.Top+3, wRect.Right-3, wRect.Bottom-3);
fillrect(dc, wRect, br);
IntersectClipRect(dc, WRect.Left, WRect.Top, WRect.Right, WRect.Bottom);
ReleaseDc(0, dc);
DeleteObject(br);
end;
//------------------------------------------------------------------------------
function OnDrawItem(wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
var
DC: HDC;
rc: TRect;
prevtx,prevbk:colorref;
lf:logfont;
buffnt:hfont;
prevfn:hfont;
br: HBRUSH;
txt:string;
hWndM: HWND;
begin
if (PDRAWITEMSTRUCT (LParam).CtlType = ODT_MENU) then
begin
DC := PDRAWITEMSTRUCT(LParam).hDC;
rc := PDRAWITEMSTRUCT (LParam).rcItem;
if (PDRAWITEMSTRUCT (LParam).itemState and ODS_SELECTED) = ODS_SELECTED then
begin
prevtx:=settextcolor (dc,GetSysColor(COLOR_HIGHLIGHTTEXT));
prevbk:=setbkcolor (dc,GetSysColor(COLOR_HIGHLIGHT));
Br:=CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
end
else
begin
prevtx:=settextcolor (dc,GetSysColor(COLOR_MENUTEXT));
prevbk:=setbkcolor (dc,(rgb(110,255,60)));
Br:=CreateSolidBrush((rgb(110,255,60)));
end;
FillRect(DC, rc, br);
DeleteObject(br);
zeromemory (@lf,sizeof (lf));
lf.lfHeight:=12;
lf.lfFaceName:="MS Sans Serif"+#0;
lf.lfCharSet:=DEFAULT_CHARSET;
lf.lfWeight:=FW_NORMAL;
buffnt:=createfontindirect (lf);
prevfn:=selectobject (dc,buffnt);
txt:=PMenuItemData(PDRAWITEMSTRUCT (LParam).itemData).text;
drawtextex(dc,pchar (txt),length (txt),rc,DT_END_ELLIPSIS or DT_LEFT or DT_MODIFYSTRING or DT_NOPREFIX or DT_VCENTER,NIL);
settextcolor (dc,prevtx);
selectobject (dc,prevfn);
setbkcolor (dc,prevbk);
deleteobject (buffnt);
hWndM := WindowFromDC(PDRAWITEMSTRUCT (LParam).hDC);
DrawWindowBorder(hWndM, true);
end;
Result:=1;
end;
//------------------------------------------------------------------------------
function OnCommand(wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
var
ctrlID: Word;
rc: TRect;
begin
ctrlID := loWord(wParam);
case ctrlID of
IDB_START:
begin
GetWindowRect(wnd, rc);
TrackPopupMenu(hMainMenu, TPM_VERNEGANIMATION, rc.Right, rc.Top, 0, Wnd, nil);
end
end;
result := 0;
end;
//------------------------------------------------------------------------------
procedure ClearMenuItemsData;
var
i: integer;
mii: TMenuItemInfo;
begin
for i := 0 to 10 do
begin
MII.cbSize := SizeOf(TMenuItemInfo);
MII.fMask := MIIM_DATA;
if (GetMenuItemInfo(hMainMenu, i, false, mii)<>false) then
begin
Dispose(PMenuItemData(mii.dwItemData));
end;
end;
end;
//------------------------------------------------------------------------------
function WindowProc(wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
case msg of
WM_MEASUREITEM: Result := OnMeasureItem(wnd, Msg, wParam, lParam);
WM_DRAWITEM: Result := OnDrawItem(wnd, Msg, wParam, lParam);
WM_COMMAND: Result := OnCommand(wnd, Msg, wParam, lParam);
WM_DESTROY:
begin
ClearMenuItemsData;
DestroyMenu(hMainMenu);
PostQuitMessage(0);
Result := 0;
exit;
end;
else
Result := DefWindowProc(Wnd, Msg, wParam, lParam);
end;
end;
//------------------------------------------------------------------------------
var
xPos, yPos, nWidth, nHeight: integer;
mii: TMenuItemInfo;
i: integer;
← →
DVM © (2004-03-11 22:57) [9]begin
wc.cbSize := SizeOf(wc);
wc.style := CS_HREDRAW or CS_VREDRAW;
wc.lpfnWndProc := @WindowProc;
wc.cbClsExtra := 0;
wc.cbWndExtra := 0;
wc.hInstance := hInstance;
wc.hIcon := 0;
wc.hCursor := 0;
wc.hbrBackground := COLOR_BTNFACE+1;
wc.lpszMenuName := nil;
wc.lpszClassName := szMainWndClass;
if RegisterClassEx(wc) = 0 then
begin
MessageBox(0, "Error Register Window Class!", "Error!", 0);
exit;
end;
xPos:=0; yPos:=0; nWidth:=200; nHeight:=100;
hMainWnd:=CreateWindowEx(0,
szMainWndClass,
szMainWndName,
WS_OVERLAPPEDWINDOW,
xPos,
yPos,
nWidth,
nHeight,
0,
0,
hInstance,
nil);
if hMainWnd = 0 then
begin
MessageBox(0, "Error Create Window!", "Error!", 0);
UnregisterClass(szMainWndClass, hInstance);
exit;
end;
hBtn := CreateWindowEx(0,
"button",
szButtonName,
BS_PUSHBUTTON or
WS_CHILD or
WS_VISIBLE,
10,
10,
75,
25,
hMainWnd,
IDB_START,
hInstance,
nil);
if hBtn = 0 then
begin
MessageBox(0, "Button not Created!", "Error!", 0);
DestroyWindow(hMainWnd);
UnregisterClass(szMainWndClass, hInstance);
exit;
end;
ShowWindow(hMainWnd, SW_SHOW);
hMainMenu:=CreatePopupMenu;
if hMainMenu<>0 then
begin
for i:=0 to 10 do
begin
ZeroMemory(@mii, SizeOf(mii));
New(PMenuItemData(mii.dwItemData));
mii.cbSize:=SizeOf(TMenuItemInfo);
mii.fType:=MFT_OWNERDRAW;
mii.fMask:=MIIM_TYPE or MIIM_DATA or MIIM_ID;
mii.wID:=i;
PMenuItemData(mii.dwItemData).text:="Item";
InsertMenuItem (hMainMenu, 0, true, mii);
end;
end;
while GetMessage(Mesg, 0, 0, 0) do
begin
TranslateMessage(Mesg);
DispatchMessage(Mesg);
end;
end.
← →
DVM © (2004-03-11 22:57) [9]begin
wc.cbSize := SizeOf(wc);
wc.style := CS_HREDRAW or CS_VREDRAW;
wc.lpfnWndProc := @WindowProc;
wc.cbClsExtra := 0;
wc.cbWndExtra := 0;
wc.hInstance := hInstance;
wc.hIcon := 0;
wc.hCursor := 0;
wc.hbrBackground := COLOR_BTNFACE+1;
wc.lpszMenuName := nil;
wc.lpszClassName := szMainWndClass;
if RegisterClassEx(wc) = 0 then
begin
MessageBox(0, "Error Register Window Class!", "Error!", 0);
exit;
end;
xPos:=0; yPos:=0; nWidth:=200; nHeight:=100;
hMainWnd:=CreateWindowEx(0,
szMainWndClass,
szMainWndName,
WS_OVERLAPPEDWINDOW,
xPos,
yPos,
nWidth,
nHeight,
0,
0,
hInstance,
nil);
if hMainWnd = 0 then
begin
MessageBox(0, "Error Create Window!", "Error!", 0);
UnregisterClass(szMainWndClass, hInstance);
exit;
end;
hBtn := CreateWindowEx(0,
"button",
szButtonName,
BS_PUSHBUTTON or
WS_CHILD or
WS_VISIBLE,
10,
10,
75,
25,
hMainWnd,
IDB_START,
hInstance,
nil);
if hBtn = 0 then
begin
MessageBox(0, "Button not Created!", "Error!", 0);
DestroyWindow(hMainWnd);
UnregisterClass(szMainWndClass, hInstance);
exit;
end;
ShowWindow(hMainWnd, SW_SHOW);
hMainMenu:=CreatePopupMenu;
if hMainMenu<>0 then
begin
for i:=0 to 10 do
begin
ZeroMemory(@mii, SizeOf(mii));
New(PMenuItemData(mii.dwItemData));
mii.cbSize:=SizeOf(TMenuItemInfo);
mii.fType:=MFT_OWNERDRAW;
mii.fMask:=MIIM_TYPE or MIIM_DATA or MIIM_ID;
mii.wID:=i;
PMenuItemData(mii.dwItemData).text:="Item";
InsertMenuItem (hMainMenu, 0, true, mii);
end;
end;
while GetMessage(Mesg, 0, 0, 0) do
begin
TranslateMessage(Mesg);
DispatchMessage(Mesg);
end;
end.
← →
Игорь Шевченко © (2004-03-11 23:27) [10]Я дико извиняюсь, а то же самое на VCL не проще будет отлаживать ? Уж больно код длинный :)
← →
Игорь Шевченко © (2004-03-11 23:27) [10]Я дико извиняюсь, а то же самое на VCL не проще будет отлаживать ? Уж больно код длинный :)
← →
Gero © (2004-03-12 07:42) [11]> Сдается мне, что лучше имитировать Popup-меню, например,
> ListBox"ом и уже его рисовать, как угодно.
> Это, кстати, не так трудно
Интересная идея.
Только как насчет исчезновения меню?
Оно ведь должно исчезать когда:
- Вызывается другое или это же меню
- Меню теряет фокус
- Приложение теряет фокус
И еще в нескольких случаях. Как это все можно отслеживать?
Чтобы это меню работало четко, как и стандартное.
← →
Gero © (2004-03-12 07:42) [11]> Сдается мне, что лучше имитировать Popup-меню, например,
> ListBox"ом и уже его рисовать, как угодно.
> Это, кстати, не так трудно
Интересная идея.
Только как насчет исчезновения меню?
Оно ведь должно исчезать когда:
- Вызывается другое или это же меню
- Меню теряет фокус
- Приложение теряет фокус
И еще в нескольких случаях. Как это все можно отслеживать?
Чтобы это меню работало четко, как и стандартное.
← →
Игорь Шевченко © (2004-03-12 10:12) [12]Gero © (12.03.04 07:42)
> Оно ведь должно исчезать когда:
> - Вызывается другое или это же меню
> - Меню теряет фокус
> - Приложение теряет фокус
На каждое из этих событий окну-владельцу меню посылается сообщение. Я встречал в свое время в сети имитаторы меню, возни много, но способ имеет право на существование. Кстати, имитаторы меню реализованы в DevExpress (TDxBarSubMenuControl), в MSDN и в MSOffice (MSOCommandBarPopup)
← →
Игорь Шевченко © (2004-03-12 10:12) [12]Gero © (12.03.04 07:42)
> Оно ведь должно исчезать когда:
> - Вызывается другое или это же меню
> - Меню теряет фокус
> - Приложение теряет фокус
На каждое из этих событий окну-владельцу меню посылается сообщение. Я встречал в свое время в сети имитаторы меню, возни много, но способ имеет право на существование. Кстати, имитаторы меню реализованы в DevExpress (TDxBarSubMenuControl), в MSDN и в MSOffice (MSOCommandBarPopup)
← →
Gero © (2004-03-12 17:30) [13]> На каждое из этих событий окну-владельцу меню посылается сообщение
А какое именно сообщение, Вы не в курсе?
← →
Gero © (2004-03-12 17:30) [13]> На каждое из этих событий окну-владельцу меню посылается сообщение
А какое именно сообщение, Вы не в курсе?
← →
Игорь Шевченко © (2004-03-12 23:55) [14]Gero © (12.03.04 17:30)
в первую очередь WM_KILLFOCUS
Также можно посмотреть реализацию класса TPopupListBox в VCL (в DBCtrls.pas, если не ошибаюсь, он себя ведет примерно так же, как меню)
← →
Игорь Шевченко © (2004-03-12 23:55) [14]Gero © (12.03.04 17:30)
в первую очередь WM_KILLFOCUS
Также можно посмотреть реализацию класса TPopupListBox в VCL (в DBCtrls.pas, если не ошибаюсь, он себя ведет примерно так же, как меню)
← →
Gero © (2004-03-13 08:56) [15]> Игорь Шевченко © (12.03.04 23:55) [14]
Спасибо за инфу.
← →
Gero © (2004-03-13 08:56) [15]> Игорь Шевченко © (12.03.04 23:55) [14]
Спасибо за инфу.
← →
Nick Denry © (2004-03-13 15:10) [16]2 > Игорь Шевченко ©
Наверно, я плохо молился. Или вопрос стал слишком популярен? :))))
Вопрос в тему : можно - ли перерисовывать сепаратор (MENUITEM SEPARATOR) своими силами (т.е. получить линию, которой рисуются все разделители). Это нужно, чтобы нарисовать битмап с надписью с левой стороны меню, как в Пуске....
С уважением, NickD.
← →
Nick Denry © (2004-03-13 15:10) [16]2 > Игорь Шевченко ©
Наверно, я плохо молился. Или вопрос стал слишком популярен? :))))
Вопрос в тему : можно - ли перерисовывать сепаратор (MENUITEM SEPARATOR) своими силами (т.е. получить линию, которой рисуются все разделители). Это нужно, чтобы нарисовать битмап с надписью с левой стороны меню, как в Пуске....
С уважением, NickD.
← →
Gero © (2004-03-13 19:04) [17]Nick Denry © (13.03.04 15:10) [16]
> можно - ли перерисовывать сепаратор (MENUITEM SEPARATOR) своими силами
Конечно можно, через OnDrawItem.
← →
Gero © (2004-03-13 19:04) [17]Nick Denry © (13.03.04 15:10) [16]
> можно - ли перерисовывать сепаратор (MENUITEM SEPARATOR) своими силами
Конечно можно, через OnDrawItem.
← →
Nick Denry © (2004-03-14 12:52) [18]2> Gero (c)
Конечно можно, через OnDrawItem.
Вопервых без VCL - это WM_DRAWITEM насколько я понимаю, во - вторых у сепаратора не может быть стиля MF_OWNERDRAW (MFT_OWNERDRAW). Я думаю, что можно как-то нарисовать (получить, если это битмап) линию, которая рисуется в сепараторе , или нет? А сам сепаратор перерисовывать вроде бесполезно...
С уважением, NIckD.
← →
Nick Denry © (2004-03-14 12:52) [18]2> Gero (c)
Конечно можно, через OnDrawItem.
Вопервых без VCL - это WM_DRAWITEM насколько я понимаю, во - вторых у сепаратора не может быть стиля MF_OWNERDRAW (MFT_OWNERDRAW). Я думаю, что можно как-то нарисовать (получить, если это битмап) линию, которая рисуется в сепараторе , или нет? А сам сепаратор перерисовывать вроде бесполезно...
С уважением, NIckD.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
Память: 0.61 MB
Время: 0.182 c