Autor Beitrag
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: Fr 06.03.15 08:51 
Hallo Leute,

mal wieder was zu der Messageproc. Ich habe eine Messageproc geschrieben, um das Mausrad abzufragen. Jetzt hat mich diese wahnsinnig genervt, weil plötzlich das simple Zuweisen von Daten zu Editfeldern Probleme machte. Das Editfeld wurde nämlich, obwohl ich ihm einen Leerstring zuordnete nicht gelöscht. Jetzt habe ich die Messageproc rausgeschmissen und nun funktioniert das wieder mit der Zuweisung. Schon beim Debuggen nervt das extrem, denn dauernd kurvt der Debugger in der Messageproc rum. Wahrscheinlich wird jeder Tastendruck in der IDE als Tastendruck im Programm und damit als Message aufgefasst. Das wollte ich Euch nur mitteilen, falls bei Euch in Programmen auch völlig unerklärliche Effekte auftauchen und das Programm einfach nicht das macht, was es machen soll.


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Di 10.03.2015 um 12:41

_________________
Toleranz ist eine Grundvoraussetzung für das Leben.
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 06.03.15 09:18 
Du kannst doch selbst bestimmen, auf welche Komponenten dein Eventhandler angewendet werden soll. Bei mir arbeitet unter Delphi2009 seit Jahren diese Methode einwandfrei:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
// ---------- Wandelt Mouse-Wheel-Bewegungen in Cursur-Runter bzw. Cursor-Hoch-Messages um (nur TjvDBGrid) ------------------------------
Procedure TFormMain.HandleOnMessage(var Msg: TMsg; var Handled: Boolean);
begin
  Case Msg.message Of
   WM_MOUSEWHEEL:
   Begin
      If  (Screen.ActiveForm.ActiveControl <> Nil)
      And (Screen.ActiveForm.ActiveControl.ClassName = 'TJvDBGrid')
      Then
      Begin // die Mousewheel Message wird in einen Tastendruck umgewandelt
         Msg.message := WM_KEYDOWN;
         Msg.lParam  := 0;
         If Msg.wParam > 0      Then
            Msg.wParam := VK_UP Else
            Msg.wParam := VK_DOWN;
         Handled := False;
      End;
   End// WM_MOUSEWHEEL
  End// Case
end;


Jetzt hab ich dir meins gezeigt, nun kannst du vielleicht auch mal deins zeigen, denn mit Sicherheit liegt die Ursache deines Problems irgendwo in deinem Code verborgen – oder wie mancher es so treffend zum Ausdruck bringt: Das Problem sitzt meist vor dem Bildschirm genau zwischen den Ohren :lol:

Für diesen Beitrag haben gedankt: Tranx
Tranx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: Di 10.03.15 13:17 
user profile iconPerlsau hat folgendes geschrieben Zum zitierten Posting springen:

Jetzt hab ich dir meins gezeigt, nun kannst du vielleicht auch mal deins zeigen, denn mit Sicherheit liegt die Ursache deines Problems irgendwo in deinem Code verborgen – oder wie mancher es so treffend zum Ausdruck bringt: Das Problem sitzt meist vor dem Bildschirm genau zwischen den Ohren :lol:


Dies ist meine Prozedur:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
procedure TMF.MessageProc(var Msg: TagMsg; var Handled: Boolean);
var
   i: SmallInt;
   loDBG: TDBGrid;
begin
   Inc(giProzaufrufe);
   {Mouse wheel behaves strangely with dgbgrids - this proc sorts this out}
   if not (Self.Visible) then
      Exit;
   if ActiveControl is TDBGrid then
      loDBG := TDBGrid(ActiveControl)
   else
   begin
      Handled := False;
      Exit;
   end;
   if Msg.message = WM_MOUSEWHEEL then
   begin
      Msg.message := WM_KEYDOWN;
      Msg.lParam := 0;
      try
         i := HiWord(Msg.wParam);
      except
         i := 0;
      end;
      if i > 0 then
         Msg.wParam := VK_UP
      else
      begin
         if loDBG <> nil then
            if not (loDBG.DataSource.DataSet.FindNext) then
            begin
               Msg.wParam := 0;
            end
            else
            begin
               Msg.wParam := VK_DOWN;
            end
         else
            Msg.wParam := VK_DOWN;
      end;
      Handled := False;
   end;
end;


allerdings habe ich den Fehler entdeckt, wieso der Compiler so merkwürdig reagiert. Die Hauptunit lag zweimal in der IDE vor. Das heißt, wenn ich eine Unit geändert habe, hat er trotzdem die andere - gleichlautende - berücksichtigt, die auf dem alten Stand war. Wieso der Compiler da keine Fehlermeldung ausgibt, ist mir rätselhat. Manchmal sieht man bei mehreren Units nicht, dass eine doppelt vorliegt. Als ich die doppelte Unit einmal rausschmiss, funktionierte alles wie gewohnt.

Danke für den Hinweis, aber eigentlich habe ich dies schon berücksichtigt, wie Du sehen kannst. Doch der Aufruf erfolgt ja bei jeder Message, auch wenn er die Prozedur dann sodfort wieder verlässt. Wahrscheinlich muss ich diese Prozedur vom Debugger ausschließen.

_________________
Toleranz ist eine Grundvoraussetzung für das Leben.
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Di 10.03.15 14:31 
TApplication.OnMessage
Zitat:
Warnung: In jeder Sekunde werden möglicherweise Tausende von Botschaften gesendet. Implementieren Sie diese Routine so effektiv wie möglich, damit die Geschwindigkeit der Anwendung nicht darunter leidet.

Daher sollte man genau aufpassen, wo man seine Haltepunkte setzt, sonst wird man bekloppt. Übrigens kommt mir Perlsaus Code bekannt vor: http://www.swissdelphicenter.ch/torry/showcode.php?id=1454
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 10.03.15 17:20 
Mehrere Units mit gleichem Namen in unterschiedlichen Verzeichnissen sind eben keine gute Idee. Der Compiler kann nicht wissen, dass da etwas falsch läuft.

In der MessageProc wäre es sinnvoller die Prüfung auf is nur zu machen, wenn es auch die gewünschte Message ist. Denn is ist relativ zeitaufwendig im Vergleich zu einem simplen Vergleich der Messagenummern.
Tranx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: Mi 11.03.15 07:52 
user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:
TApplication.OnMessage
Zitat:
Warnung: In jeder Sekunde werden möglicherweise Tausende von Botschaften gesendet. Implementieren Sie diese Routine so effektiv wie möglich, damit die Geschwindigkeit der Anwendung nicht darunter leidet.

Daher sollte man genau aufpassen, wo man seine Haltepunkte setzt, sonst wird man bekloppt. Übrigens kommt mir Perlsaus Code bekannt vor: http://www.swissdelphicenter.ch/torry/showcode.php?id=1454


Das habe ich auch daher. Deswegen kommt Dir das so bekannt vor. Ich habe nach einer Prozedur gesucht, die das Mausrad verarbeitet und das gefunden.

Moderiert von user profile iconNarses: Beiträge zusammengefasst

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Mehrere Units mit gleichem Namen in unterschiedlichen Verzeichnissen sind eben keine gute Idee. Der Compiler kann nicht wissen, dass da etwas falsch läuft.

In der MessageProc wäre es sinnvoller die Prüfung auf is nur zu machen, wenn es auch die gewünschte Message ist. Denn is ist relativ zeitaufwendig im Vergleich zu einem simplen Vergleich der Messagenummern.


Das waren nicht mehrer Units in verschiedenen Verzeichnissen, sowas habe ich nicht. Wenigstens nicht in dem Arbeitsverzeichnis von Delphi, in der das Programm geschrieben wurde. Mag sein, dass die beiden Units durch das Verwenden des Backup-Verzeichnisses zustande kamen. Ich werde in Zukunft genauer auf sowas achten. Zum Glück löschen sich die auffgerufenen Units in der IDE-Ansicht wenn ich statt zuhause am Arbeitsplatzrechner arbeite, weil die .dsk-Datei eine andere ist.

Allerdings hätte eigentlich der Compiler meckern müssen, denn es war die Hauptunit, mit demnach einer doppelten Definition des Hauptformulars. Das verstehe ich nicht. Oder betrachtet er die beiden aufgelisteten Units als eine?

_________________
Toleranz ist eine Grundvoraussetzung für das Leben.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 11.03.15 14:29 
user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Allerdings hätte eigentlich der Compiler meckern müssen, denn es war die Hauptunit, mit demnach einer doppelten Definition des Hauptformulars. Das verstehe ich nicht. Oder betrachtet er die beiden aufgelisteten Units als eine?
Der Compiler weiß nicht was du in der IDE machst. Der kompiliert einfach den Quelltext. Und im Projekt kannst du nur eine Unit desselben Namens haben. Eine der beiden war also gar nicht im Projekt. Das weiß der Compiler aber nicht.

Delphi zeigt aber eigentlich dann die blauen Debuggermarkierungen nach dem Kompilieren nur in der richtigen Unit an. Daran sieht man das recht gut.