Entwickler-Ecke
Windows API - Mauswheel - Drehrichtung
M. Raab - Do 29.05.03 15:52
Titel: Mauswheel - Drehrichtung
Hallo NG,
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; begin case (Msg) of WM_MOUSEWHEEL: begin if HIWORD(wParam) > 0 then begin skalar:=skalar - 0.05; if skalar<0.5 then skalar:=0.5; form1.normierung; result:=0; end else begin skalar:=skalar + 0.05; form1.normierung; result:=0; end;
end; |
Mit o.g. Code bestimme ich, in welchse Richtung das Mausrad gedreht wird. Seit ich im Compiler die Bereichsprüfung aktiviert habe (DELPHI 7) erscheint nun eine Fehlermeldung, dass eine Bereichsüberschreitung vorliegen würde. Grund hierfür scheint mir zu sein, dass wParam negativ wird. Kann mir jemand helfen ? Ich könnte den Compilerschalter wieder deaktivieren und dann klappt alles wieder - ich möchte jedoch den Grund erfahren .... :?:
Gruss
Markus
w3seek - Fr 30.05.03 11:53
welcher typ ist skalar?
MaxiTB - Fr 30.05.03 13:30
Hm - WPARAM ist ein unsigned int32 - also auf Delphisch ein Cardinal.
Cardinals können gar nicht negativ werden ... also mutet mir das ganze ein bisserl komisch an ...
w3seek - Sa 31.05.03 01:09
evtl funktioniert das hier indem du den HiWord zu einem signed word (smallint) konvertierst (in einem aelteren Projekt von mir hat das jedenfalls funktioniert und in der psdk steht glaube ich ein beispiel das genau so arbeitet):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; var wDelta: Smallint; begin case (Msg) of WM_MOUSEWHEEL: begin wDelta := HIWORD(wParam); if wDelta > 0 then begin skalar:=skalar - 0.05; if skalar<0.5 then skalar:=0.5; form1.normierung; result:=0; end else begin skalar:=skalar + 0.05; form1.normierung; result:=0; end; end; |
M. Raab - Sa 31.05.03 10:56
Hallo NG,
nö, hilft nicht. Wie schon gesagt: wenn ich bei den Compilerschaltern die Bereichsprüfung ausschalte, kalppt es wieder. Ansonsten kommt sofort eine Meldung: Bereichsprüfung Fehler.
Aber die Lösung war:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; Var wDelta : Longint; begin case (Msg) of WM_MOUSEWHEEL: begin wDelta := wParam; if wDelta > 0 then begin skalar:=skalar - 0.05; // WHEEL_DELTA; if skalar<0.5 then skalar:=0.5; form1.normierung; result:=0; end else begin skalar:=skalar + 0.05; // WHEEL_DELTA; form1.normierung; result:=0; end;
end; |
Es ist offenbar so, dass DELPHI 7 empfindlicher reagiert als DELPHI 5. Dort hat dieser Code nämlich problemlos funktioniert. Mit dem Wechsel auf DELPHI 7 und diesen Compilerschaltern gab es dieses Problem.
Nun ja, es klappt.
Gruss und Vielen Dank
Markus
w3seek - Sa 31.05.03 11:35
kommt die Warnung/Hinweis auch bei wDelta := Longint(wParam);
M. Raab - So 01.06.03 09:52
Hallo,
so funzt es auch:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; begin case (Msg) of WM_MOUSEWHEEL: begin if longint(wParam) > 0 then begin skalar:=skalar - 0.05; if skalar<0.5 then skalar:=0.5; form1.normierung; result:=0; end else begin skalar:=skalar + 0.05; form1.normierung; result:=0; end;
end; |
Also mit LongInt(WParam) klappt das ganze auch - wie schon gesagt. Deaktiviert man die Berechsprüfung im Compiler, scheint es kein Problem zu sein, dass das negativ werden kann. Vielleicht ist das Ganze auch ein Bug von DELPHI 7. :?: :?:
Gruss
Markus
MaxiTB - Mo 02.06.03 10:46
Titel: Kleiner theoretischer Exkurs
Gegeben sei eine nette Standard-WinProc:
Quelltext
1:
| function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; |
Nun weiß man, daß sowohl wParam wie auch lParam vorzeichenlose Zahlen sind.
Nun sehen wir uns das mal an:
Was will uns dieser Code sagen ?
Tja - unter C käme die nette Meldung 'Condition always true' (wenn >= verwendet würde).
Wie kann auch eine vorzeichenlose Zahl jemals negativ werden ? - Also stimmt die Bedingung nur bei 0 nicht ... sozusagen ist das ganze Müll. *g*
Klar werden die einen sagen, vorzeichenlose, vorzeichenbehaftet - 2er Kompliment machts möglich und eigentlich Wurscht.
Das scheint falsch zu sein, sonst würde der D7-Compiler nicht so empfindlich darauf reagieren (sollte man sich den Assembercode mal ansehen, was da intern bei sowas passiert).
Wiefe Leute haben einen type-cast gesetzt - so nach dem Motto:
Quelltext
1:
| if longint(wParam) > 0 then |
Aber ist das so fein ?
Hm - meines Achtens sehr gefährlich die Sache oder besser unhübsch. Ein type-cast kann ebenfalls sehr suspekt sein ... also warum nicht gleich auf die hübsche Weise ...
Quelltext
1:
| if not (wParam and $80000000) then |
Das ist
a) das selbe ...
b) sagt mehr aus (meiner Meinung - wenn das HSB high, dann negativ) ...
c) es ist transparent.
Fazit: Interessantes Thema zum Fachsimplen, besonders da ja sogar der obrige Code Maschinen- und OS-abhängig ist - aber eh, das ist die WinProc von sich aus (man denke nur an die 16Bit/32Bit Umstellung). Also wenn ein 64Bit Windows kommt, dann muß man die Funktion sowieso umstellen (schon alleine wegen der WinProc das Programm mindestens neu programmieren).
M. Raab - Do 05.06.03 11:37
Hallo,
ist wirklich ne akademische Diskussion - aber unsauber programmiert. DELPHI 5 war da tolleranter und hat den Cardinal also anders behandelt: mit nem Vorzeichen. Der Witz war aber, dass der Code bei ausgeschalteter Bereichsprüfung funzt.
Nun ja..... :?: :idea:
Danke an A L L E !!
Gruss
Markus
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!