einen wunderschönen Guten Abend!
Kann mir jemand einen Tipp geben, wie ich ermitteln kann,
wie weit ein Formular - oder genauer der Detailbereich -
gescrollt vorliegt, wenn keine Scrollbars vorhanden sind,
aus denen ich diese Info auslesen kann?
Ich meine zB die Situation, wenn das Formular relativ
stark verkleinert (wiederhergestellt) wurde, ein
weiter unten liegendes Steuerelement den Fokus hat und
somit der tatsächliche Ursprung des Detailbereichs
nicht mehr sichtbar ist.
Vielen Dank und viele Grüße
Jörg Ostendorp
Jörg Ostendorp wrote in news:%23fz4Cnc...@tk2msftngp13.phx.gbl:
> Kann mir jemand einen Tipp geben, wie ich ermitteln kann,
> wie weit ein Formular - oder genauer der Detailbereich -
> gescrollt vorliegt, wenn keine Scrollbars vorhanden sind,
> aus denen ich diese Info auslesen kann?
> Ich meine zB die Situation, wenn das Formular relativ
> stark verkleinert (wiederhergestellt) wurde, ein
> weiter unten liegendes Steuerelement den Fokus hat und
> somit der tatsächliche Ursprung des Detailbereichs
> nicht mehr sichtbar ist.
IMO gibt es keine Möglichkeit, herauszufinden, was auf dem sichtbaren
Bereich eines verkleinerten Formulars drauf ist. Wenn Du aber einem
Control den Focus gibt, sollte der sichtbare Bereich jedoch so
verschoben werden, dass dieses sichtbar wird.
Du kannst Dir dies zu Nutzen machen, indem Du nach dem Restore des Forms
folgenden Code ausführst:
On Error Resume Next
Forms("DeinFormular").Controls(Screen.ActiveControl.Name).SetFocus
Du kannst diesen Code auch beim Form_Activate Ereignis reinmachen. Das
Minimieren und anschliessende Restaurieren des Forms löst dieses
Ereignis jedoch nicht aus. Dieses wird nur ausgelöst, wenn das Formular
den Focus abgegeben hat.
Hoffe, dass das wenigstens ein bisschen weiterhilft, wenn ich schon die
eigentliche Frage negativ beantworten musste.
Gruss
Henry
--
Keine E-Mails auf Postings in NGs senden!
Don't send e-mails to postings in newsgroups!
KB: http://support.microsoft.com/default.aspx
FAQ: http://www.donkarl.com/FAQ/FAQStart.htm
OH: Online Hilfe von Microsoft Access (Taste F1)
Downloads: http://www.dbdev.org
>> Kann mir jemand einen Tipp geben, wie ich ermitteln kann,
>> wie weit ein Formular - oder genauer der Detailbereich -
>> gescrollt vorliegt, wenn keine Scrollbars vorhanden sind,
>> aus denen ich diese Info auslesen kann?
>> Ich meine zB die Situation, wenn das Formular relativ
>> stark verkleinert (wiederhergestellt) wurde, ein
>> weiter unten liegendes Steuerelement den Fokus hat und
>> somit der tatsächliche Ursprung des Detailbereichs
>> nicht mehr sichtbar ist.
> IMO gibt es keine Möglichkeit, herauszufinden, was auf dem sichtbaren
> Bereich eines verkleinerten Formulars drauf ist. Wenn Du aber einem
> Control den Focus gibt, sollte der sichtbare Bereich jedoch so
> verschoben werden, dass dieses sichtbar wird.
Leider gehts bei meinem Problem wirklich nur darum, die
genaue Scrollposition festzustellen, nicht darum, auf ein Control zu
fokussieren.
Zur Erklärung: Ich möchte die relative Mausposition zum Detailbereich
ermitteln, unabhängig vom Mousemove der Steuerelemente oder des
Formulares. Das ist eigentlich ja auch kein Problem, wird aber einfach
unverhältnismäßig aufwendig, wenn das Formular bzw der Detailbereich
gescrollt vorliegt. Eine Möglichkeit, die aktuelle Scrollposition direkt
auszulesen wäre daher ziemlich ideal gewesen.
<Schneuz>.
Trotzdem vielen Dank!
Viele Grüße
Jörg Ostendorp
Jörg Ostendorp wrote in news:OffSS2lF...@TK2MSFTNGP12.phx.gbl:
> Zur Erklärung: Ich möchte die relative Mausposition zum Detailbereich
> ermitteln, unabhängig vom Mousemove der Steuerelemente oder des
> Formulares. Das ist eigentlich ja auch kein Problem, wird aber einfach
> unverhältnismäßig aufwendig, wenn das Formular bzw der Detailbereich
> gescrollt vorliegt. Eine Möglichkeit, die aktuelle Scrollposition
> direkt auszulesen wäre daher ziemlich ideal gewesen.
> <Schneuz>.
Mit Access Boardmitteln geht das nicht, vielleicht mit einem API
Gehangel, aber das entzieht sich für diesen Fall meiner Kenntnis. Sorry.
Vielleicht findest Du was wenn Du in der englischen FormsCoding NG
googelst?
Paul Rohorzka wrote in news:wovac.313844$Or1....@news.chello.at:
> Schau bei Stephen Lebans www.lebans.com .
> Der kann das.
Das ist aber für Endlosformulare und gibt nicht wieder, wie weit der
einzelne Detailbereich sichtbar ist oder nicht. Der Scrollbar gibt doch
die Recordnummer des obersten Records zurück, der in der
Endlosdarstellung angezeigt ist. Oder habe ich da was falsch verstanden?
Ich hab's mir jetzt zwar nicht noch einmal angesehen,
aber soweit ich mich erinnern kann, hast du recht, dass
in einem Endlosformular die Datensatz-Nummer zurück-
gegeben wird. Wenn es sich tatsächlich um ein Einzel-
formular handelt, was ich dem Ursprungsposting aller-
dings nicht entnehmen kann, sind für die Bildlaufleiste
sicher andere Min/Max-Werte verwendet. Das ist aber
wohl nicht das Problem, sondern eher, wie man an die
aktuelle Position des Schiebers kommt. Das kann Jörg
aus Stephens Beispiel auf jeden Fall übernehmen.
Mit den Min/Max-Werten und der Position des Schiebers
sowie der Höhe der Formularbereiche und der InsideHeight
des Formulars sollte sich der sichtbare Ausschnitt mit
ein bissl kx+d et al berechnen lassen. Bei Interesse
an der horizontalen Bildlaufleiste entsprechend einfacher.
LG,
Paul
>>> [Scrollposition des Detailbereichs bei fehlenden Scrollbars ermitteln]
Paul Rohorzka schrieb:
> > Schau bei Stephen Lebans www.lebans.com .
> > Der kann das.
Henry Habermacher [MVP Access] schrieb,
> Das ist aber für Endlosformulare und gibt nicht wieder, wie weit der
> einzelne Detailbereich sichtbar ist oder nicht. Der Scrollbar gibt doch
> die Recordnummer des obersten Records zurück, der in der
> Endlosdarstellung angezeigt ist. Oder habe ich da was falsch verstanden?
Nein, Du irrst nicht, der Stephen kann das auch nicht (oder vorsichtshalber:
hat kein Bsp auf seiner Homepage, man weiß bei dem Kerl ja nie ..)
Ich habe mittlerweile fleißig weiter probiert und gesucht aber nüscht
gefunden, auch nicht in den anderen NGs (mp.vbwinapi & Co). Entweder muß es
eine so popelige Api-Funktion geben, daß niemand sie für wichtig genug hält,
um sie ins Netz zu Stellen, oder das posthum-Auslesen geht einfach wirklich nicht.
Daher gibts imho zwei Möglichkeiten:
1. Detailbereich hooken und Scroll-Message abfangen bzw auslesen
Das wäre sicherlich die korrekte Variante, hab ich aber noch nicht
ausprobiert
2. Bei nicht sichtbaren Scrollbars: wenn RECT < Width bzw Height
den Detailbereich einfach per SendMessage auf X=0/Y=0 zurückscrollen lassen bzw.
bei sichtbaren Scrollbars: Infos aus GetScrollInfo holen.
Das funktioniert soweit, ist aber ekelig, weil man dann erst wieder
prüfen muß wieviele ScrollBars angeschaltet sind (Me.ScrollBar), denn
dementsprechend ändert sich auch die Reihenfolge in der die ScrollBars
als ChildWindow ins Formular gesetzt werden bzw die Reihenfolge in der
die Handles vergeben werden (wenn ich das richtig getestet habe werden
zwar immer beide Scrollbars gezeichnet nur die sichtbare bekommt aber auch
ein Handle verpasst). Und da die ScrollBars SB_CTLs des Formulares
sind und keine SB-VERT/SB_HORZ des Detailbereichs, brauchts deren Handles
fürs GetScrollInfo. Sehr Unschön.
Viele Grüße
Jörg Ostendorp
>> [...]
> [...]
> Wenn es sich tatsächlich um ein Einzel-
> formular handelt, was ich dem Ursprungsposting aller-
> dings nicht entnehmen kann, sind für die Bildlaufleiste
> sicher andere Min/Max-Werte verwendet.
Nochmal die Situation:
Es geht um ein Einzel-Formular. Dieses Formular
hat *keine* ScrollBars. Der sichtbare Ausschnitt des Detailbereichs ist
kleiner als der tatsächliche Detailbereich. Ein Steuerelement weit unten
hat den Fokus, so daß der eigentliche Ursprung 0/0 des Detailbereichs
nicht mehr sichtbar ist .
Es handelt sich hierbei also um eine "Ausnahmesituation", die
aber eben auch mal vorkommen kann und berücksichtigt werden soll
um korrekte Cursor-Koordinaten zu erhalten.
> Das ist aber wohl nicht das Problem, sondern eher, wie man an die
> aktuelle Position des Schiebers kommt. Das kann Jörg
> aus Stephens Beispiel auf jeden Fall übernehmen.
Naa, die Position des Schiebers zu ermitteln ist einfach. Voraussetzung
dafür ist aber, daß man überhaupt Bildlaufleisten hat
> Mit den Min/Max-Werten und der Position des Schiebers
> sowie der Höhe der Formularbereiche und der InsideHeight
> des Formulars sollte sich der sichtbare Ausschnitt mit
> ein bissl kx+d et al berechnen lassen.
Obacht, es geht um den Detailbereich, nicht ums Formular :-)
Das kann ja auch mal einen Formularkopf enthalten. InsideHeight & Co
geben letztlich nur den ClientRect des *Formulares* wieder...
Aber Du hast im Prinzip schon Recht: Wenn ScrollBars da sind
kann man aus ihnen alle benötigten Infos ziehen.
Viele Grüße
Jörg Ostendorp
Sorry, das hatte ich überlesen. Damit erübrigen sich
meine Antworten natürlich. :-/
> Der sichtbare Ausschnitt des Detailbereichs ist
> kleiner als der tatsächliche Detailbereich. Ein Steuerelement weit unten
> hat den Fokus, so daß der eigentliche Ursprung 0/0 des Detailbereichs
> nicht mehr sichtbar ist .
> Es handelt sich hierbei also um eine "Ausnahmesituation", die
> aber eben auch mal vorkommen kann und berücksichtigt werden soll
> um korrekte Cursor-Koordinaten zu erhalten.
Hmmm. Ratlos.
>>Das ist aber wohl nicht das Problem, sondern eher, wie man an die
>>aktuelle Position des Schiebers kommt. Das kann Jörg
>>aus Stephens Beispiel auf jeden Fall übernehmen.
>
>
> Naa, die Position des Schiebers zu ermitteln ist einfach. Voraussetzung
> dafür ist aber, daß man überhaupt Bildlaufleisten hat
Klar. :-)
>>Mit den Min/Max-Werten und der Position des Schiebers
>>sowie der Höhe der Formularbereiche und der InsideHeight
>>des Formulars sollte sich der sichtbare Ausschnitt mit
>>ein bissl kx+d et al berechnen lassen.
>
> Obacht, es geht um den Detailbereich, nicht ums Formular :-)
> Das kann ja auch mal einen Formularkopf enthalten.
Aus diesem Grund hatte ich ja "Formularbereichen" geschrieben.
> InsideHeight & Co
> geben letztlich nur den ClientRect des *Formulares* wieder...
> Aber Du hast im Prinzip schon Recht: Wenn ScrollBars da sind
> kann man aus ihnen alle benötigten Infos ziehen.
Würde mich interessieren, wenn du weiter gekommen bist.
LG,
Paul
> Es geht um ein Einzel-Formular. Dieses Formular hat *keine*
> ScrollBars. Der sichtbare Ausschnitt des Detailbereichs ist
> kleiner als der tatsächliche Detailbereich. Ein Steuerelement
> weit unten hat den Fokus, so daß der eigentliche Ursprung 0/0
> des Detailbereichs nicht mehr sichtbar ist .
> Es handelt sich hierbei also um eine "Ausnahmesituation", die
> aber eben auch mal vorkommen kann und berücksichtigt werden soll
> um korrekte Cursor-Koordinaten zu erhalten.
Mit der Höhe des Kopfbereichs, der Höhe des Fußbereichs, der Höhe des
Fensters das das Formular enthält (InsideHeight) und Oben und Höhe
des Steuerelements das den Fokus (Application.Screen.ActiveControl)
hat, mit dem allem zusammengenommen, müsstest du eigentlich so
ungefähr hinkommen, oder? Aufs Twip genau würde ich mich nicht
darauf verlassen wollen, aber auf Plus/Minus 5 Twips genau könnte
es schon das sein was du möchtest.
Salü,
Sven
--
Im Übrigen bin ich der Meinung, dass die Groß-/Kleinschreibung
abzuschaffen ist.
>>[...]
> > Es handelt sich hierbei also um eine "Ausnahmesituation", die
> > aber eben auch mal vorkommen kann und berücksichtigt werden soll
> > um korrekte Cursor-Koordinaten zu erhalten.
>
> Hmmm. Ratlos.
Das beruhigt mich :-)
>> [..]
> > Naa, die Position des Schiebers zu ermitteln ist einfach. Voraussetzung
> > dafür ist aber, daß man überhaupt Bildlaufleisten hat
>
> Klar. :-)
Hab ich didaktisch gut erklärt, nicht?
> > Obacht, es geht um den Detailbereich, nicht ums Formular :-)
> > Das kann ja auch mal einen Formularkopf enthalten.
>
> Aus diesem Grund hatte ich ja "Formularbereichen" geschrieben.
Immer dieses Kleingedruckte..
> > Aber Du hast im Prinzip schon Recht: Wenn ScrollBars da sind
> > kann man aus ihnen alle benötigten Infos ziehen.
>
> Würde mich interessieren, wenn du weiter gekommen bist.
Ich bastle gerade noch am hooken, irgendwie kriege ich die ScrollMessage
aber nicht rein. Lösung kommt (hoffentlich) heute Abend. Muß mir jetzt
erstmal Schokolade kaufen gehen....
Viele Grüße
Jörg Ostendorp
>> Es geht um ein Einzel-Formular. Dieses Formular hat *keine*
>> ScrollBars. Der sichtbare Ausschnitt des Detailbereichs ist
>> kleiner als der tatsächliche Detailbereich. Ein Steuerelement
>> weit unten hat den Fokus, so daß der eigentliche Ursprung 0/0
>> des Detailbereichs nicht mehr sichtbar ist .
>> Es handelt sich hierbei also um eine "Ausnahmesituation", die
>> aber eben auch mal vorkommen kann und berücksichtigt werden soll
>> um korrekte Cursor-Koordinaten zu erhalten.
> Mit der Höhe des Kopfbereichs, der Höhe des Fußbereichs, der Höhe des
> Fensters das das Formular enthält (InsideHeight) und Oben und Höhe
> des Steuerelements das den Fokus (Application.Screen.ActiveControl)
> hat, mit dem allem zusammengenommen, müsstest du eigentlich so
> ungefähr hinkommen, oder? Aufs Twip genau würde ich mich nicht
> darauf verlassen wollen, aber auf Plus/Minus 5 Twips genau könnte
> es schon das sein was du möchtest.
Ich glaube, so wie Du Dir das vorstellst klappt das eher auch nicht, oder
wie meinst Du das genau? Kopf- und Fußbereich sind imho ebenso unwichtig
wie das InsideHeight des Formulares ;-)
Bei "Oben" des Steuerelementes wird es aber schon interessanter.
Wenn man das WindowRect der Steuerelemente ermitteln könnte wär es
eigentlich ganz einfach: (Einheiten mal vernachlässigt)
Detailbereich-Ursprung-X = Abstand Steuerelement linker
Bildschirmrand - Steuerelement.Left
Detailbereich-Ursprung-Y = Abstand Steuerelement oberer
Bildschirmrand - Steuerelement.Top
Und auf diesen Punkt X/Y müßte sich dann halt der relative Cursor
beziehen.
Der Haken: Einige Steuerelemente, darunter auch Commandbuttons, scheinen
gar keine hwnd spendiert zu bekommen, mit der man die Bildschirmposition
ermitteln könnte, auch nicht wenn ich den Fokus nochmal extra draufsetze.
Beim Versuch das hwnd über Api GetFocus zu ermitteln
( http://www.mvps.org/access/api/api0027.htm ) kriege
ich jedenfalls nur das Formular zurück nicht die CommandButtons
(bei ActiveX-Zeugs klappts hingegen).
Viele Grüße
Jörg Ostendorp
> Ich bastle gerade noch am hooken, irgendwie kriege ich die ScrollMessage
> aber nicht rein.
Ich gebs auf, das mit dem hooken will einfach nicht. :-(
Ich dachte, es würde in jedem Fall eine WM_VSCROLL/WM_HSCROLL
verschickt werden, wenn der sichtbare Teil des Detailbereichs
verschoben wird. Pustekuchen, 'ne ScrollMessages gibts nur
wenn auch ScrollBars vorhanden sind.
Und aus den anderen Msgs werde ich einfach nicht schlau:
Ich habe mal ausprobiert was passiert, wenn ich zwei
Commandbuttons an weit entfernte Stellen in
den Detailbereich setze und mich dann per Pfeiltasten
oder Tabulator von einem zum anderen bewege, so daß das
Formular gescrollt wird (wie gesagt Scrollbars sind nicht
vorhanden). Dabei werden folgende Msgs gefeuert (teilweise
mehrfach):
Für das Formular:
WM_KEYDOWN
Parameter: wparam/lparam für die gedrückte Taste
WM_KILLFOCUS
hwnd receiving focus
WM_SETFOCUS
hwnd losing focus
WM_PAINT
wparam 0x00000000 lparam 0x00000000
WM_ERASEBKGND
hdc-nummer
WM_KILLFOCUS
WM_SETFOCUS
WM_USER + 511 (0x000005ff)
wparam lparam (unterschiedlich)
WM_KEYUP
wieder param Taste
[..]
Für den Detailbereich (Parameter wie oben):
WM_SETFOCUS
WM_KILLFOCUS
WM_PAINT (auch 0)
WM_ERASEBKGGND
WM_SETFOCUS
WM_KILLFOCUS
Applikationsfenster:
gar nichts
Datenbankfenster:
WM_GETACTIVE
und diverse WM_USER
Wie Access sich daraus die Scroll-Position
bzw den neu zu zeichnenden Bereich ableitet
ist mir schleierhaft.
Bleibt wohl nur Variante 2:
wenn Scrollbars vorhanden sind notwendige Infos
per GetScrollInfo holen und wenn keine (oder nur eine)
vorhanden sind eben per SendMessage auf 0/0 bzw 0/Y
oder x/0 zurückscrollen.
Viele Grüße
Jörg Ostendorp
Nun ja, ich schätze einmal, dass hier die interessierende
Information versteckt ist. Hast du schon einmal versucht,
diese Daten zu interpretieren? Vielleicht den Detailbereich
einmal gerade so groß machen, dass er ein Pixelchen zu
groß ist und schauen, was die beiden Parameter sagen. Dann
könntest du versuchen, mehr Pixel zu nehmen, um zu sehen,
was sich ändert. Hast du dann eine Vorstellung, wie die
Daten zu interpretieren sind, dann kannst du versuchen,
die User-Messages selbst zu schicken um zu sehen, ob der
Detailbereich reagiert.
Aaaaber: ich beneide dich nicht um diese Tüftlerei. :-/
> WM_KEYUP
> wieder param Taste
> [..]
>
> Für den Detailbereich (Parameter wie oben):
> WM_SETFOCUS
> WM_KILLFOCUS
> WM_PAINT (auch 0)
> WM_ERASEBKGGND
> WM_SETFOCUS
> WM_KILLFOCUS
>
> Applikationsfenster:
> gar nichts
>
> Datenbankfenster:
> WM_GETACTIVE
> und diverse WM_USER
>
>
> Wie Access sich daraus die Scroll-Position
> bzw den neu zu zeichnenden Bereich ableitet
> ist mir schleierhaft.
>
> Bleibt wohl nur Variante 2:
> wenn Scrollbars vorhanden sind notwendige Infos
> per GetScrollInfo holen und wenn keine (oder nur eine)
> vorhanden sind eben per SendMessage auf 0/0 bzw 0/Y
> oder x/0 zurückscrollen.
Hm? Wie? Das habe ich nicht verstanden?
Auf jeden Fall danke für die Infos, Jörg!
Falls du noch Nerven hast, hier weiterzuforschen,
wäre ich immer noch an den Erkenntnissen interessiert.
LG,
Paul
noch ein kleiner Gedanke zum Problem.
Wenn ich mir vorstelle, dass Access bekanntlich seine
Steuerelemente selbst zeichnet und keine Windows dafür
verwendet, könnte man doch daraus schließen, dass
Access für jedes Window, das einen Formularbereich
aufnimmt, in einer internen Datenstruktur den
jeweiligen virtuellen Ursprung speichert und daraus
beim WM_PAINT die Positionen der Steuerelemente ab-
leitet.
Die ganze Scrollerei ohne Scrollbalken wird wahr-
scheinlich nur intern von Access selbst gehandelt,
und daher nicht zugänglich sein, da dafür eher
keine Windows-Messages verwendet werden.
Vielleicht liege ich aber falsch und die Parameter
der WM_USER-Messages des Detailbereichs-Windows
können Auskunft geben.
LG,
Paul
> Detailbereich-Ursprung-X = Abstand Steuerelement linker
> Bildschirmrand - Steuerelement.Left
> Detailbereich-Ursprung-Y = Abstand Steuerelement oberer
> Bildschirmrand - Steuerelement.Top
>
> Und auf diesen Punkt X/Y müßte sich dann halt der relative Cursor
> beziehen.
Nun, es gilt ja:
Höhe_sichtbarer_Ausschnitt = InsideHeight - Höhe_Kopfbereich
- Höhe_Fußbereich
Wenn nun zu einem Steuerelement außerhalb des momentan sichtbaren
Ausschnitts des Detailbereichs gesprungen wird, dann wird
gescrollt.
Das könnte man ja prüfen, ob aufgrund von Detailbereich_Ursprung_Y,
Höhe_sichtbarer_Ausschnitt, Oben_Steuerelement und Höhe_Steuerelement
das gerade zum aktiven Steuerelement gewordene Steuerelement ein
Scrollen hätte bewirken müssen oder nicht. Wenn ja, dann muss
Detailbereich_Ursprung_Y zu
Detailbereich_Ursprung_Y = Höhe_Detailbereich - (Oben_Steuerelement
+ Höhe_Steuerelement)
- Höhe_sichtbarer_Ausschnitt
neu ermittelt werden, wenn nicht dann darf das nicht gemacht werden.
Das gleiche gilt analog für Detailbereich_Ursprung_X. Dabei dann
viel Vergnügen.
> Die ganze Scrollerei ohne Scrollbalken wird wahr-
> scheinlich nur intern von Access selbst gehandelt,
> und daher nicht zugänglich sein, da dafür eher
> keine Windows-Messages verwendet werden.
Servus
Sicher hat Access solche Routinen. Wahrscheinlich ist deshalb
auch die Anzahl der Elemente je Formular limitiert.
Soweit ich mich erinnern kann mußte zumindest früher jede
Anwendung auf das Repaint Ereignis selbst reagieren.
Das GUI stellt dabei nur die Koordinaten des Innenteils des
eigenen Fensters zur Verfügung. Ob es Bereiche aus einem
'privatem' Cache einblendet, verschiebt oder neu zeichnet, muß
die Anwendung (in diesem Fall Access/Jet) selbst entscheiden
und ausführen.
mfg Ka Prucha
>> [..]
> > Wie Access sich daraus die Scroll-Position
> > bzw den neu zu zeichnenden Bereich ableitet
> > ist mir schleierhaft.
> >
> > Bleibt wohl nur Variante 2:
> > wenn Scrollbars vorhanden sind notwendige Infos
> > per GetScrollInfo holen und wenn keine (oder nur eine)
> > vorhanden sind eben per SendMessage auf 0/0 bzw 0/Y
> > oder x/0 zurückscrollen.
>
> Hm? Wie? Das habe ich nicht verstanden?
Na dann nochmal für die ganz langsamen zum mitschreiben ;-)
Was ich meine ist folgendes (mal +- unkommentiert und ohne
Fehlerbehandlung):
-(Ich hoffe, die Formatierung haut so einigermaßen hin)
-(den unschönen Timer, sollte man noch durch ein Public
-Event ersetzen, irgendwas wie ScreenMouseMove o.ä.)
-(Bei Bugs bitte melden)
' ****************************** <CODE> *********************************
' (Code ins Formular)
Option Compare Database
Option Explicit
'Typen
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Type RECT
left As Long
top As Long
right As Long
bottom As Long
End Type
Private Type SCROLLINFO
cbSize As Long
fMask As Long
nMin As Long
nMax As Long
nPage As Long
nPos As Long
nTrackPos As Long
End Type
'Konstanten
'GetWindow
Private Const GW_CHILD = 5
Private Const GW_HWNDNEXT = 2
'WindowMessage
Private Const WM_HSCROLL As Long = &H114
Private Const WM_VSCROLL As Long = &H115
'ScrollBar
Private Const SB_PAGELEFT As Long = 2
Private Const SB_PAGEUP As Long = 2
Private Const SB_CTL As Long = 2
'ScrollInfo
Private Const SIF_RANGE = &H1
Private Const SIF_PAGE = &H2
Private Const SIF_POS = &H4
Private Const SIF_DISABLENOSCROLL = &H8
Private Const SIF_ALL = SIF_RANGE Or SIF_PAGE Or SIF_POS
'Eigene Variablen
Private P As POINTAPI
Private R As RECT
Private ScrI As SCROLLINFO
'APIS
Private Declare Function GetWindowRect Lib "user32.dll" _
(ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function GetWindow Lib "user32" _
(ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Function GetClassName Lib "user32" _
Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" ( _
ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function GetScrollInfo Lib "user32.dll" (ByVal hwnd As Long, _
ByVal n As Long, lpScrollInfo As SCROLLINFO) As Long
'Prozeduren
Private Sub Detailbereich_MouseMove(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
Me!lblDetailCursorX.Caption = X
Me!lblDetailCursorY.Caption = Y
End Sub
Private Sub Form_Timer()
'(Besser Timer durch Public Event ScreenMouseMove ersetzen o.ä.)
'Mach was mit der *GetDetailCursorPosition*, zB:
'
GetCursorPos P
Me!lblScrollBars.Caption = Switch(Me.ScrollBars = 0, "Keine", Me.ScrollBars = 1, _
"Horizontal", Me.ScrollBars = 2, "Vertikal", Me.ScrollBars =
3, _
"Beide")
Me!lblAbsScreenCursorX.Caption = P.X
Me!lblAbsScreenCursorY.Caption = P.Y
Me!lblRelScreenCursorX.Caption = GetDetailCursorPosition.X
Me!lblRelScreenCursorY.Caption = GetDetailCursorPosition.Y
Me!lblHScrollPos.Caption = GetHScrollposition.nPos * 15
Me!lblVScrollPos.Caption = GetVScrollposition.nPos * 15
End Sub
Private Function FindDetailWindow(ByVal frmhwnd As Long) As Long
'Funktion von Stephen Lebans(?)
'Ermittel das Handle des Detailereichs
Dim Dhwnd As Long
Dim hwnd As Long
Dim ctr As Long
Dim counter As Long
counter = 2 ' Der Detailbereich ist IMMER das zweite "OFormSub"-ChildWindow
'des Formulares
ctr = 0
hwnd = frmhwnd
Dhwnd = GetWindow(hwnd, GW_CHILD)
Do
If fGetClassName(Dhwnd) = "OFormSub" Then
ctr = ctr + 1
If ctr = counter Then
FindDetailWindow = Dhwnd
Exit Function
End If
End If
Dhwnd = GetWindow(Dhwnd, GW_HWNDNEXT)
Loop While Dhwnd <> 0
FindDetailWindow = 0
End Function
Private Function FindHScrollbar(ByVal frmhwnd As Long) As Long
'Ermittelt das Handle der horizontalen ScrollBar
Dim Dhwnd As Long
Dim hwnd As Long
Dim ctr As Long
Dim counter As Long ' Reihenfolge der Scrollbar
'ist unterschiedlich je nachdem welche Scrollbars "an" sind
'Die Horizontale ist aber immer an erster Stelle, also
counter = 1
ctr = 0
hwnd = frmhwnd
Dhwnd = GetWindow(hwnd, GW_CHILD)
Do
If fGetClassName(Dhwnd) = "ScrollBar" Then
ctr = ctr + 1
If ctr = counter Then
FindHScrollbar = Dhwnd
Exit Function
End If
End If
Dhwnd = GetWindow(Dhwnd, GW_HWNDNEXT)
Loop While Dhwnd <> 0
FindHScrollbar = 0
End Function
Private Function FindVScrollbar(ByVal frmhwnd As Long) As Long
'Ermittelt das Handle der vertikalen ScrollBar
Dim Dhwnd As Long
Dim hwnd As Long
Dim ctr As Long
Dim counter As Long ' Reihenfolge der Scrollbar
'ist unterschiedlich je nachdem welche Scrollbars "an" sind
'Die vertikale kann an Stelle 1 oder 2 stehen, alse
Select Case Me.ScrollBars
Case 2
counter = 1
Case 3
counter = 2
Case Else
FindVScrollbar = 0 ' keine veretikale Scrollbar
Exit Function
End Select
ctr = 0
hwnd = frmhwnd
Dhwnd = GetWindow(hwnd, GW_CHILD)
Do
If fGetClassName(Dhwnd) = "ScrollBar" Then
ctr = ctr + 1
If ctr = counter Then
FindVScrollbar = Dhwnd
Exit Function
End If
End If
Dhwnd = GetWindow(Dhwnd, GW_HWNDNEXT)
Loop While Dhwnd <> 0
FindVScrollbar = 0
End Function
Private Function fGetClassName(hwnd As Long)
'Übersetzt die Klasse in eine verständliche Sprache :-)
Dim strBuffer As String
Dim lngLen As Long
Const MAX_LEN = 255
strBuffer = Space$(MAX_LEN)
lngLen = GetClassName(hwnd, strBuffer, MAX_LEN)
If lngLen > 0 Then fGetClassName = left$(strBuffer, lngLen)
End Function
Private Function GetHScrollposition() As SCROLLINFO
'Ermittelt alle Infos zur horizontalen
'Scrollbar. Ok, ein GetScrollPos-Api hätte es auch getan,
'aber dafür heißt diese Funkion jetzt so
Dim Dhwnd As Long
Dhwnd = FindHScrollbar(Me.hwnd)
With ScrI
.cbSize = LenB(ScrI)
.fMask = SIF_ALL
End With
GetScrollInfo Dhwnd, SB_CTL, ScrI
GetHScrollposition = ScrI
End Function
Private Function GetVScrollposition() As SCROLLINFO
'Ermittelt entsprechend die Infos zur vertikalen Scrollbar
Dim Dhwnd As Long
Dhwnd = FindVScrollbar(Me.hwnd)
With ScrI
.cbSize = LenB(ScrI)
.fMask = SIF_ALL
End With
GetScrollInfo Dhwnd, SB_CTL, ScrI
GetVScrollposition = ScrI
End Function
Private Function GetDetailCursorPosition() As POINTAPI ' in Twips
'Ermittelt nun endlich den relativen Cursor, je nachdem
'welche Scrollbar aktiviert ist
GetCursorPos P
GetWindowRect FindDetailWindow(Me.hwnd), R
'Anmerkung: *15 Umrechung in Twips (geht auch eleganter..), +15 weil
'der Detailbereich hier offenbar 1 Pixel-Offset hat)
Select Case Me.ScrollBars
Case 0
ScrollHome ' wenn keine Scrollbar zurückscrollen
GetDetailCursorPosition.X = (P.X - R.left) * 15 + 15
GetDetailCursorPosition.Y = (P.Y - R.top) * 15 + 15
Case 1
ScrollYHome 'wenn keine vertikale SB vertikal zurücksrollen
GetDetailCursorPosition.X = (P.X - R.left + GetHScrollposition.nPos) * 15 + 15
GetDetailCursorPosition.Y = (P.Y - R.top) * 15 + 15
Case 2
ScrollXHome 'wenn keine horizontale SB horizontal zurückscrollen
GetDetailCursorPosition.X = (P.X - R.left) * 15 + 15
GetDetailCursorPosition.Y = (P.Y - R.top + GetVScrollposition.nPos) * 15 + 15
Case 3
GetDetailCursorPosition.X = (P.X - R.left + GetHScrollposition.nPos) * 15 + 15
GetDetailCursorPosition.Y = (P.Y - R.top + GetVScrollposition.nPos) * 15 + 15
End Select
End Function
'Rückscroll-Funktionen
'For..next, weils 10fach einfach besser hält
'kann bei stark verkleinertem Fenster sonst schon mal
'Probleme machen
Private Function ScrollXHome()
Dim i As Integer
For i = 1 To 10
SendMessage Me.hwnd, WM_HSCROLL, SB_PAGELEFT, 0&
Next i
End Function
Private Function ScrollYHome()
Dim i As Integer
For i = 1 To 10
SendMessage Me.hwnd, WM_VSCROLL, SB_PAGEUP, 0&
Next i
End Function
Private Function ScrollHome()
Dim i As Integer
For i = 1 To 10
SendMessage Me.hwnd, WM_VSCROLL, SB_PAGEUP, 0&
SendMessage Me.hwnd, WM_HSCROLL, SB_PAGELEFT, 0&
Next i
End Function
'*********************************</Code>********************************
Bei mir funktioniert das so. Allerdings finde ich die
Lösung mit dem Zurücksrollen suboptimal. Daher ja
meine ursprüngliche Frage, ob es nicht eine Möglichkeit gibt
Scrollinfos auszulesen, wenn es keine ScrollBars gibt....
Viele Grüße
Jörg Ostendorp
> [..]
> Das gleiche gilt analog für Detailbereich_Ursprung_X. Dabei dann
> viel Vergnügen.
Danke ;-)
Ja, aber wenn ich das Access-Fenster verschiebe, wär alles für die Katz...
Ums nochmal deutlich zu machen: Mein ursprüngliches Problem war es
ja nicht einen relativen Cursor zu ermitteln, sondern eine einfachere bzw
elegantere Möglichkeit zu finden, als die die ich jetzt habe (schau mal ins Postign von
mir an Paul). Das wäre imho (nur) dann gegangen, wenn es eine Api-Funktion
gegeben hätte, mit der ich gleichzeitig die Rects des sichtbaren Teils
eines Fensters und des vollständigen Fenster hätte auslesen können.
Viele Grüße
Jörg Ostendorp
sorry, da hab ich wohl vergessen vor die
Me!lbl....Caption... noch nen Fliegendreck hinzusetzen
Aber ich hoffe, das ist selbsterklärend .. :-()
Viele Grüße
Jörg Ostendorp
Danke für den Code. Da wir dieses WoE (beginnend mit
heute) unsere Wohnung neu ausmalen, komme ich aber
wohl erst in ein paar Tagen dazu, mir das genauer
anzusehen. Danke aber vorerst. :-)
LG,
Paul
>>Die ganze Scrollerei ohne Scrollbalken wird wahr-
>>scheinlich nur intern von Access selbst gehandelt,
>>und daher nicht zugänglich sein, da dafür eher
>>keine Windows-Messages verwendet werden.
>
>
> Servus
>
> Sicher hat Access solche Routinen. Wahrscheinlich ist deshalb
> auch die Anzahl der Elemente je Formular limitiert.
> Soweit ich mich erinnern kann mußte zumindest früher jede
> Anwendung auf das Repaint Ereignis selbst reagieren.
Das ist auch heute noch so, dass jedes Fenster auf
WM_PAINT reagieren muss. Da gibt es IMHO eine Ausnahme:
Man kann beim Registrieren der Fensterklasse einen
Stil angeben, damit Windows das Bitmap des Client-Bereichs
selbstständig puffert und ggflls. wiederherstellt. Ist
aber aus Gründen der Systemressourcen nicht wirklich
besonders sinnvoll. Eher brute-force, quick'n'dirty.
> Das GUI stellt dabei nur die Koordinaten des Innenteils des
> eigenen Fensters zur Verfügung. Ob es Bereiche aus einem
> 'privatem' Cache einblendet, verschiebt oder neu zeichnet, muß
> die Anwendung (in diesem Fall Access/Jet) selbst entscheiden
> und ausführen.
Meine Worte. :-)
LG,
Paul
nur noch mal fürs Protokoll :-)
Ich hab mir das Ganze jetzt als Klassenmodul zusammengezimmert.
Darin gibts ein Event "DetailMouseMove", das dann vom Formular her aufgerufen
werden kann. Der Unterschied zum normalen Detailbereich_Mousemove
ist letztlich nur der, daß einerseits die Shift- und Button-Sachen fehlen
(war ich zu faul für) andererseits, daß die Cursorposition nun aber auch auch
über den Steuerlementen (auch Subform & Co) zurückgegeben wird und zwar ohne
das nervige Flackern eines Timers.
Änderungen gegenüber dem bisher geposteten Code:
- Ich habe ein bißchen aufgeräumt
- Umrechnung des Pixel und Twips korrekt übern DeviceCap
- Zusätzliche Prüfung auf IsWindowEnabled bei den
Scrollbars. (Gibt ansonsten ggf falsche Koordinaten,
wenn man ein gescrolltes Fenste vergrößert, so daß die Scrollbars
nicht mehr sichtbar sind. Dann wird nämlich die Position
immer noch gespeichert, obwohl der Detailbereich ab
0/0 neu gezeichnet wird. <Nerv>)
Ich denke mal, allgemeine Warnungen wegen des hookens könnte ich mir
ersparen ;-), aber falls jemand anderes das noch lesen sollte:
Das Ganze läuft wegen des "AdressOf" im Klassenmodul nur
ab A00 (glaube ich zumindest), ist ohne Fehlerbehandlung,
Netz und doppelten Boden und somit eine prima Gelegenheit,
seine Anwendung ins Nirwana zu schicken.
Der Code besteht also jetzt aus drei Teilen
1. Formular
2. Allg Modul "modPublicDetailEvents"
3. Klassenmodul "clsPublicDetailEvents"
*******************************************************************
1. Formular:
Option Compare Database
Option Explicit
Dim WithEvents cDetailMouseMove As clsPublicDetailEvents
Private Sub Form_Load()
Set cDetailMouseMove = New clsPublicDetailEvents
cDetailMouseMove.ini Me
End Sub
Private Sub cDetailMouseMove_DetailMouseMove(x As Long, y As Long)
'Mach was mit den Cursorkoordinaten
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set cDetailMouseMove = Nothing
End Sub
*******************************************************************
2. Allgemeines Modul, dieses MUß "modPublicDetailEvents"
heißen (oder AdressOf im cls muß angepaßt.)
(Name, weil man hier ja btw auch noch andere Events einbauen könnte..)
Option Compare Database
Option Explicit
Public pPublicDetailEvents As clsPublicDetailEvents
Public Function fctDetailProc(ByVal hwnd As Long, ByVal msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
fctDetailProc = pPublicDetailEvents.DetailProc(hwnd, msg, wParam, lParam)
End Function
*********************************************************************
3. Klassenmodul clsPublicDetailEvents (muß ebenfalls so heißen..)
Option Compare Database
Option Explicit
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Type RECT
left As Long
top As Long
right As Long
bottom As Long
End Type
Private Type SCROLLINFO
cbSize As Long
fMask As Long
nMin As Long
nMax As Long
nPage As Long
nPos As Long
nTrackPos As Long
End Type
'Events ------------------------------------------------------
Public Event DetailMouseMove(X As Long, Y As Long)
'Konstanten --------------------------------------------------
'GetWindow
Private Const GW_CHILD = 5
Private Const GW_HWNDNEXT = 2
'GetWindowLong
Private Const GWL_WNDPROC As Long = (-4)
'WindowMessage
Private Const WM_HSCROLL As Long = &H114
Private Const WM_VSCROLL As Long = &H115
Private Const WM_NCHITTEST As Long = &H84
Private Const WM_SETCURSOR As Long = &H20
'ScrollBar
Private Const SB_PAGELEFT As Long = 2
Private Const SB_PAGEUP As Long = 2
Private Const SB_CTL As Long = 2
'SCROLLINFO
Private Const SIF_RANGE = &H1
Private Const SIF_PAGE = &H2
Private Const SIF_POS = &H4
Private Const SIF_ALL = SIF_RANGE Or SIF_PAGE Or SIF_POS
'Devicecap
Private Const DC_LOGPIXELSX As Long = 88
Private Const DC_LOGPIXELSY As Long = 90
'Eigene Konstanten
Private Const conOffset As Long = 1 'Pixel-Offset des Detailbereichs
Private Const tpi As Long = 1440 ' Twips per Inch
'Variablen -------------------------------------------------
Private P As POINTAPI
Private R As RECT
Private ScrI As SCROLLINFO
Private mform As Form
Private mDetailhwnd As Long
Private mDetailProc As Long
Dim zzz As Long
'APIS--------------------------------------------------------
Private Declare Function GetWindowRect Lib "user32.dll" _
(ByVal hwnd As Long, lpRECT As RECT) As Long
Private Declare Function GetWindow Lib "user32" _
(ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Function GetClassName Lib "user32" _
Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" ( _
ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function GetScrollInfo Lib "user32.dll" (ByVal hwnd As Long, _
ByVal n As Long, lpScrollInfo As SCROLLINFO) As Long
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, _
ByVal hDC As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hDC As Long, _
ByVal iCapability As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long, ByVal wNewWord As Long) As Long
Private Declare Function IsWindowEnabled Lib "user32.dll" ( _
ByVal hwnd As Long) As Long
'Prozeduren ---------------------------------------------------
Public Sub ini(frm As Form)
Set mform = frm
mDetailhwnd = FindDetailWindow
Set modPublicDetailEvents.pPublicDetailEvents = Me
hook
End Sub
Private Function GetDetailCursorPosition() As POINTAPI ' in Twips
'Ermittelt relativen Cursor zum Detailbereich, je nachdem
'welche Scrollbar aktiviert ist
GetCursorPos P
GetWindowRect mDetailhwnd, R
Select Case mform.ScrollBars
Case 0
ScrollHome ' wenn keine Scrollbar zurückscrollen
P.X = P.X - R.left + conOffset
P.Y = P.Y - R.top + conOffset
Case 1
ScrollYHome 'wenn keine vertikale SB vertikal zurücksrollen
P.X = P.X - R.left + GetHScrollposition.nPos + conOffset
P.Y = P.Y - R.top + conOffset
Case 2
ScrollXHome 'wenn keine horizontale SB horizontal zurückscrollen
P.X = P.X - R.left + conOffset
P.Y = P.Y - R.top + GetVScrollposition.nPos + conOffset
Case 3
P.X = P.X - R.left + GetHScrollposition.nPos + conOffset
P.Y = P.Y - R.top + GetVScrollposition.nPos + conOffset
End Select
GetDetailCursorPosition = GetTwipsFromPixel(P)
End Function
Private Function FindDetailWindow() As Long
'Funktion stammt von Stephen Lebans(?)
'Ermittel das Handle des Detailereichs
Dim hwnd As Long 'Formular-Handle
Dim chwnd As Long 'Child-Handle
Dim counter1 As Long
Dim counter2 As Long
counter1 = 0
counter2 = 2 ' Der Detailbereich ist IMMER das zweite
'"OFormSub"-ChildWindow des Formulares
hwnd = mform.hwnd
chwnd = GetWindow(hwnd, GW_CHILD)
Do
If fGetClassName(chwnd) = "OFormSub" Then
counter1 = counter1 + 1
If counter1 = counter2 Then
FindDetailWindow = chwnd
Exit Function
End If
End If
chwnd = GetWindow(chwnd, GW_HWNDNEXT)
Loop While chwnd <> 0
FindDetailWindow = 0
End Function
Private Function FindHScrollbar() As Long
'Ermittelt das Handle der horizontalen ScrollBar
Dim hwnd As Long
Dim chwnd As Long
Dim counter1 As Long
Dim counter2 As Long ' Reihenfolge der Scrollbar
'ist unterschiedlich je nachdem welche Scrollbars "an" sind
'Die Horizontale ist aber immer an erster Stelle, also
counter1 = 0
counter2 = 1
hwnd = mform.hwnd
chwnd = GetWindow(hwnd, GW_CHILD)
Do
If fGetClassName(chwnd) = "ScrollBar" Then
counter1 = counter1 + 1
If counter1 = counter2 Then
FindHScrollbar = chwnd
Exit Function
End If
End If
chwnd = GetWindow(chwnd, GW_HWNDNEXT)
Loop While chwnd <> 0
FindHScrollbar = 0
End Function
Private Function FindVScrollbar() As Long
'Ermittelt das Handle der vertikalen ScrollBar
Dim hwnd As Long
Dim chwnd As Long
Dim counter1 As Long
Dim counter2 As Long ' Reihenfolge der Scrollbar
'ist unterschiedlich je nachdem welche Scrollbars "an" sind
'Die vertikale kann an Stelle 1 oder 2 stehen, alse
Select Case mform.ScrollBars
Case 2 'nur vertikale SB
counter2 = 1
Case 3 ' beide SBs
counter2 = 2
End Select
counter1 = 0
hwnd = mform.hwnd
chwnd = GetWindow(hwnd, GW_CHILD)
Do
If fGetClassName(chwnd) = "ScrollBar" Then
counter1 = counter1 + 1
If counter1 = counter2 Then
FindVScrollbar = chwnd
Exit Function
End If
End If
chwnd = GetWindow(chwnd, GW_HWNDNEXT)
Loop While chwnd <> 0
FindVScrollbar = 0
End Function
Private Function fGetClassName(hwnd As Long)
'Übersetzt die Klasse in eine verständliche Sprache :-)
Dim strBuffer As String
Dim lngLen As Long
Const MAX_LEN = 255
strBuffer = Space$(MAX_LEN)
lngLen = GetClassName(hwnd, strBuffer, MAX_LEN)
If lngLen > 0 Then fGetClassName = left$(strBuffer, lngLen)
End Function
Private Function GetHScrollposition() As SCROLLINFO
'Ermittelt alle Infos zur horizontalen
'Scrollbar.
Dim DhWnd As Long
DhWnd = FindHScrollbar
With ScrI
.cbSize = LenB(ScrI)
.fMask = SIF_ALL
End With
GetScrollInfo DhWnd, SB_CTL, ScrI
GetHScrollposition = ScrI
If IsWindowEnabled(DhWnd) = False Then
GetHScrollposition.nPos = 0
End If
End Function
Private Function GetVScrollposition() As SCROLLINFO
'Ermittelt entsprechend die Infos zur vertikalen Scrollbar
Dim DhWnd As Long
DhWnd = FindVScrollbar
With ScrI
.cbSize = LenB(ScrI)
.fMask = SIF_ALL
End With
GetScrollInfo DhWnd, SB_CTL, ScrI
GetVScrollposition = ScrI
If IsWindowEnabled(DhWnd) = False Then
GetVScrollposition.nPos = 0
End If
End Function
'Rückscroll-Funktionen (For..next, weils 10fach einfach besser hält)
Private Sub ScrollXHome()
Dim i As Integer
For i = 1 To 10
SendMessage mform.hwnd, WM_HSCROLL, SB_PAGELEFT, 0&
Next i
End Sub
Private Sub ScrollYHome()
Dim i As Integer
For i = 1 To 10
SendMessage mform.hwnd, WM_VSCROLL, SB_PAGEUP, 0&
Next i
End Sub
Public Sub ScrollHome()
Dim i As Integer
For i = 1 To 10
SendMessage mform.hwnd, WM_VSCROLL, SB_PAGEUP, 0&
SendMessage mform.hwnd, WM_HSCROLL, SB_PAGELEFT, 0&
Next i
End Sub
'Umrechnung Pixel in Twips
Private Function GetTwipsFromPixel(pixel As POINTAPI) As POINTAPI
Dim dc As Long
dc = GetDC(0)
GetTwipsFromPixel.X = (pixel.X / GetDeviceCaps(dc, DC_LOGPIXELSX)) * tpi
GetTwipsFromPixel.Y = (pixel.Y / GetDeviceCaps(dc, DC_LOGPIXELSY)) * tpi
ReleaseDC 0, dc
End Function
Public Function DetailProc(ByVal hwnd As Long, ByVal msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
Select Case msg
Case WM_NCHITTEST, WM_SETCURSOR
RaiseEvent DetailMouseMove(GetDetailCursorPosition.X, _
GetDetailCursorPosition.Y)
'Werbung: Hier könnte auch Ihre Message stehen :-)
End Select
DetailProc = CallWindowProc(mDetailProc, hwnd, msg, wParam, lParam)
End Function
Private Sub hook()
mDetailProc = SetWindowLong(mDetailhwnd, GWL_WNDPROC, _
AddressOf modPublicDetailEvents.fctDetailProc)
End Sub
Private Sub unhook()
SetWindowLong mDetailhwnd, GWL_WNDPROC, mDetailProc
End Sub
Private Sub Class_Terminate()
unhook
End Sub
'**************************************************************************
</Code>
Noch ein schönes Wochenende!
Viele Grüße
Jörg Ostendorp
> Ich denke mal, allgemeine Warnungen wegen des hookens könnte ich mir
> ersparen ;-), aber falls jemand anderes das noch lesen sollte:
> Das Ganze läuft wegen des "AdressOf" im Klassenmodul nur
> ab A00 (glaube ich zumindest),
Nope, für Access 97 gibt es einen unsupporteten "Hack" für AddressOf
http://www.mvps.org/access/api/api0031.htm
bzw gleich bei
http://www.trigeminal.com/lang/1033/codes.asp?ItemID=19#19
mfg
Klaus Oberdalhoff
> > Das Ganze läuft wegen des "AdressOf" im Klassenmodul nur
> > ab A00 (glaube ich zumindest),
> Nope, für Access 97 gibt es einen unsupporteten "Hack" für AddressOf
>
> http://www.mvps.org/access/api/api0031.htm
> http://www.trigeminal.com/lang/1033/codes.asp?ItemID=19#19
Danke für den Hinweis, gut zu wissen..
Da steht sogar was in der KnowHow zu, unglaublich :-)
Viele Grüße
Jörg Ostendorp
Falls es jemanden interessiert, noch eine kleine Berichtigung:
Hatte beim Testen irgendwie Probleme wenn ich bei AddressOf
nur die Funktion ohne Modulanamen angegeben habe, lag aber
anscheinend doch an was anderem...
(3. ".. there are so many different ways to set up things wrong.")
Also reicht doch:
Public Sub ini(frm As Form)
'..
Set pPublicDetailEvents = Me
'.. ^^^^^^^^^^^^
End Sub
'und
Private Sub hook()
mDetailProc = SetWindowLong(mDetailhwnd, GWL_WNDPROC, _
AddressOf fctDetailProc)
' ^^^^^^^^
End Sub
und das mit der festen Modulbezeichnung ist dann Unsinn.