Access 2003 VBA Form_Timer wird beim Ziehen mit der Maus nicht ausgelöst

904
user167471

Ich möchte ein wiederholtes 500ms Form_Timer-Ereignis beim Ziehen der Maus abfangen. dh zwischen Mouse Down und Mouse Up Events. Das Timer-Ereignis wird außerhalb des Widerstands ausgelöst, jedoch nicht innerhalb des Widerstands.

Der Grund für das Timer-Ereignis besteht darin, dass das Programm während des Ziehens eine bedeutende Verarbeitung durchführt und die letzte Mausposition häufig nicht erfasst. Nachdem das Timer-Ereignis erfasst wurde, kann das Programm die aktuelle Mausposition abfragen. [Zum Beispiel hat der Benutzer die Maus möglicherweise schnell an eine Position gezogen, die nicht von MouseMove gemeldet wird, und dann den Mauszeiger dort halten.]

Hat jemand anderes dieses Problem gehabt oder gelöst?

Ich habe es unter Windows XP Pro SP3 und Windows 7 Starter erlebt.

2

1 Antwort auf die Frage

1
Horn OK Please

Dies liegt daran, dass alle Ereignisse in der grafischen Benutzeroberfläche in einem einzigen "Event Dispatch Thread" ausgeführt werden, und die durch Ziehen verursachten Mausereignisse dazu führen, dass der Timer in die Warteschlange gestellt wird. Die Ereignisse sind eigentlich Fenstermeldungen, und die Meldungshandler müssen von einem einzigen Thread aus aufgerufen werden. Durch Ziehen mit der Maus bleibt der Ereignis-Thread "beschäftigt", sodass während des Ziehens keine anderen Fensterprozeduren ausgeführt werden können. Dies ist eine der Designeinschränkungen der ursprünglichen ursprünglichen Windows-GUIs, von denen Access 2003 ein solches Programm ist, das es verwendet.

Die Eingabebehandlung und das Threading-Modell wurden in neueren Windows-Versionen und mit anderen Frameworks, z. B. den in Office 2010 verwendeten, verbessert. Sie sind nicht sicher, ob das Problem dadurch gelöst wird, es kann jedoch hilfreich sein, eine neue Office-Version auszuprobieren.

Sie können auch versuchen, eine ausgelastete Schleife auszuführen, in der DoEvents von Zeit zu Zeit aufgerufen wird, um die Fenstermeldungen zu verarbeiten. Verwenden Sie einfach sleeps, um die 500-ms-Interrupts festzulegen, anstatt dass das System alle 500 ms Ihr Ereignis aufruft.

DoEvents werden funktionieren, aber es gibt einen Kompromiss: Schleifen ohne Schleifen werden um eine Größenordnung schneller ausgeführt. Wenn Sie lediglich Benutzerinformationen bereitstellen (z. B. eine Fortschrittsleiste), ist DoEvents bei jeder 10. Iteration (usw.) die bessere Wahl. horatio vor 11 Jahren 1