 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
WankaUSR
Joined: 14 Aug 2007 Posts: 86
|
Posted: Fri Jan 09, 2009 5:51 pm Post subject: |
|
|
| can it be used to scroll only a groupbox from a gui? |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Sat Jan 10, 2009 3:05 am Post subject: |
|
|
| Not directly. The same methods would be used. If you want to take a crack at it, go ahead... |
|
| Back to top |
|
 |
DHMH
Joined: 17 Jul 2008 Posts: 225
|
Posted: Thu Jun 04, 2009 4:26 pm Post subject: |
|
|
Hi Lexikos, can you tell me whats wrong in this code ?
| Code: |
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
a::
;---------------------------------------------------------------------------------------------------------------
;
; CONFIGURATION
;
UPDATE_RATE = 10 ; milliseconds
SENSITIVITY = 0.5
INERTIA = 0.95
;
; WIN32 DEFINES
;
; SetWinEventHook Flags
WINEVENT_OUTOFCONTEXT = 0x0000
; Events
EVENT_SYSTEM_SCROLLINGSTART = 0x0012
EVENT_SYSTEM_SCROLLINGEND = 0x0013
; Scrollbar Constants
SB_HORZ = 0
SB_VERT = 1
;
; INITIALIZATION
;
SpeedA := 1 - SENSITIVITY
; Register callback proc.
cbOnScrollEvent := RegisterCallback("OnScrollEvent")
; IE support init.
WM_HTML_GETOBJECT := DllCall("RegisterWindowMessage", "str", "WM_HTML_GETOBJECT")
COM_CoInitialize()
;Get main window's handle
WinGet, hMainGUIHwnd, ID, ahk_class AutoHotkeyGUI
ControlGet, hEditControlHwnd, Hwnd, , Internet Explorer_Server1, ahk_class AutoHotkeyGUI
hHwnd := hMainGUIHwnd
Scroll_Type := "scrollbarHThumb"
info := GetAbstractScrollInfo(hWnd,Scroll_type)
MsgBox % info
;---------------------------------------------------------------------------------------------------------------
;
; FUNCTIONS - Standard Windows Scrollbars
;
GetScrollInfo(hwnd, fnBar, ByRef nPos=0, ByRef nTrackPos=0, ByRef nMin=0, ByRef nMax=0, ByRef nPage=0)
{
WinGet, Style, Style, ahk_id %hwnd%
if !(Style & (fnBar ? 0x200000 : 0x100000))
return false ; Fix for some controls which report {min:0,max:100} even though scroll bar doesn't exist.
VarSetCapacity(si, 28, 0) ; SCROLLINFO si
NumPut(28 , si, 0) ; si.cbSize := sizeof(SCROLLINFO)
NumPut(0x17, si, 4) ; si.fMask := SIF_ALL
if ! DllCall("GetScrollInfo", "uint", hwnd, "int", fnBar, "uint", &si)
return false
nPos := NumGet(si, 20)
nTrackPos := NumGet(si, 24)
nMin := NumGet(si, 8)
nMax := NumGet(si, 12)
nPage := NumGet(si, 16)
return true
}
SetScrollPos(hwnd, fnBar, nPos)
{
VarSetCapacity(si, 28, 0) ; SCROLLINFO si
NumPut(28 , si, 0) ; si.cbSize := sizeof(SCROLLINFO)
NumPut(0x4 , si, 4) ; si.fMask := SIF_POS
NumPut(nPos, si, 20) ; si.nPos := nPos
; Use SetScrollInfo first because it supports 32-bit positions.
; If an application supports positions < 0 or > 65535, it most likely
; ignores WM_#SCROLL's wParam and uses GetScrollPos or GetScrollInfo
; to get the actual scroll position.
DllCall("SetScrollInfo", "uint", hwnd, "int", fnBar, "uint", &si, "int", 0)
; WM_HSCROLL or WM_VSCROLL must be sent for the window to update it's contents.
msg := (fnBar=0) ? 0x114 : 0x115
wParam := 4 ; SB_THUMBPOSITION
| ((nPos&0xFFFF)<<16)
SendMessage, msg, wParam,,, ahk_id %hwnd%
return (ErrorLevel != "FAIL")
}
;
; ABSTRACT FUNCTIONS - for both standard Windows scrollbar and IE scrollbar support.
;
GetAbstractScrollInfo(Container, Type, ByRef Pos=0, ByRef Min=0, ByRef Max=0)
{
if !Container
return false
if Type in 0,1 ; SB_HORZ,SB_VERT
return GetScrollInfo(Container, Type, Pos, track_pos, Min, Max)
if Type = scrollbarHThumb
Pos:=COM_Invoke(Container,"scrollLeft"), Max:=COM_Invoke(Container,"scrollWidth"), Min:=0
else if Type = scrollbarVThumb
Pos:=COM_Invoke(Container,"scrollTop"), Max:=COM_Invoke(Container,"scrollHeight"), Min:=0
return Pos!=""
}
SetAbstractScrollPos(Container, Type, Pos)
{
if !Container
return false
if Type in 0,1 ; SB_HORZ,SB_VERT
return SetScrollPos(Container, Type, Pos)
; TODO: determine success or failure for assignment.
if Type = scrollbarHThumb
return true, COM_Invoke(Container,"scrollLeft=",Pos)
else if Type = scrollbarVThumb
return true, COM_Invoke(Container,"scrollTop=",Pos)
return false
}
;
; IE FUNCTIONS & SUBROUTINES
;
GetDeepestScrollElement(pWin, x, y, ByRef pElement, ByRef pElementWin)
{
; AddRef so we don't release pWin below. (Caller may still need it.)
COM_AddRef(win:=pWin)
Loop {
if (!win)
break ; Error
if !(doc:=COM_Invoke(win,"document"))
break ; Error
if !(element:=COM_Invoke(doc,"elementFromPoint",x-COM_Invoke(win,"screenLeft"),y-COM_Invoke(win,"screenTop")))
break ; Error
if (tag:=COM_Invoke(element,"tagName")) != "FRAME"
{ ; return element.isScrollable ? element : frame.body
scrollHeight:=COM_Invoke(element,"scrollHeight"), clientHeight:=COM_Invoke(element,"clientHeight")
if !(clientHeight && clientHeight < scrollHeight)
COM_Release(element), element:=COM_Invoke(doc,"body")
break
}
COM_Release(doc), doc:=0, COM_Release(win), win:=0
if !(win:=COM_Invoke(element,"contentWindow"))
{
COM_Release(element), element:=0
break ; Error
}
}
if doc
COM_Release(doc), doc:=0
if (win && !element)
COM_Release(win), win:=0
pElement := element
pElementWin := win
return pElement
}
GetIEDocumentAtMouse:
MouseGetPos,,,, hIESvr, 2
WinGetClass, class, ahk_id %hIESvr%
if (!hIESvr or class != "Internet Explorer_Server")
{ ; Try again with alternate method (for "Microsoft Document Explorer" support.)
MouseGetPos,,,, hIESvr, 3
WinGetClass, class, ahk_id %hIESvr%
if (!hIESvr or class != "Internet Explorer_Server")
return
}
SendMessage, WM_HTML_GETOBJECT,,,, ahk_id %hIESvr%
lResult := ErrorLevel
DllCall("oleacc\ObjectFromLresult", "uint", lResult
, "uint", COM_GUID4String(IID_IHTMLDocument2,"{332C4425-26CB-11D0-B483-00C04FD90119}")
, "int", 0, "uint*", pDoc)
return
GetActiveScrollElement(win)
{
if !win
return 0
COM_AddRef(win) ; caller is responsible for releasing win
Loop {
if (!win)
break ; Error
if !(doc:=COM_Invoke(win,"document")), COM_Release(win),win:=0
break ; Error
if !(element:=COM_Invoke(doc,"activeElement"))
break ; Error
if (tag:=COM_Invoke(element,"tagName")) != "FRAME"
{ ; return element.isScrollable ? element : frame.body
scrollHeight:=COM_Invoke(element,"scrollHeight"), clientHeight:=COM_Invoke(element,"clientHeight")
if !(clientHeight && clientHeight < scrollHeight)
COM_Release(element), element:=COM_Invoke(doc,"body")
break
}
COM_Release(doc),doc:=0
if !(win:=COM_Invoke(element,"contentWindow"))
{
COM_Release(element), element:=0
break ; Error
}
}
doc ? COM_Release(doc) . doc:=0 : ""
return element
}
#include, resources\COM.ahk |
Ive got 2 Scripts, first the script above and another, the other script has got an ie control, but the msgbox is empty
any solution ?
Thank you!
Greets,
DHMH |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Fri Jun 05, 2009 1:14 am Post subject: |
|
|
| hWnd is a window handle. If Scroll_Type is scrollbarHThumb, GetAbstractScrollInfo expects a pointer to a DOM object (from within an IE control). |
|
| Back to top |
|
 |
DHMH
Joined: 17 Jul 2008 Posts: 225
|
Posted: Fri Jun 05, 2009 11:35 am Post subject: |
|
|
Thank you, but can you give me an example ?
Is the variable pwb in my first script a DOM Pointer ?
Thanks in advance!
greets,
DHMH |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Fri Jun 05, 2009 4:17 pm Post subject: |
|
|
What are you trying to do?
pwb is presumably a pointer to a WebBrowser control, which is not a DOM object. You may use its Document property to access a document object through which other DOM objects can be retrieved. ScrollMomentum contains two functions which get a particular element, and also demonstrates their use: GetDeepestScrollElement and GetActiveScrollElement. Both expect a pointer to a window object, which can be retrieved via pwb.Document.parentWindow. |
|
| Back to top |
|
 |
DHMH
Joined: 17 Jul 2008 Posts: 225
|
Posted: Sat Jun 06, 2009 7:52 am Post subject: |
|
|
Thank you
Ok, my situation:
I've got 2 Scripts, the first script is my main program, it contains a normal Internet Explorer control, the second script is this:
| Code: |
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
a::
;---------------------------------------------------------------------------------------------------------------
;
; CONFIGURATION
;
UPDATE_RATE = 10 ; milliseconds
SENSITIVITY = 0.5
INERTIA = 0.95
;
; WIN32 DEFINES
;
; SetWinEventHook Flags
WINEVENT_OUTOFCONTEXT = 0x0000
; Events
EVENT_SYSTEM_SCROLLINGSTART = 0x0012
EVENT_SYSTEM_SCROLLINGEND = 0x0013
; Scrollbar Constants
SB_HORZ = 0
SB_VERT = 1
;
; INITIALIZATION
;
SpeedA := 1 - SENSITIVITY
; Register callback proc.
cbOnScrollEvent := RegisterCallback("OnScrollEvent")
; IE support init.
WM_HTML_GETOBJECT := DllCall("RegisterWindowMessage", "str", "WM_HTML_GETOBJECT")
COM_CoInitialize()
;Get main window's handle
WinGet, hMainGUIHwnd, ID, ahk_class AutoHotkeyGUI
ControlGet, hEditControlHwnd, Hwnd, , Internet Explorer_Server1, ahk_class AutoHotkeyGUI
hHwnd := hMainGUIHwnd
Scroll_Type := "scrollbarHThumb"
info := GetAbstractScrollInfo(hWnd,Scroll_type)
Loop,
{
ifnotexist,dom.txt
continue
fileread,dom,dom.txt
Break
}
GetDeepestScrollElement(dom)
Return
;---------------------------------------------------------------------------------------------------------------
;
; FUNCTIONS - Standard Windows Scrollbars
;
GetScrollInfo(hwnd, fnBar, ByRef nPos=0, ByRef nTrackPos=0, ByRef nMin=0, ByRef nMax=0, ByRef nPage=0)
{
WinGet, Style, Style, ahk_id %hwnd%
if !(Style & (fnBar ? 0x200000 : 0x100000))
return false ; Fix for some controls which report {min:0,max:100} even though scroll bar doesn't exist.
VarSetCapacity(si, 28, 0) ; SCROLLINFO si
NumPut(28 , si, 0) ; si.cbSize := sizeof(SCROLLINFO)
NumPut(0x17, si, 4) ; si.fMask := SIF_ALL
if ! DllCall("GetScrollInfo", "uint", hwnd, "int", fnBar, "uint", &si)
return false
nPos := NumGet(si, 20)
nTrackPos := NumGet(si, 24)
nMin := NumGet(si, 8)
nMax := NumGet(si, 12)
nPage := NumGet(si, 16)
return true
}
SetScrollPos(hwnd, fnBar, nPos)
{
VarSetCapacity(si, 28, 0) ; SCROLLINFO si
NumPut(28 , si, 0) ; si.cbSize := sizeof(SCROLLINFO)
NumPut(0x4 , si, 4) ; si.fMask := SIF_POS
NumPut(nPos, si, 20) ; si.nPos := nPos
; Use SetScrollInfo first because it supports 32-bit positions.
; If an application supports positions < 0 or > 65535, it most likely
; ignores WM_#SCROLL's wParam and uses GetScrollPos or GetScrollInfo
; to get the actual scroll position.
DllCall("SetScrollInfo", "uint", hwnd, "int", fnBar, "uint", &si, "int", 0)
; WM_HSCROLL or WM_VSCROLL must be sent for the window to update it's contents.
msg := (fnBar=0) ? 0x114 : 0x115
wParam := 4 ; SB_THUMBPOSITION
| ((nPos&0xFFFF)<<16)
SendMessage, msg, wParam,,, ahk_id %hwnd%
return (ErrorLevel != "FAIL")
}
;
; ABSTRACT FUNCTIONS - for both standard Windows scrollbar and IE scrollbar support.
;
GetAbstractScrollInfo(Container, Type, ByRef Pos=0, ByRef Min=0, ByRef Max=0)
{
if !Container
return false
if Type in 0,1 ; SB_HORZ,SB_VERT
return GetScrollInfo(Container, Type, Pos, track_pos, Min, Max)
if Type = scrollbarHThumb
Pos:=COM_Invoke(Container,"scrollLeft"), Max:=COM_Invoke(Container,"scrollWidth"), Min:=0
else if Type = scrollbarVThumb
Pos:=COM_Invoke(Container,"scrollTop"), Max:=COM_Invoke(Container,"scrollHeight"), Min:=0
return Pos!=""
}
SetAbstractScrollPos(Container, Type, Pos)
{
if !Container
return false
if Type in 0,1 ; SB_HORZ,SB_VERT
return SetScrollPos(Container, Type, Pos)
; TODO: determine success or failure for assignment.
if Type = scrollbarHThumb
return true, COM_Invoke(Container,"scrollLeft=",Pos)
else if Type = scrollbarVThumb
return true, COM_Invoke(Container,"scrollTop=",Pos)
return false
}
;
; IE FUNCTIONS & SUBROUTINES
;
GetDeepestScrollElement(pWin, x, y, ByRef pElement, ByRef pElementWin)
{
; AddRef so we don't release pWin below. (Caller may still need it.)
COM_AddRef(win:=pWin)
Loop {
if (!win)
break ; Error
if !(doc:=COM_Invoke(win,"document"))
break ; Error
if !(element:=COM_Invoke(doc,"elementFromPoint",x-COM_Invoke(win,"screenLeft"),y-COM_Invoke(win,"screenTop")))
break ; Error
if (tag:=COM_Invoke(element,"tagName")) != "FRAME"
{ ; return element.isScrollable ? element : frame.body
scrollHeight:=COM_Invoke(element,"scrollHeight"), clientHeight:=COM_Invoke(element,"clientHeight")
if !(clientHeight && clientHeight < scrollHeight)
COM_Release(element), element:=COM_Invoke(doc,"body")
break
}
COM_Release(doc), doc:=0, COM_Release(win), win:=0
if !(win:=COM_Invoke(element,"contentWindow"))
{
COM_Release(element), element:=0
break ; Error
}
}
if doc
COM_Release(doc), doc:=0
if (win && !element)
COM_Release(win), win:=0
pElement := element
pElementWin := win
return pElement
}
GetIEDocumentAtMouse:
MouseGetPos,,,, hIESvr, 2
WinGetClass, class, ahk_id %hIESvr%
if (!hIESvr or class != "Internet Explorer_Server")
{ ; Try again with alternate method (for "Microsoft Document Explorer" support.)
MouseGetPos,,,, hIESvr, 3
WinGetClass, class, ahk_id %hIESvr%
if (!hIESvr or class != "Internet Explorer_Server")
return
}
SendMessage, WM_HTML_GETOBJECT,,,, ahk_id %hIESvr%
lResult := ErrorLevel
DllCall("oleacc\ObjectFromLresult", "uint", lResult
, "uint", COM_GUID4String(IID_IHTMLDocument2,"{332C4425-26CB-11D0-B483-00C04FD90119}")
, "int", 0, "uint*", pDoc)
return
GetActiveScrollElement(win)
{
if !win
return 0
COM_AddRef(win) ; caller is responsible for releasing win
Loop {
if (!win)
break ; Error
if !(doc:=COM_Invoke(win,"document")), COM_Release(win),win:=0
break ; Error
if !(element:=COM_Invoke(doc,"activeElement"))
break ; Error
if (tag:=COM_Invoke(element,"tagName")) != "FRAME"
{ ; return element.isScrollable ? element : frame.body
scrollHeight:=COM_Invoke(element,"scrollHeight"), clientHeight:=COM_Invoke(element,"clientHeight")
if !(clientHeight && clientHeight < scrollHeight)
COM_Release(element), element:=COM_Invoke(doc,"body")
break
}
COM_Release(doc),doc:=0
if !(win:=COM_Invoke(element,"contentWindow"))
{
COM_Release(element), element:=0
break ; Error
}
}
doc ? COM_Release(doc) . doc:=0 : ""
return element
}
#include, resources\COM.ahk |
(got an errormessage Too few parameters passed to function)
In my first script i'd insert this, before the first return:
| Code: | dom := COM_Invoke(pwb,"Document.parentWindow" )
filedelete,dom.txt
fileappend,%dom%,dom.txt |
The Dom Var contains some numbers ...
Could you please give me an example, how i could use your function (with an IE Control)?
I want to set the scroll position of the IE Control.
Thanks!
Greets,
DHMH |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Sat Jun 06, 2009 10:05 am Post subject: |
|
|
| If you want an example, use ScrollMomentum. |
|
| Back to top |
|
 |
hughman
Joined: 11 Feb 2007 Posts: 166
|
Posted: Sat Jun 06, 2009 12:40 pm Post subject: |
|
|
I changed the function OnScroll to only scroll a part of client area, but the controls in the scrollable area can't be redrawed correctly when scrolling.
What's the problem?
Below is my fixed code:
| Code: |
OnScroll(wParam, lParam, msg, hwnd)
{
static SIF_ALL=0x17, SCROLL_STEP=30
bar := msg=0x115 ; SB_HORZ=0, SB_VERT=1
VarSetCapacity(si, 28, 0)
NumPut(28, si) ; cbSize
NumPut(SIF_ALL, si, 4) ; fMask
if !DllCall("GetScrollInfo", "uint", hwnd, "int", bar, "uint", &si)
return
VarSetCapacity(rect, 16)
NumPut(205, rect, 0)
NumPut(60, rect, 4)
NumPut(800, rect, 8)
NumPut(600, rect, 12)
;DllCall("GetClientRect", "uint", hwnd, "uint", &rect)
new_pos := NumGet(si, 20) ; nPos
action := wParam & 0xFFFF
if action = 0 ; SB_LINEUP
new_pos -= SCROLL_STEP
else if action = 1 ; SB_LINEDOWN
new_pos += SCROLL_STEP
else if action = 2 ; SB_PAGEUP
new_pos -= NumGet(rect, 12, "int") - SCROLL_STEP
else if action = 3 ; SB_PAGEDOWN
new_pos += NumGet(rect, 12, "int") - SCROLL_STEP
else if (action = 5 || action = 4) ; SB_THUMBTRACK || SB_THUMBPOSITION
new_pos := wParam>>16
else if action = 6 ; SB_TOP
new_pos := NumGet(si, 8, "int") ; nMin
else if action = 7 ; SB_BOTTOM
new_pos := NumGet(si, 12, "int") ; nMax
else
return
min := NumGet(si, 8, "int") ; nMin
max := NumGet(si, 12, "int") - NumGet(si, 16) ; nMax-nPage
new_pos := new_pos > max ? max : new_pos
new_pos := new_pos < min ? min : new_pos
old_pos := NumGet(si, 20, "int") ; nPos
x := y := 0
if bar = 0 ; SB_HORZ
x := old_pos - new_pos
else
y := old_pos - new_pos
; Scroll contents of window and invalidate uncovered area.
DllCall("ScrollWindow", "uint", hwnd, "int", x, "int", y, "uint", &rect, "uint", 0)
; Update scroll bar.
NumPut(new_pos, si, 20, "int") ; nPos
DllCall("SetScrollInfo", "uint", hwnd, "int", bar, "uint", &si, "int", 1)
}
|
|
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Sat Jun 06, 2009 1:59 pm Post subject: |
|
|
| hughman wrote: | | What's the problem? | I guess that would be:
| Quote: | | I changed the function OnScroll to only scroll a part of client area, |
| Quote: | | Below is my fixed code: | "Fixed" how?
ScrollWindow moves/copies a portion of the window's image. MSDN isn't very clear- when you specify a region of the window, child windows (controls) intersecting that region may or may not actually be moved. Testing suggests they are not moved, however ScrollWindowEx will do so if the SW_SCROLLCHILDREN flag is specified. Although any controls which partially intersect that region will be moved, if any part of the control is visible outside that region it is not (visibly) moved or repainted.
Basically, ScrollWindow isn't designed to do what you want.
You could try placing the controls inside another Gui, and "parenting" this Gui to your main Gui. Search the forums for "SetParent".
WinSet, Redraw might work for your purposes, but I doubt it would be a complete solution. |
|
| Back to top |
|
 |
hughman
Joined: 11 Feb 2007 Posts: 166
|
Posted: Sun Jun 07, 2009 4:57 am Post subject: |
|
|
I have already tried WinSet, Redraw before replying here, the result is that the scrollbar also will be reset to jump to the top.
Maybe the best solution is to create child gui although I prefer Tab |
|
| Back to top |
|
 |
DHMH
Joined: 17 Jul 2008 Posts: 225
|
Posted: Sun Jun 07, 2009 7:19 am Post subject: |
|
|
Thank you, but i got a problem
When i use 2 scripts ( ), it works, but when i want to integrate the 2nd script, into the 1st, it won't work,
SetAbstractScrollPos() returns 1, but the position won't have been set
| Code: | | SetAbstractScrollPos(Scroll_Container, Scroll_Type,Scroll_min + 200) |
I've created a function, called getscrollpos():
| Code: | getscrollinfos(){
global
if (pDoc && (pWin:=COM_Invoke(pDoc,"parentWindow"), COM_Release(pDoc),pDoc:=0))
if (pElement:=GetActiveScrollElement(pWin)), COM_Release(pWin),pWin:=0
{
Scroll_Container := pElement
Scroll_Type := Scroll_Type ? "scrollbarVThumb" : "scrollbarHThumb"
GetAbstractScrollInfo(Scroll_Container, Scroll_Type, Scroll_Pos, Scroll_Min, Scroll_Max)
}
} |
Ever Var is filled, but it won't work
Please help me.
Thanks
Greets,
DHMH |
|
| Back to top |
|
 |
luetkmeyer
Joined: 26 Feb 2010 Posts: 38
|
Posted: Sun Apr 18, 2010 3:55 pm Post subject: |
|
|
Thank you man! Others scrolls donk works perfctly. This works great! Thank you! | Lexikos wrote: | Here is my attempt (based on some C++ code I wrote long ago.)
...
[Moderator's note: Duplicate script and other irrelevant details removed. Please see the original post.] |
|
|
| Back to top |
|
 |
ribbs2521
Joined: 28 Sep 2007 Posts: 273 Location: New York
|
Posted: Fri May 28, 2010 6:03 pm Post subject: |
|
|
Just wondering if anyone else has noticed this issue? I didn't see anything regarding listviews discussed in previous posts.
When I have a listview and there are no GUI scroll bars, anywhere I scroll on the window causes the listview to scroll. If GUI scroll bars do exist, the problem goes away.
Another, which I found a resolution for, is that when you use the scroll wheel over a listview it causes some really messed up views on the listview (rows are stretched and text gets all skewed). I just put a little chunk of code in there to say, if the mouse is over a SysListView return.
I think the second issue would be fixed automatically when the first one is because I think it's trying to do the same thing, so when the mouse is over the LV it's scrolling the LV AND it's scrolling the GUI. I'm not that good but that is my guess.
Here is an example: Take out the MouseGetPos and two following commands to see the skewed LV rows
| Code: |
OnMessage(0x115, "OnScroll") ; WM_VSCROLL
OnMessage(0x114, "OnScroll") ; WM_HSCROLL
Gui, +Resize
Gui, Add, ListView, x36 y40 w390 h270, Some Listview
Gui, Show, x131 y91 h377 w477, TEST
Loop, 25
LV_Add("", "Row " . A_Index)
Return
GuiClose:
ExitApp
GuiSize:
UpdateScrollBars(A_Gui, A_GuiWidth, A_GuiHeight)
return
UpdateScrollBars(GuiNum, GuiWidth, GuiHeight)
{
static SIF_RANGE=0x1, SIF_PAGE=0x2, SIF_DISABLENOSCROLL=0x8, SB_HORZ=0, SB_VERT=1
Gui, %GuiNum%:Default
Gui, +LastFound
; Calculate scrolling area.
Left := Top := 9999
Right := Bottom := 0
WinGet, ControlList, ControlList
Loop, Parse, ControlList, `n
{
GuiControlGet, c, Pos, %A_LoopField%
if (cX < Left)
Left := cX
if (cY < Top)
Top := cY
if (cX + cW > Right)
Right := cX + cW
if (cY + cH > Bottom)
Bottom := cY + cH
}
Left -= 8
Top -= 8
Right += 8
Bottom += 8
ScrollWidth := Right-Left
ScrollHeight := Bottom-Top
; Initialize SCROLLINFO.
VarSetCapacity(si, 28, 0)
NumPut(28, si) ; cbSize
NumPut(SIF_RANGE | SIF_PAGE, si, 4) ; fMask
; Update horizontal scroll bar.
NumPut(ScrollWidth, si, 12) ; nMax
NumPut(GuiWidth, si, 16) ; nPage
DllCall("SetScrollInfo", "uint", WinExist(), "uint", SB_HORZ, "uint", &si, "int", 1)
; Update vertical scroll bar.
; NumPut(SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL, si, 4) ; fMask
NumPut(ScrollHeight, si, 12) ; nMax
NumPut(GuiHeight, si, 16) ; nPage
DllCall("SetScrollInfo", "uint", WinExist(), "uint", SB_VERT, "uint", &si, "int", 1)
if (Left < 0 && Right < GuiWidth)
x := Abs(Left) > GuiWidth-Right ? GuiWidth-Right : Abs(Left)
if (Top < 0 && Bottom < GuiHeight)
y := Abs(Top) > GuiHeight-Bottom ? GuiHeight-Bottom : Abs(Top)
if (x || y)
DllCall("ScrollWindow", "uint", WinExist(), "int", x, "int", y, "uint", 0, "uint", 0)
}
OnScroll(wParam, lParam, msg, hwnd)
{
static SIF_ALL=0x17, SCROLL_STEP=10
;**HERE IS MY RUDAMENTARY CODE TO STOP THE SKEWAGE.**
MouseGetPos,,,, someControl
if (InStr(someControl,"SysListView"))
return
;**END RUDAMENTARY SKEWAGE STOPPER**
bar := msg=0x115 ; SB_HORZ=0, SB_VERT=1
VarSetCapacity(si, 28, 0)
NumPut(28, si) ; cbSize
NumPut(SIF_ALL, si, 4) ; fMask
if !DllCall("GetScrollInfo", "uint", hwnd, "int", bar, "uint", &si)
return
VarSetCapacity(rect, 16)
DllCall("GetClientRect", "uint", hwnd, "uint", &rect)
new_pos := NumGet(si, 20) ; nPos
action := wParam & 0xFFFF
if action = 0 ; SB_LINEUP
new_pos -= SCROLL_STEP
else if action = 1 ; SB_LINEDOWN
new_pos += SCROLL_STEP
else if action = 2 ; SB_PAGEUP
new_pos -= NumGet(rect, 12, "int") - SCROLL_STEP
else if action = 3 ; SB_PAGEDOWN
new_pos += NumGet(rect, 12, "int") - SCROLL_STEP
else if (action = 5 || action = 4) ; SB_THUMBTRACK || SB_THUMBPOSITION
new_pos := wParam>>16
else if action = 6 ; SB_TOP
new_pos := NumGet(si, 8, "int") ; nMin
else if action = 7 ; SB_BOTTOM
new_pos := NumGet(si, 12, "int") ; nMax
else
return
min := NumGet(si, 8, "int") ; nMin
max := NumGet(si, 12, "int") - NumGet(si, 16) ; nMax-nPage
new_pos := new_pos > max ? max : new_pos
new_pos := new_pos < min ? min : new_pos
old_pos := NumGet(si, 20, "int") ; nPos
x := y := 0
if bar = 0 ; SB_HORZ
x := old_pos-new_pos
else
y := old_pos-new_pos
; Scroll contents of window and invalidate uncovered area.
DllCall("ScrollWindow", "uint", hwnd, "int", x, "int", y, "uint", 0, "uint", 0)
; Update scroll bar.
NumPut(new_pos, si, 20, "int") ; nPos
DllCall("SetScrollInfo", "uint", hwnd, "int", bar, "uint", &si, "int", 1)
} |
I'm trying to figure out what I would need to find out if scroll bars exist on the GUI and say, if no scroll bars exist on the GUI, return. No such luck though. Anyone have any ideas? |
|
| Back to top |
|
 |
jsherk
Joined: 11 Jun 2011 Posts: 64
|
Posted: Thu Jun 16, 2011 8:00 pm Post subject: Scrollbars for two GUI's |
|
|
This seems to work good for a single GUI, but if you have multiple GUI's it acts weird on the second GUI. Here is my example with switching between 2 gui's:
| Code: | ; SWITCHING BETWEEN TWO GUI WINDOWS WITH SCROLLBARS
#NoEnv
OnMessage(0x115, "OnScroll") ; WM_VSCROLL
OnMessage(0x114, "OnScroll") ; WM_HSCROLL
Gui, +Resize +0x300000 ; WS_VSCROLL | WS_HSCROLL
Gui, 2:+Resize +0x300000 ; WS_VSCROLL | WS_HSCROLL
Loop 5
Gui, 2:Add, Edit, R5 W400, GUI 2 Edit %A_Index%
Gui, 2:Add, Button,, Back To ONE
Gui, 2:Show, W200 H200
Gui, 2:+LastFound
GroupAdd, MyGui, % "ahk_id " . WinExist()
Gui, 2:hide
Loop 5 ; Add second window
Gui, Add, Edit, R5 W400, Edit %A_Index%
Gui, Add, Button,, Go To TWO
Gui, Show, W200 H200
Gui, +LastFound
GroupAdd, MyGui, % "ahk_id " . WinExist()
return
GuiSize:
UpdateScrollBars(A_Gui, A_GuiWidth, A_GuiHeight)
return
GuiClose:
ExitApp
ButtonGoToTWO:
Gui, 2:Show
Gui, 1:Hide
return
2ButtonBackToONE:
Gui, 1:Show
Gui, 2:Hide
return
#IfWinActive ahk_group MyGui
WheelUp::
WheelDown::
+WheelUp::
+WheelDown::
; SB_LINEDOWN=1, SB_LINEUP=0, WM_HSCROLL=0x114, WM_VSCROLL=0x115
OnScroll(InStr(A_ThisHotkey,"Down") ? 1 : 0, 0, GetKeyState("Shift") ? 0x114 : 0x115, WinExist())
return
#IfWinActive
UpdateScrollBars(GuiNum, GuiWidth, GuiHeight)
{
static SIF_RANGE=0x1, SIF_PAGE=0x2, SIF_DISABLENOSCROLL=0x8, SB_HORZ=0, SB_VERT=1
Gui, %GuiNum%:Default
Gui, +LastFound
; Calculate scrolling area.
Left := Top := 9999
Right := Bottom := 0
WinGet, ControlList, ControlList
Loop, Parse, ControlList, `n
{
GuiControlGet, c, Pos, %A_LoopField%
if (cX < Left)
Left := cX
if (cY < Top)
Top := cY
if (cX + cW > Right)
Right := cX + cW
if (cY + cH > Bottom)
Bottom := cY + cH
}
Left -= 8
Top -= 8
Right += 8
Bottom += 8
ScrollWidth := Right-Left
ScrollHeight := Bottom-Top
; Initialize SCROLLINFO.
VarSetCapacity(si, 28, 0)
NumPut(28, si) ; cbSize
NumPut(SIF_RANGE | SIF_PAGE, si, 4) ; fMask
; Update horizontal scroll bar.
NumPut(ScrollWidth, si, 12) ; nMax
NumPut(GuiWidth, si, 16) ; nPage
DllCall("SetScrollInfo", "uint", WinExist(), "uint", SB_HORZ, "uint", &si, "int", 1)
; Update vertical scroll bar.
; NumPut(SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL, si, 4) ; fMask
NumPut(ScrollHeight, si, 12) ; nMax
NumPut(GuiHeight, si, 16) ; nPage
DllCall("SetScrollInfo", "uint", WinExist(), "uint", SB_VERT, "uint", &si, "int", 1)
if (Left < 0 && Right < GuiWidth)
x := Abs(Left) > GuiWidth-Right ? GuiWidth-Right : Abs(Left)
if (Top < 0 && Bottom < GuiHeight)
y := Abs(Top) > GuiHeight-Bottom ? GuiHeight-Bottom : Abs(Top)
if (x || y)
DllCall("ScrollWindow", "uint", WinExist(), "int", x, "int", y, "uint", 0, "uint", 0)
}
OnScroll(wParam, lParam, msg, hwnd)
{
static SIF_ALL=0x17, SCROLL_STEP=10
bar := msg=0x115 ; SB_HORZ=0, SB_VERT=1
VarSetCapacity(si, 28, 0)
NumPut(28, si) ; cbSize
NumPut(SIF_ALL, si, 4) ; fMask
if !DllCall("GetScrollInfo", "uint", hwnd, "int", bar, "uint", &si)
return
VarSetCapacity(rect, 16)
DllCall("GetClientRect", "uint", hwnd, "uint", &rect)
new_pos := NumGet(si, 20) ; nPos
action := wParam & 0xFFFF
if action = 0 ; SB_LINEUP
new_pos -= SCROLL_STEP
else if action = 1 ; SB_LINEDOWN
new_pos += SCROLL_STEP
else if action = 2 ; SB_PAGEUP
new_pos -= NumGet(rect, 12, "int") - SCROLL_STEP
else if action = 3 ; SB_PAGEDOWN
new_pos += NumGet(rect, 12, "int") - SCROLL_STEP
else if (action = 5 || action = 4) ; SB_THUMBTRACK || SB_THUMBPOSITION
new_pos := wParam>>16
else if action = 6 ; SB_TOP
new_pos := NumGet(si, 8, "int") ; nMin
else if action = 7 ; SB_BOTTOM
new_pos := NumGet(si, 12, "int") ; nMax
else
return
min := NumGet(si, 8, "int") ; nMin
max := NumGet(si, 12, "int") - NumGet(si, 16) ; nMax-nPage
new_pos := new_pos > max ? max : new_pos
new_pos := new_pos < min ? min : new_pos
old_pos := NumGet(si, 20, "int") ; nPos
x := y := 0
if bar = 0 ; SB_HORZ
x := old_pos-new_pos
else
y := old_pos-new_pos
; Scroll contents of window and invalidate uncovered area.
DllCall("ScrollWindow", "uint", hwnd, "int", x, "int", y, "uint", 0, "uint", 0)
; Update scroll bar.
NumPut(new_pos, si, 20, "int") ; nPos
DllCall("SetScrollInfo", "uint", hwnd, "int", bar, "uint", &si, "int", 1)
}
|
|
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|