![]() |
Verhalten diverser Komponenten ändern
Liebe Community,
ich habe in meiner Anwedung eine Schaltfläche (mit dem Symbol des Hilfepfeil crHelp als Bild). Klickt der Anwender diese Schaltflähe und anschließend auf ein Element, wird in der Statuszeile eine Hilfe zu dem entsprechenden Element angezeigt. Eigentlich nichts kompliziertes. Dazu habe ich in meinem Hauptformular eine Funktion ZeigeHilfe, die überprüft, ob der Hilfemodus aktiv ist oder nicht (sobald man den Button Hilfe klickt, wird der Hilfemodus auf True gesetzt). Ist der Hilfemodus aktiv, wird ein übergebener Text als Hilfe in der Statuszeile angezeigt, der Hilfemodus auf False gesetzt (und der Cursor auf crDefault) und die Funktion liefert ein TRUE zurück (also dass eine Hilfe anzuzeigen war). Ist der Hilfemodus nicht aktiv, wird nur ein False zurückgeliefert (bedeuted dass nichts anzuzeigen war). Der Code dazu schaut so aus:
Delphi-Quellcode:
Bei einer normalen Schaltfläche (z.B. Button "Neuer Datensatz") führe ich folgendes aus:
function TfrmHauptFenster.ZeigeHilfe(aHelpText: string): Boolean;
begin if HilfeModus then begin ZeigeHinweisInStatusbar(aHelpText); HilfeModus := False; Result := True end else begin Result := False; end; end;
Delphi-Quellcode:
Das ganze funktioniert also ganz gut.
procedure TfrmHauptFenster.btnToolbarNewClick(Sender: TObject);
begin if not ZeigeHilfe(HilfeTextFuerNeuenDatensatz) then begin // Es soll keine Hilfe angezeigt werden -> hier kommen Aktionen für den neuen Datensatz (habe ich hier im Forum weg gelassen) end; end; Bei Buttons habe ich das Event "OnClick" verwendet, um die Hilfe anzuzeigen. Bei Eingabelfern (TEdit und TDBEdit) habe ich auch das Event "OnClick". Eine Bitte an dieser Stelle: Bitte bewertet hier nicht meinen bisherigen Code. Manch einer könnte sagen, dass man das letzte begin...end bei "ZeigeHilfe" weglassen kann, aber das ist nicht mein Problem. Es soll hier keine Diskussion über meinen Code entstehen, sondern auf mein Problem eingegangen werden. Mein Problem folgt hier.... Jetzt habe ich das Problem mit folgenden Komponenten: - TComboBox - TDBComboBox - TKADaoDBGrid - TCheckBox - TDBCheckBox Bei Checkboxen wird bei OnClick und bei OnMouseDown immer die CheckBox angehakt. Einfach nur die Checkbox im Hilfemodus wieder abhaken (also Checkbox.checked := not Checkbox.checked) ist bescheuert, da manche Checkboxen Datensatzfilter auslösen und man dann beim Klicken der Checkbox mit dem Hilfecursor einen ganz anderen Kunden (dann ist der Filter aktiv) angezeigt bekommt und dann wieder plötzlich alle Kunden (aber auch nicht den aktuellen). Gibt es einen Weg bei einer Checkbox beim OnClick die Checkbox NICHT anzuhaken? Bei ComboBoxen habe ich das Problem, dass ich gerne das aufklappen der Liste verhinder würde. Bei folgendem Quelltext:
Delphi-Quellcode:
wird die Liste NICHT aufgeklappt und nur der Hinweis angezeigt (in einem Hinweisfenster).
procedure cboKundenArtMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin if (HilfeModus) then ShowMessage('Hilfe zu KundenArt') else cboKundenArt.DropDown; end; Ersetze ich das "ShowMessage" durch "ZeigeHilfe" wird zwar der Hinweistext in der Statuszeile angezeigt, aber die Listbox klappt auf. Wie kann ich das Aufklappen der ComboBoxen beim Anklicken verhindern? Bei dem TKADaoDBGrid habe ich das Problem, dass auch im Hilfemodus der aktuelle Datensatz gewechselt wird (die TKADaoDBGrid wird zur auswahl eines Kunden und damit zur Datensatznavigation verwendet). Im Hilfemodus soll aber kein Datensatz gewechselt werden. Ich verwende hier den Event "OnMouseDown" , da der Event "OnCellClick" nur bei Datenzeilen funktioniert. Wenn das Grid selbst aber nur wenige Datensätze enthält und der User klickt in den weißen Bereich unterhalb des letzten Datensatzes, passiert nichts (kein Event "OnCellClick"). Wie kann ich hier die Datensatznavigation unterbinden? Vielen Dank für Eure Hilfe Gruß OLLI |
Re: Verhalten diverser Komponenten ändern
Hi,
mir fallen spontan folgende Lösungsansätze ein. Verwendung von onEnter (Control wird aktiv)... Verwendung von OnMouseMove... Einrichten eines MouseHooks und WM_LBUTTONDOWN abfangen... ...oder von ecSoftware die VCL ![]() |
Re: Verhalten diverser Komponenten ändern
Hallo dataspider,
danke für Deine Antwort. Zitat:
Und sie im Hilfemodus manuell wieder abhaken ist bescheuert, da manche Checkboxen Filter auslösen. Zitat:
Aber sonst eine interessante Idee: den Hilfemodus pauschal mit dem Button ein und wieder ausschalten und dann bei OnMouseMove die Hilfe anzeigen. Ein Ansatz, der mir sehr gut gefällt, da man damit nur ein mal klicken muss und sich für mehrere Komponenten die Hilfe anzuzeigen. Hast Du vielleicht eine Idee für OnMouseMove? Vielleicht mache ich eine eigene Komponente, die das kann, aber darin bin ich nicht soooo fit. Aber mal schauen. Zitat:
Aber OnMouseMove klingt schon mal vielversprechend..... Zitat:
Es reichen wirklich kleine Hinweistexte, die ich in der Statuszile ausgebe. Danke und Gruß OLLI |
Re: Verhalten diverser Komponenten ändern
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,
ok, hab mal ein kleines Beispiel mit MouseHook gemacht. Vielleicht hilft es dir ja weiter. Cu, Frank [EDIT] Sorry, die EXE wollte ich eigentlich nicht mit einpacken... |
Re: Verhalten diverser Komponenten ändern
Wie wäre es denn mal so:
Delphi-Quellcode:
Also im Prinzip werden die aktiven Elemente auf einem Panel plaziert. Dieses Panel wird im Hilfmodus deaktiviert.
unit Unit6;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, ExtCtrls; type TForm6 = class(TForm) Panel1: TPanel; CheckBox1: TCheckBox; Edit1: TEdit; CheckBox2: TCheckBox; Panel2: TPanel; StatusBar1: TStatusBar; procedure CheckBox1Click(Sender: TObject); procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form6: TForm6; implementation {$R *.dfm} procedure TForm6.CheckBox1Click(Sender: TObject); begin Panel2.Enabled := not CheckBox1.Checked; end; procedure TForm6.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var PosPoint : TPoint; s : string; begin PosPoint.X := x - Panel2.Left; PosPoint.Y := y - Panel2.Top; s := ''; if Panel2.ControlAtPos( PosPoint, true, true ) <> nil then s := TControl( Panel2.ControlAtPos( PosPoint, true, true ) ).Name; StatusBar1.SimpleText := Format( 'Maus an Position %d:%d Control: %s', [ x, y, s ] ); end; end. Dann wird MouseDown abgefragt und die Klickposition im Panel bestimmt und das entsprechende Control gesucht. Fertig. cu Oliver |
Re: Verhalten diverser Komponenten ändern
Hallo,
danke für die vielen Anregungen! Ich denke ich werde das mit OnMouseMover machen, da man damit nur ein mal klicken muss und sich für mehrere Komponenten die Hilfe anzuzeigen (also der Button aktiviert und deaktiviert den Hilfemodus, bei MouseOver zeige ich den Hilfetext an). Ist der Hilfemodus aktiv, kann ich über alle Komponenten drüber fahren und bekomme so eine Hilfe angezeigt. Habe mal ein wenig bei TControl ein wenig geschaut und mir dort Code geklaut. Funktioniert! Falls es auch andere User interessiert, hier der Quelltext einer Componente, die von TComboBox abgeleitet ist und den event "MouseMove" hat. Die Inhalte sind wie gesagt von TControl geklaut.....
Delphi-Quellcode:
unit ComboBoxWithMouseMove;
interface uses SysUtils, Classes, Controls, StdCtrls, Messages; type TComboBoxWithMouseMove = class(TComboBox) private FOnMouseMove: TMouseMoveEvent; procedure WMMouseMove(var Message: TWMMouseMove); message WM_MOUSEMOVE; protected procedure MouseMove(Shift: TShiftState; X, Y: Integer); dynamic; public { Public-Deklarationen } published property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove; end; procedure Register; implementation uses Forms; {------------------------------------------------------------------------------} procedure Register; begin RegisterComponents('OLLI', [TComboBoxWithMouseMove]); end; {------------------------------------------------------------------------------} procedure TComboBoxWithMouseMove.MouseMove(Shift: TShiftState; X, Y: Integer); begin if Assigned(FOnMouseMove) then FOnMouseMove(Self, Shift, X, Y); end; {------------------------------------------------------------------------------} procedure TComboBoxWithMouseMove.WMMouseMove(var Message: TWMMouseMove); begin if not (csNoStdEvents in ControlStyle) then with Message do if (Width > 32768) or (Height > 32768) then with CalcCursorPos do MouseMove(KeysToShiftState(Keys), X, Y) else MouseMove(KeysToShiftState(Keys), Message.XPos, Message.YPos); end; {------------------------------------------------------------------------------} end. Gruß OLLI |
Re: Verhalten diverser Komponenten ändern
Hallo,
ich habe es umgesetzt und verwende jetzt das Ereignis "OnMouseMove" um die Hilfe anzuzeigen. Habe jetzt nur ein "Problem": Ich gebe den Hinweistext in einer Statuszeilen-Komponente aus. Diese ist abgeleitet von TPanel und hat als Besonderheit links und rechts jeweils zwei Schaltflächen, mit der man überlange Texte scrollen kann. Wenn ich also in dem Panel einen kurzen Text ausgebe, habe ich kein Problem. Gebe ich einen längeren Text aus, kann man den nicht komplett sehen, sondern muss die Scrolltasten drücken, um den Text zu scrollen. Will man die Hilfe zu einem Eingabefeld ausgeben, drückt man die "Hilfe" Schaltfläche und bewegt die Maus auf das Eingabefeld. Der Hilfetext wird angezeigt, aber nicht komplett, da er zu lang ist. Also bewegt man die Maus zu der Statusleite, um die Scrollbuttons zu drücken. Damit verlässt man das Eingabefeld (mit der Maus) und die Hilfe wird nicht mehr angezeigt. Ich will in die Hilfe wenig aufwand stecken. Momentan habe ich einfach nur normale Texte, die ich da anzeige. Hints der einzelnen Komponenten sind keine Lösung, da die nicht dauerhaft angezeigt werden. Wenn man die Maus bewegt, wverschwindet der Hint. Die Lösung von "EC Software Help Suite" in der Demo.exe schaut gut aus: man klickt auf die Schaltfläche "Hilfe" und dann auf ein Element (ich würde onMouseMove verwenden) und die Hilfe wird dauerhaft angezeigt. Aber leider muss ich dafür eine HLP Datei erzeugen. Viel zu viel Aufwand! Ich will einfach nur einen Text ausgeben, ohne gleich eine HLP kompilieren zu müssen. Gibt es denn keine Möglichkeit ein Hilfetext wie bei "EC Software Help Suite" ausgeben zu lassen, und dabei den Text einfach als "Caption" zu übergeben? Vielleicht mache ich ein Fenster, das ich als ToolFenster definiere und gebe dort die Hilfe aus. Meine Frage ist nur, wie ich es dynamisch an den Mauszeiger binde, so dass es immer mit der Maus verschoben wird. Oder hat jemand eine bessere Idee? Gruß OLLI |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:22 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