![]() |
Submenu anzeigen
Ich zeichne mein Submenu in WM_DRAWITEM:
Das zeichnen kann unter umständen länger dauern je nach dem wie viele Einträge das Menu hat. Jetzt möchte ich das SubMenu erst Anzeigen wenn das zeichnen der Einträge fertig ist. Ein SubMenu hat aber kein Window Handle. Wie kann ich es trotzdem solange verstecken bis das zeichnen fertig ist? Theoretisch..
Delphi-Quellcode:
PDis.hwndItem ist nicht gültig.
IDM_SELECTCHAPTER .. IDM_SELECTCHAPTER_LAST:
begin ShowWindow(PDis.hwndItem, IIF((integer(PDis.ItemId) - IDM_SELECTCHAPTER = aMediaProperty.NumChapter), SW_SHOW, SW_HIDE)); end; Wie komme ich an das Handle auf dem die Items gezeichnet werden ? gruss |
AW: Submenu anzeigen
Garnicht?
Paint-Events werden ausgelöst, wenn jetzt gezeichnet werden soll, also auch nach dem Anzeigen. Vor dem Anzeigen existiert hier auch noch kein HWND oder HDC dafür. Aus Sicht des Users ist es aber ein No-Go, dass Paint-Ereignisse "lange" dauern. Die Daten müssen also zu dem Zeitpunkt schnell verfügbar sein, also die Daten oder gleich die schlimmsten Zeichnungen vorbereiten (Offscreenbitmaps usw.) |
AW: Submenu anzeigen
Zitat:
Wie ohne Handle. :stupid: Du weist aber schon das jedes Item einzeln gezeichnet wird und nicht das gesamte Menu auf einmal. Zitat:
gruss |
AW: Submenu anzeigen
Wozu brauchst du das Handle
und wieso ein Wiederspruch? Vorher das Bitmap und das dann im Paintereignis auf das Canvas/HDC drauf. :angle: Ja, weiß ich. Darum z.B. je ein Bitmap pro Item. PS: Bei SubMenüs wird ein "OnClick" im Parent-Item ausgelöst, ähnlich dem OnPopup bei PupupMenüs, kurz bevor das Fenster erstellt und angezeigt wird. |
AW: Submenu anzeigen
Zitat:
Zitat:
Delphi-Quellcode:
ImgBack = Hintergrund Bitmap wird aufgeteilt auf die gesamten Items abhängig vom PDis.rcItem.
// DrawButton
if (PDis.itemState and ODS_SELECTED) <> 0 then SKAERO_PaintButton(Graphics, 3, ImgItem, 20, PDis.rcItem.top, PDis.rcItem.Right - SideBarWidth, ImgItemHeight, BS_PUSHBUTTON) // Selektierter Eintrag else begin ImgBack := Cardinal(SKAERO_GetProperty(WinHandle, FORM_Center)); GetClientRect(hMenuWnd, rRect); GDIP_GetImageSize(ImgBack, imgW, imgH); GDIP_SetInterpolationMode(Graphics, InterpolationModeHighQualityBicubic); GDIP_DrawImageRectRectI(Graphics, ImgBack, 20, PDis.rcItem.top, rRect.Right, ImgItemHeight, 0, PDis.rcItem.top * (integer(imgH) div rRect.Bottom), imgW, (integer(imgH) div rRect.Bottom) * ImgItemHeight, 2, nil, false, nil); // << Hintergrund Bitmap if (PDis.ItemId = IDM_SeperatorFiles) or (PDis.ItemId = IDM_SeperatorSkins) or (PDis.ItemId = IDM_SeperatorOption) or (PDis.ItemId = IDM_SeperatorClose) or (PDis.ItemId = IDM_SeperatorFilter) then SKAERO_PaintButton(Graphics, 4, ImgItem, 20, PDis.rcItem.top, PDis.rcItem.Right - SideBarWidth, ImgItemHeight, BS_PUSHBUTTON) // Separator end; Das Bitmap ist also schon vorhanden. In WM_DRAWITEM:
Delphi-Quellcode:
mit GDIP_DrawImageRectRectI werden die Icons gezeichnet abhängig vom Status ob selektiert oder nicht.
IDM_FILTERS .. IDM_FILTERS_LAST:
begin newItem := VideoFilter[ActiveFilter]; if Txt = newItem then begin imgW := imgW div 2; GDIP_DrawImageRectRectI(Graphics, Img, PDis.rcItem.left + 23, PDis.rcItem.top + 2, imgW, imgH, imgW, 0, imgW, imgH, 2, nil, false, nil); GDIP_DisposeImage(Img); end else begin if (PDis.ItemId >= IDM_FILTERS) and (PDis.ItemId <= IDM_FILTERS_LAST) then imgW := imgW div 2; GDIP_DrawImageRectRectI(Graphics, Img, PDis.rcItem.left + 23, PDis.rcItem.top + 2, imgW, imgH, 0, 0, imgW, imgH, 2, nil, false, nil); GDIP_DisposeImage(Img); end; PDis.rcItem.left := 0; end; hier der Text..
Delphi-Quellcode:
Wie soll ich das in einem OffsetBitmap zeichen wenn ich die Items und deren Position vorher gar nicht kenne ?
// DrawText
GDIP_GetImageSize(Img, imgW, imgH); if not(PDis.ItemId = IDM_SeperatorFiles) and not(PDis.ItemId = IDM_SeperatorSkins) and not (PDis.ItemId = IDM_SeperatorClose) and not(PDis.ItemId = IDM_SeperatorOption) and not (PDis.ItemId = IDM_SeperatorFilter) then begin PDis.rcItem.left := 40; PDis.rcItem.top := PDis.rcItem.top + 2; if (PDis.itemState and ODS_DISABLED) <> 0 then begin GDIP_DrawTextToDC(PDis.HDC, Txt, PDis.rcItem, $FF737373, PWideChar(SKAERO_TEXTFONT), SKAERO_PUSHBUTFONTSIZE, FontStyleBoldItalic, 1.1, 0, nil) end else GDIP_DrawTextToDC(PDis.HDC, Txt, PDis.rcItem, SKAERO_INACTIVECAPTION, PWideChar (SKAERO_TEXTFONT), SKAERO_PUSHBUTFONTSIZE, FontStyleBoldItalic, 1.1, 0, nil); end else begin // Allign Text Center GDIP_GetTextBound(Txt, SKAERO_TEXTFONT, SKAERO_PUSHBUTFONTSIZE, w, h, 0); PDis.rcItem.left := ((PDis.rcItem.Right - w) div 2); PDis.rcItem.top := PDis.rcItem.top; GDIP_DrawTextToDC(PDis.HDC, Txt, PDis.rcItem, SKAERO_ACTIVECAPTION, PWideChar (SKAERO_TEXTFONT), 13, FontStyleBold, 1.1, 0, nil); end; Bei den Chapter Menu dauert es einige zeit bis jedes Item gezeichnet ist. Man sieht quasi wie sich das Menu aufbaut. Am liebsten wäre mir wenn ich das Popup Menu öffne alles vorher schon gezeichnet ist. Das ist mein Problem! gruss |
AW: Submenu anzeigen
mal so ins unreine gedacht:
- wenn du eh alles selbst zeichnest, warum nimmst du dann überhaupt noch ein "Menü"? - wäre es nicht einfacher und WinVersion unabhängiger, wenn du ein simples Fenster ohne Rahmen/Titel platzierst zeichnest und dann sichtbar machst... "Submenü" eben ein zweites solches Fenster usw. Speziell bei Menüs und neues WinVersionen können Nutzer viel mit den Einstellungen spielen... verzögert/animiert anzeigen ein oder aus... du bist da ja sehr "optisch Detail verliebt" und gibst dir richtig Mühe das innerhalb deiner Software alles wie aus einem Guß aussieht. Daher würde ich dieses Ziel beim Menü eben "alternativ" lösen:) |
AW: Submenu anzeigen
Zitat:
Das verhalten soll sich nicht vom Normalen Menu unterschieden. Ich habe das ja im Programm OTTB so gemacht allerdings OHNE Submenu gruss |
AW: Submenu anzeigen
auch wenn ich es grad nicht probiert habe, aber ich würde wenn ich das MainMenü komplett gezeichnet hätte und alle Maus/Tastatur Events in meinem eigenen Fenster hätte,
es mir dann sogar leicher vorstellen selbst noch ein eigenes weiteres Untermenüfenster als "Child passend neben mir" zu erzeugen. Würdest du bitte kurz schreiben warum es nicht so einfach ist, soetwas vergleichbar dem Verhalten eines normalen Submenü "mal schnell" selbst zu lösen... ich mag schwierige Fälle wenn die so gut wie möglich beschrieben sind:) |
AW: Submenu anzeigen
Die Events zu managen ;)
Dann muss ich für jedes SubMenu ein neues Fenster erstellen das scheint mir doch sehr aufwendig oder? Na ja ich kann es mal mit den Sub Menus versuchen wieder so viel Arbeit. LOL Wieder ne neue unit inklusive Subclassing das nervt. ;) ABER mit Zitat:
gruss |
AW: Submenu anzeigen
Zitat:
|
AW: Submenu anzeigen
Zitat:
probieren geht über studieren. gruss |
AW: Submenu anzeigen
Ich habe das jetzt mal umgesetzt.
Jetzt kommen die Probleme bzw.. mir fällt im Moment nicht ein wie ich das umsetzen kann. Die Basis.. auf Interface aufgebaut. Popup erstellen
Delphi-Quellcode:
Jetzt habe ich ein Fenster auf dem ich die Button platziere.
procedure TMainApp.CreatePopUpMenu;
begin PopupMenu := CTRL_PopUpMenuCreate; PopupMenu.Width := CLIENT_WIDTH; PopupMenu.Height := CLIENT_HEIGHT; PopupMenu.SkinConfigFile := PWideChar(FolderResource + 'PopUpWindow\OTTB.ske'); PopupMenu.UseVistaCrystal := false; PopupMenu.UseVistaBlur := false; hPopUpHandle := PopupMenu.CreatePopUpMenu(MainHandle); if hPopUpHandle <> 0 then begin AddChildControls(hPopUpHandle); PopupMenu.CreatePrivateFont(PWideChar(FolderResource + 'PopUpWindow\OTTB.ttf')); Prop.PopupMenu := hPopUpHandle; Prop.bPopupMenu := True; end; end; Beispiel einfacher Button für About Informationen.
Delphi-Quellcode:
Jeder Button hat eine ID hier (IDM_About) über die ich diesen steuern kann.
btnAbout := CTRL_PushButtonCreate;
btnAbout.ImagePath := SKAERO_FOLDER + 'MEN_Select.png'; btnAbout.Text := 'About'; btnAbout.Left := 29; btnAbout.Top := 9; btnAbout.Width := 190; btnAbout.Height := 20; btnAbout.DlgItemID := IDM_About; btnAbout.TextCol := SKAERO_BTNTEXTCOLOR; btnAbout.Label3D := 1; btnAbout.ImageStateMax := 0; btnAbout.TextAlligment := Left; btnAbout.TextLeft := 20; btnAbout.CreateWindow(hMain); SKAERO_SetAnchorMode(btnAbout.Handle, ANCHOR_NONE); SKAERO_SetZorder(btnAbout.Handle, HWND_TOP); SKAERO_SetToolTipText(btnAbout.Handle, 'Oops...' + CHR(13) + 'Are they in the wrong place?', True); WinProc..
Delphi-Quellcode:
Das Problem ist nun wie soll ich diese ID verarbeiten?
WM_COMMAND:
begin case loword(wP) of IDM_About: begin ShellExecute(0, 'open', 'http://www.delphipraxis.net/192767-ordnung-muss-sein-launchbar.html', '', '', SW_SHOW); DestroyWindow(WinHandle); end; Denn in meiner Anwendung selbst habe ich ja nun keine WinProc für das Popup Fenster mehr. Und die DLL in der das Popup Fenster erstellt wird kennt die ID und die Funktion die ich mit einem Klick ausführen will nicht! Also wie koordiniere ich das jetzt so das ich trotzdem in der Anwendung die Messagen verarbeiten kann wie gehabt! OK! Das hat sich erledigt. Ich initailisere das PopUpMenu mit
Delphi-Quellcode:
In der PopUpProc innerhalb der DLL schicke ich jetzt bei WM_COMMAND einfach die Message zurück an das Parent Fenster.
hPopUpHandle := PopupMenu.CreatePopUpMenu(MainHandle);
Delphi-Quellcode:
jetzt noch die SubMenu Windows..
WM_COMMAND:
SendMessageW(FParentHandle, Msg, wP, lP); gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:07 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz