Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi ListBox zerstört PaintEvent vom Menu (https://www.delphipraxis.net/128305-listbox-zerstoert-paintevent-vom-menu.html)

EWeiss 27. Jan 2009 17:20


ListBox zerstört PaintEvent vom Menu
 
Delphi-Quellcode:
unit uListBox;

interface

uses Windows, Classes, Messages, uGlobal, uGDIUnit, uSkin, uDrawText,
  uCheckButton, uTrackBar, uFXEffect, Bass, uBass, uBassVis, BassVis;

type
  TListBox = class
  private
    FHListBox: HWND;
    FHOwner : HWND;
    Img:       cardinal;
    LStyle:    DWORD;
    procedure SubClass(WinHandle: HWND);
    procedure UnSubClass(WinHandle: HWND);
  public
    property Handle: HWND Read FHListBox;
    constructor Create(hOwner: HWND; FullpathImageName: string; x, y, xW, yH,
      PlayListID: integer; BackColor: COLORREF);
    destructor Destroy; override;
  end;

type
  LBTYPE = Record
    Forecolor : LongInt;
    Backcolor : LongInt;
    ForeColorSelected : LongInt;
    BackColorSelected : LongInt;
    BorderStyle : LongInt;
    DrawStyle : LongInt;
    ItemHeight : LongInt;
    hWnd : LongInt;
    Left : LongInt;
    Top : LongInt;
    Width : LongInt;
    Height : LongInt;
    hFont : LongInt;
    Parent : LongInt;
  end;

var
  TMListBox : LBTYPE;

function ListBoxProc(WinHandle: HWND; Msg: UINT; wP: WParam; lP: LParam): LRESULT; stdcall;


implementation
var
  PrevWndProc, PrevWndProcLB: Integer;

constructor TListBox.Create(hOwner: HWND; FullpathImageName: string; x, y, xW, yH,
  PlayListID: integer; BackColor: COLORREF);
begin

  with SkinEngine do
  begin
      // Erstelle das GDIPLUS image von Datei
      Img := AddResource(PAnsiChar(FullpathImageName));
      if Img <> 0 then
      begin
        // Hole die Thumb GDIPLUS image größe
        GetImageSize(Img, imgW, imgH);
        LStyle := {LBS_HASSTRINGS Or LBS_OWNERDRAWFIXED Or}
                  LBS_NOINTEGRALHEIGHT Or WS_CHILD {Or WS_VISIBLE}
                  Or WS_BORDER Or WS_VSCROLL;

        FHListBox := CreateWindowEx(WS_EX_CLIENTEDGE or WS_EX_TRANSPARENT,
          SKLISTBOX, nil, LStyle, x, y, xW, yH,
          hOwner, PlayListID, skInstance, nil);

        if FHListBox <> 0 then
        begin
          SetImageProperty(FHListBox, PROP_IMAGE_BACK, Img);
          TMListBox.DrawStyle := BackColor;
          TMListBox.hWnd := FHListBox;
          FHOwner := hOwner;
          SubClass(FHOwner);
        end else
          // Image löschen wenn Fehler
          DeleteResource(Img);
      end;
  end;
end;

destructor TListBox.Destroy;
begin
  UnSubClass(FHOwner);

  inherited Destroy;
end;

function WndProc(WinHandle: HWND; Msg: UINT; wP: WParam; lP: LParam): LRESULT; stdcall;
begin
  Case MSG of
     WM_CTLCOLORLISTBOX:
       Result := TMListBox.DrawStyle;
     WM_DRAWITEM:
         Result := 0
     Else
       Result := CallWindowProc(Pointer(PrevWndProc), WinHandle, Msg, wP, lP);
  end;

end;

procedure TListBox.SubClass(WinHandle: HWND);
begin
  PrevWndProc := SetWindowLong(WinHandle, GWL_WNDPROC, integer(@WndProc));
  PrevWndProcLB := SetWindowLong(TMListBox.hWnd, GWL_WNDPROC, integer(@ListBoxProc));

end;

procedure TListBox.UnSubClass(WinHandle: HWND);
begin
  SetWindowLong(WinHandle, GWL_WNDPROC, PrevWndProc);
  SetWindowLong(TMListBox.hWnd, GWL_WNDPROC, integer(@ListBoxProc));
end;

function ListBoxProc(WinHandle: HWND; Msg: UINT; wP: WParam; lP: LParam): LRESULT; stdcall;
begin
    Result := CallWindowProc(Pointer(PrevWndProcLB), WinHandle, Msg, wP, lP);

end;

end.
Was ist falsch das die ListBox das Zeichnen vom Menu zerstört ?

gruss Emil

EWeiss 27. Jan 2009 18:08

Re: ListBox zerstört PaintEvent vom Menu
 
Sorry Push :duck:

Hab das probem erkannt nun aber andere probleme.

So gehe ich vor!
Ich setze die Listbox auf die Hauptform wobei das Handle dieser als Parent der Listbox übergeben wird.
Um eine Ownerdraw Listbox zu erstellen verwende ich ein SubClassing auf hMain (Hauptform).
Wenn ich jetzt in der Proc der ListBox WM_DRAWITEM verwende und den wert 1 übergebewird das Menu nicht mehr gezeichnet.
caste ich die Msg mit
Delphi-Quellcode:
WM_DRAWITEM:
  Result := CallWindowProc(Pointer(PrevWndProc), WinHandle, Msg, wP, lP);
dann geht das Menu.

Ich will aber in der Listboxproc unter der Msg für jeden Eintrag ein Icon zeichnen
aber wie wenn in der Hauptform (WinProc) WM_DRAWITEM: aus der ListBoxProc geblockt wird.

gruss Emil


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:06 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