Delphi-PRAXiS
Seite 3 von 5     123 45      

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)

Assertor 19. Aug 2008 09:57

Re: VCL für Microsoft-Style URL-Label
 
Hi Daniel,

Zitat:

Zitat von Daniel
das TLinkLabel aus Delphi 2009. :-)

Wenn das TLinkLabel aus D2009 auf WC_LINK / SysLink aus der ComCtl32.dll v6 aufbauen würde, funktioniert das erst ab XP. Unter W2K hätte es den Static Look - also keinerlei Linkfunktion. Aber das werden wir ja dann sehen...

Gruß Assertor

blackdrake 20. Aug 2008 14:48

Re: VCL für Microsoft-Style URL-Label
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo.

Am liebsten wäre mir ja eine "professionelle" TLinkLabel Komponente, die exakt das selbe Ergebnis liefert wie Windows (API?). Aber ich glaube, da in der VCL ja sowieso meist alles Eigenentwicklungen sind, ist das eine Utopie.

@Assertor / @Daniel: Ja, es wäre sehr interessant zu wissen, ob diese Link-Komponente von D2009 XP erfordern wird oder nicht. Wenn es auch mit Windows 2000 funktionieren würde, wäre es die Non-Plus-Ultra-Lösung.

@Michael Habbe: Von der Idee halte ich leider nichts. Eine TEdit Komponente handelt den Focus anderst. Es gibt zum einen einen Text-Tastaturcursor, zum anderen sind Tastenkombinationen wie Strg+A möglich etc.

@omata: Vielen Dank für dieses Beispiel. Ich bin gerade dabei, es mir anzuschauen und zu begreifen.

Derzeit sehe ich aber in deinem Beispiel folgende Probleme:
1. Wenn das Label den Focus hat, dann erscheint es in fetter Schrift (liegt das an meiner ClearType-Schriftartenglättung?) Ich finde aber keine override-Eigenschaft, die Code ausführt, wenn das Label den Focus erhält. Ich weiß echt nicht, was hier los ist.
2. Der Focus-Rahmen ist nicht korrekt um den Link positioniert. Abstände vor und hinter dem Link sind mir etwas zu groß.
3. Die Strichellinien um den fokusierten Link sind zu breit. Windows strichelt ein Focus'ed Item mit 1-1 Pixel Strichen.
4. Die Link-Standardfarben sollten verwendet werden. Ich glaube, dass (siehe Post 1) die Standardfarbe für einen Link innerhalb eines Windows-Dialoges clHotLight ist.
5. Links natürlich standardgemäß unterstreichen.

Außerdem würde ich mir einen Microsoft-Hand-Cursor wünschen (natürlich über die API, nicht als fest eingebundene statische Ressource) - leider finde ich in DP und Google nichts dergleichen. (Schlagwörter: Hand Cursor, Windows Hand Cursor, IE-Cursor, IDC_Hand, Microsoft Hand Cursor)

Ich würde gerne ein Spin-Off von deiner VCL machen, in der ich zum einen die Probleme behebe und eventuell den Microsoft-Cursor-Support aktiviere.

Außerdem möchte ich eine VCL mit weniger Umfang erstellen, die nur 1 Link enthält.

Sprich:
- 1 Label = 1 Link
- Keine "<link>" und "</link>"
- Folglich nur 1 möglicher Linkfokus, der dem Labelfokus entspricht
- Folglich keine Focuswechsel mit Pfeiltasten etc.

Mal gucken, ob ich das hinbekomme. Der Quellcode ist mir im Moment noch ein Rätsel.

Gruß
blackdrake

blackdrake 20. Aug 2008 18:39

Re: VCL für Microsoft-Style URL-Label
 
Ich habe folgendes nun nach langer Arbeit hinbekommen:

Im Header sind ToDo-Einträge gelistet. Hier habe ich noch einige Probleme... Bitte schreibt mir, wenn ihr weiter wisst!

Delphi-Quellcode:
{
  TSingleLinkLabel
  (c) 2008 Daniel Marschall / ViaThinkSoft

  Original code and partitions
  (c) 2008 by omata (Thorsten) - [url]http://www.delphipraxis.net[/url]
}

// ToDo
// + AutoSize
// + Transparent
// + ParentColor
// + ParentFont
// (+ Sonstige Eigenschaften von echten Labels)
// Enabled=False * Schrift wird nicht grau
//                * Das nächste Item bekommt nicht den Focus
// Microsoft Hand-Cursor

unit SingleLinkLabel;

interface

uses Windows, Controls, Classes, Graphics, SysUtils;

type
  TSingleLinkLabel = class(TCustomControl)
  private
    FLines:TStringList;
    function GetCaption: string;
    procedure SetCaption(const Value: string);
  protected
    procedure Paint; override;
    procedure DoEnter; override;
    procedure DoExit; override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure Resize; override;
  published
    property OnClick;
    property Font;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    property Caption:string read GetCaption write SetCaption;
  end;

implementation

{ TSingleLinkLabel }

constructor TSingleLinkLabel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FLines := TStringList.Create;
  Width := 65;
  Height := 17;
  TabStop := True;

  Font.Color := clHotLight;
  Font.Style := [fsUnderline];
end;

destructor TSingleLinkLabel.Destroy;
begin
  FLines.free;
  inherited;
end;

procedure TSingleLinkLabel.DoEnter;
begin
  inherited;
  Paint;
end;

procedure TSingleLinkLabel.DoExit;
begin
  inherited;
  Paint;
end;

function TSingleLinkLabel.GetCaption: string;
begin
  Result := FLines.Text;
end;

procedure TSingleLinkLabel.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited;

  if Key = 13 then Click;
end;

procedure TSingleLinkLabel.MouseDown(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
begin
  inherited;
  SetFocus;
end;

procedure TSingleLinkLabel.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
  inherited;
  Cursor := crHandPoint;
end;

procedure TSingleLinkLabel.Paint;
var
  i: integer;
begin
  inherited;

  Canvas.Font := Font;

  Canvas.Brush.Color := clBtnFace;
  Canvas.Brush.Style := bsSolid;
  Canvas.FillRect(Canvas.ClipRect);

  for i := 0 to FLines.Count - 1 do
  begin
    Canvas.TextOut(0, Canvas.TextHeight('X')*i, FLines.Strings[i]);
  end;

  if Focused then Canvas.DrawFocusRect(Canvas.ClipRect);
end;

procedure TSingleLinkLabel.Resize;
begin
  inherited;
  SetCaption(Caption);
  Paint;
end;

procedure TSingleLinkLabel.SetCaption(const Value: string);
begin
  FLines.Text := Value;

  Paint;
end;

end.
Gruß
blackdrake

blackdrake 21. Aug 2008 12:27

Re: VCL für Microsoft-Style URL-Label
 
Oh mann, die oben gepostete VCL - deren Ableitung mich viel Zeit gekostet hat - ist nach einiger Überlegung doch totaler Müll. Sie hat zwar einen Fokus und TabStopps, ist aber super-primitiv und verhält sich absolut nicht wie ein TLabel (z.B. beim Deaktivieren). Hinzu kommt, dass ich alle Properties und die Reaktion auf deren Zustände nachmachen müsste (Ich müsste das Rad "TLabel" neu erfinden!).
Ist es denn nicht einfach, ein TLabel abzuleiten und ihm ein TabStopp zu geben? Ich habe leider von diesem ganzen Zeug überhaupt keine Ahnung und weiß nicht einmal, was ein Handle/DC/HDC/HWND/etc überhaupt ist und wie man damit umgeht (es definiert etc) :( :(

blackdrake 22. Aug 2008 00:10

Re: VCL für Microsoft-Style URL-Label
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich sitze jetzt hier schon seit Tagen daran, mit dem Erstellen einer solchen VCL herumzuexperimentieren und niemand hilft mir...

Jetzt habe ich folgenden Plan versucht:

Eine Klasse von TLabel ableiten und diese Klasse erzeugt ein Tab-Objekt, das über das Label gelegt wird. Dieses Tab-Object ist eine Klasse, die vom TCustomControl (enthält TabStop) abgeleitet ist, aber Transparent sein muss.

Im Moment sieht das so aus:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, jpeg, ExtCtrls, Buttons;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Button1: TButton;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
  end;

  // FUNKTIONIERT NICHT!!! DAS TEIL IST NICHT DURCHSICHTIG!!!
  TTransparentCustomControl = class(TCustomControl)
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  end;

  TTabElement = class(TTransparentCustomControl)
  protected
    procedure Paint; override;
    procedure DoEnter; override;
    procedure DoExit; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TSingleLinkLabel = class(TLabel)
  protected
    procedure Paint; override;
  private
    FTabElement: TTabElement;
  public
    procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

var
  Form1: TForm1;

implementation

{uses
  Themes;}

{$R *.dfm}

{ TTransparentCustomControl }

procedure TTransparentCustomControl.CreateParams(var Params: TCreateParams);
begin
  // Transparenz herstellen
  // [url]http://www.coding-board.de/board/showpost.php?p=25336&postcount=7[/url]

  // Problem: Die Transparenz funktioniert nicht! Es wird nur die
  // Formhintergrundfarbe übernommen. Das dahinterliegende Label ist
  // verdeckt!

  // ToDo: Transparenz des TSingleLinkLabel anzapfen

  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle+WS_EX_Transparent;
  ControlStyle := ControlStyle-[csOpaque]+[csAcceptsControls];
end;

{ TTabElement }

procedure TTabElement.Paint;
begin
  inherited;

  if Focused then
  begin
    Canvas.DrawFocusRect(Canvas.ClipRect);
  end;

  Repaint;
end;

constructor TTabElement.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  Parent := AOwner as TWinControl;
  DoubleBuffered := true;
  TabStop := True;

  // ToDo: Transparent, Click -> FocusGet, Enter=ClickNotify

  {if ThemeServices.ThemesEnabled then
    ControlStyle := ControlStyle - [csOpaque]
  else
    ControlStyle := ControlStyle + [csOpaque];}
end;

procedure TTabElement.DoEnter;
begin
  inherited;
  Paint;
end;

procedure TTabElement.DoExit;
begin
  inherited;
  Paint;
end;

{ TSingleLinkLabel }

procedure TSingleLinkLabel.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
  inherited;

  FTabElement.Left := ALeft;
  FTabElement.Top := ATop;
  FTabElement.Width := AWidth;
  FTabElement.Height := AHeight;
end;

constructor TSingleLinkLabel.Create(AOwner: TComponent);
begin
  FTabElement := TTabElement.Create(AOwner);
  FTabElement.Parent := AOwner as TWinControl;

  inherited Create(FTabElement);
  Parent := FTabElement as TWinControl;

  Font.Color := clHotLight;
  Font.Style := [fsUnderline];

  Cursor := crHandPoint; // ToDo: Microsoft-Hand verwenden
end;

procedure TSingleLinkLabel.Paint;
begin
  inherited;
end;

destructor TSingleLinkLabel.Destroy;
begin
  // FTabElement.Free; // EXCEPTION

  inherited;
end;

{ Testform }

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

  x.AutoSize := true;
  x.Caption := 'Dies ist ein Label ... als Link';
  x.Top := 10;
  x.Left := 20;
end;

end.
TSingleLinkLabel ist ein Label, das beim Erstellen ein TTabElement über das Label legt.

TTabElement hat die einzige Aufgabe, lediglich einen Rahmen zu zeichnen, sobald es den Fokus hat!

Aber: Großes Problem besteht bei der Transparenz! Ich bekomme TCustomControl nicht transparent, weswegen in meinem Beispiel das Label unter dem TTabElement verschwindet und somit unsichtbar ist.

Bitte helft mir doch endlich mal! Ich habe so wenig Ahnung von Vererbung und VCL und hocke hier jetzt schon seit 1 Woche an diesem Zeug, was eigentlich vollkommen trivial ist! :(

Gruß
blackdrake

hitzi 22. Aug 2008 07:34

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

Zitat von blackdrake
Ich sitze jetzt hier schon seit Tagen daran, mit dem Erstellen einer solchen VCL herumzuexperimentieren und niemand hilft mir...
[...]
Bitte helft mir doch endlich mal!

Ähmm ... wieso hat der Thread hier dann schon zwei Seiten. Über fehlende Hilfe würde ich mich da nicht beklagen!

Zitat:

Zitat von blackdrake
Ich habe so wenig Ahnung von Vererbung und VCL und hocke hier jetzt schon seit 1 Woche an diesem Zeug, was eigentlich vollkommen trivial ist! :(

Wenn du keine Ahnung hast, woher weißt du dann, dass es "vollkommen trivial" ist? Meinst du nicht auch, dass bei einem einfachen Problem, entweder die Lösung schon hier im Forum stehen würde oder mit dir hier schon erarbeitet wäre?

Wegen deiner Transparenz: http://delphi.newswhat.com/geoxml/fo...ps.borland.com

DeddyH 22. Aug 2008 08:08

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

Transparency with TWincontrols on arbitrary containers is next to impossible
to achieve.
Diese Erfahrung habe ich auch schon schmerzhaft machen müssen. Eine Lösung wäre, von TGraphicControl abzuleiten und ein Pseudohandle für die Botschaftsbehandlung anzufordern (AllocateHwnd).

blackdrake 22. Aug 2008 13:17

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

Das Problem, was ich sehe, (wieso ich vorsichtig sage, dass ich - bei dieser Problematik - kaum Hilfe erhalte) ist, dass ich mit den meisten Hinweisen nichts anfangen kann. Wenn jemand schreibt, es wäre doch sehr einfach, ein TLabel abzuleiten und einfach ein Handle zu setzen und dieses mit TabStop-Methoden zu versehen, dann bringt mir das leider nichts.

Schade, dass mein Anlauf von Gestern scheinbar nicht funktionieren wird. Wenn ich das TTabElement nicht transparent bekomme, wird meine Idee vom TLabel+TTabElement-Hybrid nicht funktionieren. Schade, dann muss ich weiter versuchen.

Ich versuche ja sehr, alle Hinweise zu befolgen und versuche auch viel selbst, bevor ich hier frage. Aber wie gesagt habe ich von Handles etc. absolut keine Ahnung und habe Delphi auch (noch) nicht professionell erlernt, sondern alles autonom erfahren. Ich kann auch schlecht beurteilen, ob es nun tatsächlich trivial ist, ein TLabel mit TabStops zu versehen, oder nicht, aber unmöglich kann es ja irgendwie nicht sein. Schade, dass mir niemand einen Codebrocken zuspielt, mit dem ich was richtiges anfangen kann. (soll nicht heißen, ich will sofort eine perfekte Lösung)

@DeddyH: Ich werde mal versuchen, etwas über AllocateHwnd() herauszufinden. Ich habe aber absolut keine Ahnung, wie ich das mit den Tabs handhaben soll.

Ich habe ja ebenfalls auch versucht, einfach ein TLabel abzuleiten und die Tab-Eigenschaften/Methoden einfach per Copy&Paste von TWinControl abzuschreiben. Das funktioniert aber nicht! Innerhalb von TWinControl gibt es eine "FTabList: TList", in der scheinbar alle Tab-Reihenfolgen gespeichert sind. Folglich kann ich hier ja gar nicht eingreifen, da TLabel mit TWinControl absolut nichts zu tun hat, da es kein Vorfahre ist. Außerdem arbeiten diverse Methoden nur mit TWinControl-Objekten und deren Derivaten, zu denen TLabel und TMeinLabel=class(TLabel) nicht zählen.

Gruß
blackdrake

bigg 22. Aug 2008 13:27

Re: VCL für Microsoft-Style URL-Label
 
omata hat doch gezeigt, wie es geht! Wenn du die Hilfe anderer nicht annimmst, brauchst du dich auch nicht zu beklagen.

DeddyH 22. Aug 2008 13:31

Re: VCL für Microsoft-Style URL-Label
 
Zu AllocateHWnd kannst Du Dir ja mal den Source von TTimer ansehen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:48 Uhr.
Seite 3 von 5     123 45      

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