Autor |
Beitrag |
Tranx
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: So 27.10.13 13:36
Ich habe nach einer Möglichkeit gesucht, um das Mausrad abzufragen und entsprechend in einem TDBGrid dieses zu nutzen. Soweit so gut, habe ich auch gefunden. Aber jetzt trat der folgende Effekt auf:
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:
| in TMF unter public:
procedure MessageProc(var Msg: TMsg; var Handled: Boolean);
procedure TMF.MessageProc(var Msg: TMsg; var Handled: Boolean); var i: SmallInt; loDBG: TDBGrid; begin
if ActiveControl is TDBGrid then loDBG := TDBGrid(ActiveControl) else loDBG := NIL; 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; |
Dies sollte eigentlich funktionieren. Denkste. Es gab die Fehlermeldung: "[Fehler] xxxx: Deklaration von 'MessageProc' unterscheidet sich von vorheriger Deklaration"
Ich konnte das gar nicht glauben. Dann habe ich mit mal anzeigen lassen, welche Definition MessageProc in TMF wirklich hat, und da stellte ich fest, dass diese statt TMsg TagMsg anzeigte. So funktioniert dann - bei gleichem Eintrag im public-Ast wie vorher:
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:
| in TMF unter public:
procedure MessageProc(var Msg: TMsg; var Handled: Boolean);
procedure TMF.MessageProc(var Msg: TagMsg; var Handled: Boolean); var i: SmallInt; loDBG: TDBGrid; begin
if ActiveControl is TDBGrid then loDBG := TDBGrid(ActiveControl) else loDBG := NIL; 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; |
Ich habe dann gesucht, wo TagMsg definiert ist: In der Unit Windows:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| PMsg = ^TMsg; {$EXTERNALSYM tagMSG} tagMSG = packed record hwnd: HWND; message: UINT; wParam: WPARAM; lParam: LPARAM; time: DWORD; pt: TPoint; end; TMsg = tagMSG; {$EXTERNALSYM MSG} MSG = tagMSG; |
Frage, was soll das? Und wieso funktioniert das mit TMsg in der Klassendefinition und mit TagMsg in der Prozedurdefinition? Irgendwie merkwürdig.
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 27.10.13 15:41
Du hast die Unit Windows nicht ganz vorne in der uses-Liste würde ich mal raten.
|
|
Tranx 
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: So 27.10.13 18:49
jaenicke hat folgendes geschrieben : | Du hast die Unit Windows nicht ganz vorne in der uses-Liste würde ich mal raten. |
Danke für den Hinweis, aber das funktioniert trotzdem nicht, auch wenn Windows an erster Stelle der Uses-Liste steht.
Es funktionieren nur die folgenden Kombinationen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| public procedure MessageProc(var Msg: TagMsg; var Handled: Boolean); end;
und
procedure TForm.MessageProc(var Msg: TagMsg; var Handled: Boolean); begin
end; |
sowie
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| public procedure MessageProc(var Msg: TMsg; var Handled: Boolean); end;
und
procedure TForm.MessageProc(var Msg: TagMsg; var Handled: Boolean); begin
end; |
Aber wieso ist überhaupt in Windows - ich will da nichts ändern - das so definiert?
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 27.10.13 19:48
Ich benutze diese Procedure schon länger (Delphi 2009), um Mauswheelbewegungen in Cursortastenklicks zu verwandeln, weil DBGrids immer zwei Zeilen weiterspringen statt einer, wenn ich das Mausrad drehe:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| Private Procedure HandleOnMessage(var Msg: TMsg; var Handled: Boolean); ...
Implementation
Procedure TFormMain.HandleOnMessage(var Msg: TMsg; var Handled: Boolean); ...
Procedure TFormMain.FormCreate(Sender: TObject); begin Application.OnMessage := Self.HandleOnMessage; ... |
Das funktioniert sowohl unter Win7-64 als auch unter XP-32 einwandfrei.
|
|
Tranx 
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: Mo 28.10.13 05:39
Perlsau hat folgendes geschrieben : | Ich benutze diese Procedure schon länger (Delphi 2009), um Mauswheelbewegungen in Cursortastenklicks zu verwandeln, weil DBGrids immer zwei Zeilen weiterspringen statt einer, wenn ich das Mausrad drehe:
|
Bei Delphi 2009 mag das wohl auch stimmen, mein Delphi 5 hat da wohl einen "Fehler" Schau mal in die Unit Windows, den Teil, den ich abgebildet habe:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| PMsg = ^TMsg; {$EXTERNALSYM tagMSG} tagMSG = packed record hwnd: HWND; message: UINT; wParam: WPARAM; lParam: LPARAM; time: DWORD; pt: TPoint; end; TMsg = tagMSG; {$EXTERNALSYM MSG} MSG = tagMSG; |
Das ist es, was ich nicht so ganz verstehe, und warum es bei mir eben nicht funktioniert. Das ist definitiv nicht von mir. Das steht so in der Windows-Unit. Aber egal, es funktioniert ja auch. Wollte es nur mal klar aufzeigen, falls jemand anderes solch einen "Fehler" bekommt.
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 28.10.13 06:09
In der Windows.pas für 2009 sieht das so aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| PMsg = ^TMsg; tagMSG = packed record hwnd: HWND; message: UINT; wParam: WPARAM; lParam: LPARAM; time: DWORD; pt: TPoint; end; {$EXTERNALSYM tagMSG} TMsg = tagMSG; MSG = tagMSG; {$EXTERNALSYM MSG} |
Unterschiede sehe ich lediglich in der Platzierung der Compiler-Direktiven. Ob's daran liegen könnte, kann ich dir jedoch nicht beantworten. Auszug aus der Delphi-Hilfe:
Die Direktive EXTERNALSYM verhindert, dass das angegebene Delphi-Symbol in für C++ generierten Header-Dateien enthalten ist. Wenn eine überladene Routine angegeben wird, werden alle Versionen der Routine aus der Header-Datei ausgeschlossen.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 28.10.13 06:34
Ich habe gerade meinen virtuellen PC wieder eingerichtet. Ich kann das unter Delphi 5 nicht reproduzieren. Bei mir funktioniert es ganz normal.
Die Klassenvervollständigung hat in der Implementierungssektion auch TMsg verwendet und es kompiliert ganz normal. Das kann eigentlich nur an Units in der uses liegen, insbesondere wenn du welche unter implementation haben solltest.
Für diesen Beitrag haben gedankt: Tranx
|
|
Tranx 
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: Mo 28.10.13 08:21
Danke für die Hinweise. Nehme das Ganze mal als gegeben hin. Jetzt jede einzelne Unit (ich habe bei dem Projekt logischwerweise einige im Implementation-Teil) zu überprüfen, ob sie dafür verantwortlich ist, erscheint mir nicht sinnvoll. Dazu ist das "Problem" - zumal ich ja die Lösung habe - nicht so wichtig. Finde es nur merkwürdig, dass ein solcher Konstrukt überhaupt gewählt wurde. Ich käme nie auf sowas. Aber ich bin ja auch kein Programmierer 
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 28.10.13 10:01
Tranx hat folgendes geschrieben : | ich habe bei dem Projekt logischwerweise einige im Implementation-Teil |
Ich normalerweise gar keine um Kreuzbeziehungen direkt zu entdecken.
Wo man Units hinschreiben sollte, ist schon fast ein Glaubenskrieg, aber was ich so an Quelltexten im Netz sehe sieht meistens von der Struktur her deutlich sauberer aus, wenn die Units im Interface stehen.
|
|