AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Verhalten diverser Komponenten ändern

Offene Frage von "OLLI_S"
Ein Thema von OLLI_S · begonnen am 15. Okt 2006 · letzter Beitrag vom 22. Okt 2006
Antwort Antwort
OLLI_S

Registriert seit: 20. Aug 2006
19 Beiträge
 
Delphi 7 Architect
 
#1

Verhalten diverser Komponenten ändern

  Alt 15. Okt 2006, 20:02
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:
function TfrmHauptFenster.ZeigeHilfe(aHelpText: string): Boolean;
begin
   if HilfeModus then
   begin
      ZeigeHinweisInStatusbar(aHelpText);
      HilfeModus := False;
      Result := True
   end
   else
   begin
      Result := False;
   end;
end;
Bei einer normalen Schaltfläche (z.B. Button "Neuer Datensatz") führe ich folgendes aus:

Delphi-Quellcode:
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;
Das ganze funktioniert also ganz gut.

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:
procedure cboKundenArtMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
   if (HilfeModus) then
      ShowMessage('Hilfe zu KundenArt') else
      cboKundenArt.DropDown;
end;
wird die Liste NICHT aufgeklappt und nur der Hinweis angezeigt (in einem Hinweisfenster).
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
  Mit Zitat antworten Zitat
Benutzerbild von dataspider
dataspider

Registriert seit: 9. Nov 2003
Ort: 04539 Groitzsch
1.350 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Verhalten diverser Komponenten ändern

  Alt 16. Okt 2006, 08:36
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 EC Software Help Suite mal probieren.
Frank Reim
  Mit Zitat antworten Zitat
OLLI_S

Registriert seit: 20. Aug 2006
19 Beiträge
 
Delphi 7 Architect
 
#3

Re: Verhalten diverser Komponenten ändern

  Alt 16. Okt 2006, 15:49
Hallo dataspider,

danke für Deine Antwort.

Zitat von dataspider:
Verwendung von onEnter (Control wird aktiv)...
Dann habe ich immer noch das Problem, dass z.B. bei einer CheckBox die Checkbox im Hilfemodus angehakt wird.
Und sie im Hilfemodus manuell wieder abhaken ist bescheuert, da manche Checkboxen Filter auslösen.

Zitat von dataspider:
Verwendung von OnMouseMove...
Leider haben ComboBoxen kein OnMouseMove.
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 von dataspider:
Einrichten eines MouseHooks und WM_LBUTTONDOWN abfangen...
Das habe ich noch nie gemacht, da bräuchte ich bitte Hilfe.
Aber OnMouseMove klingt schon mal vielversprechend.....

Zitat von dataspider:
...oder von ecSoftwae die VCL EC Software Help Suite mal probieren.
Viel zu viel Aufwand.
Es reichen wirklich kleine Hinweistexte, die ich in der Statuszile ausgebe.

Danke und Gruß


OLLI
  Mit Zitat antworten Zitat
Benutzerbild von dataspider
dataspider

Registriert seit: 9. Nov 2003
Ort: 04539 Groitzsch
1.350 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: Verhalten diverser Komponenten ändern

  Alt 16. Okt 2006, 17:07
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...
Angehängte Dateien
Dateityp: zip sample_with_mousehook_172.zip (212,0 KB, 13x aufgerufen)
Frank Reim
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

Re: Verhalten diverser Komponenten ändern

  Alt 16. Okt 2006, 17:52
Wie wäre es denn mal so:
Delphi-Quellcode:
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.
Also im Prinzip werden die aktiven Elemente auf einem Panel plaziert. Dieses Panel wird im Hilfmodus deaktiviert.
Dann wird MouseDown abgefragt und die Klickposition im Panel bestimmt und das entsprechende Control gesucht.

Fertig.

cu

Oliver
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
OLLI_S

Registriert seit: 20. Aug 2006
19 Beiträge
 
Delphi 7 Architect
 
#6

Re: Verhalten diverser Komponenten ändern

  Alt 16. Okt 2006, 20:01
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
  Mit Zitat antworten Zitat
OLLI_S

Registriert seit: 20. Aug 2006
19 Beiträge
 
Delphi 7 Architect
 
#7

Re: Verhalten diverser Komponenten ändern

  Alt 22. Okt 2006, 16:14
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
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:17 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