Delphi-PRAXiS
Seite 4 von 5   « Erste     234 5      

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 VCL für Microsoft-Style URL-Label (https://www.delphipraxis.net/118874-vcl-fuer-microsoft-style-url-label.html)

blackdrake 22. Aug 2008 13:33

Re: VCL für Microsoft-Style URL-Label
 
Zitat:

Zitat von bigg
omata hat doch gezeigt, wie es geht! Wenn du die Hilfe anderer nicht annimmst, brauchst du dich auch nicht zu beklagen.

Stimmt doch gar nicht. Ich nehme jede Hilfe gerne an und freue mich über Beiträge. Ich habe mich mit dem Beispiel von omata lange beschäftigt und auch einiges daraus gelernt. (Siehe mein darauffolgender Beitrag, in dem ich die Komponente von omata abgeleitet, etwas verbessert und vereinfacht habe!)

Das Problem war aber, dass omata's Beispiel zwar auf den ersten Blick wie ein Label aussieht, aber die properties des TLabel nicht besitzt sowie nicht erkennbar deaktivierbar ist. Sollte ich keine bessere Lösung (= direkte Ableitung von TLabel) erhalten, müsste ich omatas Beispiel noch einmal aufrollen und Canvas.Textout komplett mit einem integrierten TLabel ersetzen, das alle Eigenschaften von der Elternklasse annimmt und ständig abgleicht.

Zitat:

Zitat von DeddyH
Zu AllocateHWnd kannst Du Dir ja mal den Source von TTimer ansehen.

Danke für die Info. Ich schaue mir das jetzt alles einmal an und sammle Informationen.

Angenommen, ich bekomme es hin, ein TLabel abzuleiten und ihm ein Handle zu geben (ohne dass der PC in Flammen aufgeht) - wie gehe ich danach vor? Wie wird aus einem TLabel mit Handle ein Control-Element, das per Tab-Taste angewählt werden kann?

Gruß
blackdrake

DeddyH 22. Aug 2008 13:38

Re: VCL für Microsoft-Style URL-Label
 
Je nach Message, die dein "Pseudo-Handle" bekommt, führst Du die entsprechende Routine aus, sofern nötig. Das Prinzip wird z.B. hier kurz erklärt.

blackdrake 22. Aug 2008 13:46

Re: VCL für Microsoft-Style URL-Label
 
Hallo.

Zitat:

Zitat von DeddyH
Je nach Message, die dein "Pseudo-Handle" bekommt, führst Du die entsprechende Routine aus, sofern nötig. Das Prinzip wird z.B. hier kurz erklärt.

Ja, das kann ich mir vorstellen, dass mein TMeinLabel eine Message erhält (CM_FocusChanged?). Wenn ich das alles gelöst hätte, dann könnte ich das Canvas.DrawFocusRect() ausführen, sofern der Focus vorhanden ist. Andernfalls, den Fokusrahmen wieder entfernen.

Das Problem sehe ich aber in der TabOrder und deren Verwaltung! Die Tab-Order-List befindet sich meines Wissens in TWinControl. Dort wird doch alles reguliert, sodass jedes TWinControl ein eigenes und korrektes TabOrder erhält, die TabOrder bei einer Änderung neu berechnet werden sowie bei einem Tab-Tastendruck das richtige Element gewählt wird.

Es sollte ja möglich sein, dass die TabOrder bestehend aus einem TButton, einem TMeinLabel und einem TEdit besteht. Hier ist aber das Problem, dass TMeinLabel kein TWinControl-Nachkomme ist.

Da mein TMeinLabel also ein absoluter "außenseiter" ist und mit TWinControl nichts zu tun hat (da kein Nachkomme) - kann ich dann überhaupt korrekt mit TabStops arbeiten? Da hab ich im Moment eine Denkblockade.

Gruß
blackdrake

DeddyH 22. Aug 2008 14:02

Re: VCL für Microsoft-Style URL-Label
 
Mit AllocateHwnd bekommst Du doch ein Fensterhandle geliefert, wenn ich das richtig verstanden habe. Dieses muss dann noch den Stil WS_TABSTOP bekommen (zur Not über SetWindowLong) und es sollte klappen. Zur Not probier ich das heute Abend mal selbst aus, im Moment kann ich das gerade nicht.

blackdrake 22. Aug 2008 16:23

Re: VCL für Microsoft-Style URL-Label
 
Hallo.

Ich habe jetzt 2 Dinge Probiert.

Versuch A (von mir bevorzugt):

TLabel ableiten, ein Handle versehen und versuchen, TabStopps setzen zu können.

Problem:
- TabOrder Problematik?
- EACCESS-VIOLATION im Message-Handler

Delphi-Quellcode:
type
  tx = class(TLabel)
  private
    FWindowHandle: HWND;
  protected
    procedure WndProc(var Msg: TMessage); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

procedure tx.WndProc(var Msg: TMessage);
var
  Handled: Boolean;
begin
  inherited;

  Handled := True;
  case Msg.Msg of
    WM_DESTROY: ; // ToDo
    else
      Handled := False;
  end;
  if Handled then
    Msg.Result := 0
  else
    Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.WParam, Msg.LParam); // EXCEPTION EACCESSVIOLATION (bei Msg.Msg = 71)
end;

constructor tx.Create(AOwner: TComponent);
var
  Style: LongInt;
begin
  inherited Create(AOwner);

{$IFDEF MSWINDOWS}
  FWindowHandle := Classes.AllocateHWnd(WndProc);
{$ENDIF}
{$IFDEF LINUX}
  FWindowHandle := WinUtils.AllocateHWnd(WndProc);
{$ENDIF}

  Style := GetWindowLong(FWindowHandle, GWL_STYLE);
  SetWindowLong(FWindowHandle, GWL_STYLE, Style and WS_TABSTOP);
end;

destructor tx.Destroy;
begin
{$IFDEF MSWINDOWS}
  Classes.DeallocateHWnd(FWindowHandle);
{$ENDIF}
{$IFDEF LINUX}
  WinUtils.DeallocateHWnd(FWindowHandle);
{$ENDIF}

  inherited Destroy;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  x: tx;
begin
  x := tx.Create(self);
  x.Parent := self;

  x.Left := 10;
  x.Top := 10;
  x.Height := 10;
  x.Width := 10;

  x.Visible := true;

  x.Caption := 'Der Versuch eines Labels...';
end;
Versuch B:

Problem:
- Das StaticLabel ist nicht Transparent.
- Das Canvas, das das DrawFocusRect() zeichnen soll, flackert.
- Wird das Control überdeckt, verliert es seine grafischen Informationen. (Ich habe schon versucht, eine TPaintBox als Objekt in die VCL zu integrieren)
- Problem mit dem Focus-Rect anzeigen/löschen

Delphi-Quellcode:
type
  TS = class(TStaticText)
  private
    FCanvas: TCanvas;
    procedure CMFocusChanged(var Message: TCMFocusChanged); message CM_FOCUSCHANGED;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  protected
    procedure Paint;
    property Canvas: TCanvas read FCanvas;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

procedure ts.WMPaint(var Message: TWMPaint);
begin
  Paint;
end;

procedure ts.CMFocusChanged(var Message: TCMFocusChanged);
begin
  inherited;
  Paint;
end;

procedure ts.Paint;
begin
  inherited;
 
  if Focused then
  begin
    Canvas.DrawFocusRect(Canvas.ClipRect);
  end;

  Repaint;
end;

constructor ts.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FCanvas := TControlCanvas.Create;
  TControlCanvas(FCanvas).Control := Self;

//  DoubleBuffered := true;
end;

destructor ts.Destroy;
begin
  FCanvas.Free;
  inherited Destroy;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  x: ts;
begin
  x := ts.Create(form1);
  x.Parent := form1;

  x.Left := StaticText1.Left;
  x.Top := StaticText1.Top+40;
  x.Height := StaticText1.Height;
  x.Width := StaticText1.Width;
  x.Caption := StaticText1.Caption;
  x.TabStop := true;
end;
Gruß
blackdrake

DeddyH 22. Aug 2008 16:26

Re: VCL für Microsoft-Style URL-Label
 
Zitat:

Delphi-Quellcode:
SetWindowLong(FWindowHandle, GWL_STYLE, Style and WS_TABSTOP);

Nicht and, sondern or. So wie oben hat das Fenster wahrscheinlich überhaupt keinen Style mehr.

blackdrake 22. Aug 2008 20:10

Re: VCL für Microsoft-Style URL-Label
 
Hallo.

Danke für die Info. Habe ich behoben. Es kommt aber weiterhin eine EAccessViolation in user32.dll.

Anmerkung: Fehler kommt auch, wenn ich GetWindowLong/SetWindowLong testweise auskommentiere.

Gruß
blackdrake

grenzgaenger 22. Aug 2008 22:44

Re: VCL für Microsoft-Style URL-Label
 
hast du denn die msg 71 (CM_SETACTIVECONTROL) implementiert?

blackdrake 22. Aug 2008 22:47

Re: VCL für Microsoft-Style URL-Label
 
Ach, 71 = CM_SETACTIVECONTROL. Ich hatte schon recherchiert unter "Message 71", aber keine Liste gefunden. Von CM_SETACTIVECONTROL habe ich bisher noch nichts gehört. Muss ich damit irgendwas machen? Klingt, als ob nur Buttons o.ä. VCLs diese Message benötigen, oder? Ich find es irgendwie komisch, dass es zu einer Exception kommt, obwohl ich einen allgemein gültigen Code zur Message-Abarbeitung verwende. Was muss ich verändern?

PS: Die Erklärung http://docs.codegear.com/docs/radstu...VECONTROL.html "Das ist die Konstante Controls.CM_SETACTIVECONTROL." ist ja irgendwie ein Klassiker - brilliant Formuliert und verständlich :wink:

grenzgaenger 22. Aug 2008 22:55

Re: VCL für Microsoft-Style URL-Label
 
kann aber auch

{$EXTERNALSYM WM_WINDOWPOSCHANGED}
WM_WINDOWPOSCHANGED = $0047;

sein, je nachdem was du angegegeben hast und welches zahlensystem du verwendest...

diese message ist z.b. aus der unit Messages die message zuvor aus der unit controls


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:37 Uhr.
Seite 4 von 5   « Erste     234 5      

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 by Thomas Breitkreuz