daiyu116 发表于 2011-7-6 12:04:15

[已解决]使用_GUIScrollBars_Init后,在GUI上创建控件时位置偏移问题

本帖最后由 daiyu116 于 2011-7-8 18:35 编辑

如题,使用滚动条控件管理对GUI设置滚动条后,在该GUI上创建控件时,控件的位置会发生偏移。
可能口述不太清楚,请直接看下面的图。

不滑动边栏,点击按钮创建控件:

滑动边栏后,点击按钮创建控件:


$ReportGUI、$GUImenu、$GUIbody分别是三个GUI窗体。
$ReportGUI为父窗体,$GUImenu、$GUIbody是他的子窗体。

问题如上,请 任何侠们 给予指点!感谢!
下面是源码:

#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GuiDateTimePicker.au3>
#Include <GuiListView.au3>
#include <GUIScrollBars.au3>
#include <ScrollBarConstants.au3>
#Include <Array.au3>
#include <StructureConstants.au3>

Global Const $WM_MOVING = 0x216
Global $addtimes=0
Dim $Group

GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL")

$ReportGUI= GUICreate("工作报告编写器",635,500,192,124,BitOR($WS_MINIMIZEBOX,$WS_CAPTION, $WS_POPUP, $WS_SYSMENU))
        WinSetOnTop($ReportGUI,"", 1)
        GUISetState()
$addButton = GUICtrlCreateButton("增加行", 295, 36, 48, 23)
;$GUImenu = GUICreate('Menu',615,150,10, 10,BitOR($WS_SYSMENU, $WS_POPUP,$WS_SIZEBOX,$WS_BORDER, $WS_CHILD), -1, $ReportGUI)
$GUImenu = GUICreate('Menu',615,150,10, 10,BitOR($WS_CHILD,$WS_BORDER), -1, $ReportGUI)
        GUISetState()
;$GUIbody = GUICreate('Body',615,300,10,160,BitOR($WS_SYSMENU, $WS_POPUP,$WS_SIZEBOX,$WS_BORDER, $WS_CHILD), -1, $ReportGUI)
$GUIbody = GUICreate('Body',615,320,10,165,BitOR($WS_CHILD,$WS_BORDER), -1, $ReportGUI)
        GUISetState()
        _GUIScrollBars_Init($GUIbody)
        _GUIScrollBars_SetScrollRange($GUIbody,$SB_VERT,10,60)

While 1
        $Msg = GUIGetMsg()
        Select
                Case $Msg=$GUI_EVENT_CLOSE
                        Exit
                Case $Msg=$addButton
                        GUISwitch($GUIbody)
                                $Group =    GUICtrlCreateCheckbox("", 5,5+22*$addtimes,15,20)
                                $Group = _GUICtrlDTP_Create($GUIbody,22,5+22*$addtimes,60,20,$DTS_TIMEFORMAT)
                                        _GUICtrlDTP_SetFormat($Group, "HH:mm")
                                $addtimes +=1
        EndSelect
WEnd
               
Func WM_VSCROLL($hWnd, $Msg, $wParam, $lParam)
        Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
        Local $index = -1, $yChar, $yPos
        Local $Min, $bechecked_MaxIndex, $Page, $Pos, $TrackPos
        For $x = 0 To UBound($aSB_WindowInfo) - 1
                If $aSB_WindowInfo[$x] = $hWnd Then
                        $index = $x
                        $yChar = $aSB_WindowInfo[$index]
                        ExitLoop
                EndIf
        Next
        If $index = -1 Then Return 0
        Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
        $Min = DllStructGetData($tSCROLLINFO, "nMin")
        $bechecked_MaxIndex = DllStructGetData($tSCROLLINFO, "nMax")
        $Page = DllStructGetData($tSCROLLINFO, "nPage")
        $yPos = DllStructGetData($tSCROLLINFO, "nPos")
        $Pos = $yPos
        $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")
      Switch $nScrollCode
                        Case $SB_TOP
                                DllStructSetData($tSCROLLINFO, "nPos", $Min)
                        Case $SB_BOTTOM
                                DllStructSetData($tSCROLLINFO, "nPos", $bechecked_MaxIndex)
                        Case $SB_LINEUP
                                DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1)
                        Case $SB_LINEDOWN
                                DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1)
                        Case $SB_PAGEUP
                                DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page)
                        Case $SB_PAGEDOWN
                                DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page)
                        Case $SB_THUMBTRACK
                                DllStructSetData($tSCROLLINFO, "nPos", $TrackPos)
      EndSwitch
        DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
        _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
        _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
        $Pos = DllStructGetData($tSCROLLINFO, "nPos")
        If ($Pos <> $yPos) Then
                _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos))
                $yPos = $Pos
        EndIf
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_VSCROLL

---------------------------------
实际上本问题产生的原因,就是无法正确判断带滚动条的GUI上面,控件的具体位置。

解决方法:
第一种方法,参照4楼设计GUI。
第二种方法,计算控件的实际位置。参照http://www.autoitx.com/thread-25941-1-1.html
UDF请参考http://www.autoitx.com/thread-25955-1-1.html
注意,与afan版主的“_ControlGetPos() [获取指定控件的屏幕坐标及大小]”是有区别的。

daiyu116 发表于 2011-7-6 13:56:18

本帖最后由 daiyu116 于 2011-7-6 14:04 编辑

占楼
希望路过的各位,用上面的代码测试一下,如能指点,感激不尽啊

另外,本人的想法是,有另外一个解决办法:
将$GUIbody的滚动条删除,为$ReportGUI添加滚动条。
这样就不会因为$GUIbody的滚动而让控件产生位置的错位了。

但是,新的问题出来了,如何让$ReportGUI只滚动一部分,让他上部分的$GUImenu不随滚动条滚动呢?

注:$ReportGUI、$GUImenu、$GUIbody分别是三个GUI窗体。
$ReportGUI为父窗体,$GUImenu、$GUIbody是他的子窗体。

daiyu116 发表于 2011-7-7 10:10:25

没有人指点?

daiyu116 发表于 2011-7-7 14:37:50

针对前两种提出的方法,实在没想出办法。
只好改用了第三种方法,目前采用了$ReportGUI、$GUImenu(内嵌$GUIbody)两个窗体分离的方法。
然后采用了窗体跟随的做法,将两个窗体绑定在一起。不算很美观。

daiyu116 发表于 2011-7-7 14:39:21

还是希望有人能指点一二

daiyu116 发表于 2011-7-7 15:48:02

本帖最后由 daiyu116 于 2011-7-7 17:28 编辑

实际上本问题产生的原因,就是无法正确判断带滚动条的GUI上面,控件的具体位置。
关于这点,本人已经有点心得,请查看这个帖子,请各位指正。
解决方法请参照:
http://www.autoitx.com/forum.php?mod=viewthread&tid=25941&page=1&extra=#pid322720

abc... 发表于 2011-7-7 17:47:49

看完帖子才知道,这是LZ的自问自答帖。。。

daiyu116 发表于 2011-7-7 17:49:11

呵呵,是因为着急用,可能没有大虾注意到这个帖子,所以自己找了一个解决方式。
有任何疑问欢迎讨论。

yhxhappy 发表于 2016-10-15 14:00:12

你的问题和我之前提出的问题很像,只是我是水平的滚动条。

http://www.autoitx.com/forum.php?mod=viewthread&tid=47809&highlight=%BF%D8%BC%FE%2B%CE%BB%D6%C3
页: [1]
查看完整版本: [已解决]使用_GUIScrollBars_Init后,在GUI上创建控件时位置偏移问题