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 Kontextsensitive Hilfe / biHelp-Button trotz Minimize-Button? (https://www.delphipraxis.net/187664-kontextsensitive-hilfe-bihelp-button-trotz-minimize-button.html)

Delphi-Laie 20. Dez 2015 09:54


Kontextsensitive Hilfe / biHelp-Button trotz Minimize-Button?
 
Hallo Delphifreunde!

Möchte man die kontextsensitive Hilfe über Aktivierung des Minimize-Buttons benutzen, so stößt man auf folgende Einschränkung, die in der Delphi-Hilfe so formuliert ist:

Zitat:

biHelp [....] Werden die Konstanten biMinimize und biMaximize nicht angegeben, erscheint in der Titelleiste ein Fragezeichen. Ansonsten wird kein Fragezeichen angezeigt.

Nun, das stimmt nicht ganz: Bei aktiviertem Minimize-Button wird dieser Fragezeichen-Button doch wenigstens angezeigt, ist jedoch leider nicht bedienbar, biMaximize läßt ihn, wie beschrieben, hingegen gänzlich verschwinden.

Nun meine beiden Fragen dazu (bitte laßt mich gleich zwei Fragen stellen, ein extra Thema für jede einzelne wäre zuviel):

Ist dieses einschränkende Verhalten windows-bedingt oder eine Schwäche der VCL?

Kann man das irgendwie überlisten? Ich hätte nämlich gern den Minimize- und Help-Button, natürlich beide bedienbar.

Danke und Gruß

Delphi-Laie

hathor 20. Dez 2015 12:47

AW: Kontextsensitive Hilfe / biHelp-Button trotz Minimize-Button?
 
Dann mach es so:

Delphi-Quellcode:
...
  protected
    procedure WMNCLButtonDown(var Message: TWMNCLButtonDown); message WM_NCLBUTTONDOWN;
  end;
...
implementation

{$R *.dfm}

procedure TForm1.WMNCLButtonDown(var Message: TWMNCLButtonDown);
begin
  if (Message.HitTest = HTCAPTION) then self.WindowState:= wsMinimized;
  if (Message.HitTest = HTCLOSE) then Application.Terminate;
  if (Message.HitTest = HTHELP) then
  begin ShowMessage('hello world'); message.Result := 0; end
  else inherited;
end;

Delphi-Laie 20. Dez 2015 12:54

AW: Kontextsensitive Hilfe / biHelp-Button trotz Minimize-Button?
 
Das ist zwar nicht das erhoffte gleichzeitige Funktionieren des biMinimize- und biHelp-Buttons, aber danke für Antwort! Zumindest sind damit alle 3 Funktionen in der Titelleiste enthalten.

SMO 20. Dez 2015 14:08

AW: Kontextsensitive Hilfe / biHelp-Button trotz Minimize-Button?
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1324920)
Zitat:

biHelp [....] Werden die Konstanten biMinimize und biMaximize nicht angegeben, erscheint in der Titelleiste ein Fragezeichen. Ansonsten wird kein Fragezeichen angezeigt.
Nun, das stimmt nicht ganz: Bei aktiviertem Minimize-Button wird dieser Fragezeichen-Button doch wenigstens angezeigt, ist jedoch leider nicht bedienbar, biMaximize läßt ihn, wie beschrieben, hingegen gänzlich verschwinden.

Doch, das stimmt, jedenfalls bei mir in Delphi XE6 und Windows 8.1. Welche Version benutzt du?
Der entsprechende Code ist in der Unit Vcl.Forms zu finden:

Delphi-Quellcode:
procedure TFormStyleHook.PaintNC(Canvas: TCanvas);
// ...
  if (biHelp in Form.BorderIcons) and (biSystemMenu in Form.BorderIcons) and
     ((not (biMaximize in Form.BorderIcons) and
     not (biMinimize in Form.BorderIcons)) or (Form.BorderStyle = bsDialog))
  then
// ...
Damit biHelp beachtet wird, muss also immer biSystemMenu gesetzt sein. Weder biMaximize noch biMinimize dürfen gesetzt sein, es sei denn BorderStyle ist bsDialog, da werden biMaximize und biMinimize einfach ignoriert.

Zitat:

Zitat von Delphi-Laie (Beitrag 1324920)
Ist dieses einschränkende Verhalten windows-bedingt oder eine Schwäche der VCL?

Windows, siehe MSDN.
biHelp entspricht dem Extended Style Flag WS_EX_CONTEXTHELP:
"WS_EX_CONTEXTHELP cannot be used with the WS_MAXIMIZEBOX or WS_MINIMIZEBOX styles."

Zitat:

Zitat von Delphi-Laie (Beitrag 1324920)
Kann man das irgendwie überlisten? Ich hätte nämlich gern den Minimize- und Help-Button, natürlich beide bedienbar.

Klar, du kannst komplett eigene Elemente in die Titelleiste von Fenstern setzen/malen. Wie das genau geht kann ich dir leider nicht erklären, und es scheint auch darauf anzukommen, ob du für alte Windows-Versionen (XP und älter), oder für neuere mit Desktop Window Manager (DWM, seit Vista) programmierst.
Hier weitere Informationen.

Zitat:

Zitat von hathor (Beitrag 1324933)
Dann mach es so:

Wieso nicht mit case? Außerdem halte ich Application.Terminate für nicht angebracht, es sei denn man möchte wirklich das Programm beenden und nicht das aktuelle Fenster schließen. Für Anwendungen mit nur einem Fenster läuf das aufs Selbe hinaus, nicht aber für Anwendungen mit mehreren Fenstern.
Delphi-Quellcode:
procedure TForm1.WMNCLButtonDown(var Message: TWMNCLButtonDown);
begin
  case Message.HitTest of
    HTCAPTION: WindowState:= wsMinimized;
//    HTCLOSE:  Close; // kann man sich sparen, ist die Standardaktion
    HTHELP:   begin ShowMessage('hello world'); Message.Result := 0; end
  else
    inherited;
  end;
end;

hathor 20. Dez 2015 14:25

AW: Kontextsensitive Hilfe / biHelp-Button trotz Minimize-Button?
 
Man könnte es umschaltbar machen:
Delphi-Quellcode:
  protected
    procedure WMNCLButtonDown(var Message: TWMNCLButtonDown); message WM_NCLBUTTONDOWN;
  end;

var
  Form1: TForm1;
  switched : Boolean;

implementation

{$R *.dfm}

procedure TForm1.WMNCLButtonDown(var Message: TWMNCLButtonDown);
begin
  if (Message.HitTest = HTCAPTION) then
  BEGIN
  if switched=TRUE then
  begin
    BorderIcons := [biSystemMenu,biMinimize,biHelp];
    BorderIcons := BorderIcons - [biMinimize];
    switched:=FALSE;
  end else
  begin
    BorderIcons := [biSystemMenu,biMinimize,biHelp];
    BorderIcons := BorderIcons - [biHelp];
    switched:=TRUE;
  end;
  END;
  if (Message.HitTest = HTCLOSE) then Application.Terminate;
  if (Message.HitTest = HTHELP) then
  begin ShowMessage('hello world'); message.Result := 0; end
  else inherited;
end;

SMO 20. Dez 2015 14:48

AW: Kontextsensitive Hilfe / biHelp-Button trotz Minimize-Button?
 
Zitat:

Zitat von hathor (Beitrag 1324938)
Man könnte es umschaltbar machen:

Hast du nicht gelesen, was ich geschrieben habe, oder bist du einfach nur stur? :)
Erstens ist
Delphi-Quellcode:
[biSystemMenu,biMinimize,biHelp] - [biMinimize]
sinnlos, da kannst du gleich
Delphi-Quellcode:
[biSystemMenu,biHelp]
schreiben.
Zweitens lass das Application.Terminate da weg, wenn schon dann Close, aber beides ist unnötig!


Delphi-Quellcode:
if switched=TRUE then
Das ist übrigens schlechter Stil, man sollte Boolsche Werte niemals per "=" auf True prüfen, sonst kann man sich schwer zu findende Bugs einfangen!
Hintergrund: "False" ist definiert als = 0, "True" ist logischerweise "not False", d.h. <> 0. Als Konstante ist "True" jedoch als 1 definiert (jedenfalls für den Standardtyp "Boolean", für die Typen ByteBool, WordBool, LongBool ist es -1, das ignorieren wir mal; der Compiler konvertiert normalerweise automatisch richtig zwischen diesen Typen).

Für Anweisungen wie
Delphi-Quellcode:
if Switched then
erzeugt der Delphi-Compiler Code, der auf <> 0 prüft (korrekt für alle Boolschen Typen und Werte).
Für Anweisungen wie
Delphi-Quellcode:
if Switched = True then
erzeugt der Delphi-Compiler für den "Boolean"-Typ Code, der auf = 1 prüft und das kann Probleme geben!
Kleiner Test:
Delphi-Quellcode:
procedure BooleanTest;
var
  B: Boolean;
begin
  Byte(B) := 2;
  // B ist <> 0, d.h. entspricht logisch "True"... wird aber NICHT bei "B = True" erkannt!
  // prüft B = 1: SCHLECHT!
  if B = True then ShowMessage('B = True');
  // prüft B = 0: OK, aber schlechter Stil
  if B = False then ShowMessage('B = False');
  // prüft B <> 0: korrekt!
  if B then ShowMessage('B *is* True!');
  // prüft B = 0: korrekt!
  if not B then ShowMessage('B *is NOT* True!');
end;
Zugegeben, das Schreiben eines anderen Wertes als 0 oder 1 in einen Boolean-Typ per Typecast hier ist etwas gekünstelt, aber wenn man Third-Party-Code benutzt, der nicht in Delphi geschrieben wurde, kann das durchaus mal vorkommen.

Delphi-Laie 20. Dez 2015 16:08

AW: Kontextsensitive Hilfe / biHelp-Button trotz Minimize-Button?
 
Leute, bitte geratet Euch nicht in die Haare, dafür sind sowohl ich als auch mein Anliegen zu unwichtig.

Zitat:

Zitat von SMO (Beitrag 1324937)
Zitat:

Zitat von Delphi-Laie (Beitrag 1324920)
Zitat:

biHelp [....] Werden die Konstanten biMinimize und biMaximize nicht angegeben, erscheint in der Titelleiste ein Fragezeichen. Ansonsten wird kein Fragezeichen angezeigt.
Nun, das stimmt nicht ganz: Bei aktiviertem Minimize-Button wird dieser Fragezeichen-Button doch wenigstens angezeigt, ist jedoch leider nicht bedienbar, biMaximize läßt ihn, wie beschrieben, hingegen gänzlich verschwinden.

Doch, das stimmt, jedenfalls bei mir in Delphi XE6 und Windows 8.1. Welche Version benutzt du?

Unter Windows XP ist es mit Delphi 2-7 und Turbo-Delphi jedenfalls so, wie oben schon beschrieben. Ich habe jetzt keine Lust, Windows 7 hochzufahren und es mit XE 2 auszuprobieren, denn es sollte möglichst auf jedem Windows laufen und auch mit möglichst kleinem Delphi erstellbar sein. Wenn das nicht gegeben ist, dann beiße ich mich nicht daran fest.

Ich werde das jetzt noch mal in Ruhe durcharbeiten, ahne aber, daß ich mit dieser Einschränkung wohl werde leben müssen.

Besten Dank für Eure Hilfe!

SMO 20. Dez 2015 17:20

AW: Kontextsensitive Hilfe / biHelp-Button trotz Minimize-Button?
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1324946)
Leute, bitte geratet Euch nicht in die Haare, dafür sind sowohl ich als auch mein Anliegen zu unwichtig.

Keine Angst, wird nicht passieren. Denn so wie ich hathor kenne, liest er meine Beiträge sowieso nicht. :wink:

Zitat:

Zitat von Delphi-Laie (Beitrag 1324946)
Ich werde das jetzt noch mal in Ruhe durcharbeiten, ahne aber, daß ich mit dieser Einschränkung wohl werde leben müssen.

Das denke ich auch. Ich schätze, das Verhalten wurde ab Windows Vista zu dem geändert, was im MSDN beschrieben ist. Ich hab's eben auch nochmal mit einem non-VCL-Fenster in Windows 8 getestet. Der WS_EX_CONTEXTHELP Hilfe-Button wird nur dann angezeigt, wenn im Fensterstil WS_SYSMENU gesetzt ist und weder WS_MINIMIZEBOX noch WS_MAXIMIZEBOX.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:05 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz