Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Interessantes Problem mit Scroll und Sendmessage (https://www.delphipraxis.net/150563-interessantes-problem-mit-scroll-und-sendmessage.html)

Shark99 20. Apr 2010 23:19


Interessantes Problem mit Scroll und Sendmessage
 
Es ist eine Form mit 2 Memo Komponenten, beide haben etwa 50 Zeilen Text im Design time.

Hier erstmals der Code.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Memo2: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  protected
    procedure WndProc(var Msg: TMessage); virtual;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  _OldProc: TWndMethod;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  _OldProc := Memo1.WindowProc;
  Memo1.WindowProc := WndProc;
end;

procedure TForm1.WndProc(var msg: TMessage);
begin
  case msg.Msg of
    WM_VSCROLL: SendMessage(Memo2.Handle, WM_VSCROLL,
        TWMVScroll(msg).ScrollCode, TWMVScroll(msg).Pos);
    WM_MOUSEWHEEL:
    begin SendMessage(Memo2.Handle, WM_VSCROLL,
        TWMVScroll(msg).ScrollCode, TWMVScroll(msg).Pos);
         caption := timetostr(now);
    end;
  end;
  _OldProc(msg);
end;

end.
Wenn man mit dem Mausrad im Memo1 Scrollt wird auch Memo2 gescrollt.

Alles funktioniert auf meinem PC, Delphi 5 + Windows 7 x64.

Ich schickte die Exe zu einem Freund (Windows 7 32 bit) und dort funktioniert es nicht und zwar das zweite Memo scrollt immer nach oben, d.h. egal ob ich nach oben oder unten links mit dem Mausrad scrolle, das rechte Memo bewegt sich immer nur nach oben!

Ich machte zwei weitere Tests unter VMWare mit WindowsXP 32bit und Windows7 64bit und in beiden VMs funktioniert es nicht richtig, d.h. das rechte Memo scrollt wieder nur nach oben!

Nach etwas mehr Untersuchung stelle ich fest dass auf meinem PC beim Scrollen mit dem Mausrad im Memo WM_VSCROLL ausgelöst wird, auf dem PC des Freundes und in beiden VMs wird hingegen beim Scrollen mit dem Mausrad WM_MOUSEWHEEL ausgelöst und da geht dann was bei der Übertragung zum zweiten Memo schief.

Hoffe jemand hat eine Vermutung was hier los ist!

Blup 23. Apr 2010 10:40

Re: Interessantes Problem mit Scroll und Sendmessage
 
Du erhältst in msg einen TWMMouseWheel-Record und castest diesen zu einem TWMVScroll-Record.
Die von dir erzeugte Nachricht WM_VSCROLL erhält dadurch unsinnige Parameter.

Delphi-Quellcode:
TWMMouseWheel = packed record
  Msg: Cardinal;
  Keys: SmallInt;
  WheelDelta: SmallInt;
  case Integer of
    0: (XPos: Smallint;
        YPos: Smallint;);
    1: (Pos: TSmallPoint;
        Result: Longint;);
end;

TWMScroll = packed record
  Msg: Cardinal;
  ScrollCode: Smallint;
  Pos: Smallint;
  ScrollBar: HWND;
  Result: Longint;
end;

TWMVScroll = TWMScroll;

Shark99 23. Apr 2010 23:11

Re: Interessantes Problem mit Scroll und Sendmessage
 
Danke!

rollstuhlfahrer 24. Apr 2010 05:39

Re: Interessantes Problem mit Scroll und Sendmessage
 
HI,

ich finde, dass das TWMMouseWheel einen logischen Fehler enthält. Wenn man sich die Struktur einer Nachricht anschaut, sieht man, dass diese immer einen Rückgabewert hat. Außerdem ich der 2. Zweig dann 1,5 mal so groß wie der erste. Meiner Meinung nach müsste es so aussehen: (Weil Pos enthällt ja XPos und YPos).

Delphi-Quellcode:
TWMMouseWheel = packed record
  Msg: Cardinal;
  Keys: SmallInt;
  WheelDelta: SmallInt;

  case Integer of
    0: (XPos: Smallint;
        YPos: Smallint;);
    1: (Pos: TSmallPoint;)

  Result: Longint;
end;
Bernhard

Hawkeye219 24. Apr 2010 10:42

Re: Interessantes Problem mit Scroll und Sendmessage
 
Hallo Bernhard,

die Sprachdefinition lässt es nicht zu, in einem varianten Record weitere Felder nach dem varianten Teil zu definieren. Aus diesem Grund packt man diese Felder üblicherweise in einen Zweig. Voraussetzung ist natürlich, dass die Teile vor den gemeinsamen Feldern in allen Zweigen eine identische Gesamtgröße besitzen, was aber hier der Fall ist:

Code:
SizeOf(Pos) = SizeOf(XPos) + SizeOf(YPos)
Es ist unerheblich, ob die einzelnen Zweige unterschiedliche Gesamtgrößen besitzen. Sie liegen quasi parallel im Speicher:

Code:
Offset 0:     Msg
Offset 4:     Keys
Offset 6:  WheelDelta
Offset 8: XPos | Pos.x
Offset 10: YPos | Pos.y
Offset 12:      | Result
Gruß Hawkeye


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:42 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