找回密码  加入

AUTOIT CN

搜索
查看: 207|回复: 19

[AU3基础] [已解决]给窗口添加滚动条后调整控件位置出错的问题,求解!

[复制链接]
发表于 2018-8-7 11:35:14 | 显示全部楼层 |阅读模式
本帖最后由 水木子 于 2018-8-7 15:08 编辑

我先说明下情况:
给窗口添加滚动条,滑动滚动条,点击 Button2 调整 Button1 的位置,不难发现 Button1 的位置出错。
经过我反复测试发现应该是 _GUIScrollBars_ScrollWindow 滚动指定窗口客户区这个函数造成的,请问该如何解决?谢谢!
测试代码如下:

  1. #include <GuiScrollBars.au3>
  2. #include <GUIConstantsEx.au3>
  3. #include <WindowsConstants.au3>

  4. $hGui1 = GUICreate('', 400, 300)
  5. GUISetBkColor(0x88AABB)
  6. $Button1 = GUICtrlCreateButton('Button1', 80, 100, 100, 30)
  7. $Button2 = GUICtrlCreateButton('Button2', 250, 100, 100, 30)

  8. GUIRegisterMsg($WM_VSCROLL, 'WM_VSCROLL')
  9. GUIRegisterMsg($WM_MOUSEWHEEL, 'WM_MOUSEWHEEL')
  10. GUISetState()

  11. _GUIScrollBars_Init($hGui1)
  12. _GUIScrollBars_SetScrollRange($hGui1, $SB_VERT, 0, 50)

  13. While 1
  14.         $hGUIMsg = GUIGetMsg()

  15.         Switch $hGUIMsg
  16.                 Case -3
  17.                         Exit
  18.                         
  19.                 Case $Button1                        
  20.                         
  21.                 Case $Button2
  22. ;~                         $iPos = _GUIScrollBars_GetScrollInfoPos($hGui1, $SB_VERT)
  23.                         GUICtrlSetPos($Button1, Default, 100)
  24.         EndSwitch
  25. WEnd

  26. Func WM_VSCROLL($hWnd, $iMsg, $wParam, $lParam) ;垂直滚动
  27.         #forceref $iMsg, $wParam, $lParam
  28.         Local $iScrollCode = BitAND($wParam, 0x0000FFFF)
  29.         Local $iIndex = -1, $iCharY, $iPosY
  30.         Local $iMin, $iMax, $iPage, $iPos, $iTrackPos

  31.         For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
  32.                 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
  33.                         $iIndex = $x
  34.                         $iCharY = $__g_aSB_WindowInfo[$iIndex][3]
  35.                         ExitLoop
  36.                 EndIf
  37.         Next
  38.         If $iIndex = -1 Then Return 0

  39.         ; 获取垂直滚动条所有信息
  40.         Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
  41.         $iMin = DllStructGetData($tSCROLLINFO, 'nMin')
  42.         $iMax = DllStructGetData($tSCROLLINFO, 'nMax')
  43.         $iPage = DllStructGetData($tSCROLLINFO, 'nPage')
  44.         ; 保存位置以后进行比较
  45.         $iPosY = DllStructGetData($tSCROLLINFO, 'nPos')
  46.         $iPos = $iPosY
  47.         $iTrackPos = DllStructGetData($tSCROLLINFO, 'nTrackPos')

  48.         Switch $iScrollCode
  49.                 Case $SB_TOP ; 用户点击键盘 HOME 键
  50.                         DllStructSetData($tSCROLLINFO, 'nPos', $iMin)

  51.                 Case $SB_BOTTOM ; 用户点击键盘 END 键
  52.                         DllStructSetData($tSCROLLINFO, 'nPos', $iMax)

  53.                 Case $SB_LINEUP ; 用户点击向上箭头
  54.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos - 1)

  55.                 Case $SB_LINEDOWN ; 用户点击底部向下箭头
  56.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos + 1)

  57.                 Case $SB_PAGEUP ; 用户点击滚动框内滚动条的上面
  58.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos - $iPage)

  59.                 Case $SB_PAGEDOWN ; 用户点击滚动框内滚动条的下面
  60.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos + $iPage)

  61.                 Case $SB_THUMBTRACK ; 用户拖动滚动条
  62.                         DllStructSetData($tSCROLLINFO, 'nPos', $iTrackPos)
  63.         EndSwitch

  64.         ; // 设置的位置,然后检索它,
  65.         ; //   因 Windows 的原因,设定值可能不相同.

  66.         DllStructSetData($tSCROLLINFO, 'fMask', $SIF_POS)
  67.         _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  68.         _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  69.         ;// 如果位置发生了变化, 则滚动窗口并更新
  70.         $iPos = DllStructGetData($tSCROLLINFO, 'nPos')

  71.         If ($iPos <> $iPosY) Then
  72.                 _GUIScrollBars_ScrollWindow($hWnd, 0, $iCharY * ($iPosY - $iPos))
  73.                 $iPosY = $iPos
  74.         EndIf

  75.         Return $GUI_RUNDEFMSG
  76. EndFunc   ;==>WM_VSCROLL

  77. Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam) ;设置滚动条鼠标滑轮
  78.         #forceref $hWnd, $iMsg, $lParam
  79.         Local $updown = BitShift($wParam, 16)
  80.         $updown = $updown / 120
  81.         Local $iIndex = -1, $iCharY, $iPosY
  82.         Local $iMin, $iMax, $iPage, $iPos, $iTrackPos
  83.         For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
  84.                 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
  85.                         $iIndex = $x
  86.                         $iCharY = $__g_aSB_WindowInfo[$iIndex][3]
  87.                         ExitLoop
  88.                 EndIf
  89.         Next
  90.         If $iIndex = -1 Then Return 0
  91.         Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
  92.         $iMin = DllStructGetData($tSCROLLINFO, 'nMin')
  93.         $iMax = DllStructGetData($tSCROLLINFO, 'nMax')
  94.         $iPage = DllStructGetData($tSCROLLINFO, 'nPage')
  95.         $iPosY = DllStructGetData($tSCROLLINFO, 'nPos')
  96.         $iPos = $iPosY
  97.         $iTrackPos = DllStructGetData($tSCROLLINFO, 'nTrackPos')
  98.         DllStructSetData($tSCROLLINFO, 'nPos', $iPos - $updown)
  99.         DllStructSetData($tSCROLLINFO, 'fMask', $SIF_POS)
  100.         _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  101.         _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  102.         $iPos = DllStructGetData($tSCROLLINFO, 'nPos')
  103.         If ($iPos <> $iPosY) Then
  104.                 _GUIScrollBars_ScrollWindow($hWnd, 0, $iCharY * ($iPosY - $iPos))
  105.                 $iPosY = $iPos
  106.         EndIf
  107.         Return $GUI_RUNDEFMSG
  108. EndFunc   ;==>WM_MOUSEWHEEL
复制代码

 楼主| 发表于 2018-8-7 11:49:47 | 显示全部楼层
已经变相解决了。
谁有解决方法,欢迎指教,谢谢!
发表于 2018-8-7 13:05:19 | 显示全部楼层
_GUIScrollBars_Init() 初始化之后就会影响控件的相对坐标
可以在创建窗口前加 Opt('GUIResizeMode', 802) 试试~

评分

1

查看全部评分

发表于 2018-8-7 14:44:48 | 显示全部楼层
是不是这样子

  1. #include <GuiScrollBars.au3>
  2. #include <GUIConstantsEx.au3>
  3. #include <WindowsConstants.au3>

  4. $hGui1 = GUICreate('', 400, 300)
  5. GUISetBkColor(0x88AABB)
  6. $Button1 = GUICtrlCreateButton('Button1', 80, 100, 100, 30)
  7. $Button2 = GUICtrlCreateButton('Button2', 250, 100, 100, 30)
  8. GUIRegisterMsg($WM_SIZE, "WM_SIZE")
  9. GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL")
  10. GUIRegisterMsg($WM_VSCROLL, 'WM_VSCROLL')
  11. GUIRegisterMsg($WM_MOUSEWHEEL, 'WM_MOUSEWHEEL')
  12. GUISetState()

  13. _GUIScrollBars_Init($hGui1)
  14. _GUIScrollBars_SetScrollRange($hGui1, $SB_VERT, 0, 50)
  15. _GUIScrollBars_SetScrollRange($hGui1, $SB_HORZ, 0, 50) ;设置水平滚动条参数
  16. While 1
  17.         $hGUIMsg = GUIGetMsg()

  18.         Switch $hGUIMsg
  19.                 Case -3
  20.                         Exit

  21.                 Case $Button1
  22.                         GUICtrlSetPos($Button2, Default, 100)
  23.                 Case $Button2
  24. ;~                         $iPos = _GUIScrollBars_GetScrollInfoPos($hGui1, $SB_VERT)
  25.                         GUICtrlSetPos($Button1, Default, 100)
  26.         EndSwitch
  27. WEnd

  28. Func WM_VSCROLL($hWnd, $iMsg, $wParam, $lParam) ;垂直滚动
  29.         #forceref $iMsg, $wParam, $lParam
  30.         Local $iScrollCode = BitAND($wParam, 0x0000FFFF)
  31.         Local $iIndex = -1, $iCharY, $iPosY
  32.         Local $iMin, $iMax, $iPage, $iPos, $iTrackPos

  33.         For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
  34.                 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
  35.                         $iIndex = $x
  36.                         $iCharY = $__g_aSB_WindowInfo[$iIndex][3]
  37.                         ExitLoop
  38.                 EndIf
  39.         Next
  40.         If $iIndex = -1 Then Return 0

  41.         ; 获取垂直滚动条所有信息
  42.         Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
  43.         $iMin = DllStructGetData($tSCROLLINFO, 'nMin')
  44.         $iMax = DllStructGetData($tSCROLLINFO, 'nMax')
  45.         $iPage = DllStructGetData($tSCROLLINFO, 'nPage')
  46.         ; 保存位置以后进行比较
  47.         $iPosY = DllStructGetData($tSCROLLINFO, 'nPos')
  48.         $iPos = $iPosY
  49.         $iTrackPos = DllStructGetData($tSCROLLINFO, 'nTrackPos')

  50.         Switch $iScrollCode
  51.                 Case $SB_TOP ; 用户点击键盘 HOME 键
  52.                         DllStructSetData($tSCROLLINFO, 'nPos', $iMin)

  53.                 Case $SB_BOTTOM ; 用户点击键盘 END 键
  54.                         DllStructSetData($tSCROLLINFO, 'nPos', $iMax)

  55.                 Case $SB_LINEUP ; 用户点击向上箭头
  56.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos - 1)

  57.                 Case $SB_LINEDOWN ; 用户点击底部向下箭头
  58.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos + 1)

  59.                 Case $SB_PAGEUP ; 用户点击滚动框内滚动条的上面
  60.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos - $iPage)

  61.                 Case $SB_PAGEDOWN ; 用户点击滚动框内滚动条的下面
  62.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos + $iPage)

  63.                 Case $SB_THUMBTRACK ; 用户拖动滚动条
  64.                         DllStructSetData($tSCROLLINFO, 'nPos', $iTrackPos)
  65.         EndSwitch

  66.         ; // 设置的位置,然后检索它,
  67.         ; //   因 Windows 的原因,设定值可能不相同.

  68.         DllStructSetData($tSCROLLINFO, 'fMask', $SIF_POS)
  69.         _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  70.         _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  71.         ;// 如果位置发生了变化, 则滚动窗口并更新
  72.         $iPos = DllStructGetData($tSCROLLINFO, 'nPos')

  73.         If ($iPos <> $iPosY) Then
  74.                 _GUIScrollBars_ScrollWindow($hWnd, 0, $iCharY * ($iPosY - $iPos))
  75.                 $iPosY = $iPos
  76.         EndIf

  77.         Return $GUI_RUNDEFMSG
  78. EndFunc   ;==>WM_VSCROLL
  79. Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam)
  80.         #forceref $iMsg, $wParam
  81.         Local $iIndex = -1, $iCharY, $iCharX, $iClientMaxX, $iClientX, $iClientY, $iMax
  82.         For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
  83.                 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
  84.                         $iIndex = $x
  85.                         $iClientMaxX = $__g_aSB_WindowInfo[$iIndex][1]
  86.                         $iCharX = $__g_aSB_WindowInfo[$iIndex][2]
  87.                         $iCharY = $__g_aSB_WindowInfo[$iIndex][3]
  88.                         $iMax = $__g_aSB_WindowInfo[$iIndex][7]
  89.                         ExitLoop
  90.                 EndIf
  91.         Next
  92.         If $iIndex = -1 Then Return 0

  93.         Local $tSCROLLINFO = DllStructCreate($tagSCROLLINFO)

  94.         ; 检索客户区尺寸.
  95.         $iClientX = BitAND($lParam, 0x0000FFFF)
  96.         $iClientY = BitShift($lParam, 16)
  97.         $__g_aSB_WindowInfo[$iIndex][4] = $iClientX
  98.         $__g_aSB_WindowInfo[$iIndex][5] = $iClientY

  99.         ; 设置垂直滚动范围和页面大小
  100.         DllStructSetData($tSCROLLINFO, "fMask", BitOR($SIF_RANGE, $SIF_PAGE))
  101.         DllStructSetData($tSCROLLINFO, "nMin", 0)
  102.         DllStructSetData($tSCROLLINFO, "nMax", $iMax)
  103.         DllStructSetData($tSCROLLINFO, "nPage", $iClientY / $iCharY)
  104.         _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)

  105.         ; 设置水平滚动范围和页面大小
  106.         DllStructSetData($tSCROLLINFO, "fMask", BitOR($SIF_RANGE, $SIF_PAGE))
  107.         DllStructSetData($tSCROLLINFO, "nMin", 0)
  108.         DllStructSetData($tSCROLLINFO, "nMax", 2 + $iClientMaxX / $iCharX)
  109.         DllStructSetData($tSCROLLINFO, "nPage", $iClientX / $iCharX)
  110.         _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)

  111.         Return $GUI_RUNDEFMSG
  112. EndFunc   ;==>WM_SIZE
  113. Func WM_HSCROLL($hWnd, $iMsg, $wParam, $lParam)
  114.         #forceref $iMsg, $lParam
  115.         Local $iScrollCode = BitAND($wParam, 0x0000FFFF)

  116.         Local $iIndex = -1, $iCharX, $iPosX
  117.         Local $iMin, $iMax, $iPage, $iPos, $iTrackPos

  118.         For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
  119.                 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
  120.                         $iIndex = $x
  121.                         $iCharX = $__g_aSB_WindowInfo[$iIndex][2]
  122.                         ExitLoop
  123.                 EndIf
  124.         Next
  125.         If $iIndex = -1 Then Return 0

  126.         ; ; 获取所有的水平滚动条信息
  127.         Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
  128.         $iMin = DllStructGetData($tSCROLLINFO, "nMin")
  129.         $iMax = DllStructGetData($tSCROLLINFO, "nMax")
  130.         $iPage = DllStructGetData($tSCROLLINFO, "nPage")
  131.         ; 保存位置以后进行比较
  132.         $iPosX = DllStructGetData($tSCROLLINFO, "nPos")
  133.         $iPos = $iPosX
  134.         $iTrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")
  135.         #forceref $iMin, $iMax
  136.         Switch $iScrollCode

  137.                 Case $SB_LINELEFT ; 用户点击向左箭头
  138.                         DllStructSetData($tSCROLLINFO, "nPos", $iPos - 1)

  139.                 Case $SB_LINERIGHT ; 用户点击向右箭头
  140.                         DllStructSetData($tSCROLLINFO, "nPos", $iPos + 1)

  141.                 Case $SB_PAGELEFT ; 用户单击滚动条轴左侧
  142.                         DllStructSetData($tSCROLLINFO, "nPos", $iPos - $iPage)

  143.                 Case $SB_PAGERIGHT ; 用户单击滚动条轴右侧
  144.                         DllStructSetData($tSCROLLINFO, "nPos", $iPos + $iPage)

  145.                 Case $SB_THUMBTRACK ; 用户拖动滚动条
  146.                         DllStructSetData($tSCROLLINFO, "nPos", $iTrackPos)
  147.         EndSwitch

  148.         ; // 设置的位置,然后检索它,
  149.         ; //   因 Windows 的原因,设定值可能不相同.

  150.         DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
  151.         _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
  152.         _GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
  153.         ;// 如果位置发生了变化, 则滚动窗口并更新
  154.         $iPos = DllStructGetData($tSCROLLINFO, "nPos")
  155.         If ($iPos <> $iPosX) Then _GUIScrollBars_ScrollWindow($hWnd, $iCharX * ($iPosX - $iPos), 0)
  156.         Return $GUI_RUNDEFMSG
  157. EndFunc   ;==>WM_HSCROLL
  158. Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam) ;设置滚动条鼠标滑轮
  159.         #forceref $hWnd, $iMsg, $lParam
  160.         Local $updown = BitShift($wParam, 16)
  161.         $updown = $updown / 120
  162.         Local $iIndex = -1, $iCharY, $iPosY
  163.         Local $iMin, $iMax, $iPage, $iPos, $iTrackPos
  164.         For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
  165.                 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
  166.                         $iIndex = $x
  167.                         $iCharY = $__g_aSB_WindowInfo[$iIndex][3]
  168.                         ExitLoop
  169.                 EndIf
  170.         Next
  171.         If $iIndex = -1 Then Return 0
  172.         Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
  173.         $iMin = DllStructGetData($tSCROLLINFO, 'nMin')
  174.         $iMax = DllStructGetData($tSCROLLINFO, 'nMax')
  175.         $iPage = DllStructGetData($tSCROLLINFO, 'nPage')
  176.         $iPosY = DllStructGetData($tSCROLLINFO, 'nPos')
  177.         $iPos = $iPosY
  178.         $iTrackPos = DllStructGetData($tSCROLLINFO, 'nTrackPos')
  179.         DllStructSetData($tSCROLLINFO, 'nPos', $iPos - $updown)
  180.         DllStructSetData($tSCROLLINFO, 'fMask', $SIF_POS)
  181.         _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  182.         _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  183.         $iPos = DllStructGetData($tSCROLLINFO, 'nPos')
  184.         If ($iPos <> $iPosY) Then
  185.                 _GUIScrollBars_ScrollWindow($hWnd, 0, $iCharY * ($iPosY - $iPos))
  186.                 $iPosY = $iPos
  187.         EndIf
  188.         Return $GUI_RUNDEFMSG
  189. EndFunc   ;==>WM_MOUSEWHEEL
复制代码

评分

1

查看全部评分

 楼主| 发表于 2018-8-7 15:05:31 | 显示全部楼层

谢谢你的回复,不过你可能没有明白我的意思。
你没发现滑动滚动条以后,再调整控件位置,控件位置不对吗?
 楼主| 发表于 2018-8-7 15:07:13 | 显示全部楼层
afan 发表于 2018-8-7 13:05
_GUIScrollBars_Init() 初始化之后就会影响控件的相对坐标
可以在创建窗口前加 Opt('GUIResizeMode', 802) ...

我晕哦!原来这么简单啊!感谢afan前辈的指点。
 楼主| 发表于 2018-8-7 15:08:58 | 显示全部楼层
本帖最后由 水木子 于 2018-8-7 15:15 编辑

问题已解决。我的解决方法如下:
  1. #include <GuiScrollBars.au3>
  2. #include <GUIConstantsEx.au3>
  3. #include <WindowsConstants.au3>

  4. ;~ Opt('GUIResizeMode', 802)
  5. Global $iYAmount

  6. $hGui1 = GUICreate('', 400, 300)
  7. GUISetBkColor(0x88AABB)
  8. $Button1 = GUICtrlCreateButton('Button1', 80, 100, 100, 30)
  9. $Button2 = GUICtrlCreateButton('Button2', 250, 100, 100, 30)

  10. GUIRegisterMsg($WM_VSCROLL, 'WM_VSCROLL')
  11. GUIRegisterMsg($WM_MOUSEWHEEL, 'WM_MOUSEWHEEL')
  12. GUISetState()

  13. _GUIScrollBars_Init($hGui1)
  14. ;~ _GUIScrollBars_SetScrollInfoPage($hGui1, $SB_VERT, 20)
  15. _GUIScrollBars_SetScrollRange($hGui1, $SB_VERT, 0, 100)

  16. $aPos = ControlGetPos($hGui1, '', $Button1)

  17. While 1
  18.         $hGUIMsg = GUIGetMsg()

  19.         Switch $hGUIMsg
  20.                 Case -3
  21.                         Exit
  22.                        
  23.                 Case $Button1
  24.                        
  25.                        
  26.                 Case $Button2
  27.                         $iPos = _GUIScrollBars_GetScrollInfoPos($hGui1, $SB_VERT)
  28.                         GUICtrlSetPos($Button1, Default, $aPos[1] - $iPos * 16)
  29.         EndSwitch
  30. WEnd

  31. Func WM_VSCROLL($hWnd, $iMsg, $wParam, $lParam) ;垂直滚动
  32.         #forceref $iMsg, $wParam, $lParam
  33.         Local $iScrollCode = BitAND($wParam, 0x0000FFFF)
  34.         Local $iIndex = -1, $iCharY, $iPosY
  35.         Local $iMin, $iMax, $iPage, $iPos, $iTrackPos

  36.         For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
  37.                 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
  38.                         $iIndex = $x
  39.                         $iCharY = $__g_aSB_WindowInfo[$iIndex][3]
  40.                         ExitLoop
  41.                 EndIf
  42.         Next
  43.         If $iIndex = -1 Then Return 0

  44.         ; 获取垂直滚动条所有信息
  45.         Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
  46.         $iMin = DllStructGetData($tSCROLLINFO, 'nMin')
  47.         $iMax = DllStructGetData($tSCROLLINFO, 'nMax')
  48.         $iPage = DllStructGetData($tSCROLLINFO, 'nPage')
  49.         ; 保存位置以后进行比较
  50.         $iPosY = DllStructGetData($tSCROLLINFO, 'nPos')
  51.         $iPos = $iPosY
  52.         $iTrackPos = DllStructGetData($tSCROLLINFO, 'nTrackPos')

  53.         Switch $iScrollCode
  54.                 Case $SB_TOP ; 用户点击键盘 HOME 键
  55.                         DllStructSetData($tSCROLLINFO, 'nPos', $iMin)

  56.                 Case $SB_BOTTOM ; 用户点击键盘 END 键
  57.                         DllStructSetData($tSCROLLINFO, 'nPos', $iMax)

  58.                 Case $SB_LINEUP ; 用户点击向上箭头
  59.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos - 1)

  60.                 Case $SB_LINEDOWN ; 用户点击底部向下箭头
  61.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos + 1)

  62.                 Case $SB_PAGEUP ; 用户点击滚动框内滚动条的上面
  63.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos - $iPage)

  64.                 Case $SB_PAGEDOWN ; 用户点击滚动框内滚动条的下面
  65.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos + $iPage)

  66.                 Case $SB_THUMBTRACK ; 用户拖动滚动条
  67.                         DllStructSetData($tSCROLLINFO, 'nPos', $iTrackPos)
  68.         EndSwitch

  69.         ; // 设置的位置,然后检索它,
  70.         ; //   因 Windows 的原因,设定值可能不相同.

  71.         DllStructSetData($tSCROLLINFO, 'fMask', $SIF_POS)
  72.         _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  73.         _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  74.         ;// 如果位置发生了变化, 则滚动窗口并更新
  75.         $iPos = DllStructGetData($tSCROLLINFO, 'nPos')

  76.         If ($iPos <> $iPosY) Then
  77.                 _GUIScrollBars_ScrollWindow($hWnd, 0, $iCharY * ($iPosY - $iPos))
  78.                 $iPosY = $iPos
  79.         EndIf

  80.         Return $GUI_RUNDEFMSG
  81. EndFunc   ;==>WM_VSCROLL

  82. Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam) ;设置滚动条鼠标滑轮
  83.         #forceref $hWnd, $iMsg, $lParam
  84.         Local $updown = BitShift($wParam, 16)
  85.         $updown = $updown / 120
  86.         Local $iIndex = -1, $iCharY, $iPosY
  87.         Local $iMin, $iMax, $iPage, $iPos, $iTrackPos
  88.         For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
  89.                 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
  90.                         $iIndex = $x
  91.                         $iCharY = $__g_aSB_WindowInfo[$iIndex][3]
  92.                         ExitLoop
  93.                 EndIf
  94.         Next
  95.         If $iIndex = -1 Then Return 0
  96.         Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
  97.         $iMin = DllStructGetData($tSCROLLINFO, 'nMin')
  98.         $iMax = DllStructGetData($tSCROLLINFO, 'nMax')
  99.         $iPage = DllStructGetData($tSCROLLINFO, 'nPage')
  100.         $iPosY = DllStructGetData($tSCROLLINFO, 'nPos')
  101.         $iPos = $iPosY
  102.         $iTrackPos = DllStructGetData($tSCROLLINFO, 'nTrackPos')
  103.         DllStructSetData($tSCROLLINFO, 'nPos', $iPos - $updown)
  104.         DllStructSetData($tSCROLLINFO, 'fMask', $SIF_POS)
  105.         _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  106.         _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  107.         $iPos = DllStructGetData($tSCROLLINFO, 'nPos')
  108.         If ($iPos <> $iPosY) Then
  109.                 _GUIScrollBars_ScrollWindow($hWnd, 0, $iCharY * ($iPosY - $iPos))
  110.                 $iPosY = $iPos
  111.         EndIf
  112.         Return $GUI_RUNDEFMSG
  113. EndFunc   ;==>WM_MOUSEWHEEL
复制代码


 楼主| 发表于 2018-8-7 15:18:42 | 显示全部楼层
afan 发表于 2018-8-7 13:05
_GUIScrollBars_Init() 初始化之后就会影响控件的相对坐标
可以在创建窗口前加 Opt('GUIResizeMode', 802) ...

afan 老师,你这个方法我测试了,控件较少的时候,确实可以。
但是我在测试了大量空间的时候,还是会有问题。不知道什么原因。
用我在7楼的代码就没问题。
发表于 2018-8-7 15:47:00 | 显示全部楼层
水木子 发表于 2018-8-7 15:18
afan 老师,你这个方法我测试了,控件较少的时候,确实可以。
但是我在测试了大量空间的时候,还是会有 ...

木子才是老师。不要闹~!
我是简单测试了一下,无实际代码测试,不知道大量控件的影响情况。其实适合自己用途的代码才是最优的,比如7#的。只是,由于我不知道你的实际情况,仅按解决代码看,既然没有移动位置,那是不是 GUICtrlSetPos($Button1, Default, Default) 就好了?
 楼主| 发表于 2018-8-7 16:15:03 | 显示全部楼层
afan 发表于 2018-8-7 15:47
木子才是老师。不要闹~!
我是简单测试了一下,无实际代码测试,不知道大量控件的影响情况。其实适合自 ...

前辈不好意思,怪我没把问题讲清楚,实际上是这样的。
我想要在有滚动条的窗口中交换多个控件的位置。代码如下:
  1. #include <GuiScrollBars.au3>
  2. #include <GUIConstantsEx.au3>
  3. #include <WindowsConstants.au3>

  4. Opt("GUICoordMode", 1)
  5. Opt('GUIResizeMode', 802)

  6. $hGui1 = GUICreate('', 400, 300)
  7. GUISetBkColor(0x88AABB)
  8. $Button1 = GUICtrlCreateButton('Button1', 80, 100, 100, 30)
  9. $Button2 = GUICtrlCreateButton('Button2', 80, 350, 100, 30)
  10. $Button3 = GUICtrlCreateButton('Button3', 250, 100, 100, 30)

  11. GUIRegisterMsg($WM_VSCROLL, 'WM_VSCROLL')
  12. GUIRegisterMsg($WM_MOUSEWHEEL, 'WM_MOUSEWHEEL')
  13. GUISetState()

  14. _GUIScrollBars_Init($hGui1)
  15. _GUIScrollBars_SetScrollRange($hGui1, $SB_VERT, 0, 50)

  16. ;~ $aPos1 = ControlGetPos($hGui1, '', $Button1)
  17. ;~ $aPos2 = ControlGetPos($hGui1, '', $Button2)

  18. While 1
  19.         $hGUIMsg = GUIGetMsg()

  20.         Switch $hGUIMsg
  21.                 Case -3
  22.                         Exit
  23.                        
  24.                 Case $Button1
  25.                        
  26.                        
  27.                 Case $Button3
  28. ;~                         $iPos = _GUIScrollBars_GetScrollInfoPos($hGui1, $SB_VERT)
  29.                         GUICtrlSetPos($Button1, Default, 350)
  30.                         GUICtrlSetPos($Button2, Default, 100)
  31.         EndSwitch
  32. WEnd

  33. Func WM_VSCROLL($hWnd, $iMsg, $wParam, $lParam) ;垂直滚动
  34.         #forceref $iMsg, $wParam, $lParam
  35.         Local $iScrollCode = BitAND($wParam, 0x0000FFFF)
  36.         Local $iIndex = -1, $iCharY, $iPosY
  37.         Local $iMin, $iMax, $iPage, $iPos, $iTrackPos

  38.         For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
  39.                 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
  40.                         $iIndex = $x
  41.                         $iCharY = $__g_aSB_WindowInfo[$iIndex][3]
  42.                         ExitLoop
  43.                 EndIf
  44.         Next
  45.         If $iIndex = -1 Then Return 0

  46.         ; 获取垂直滚动条所有信息
  47.         Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
  48.         $iMin = DllStructGetData($tSCROLLINFO, 'nMin')
  49.         $iMax = DllStructGetData($tSCROLLINFO, 'nMax')
  50.         $iPage = DllStructGetData($tSCROLLINFO, 'nPage')
  51.         ; 保存位置以后进行比较
  52.         $iPosY = DllStructGetData($tSCROLLINFO, 'nPos')
  53.         $iPos = $iPosY
  54.         $iTrackPos = DllStructGetData($tSCROLLINFO, 'nTrackPos')

  55.         Switch $iScrollCode
  56.                 Case $SB_TOP ; 用户点击键盘 HOME 键
  57.                         DllStructSetData($tSCROLLINFO, 'nPos', $iMin)

  58.                 Case $SB_BOTTOM ; 用户点击键盘 END 键
  59.                         DllStructSetData($tSCROLLINFO, 'nPos', $iMax)

  60.                 Case $SB_LINEUP ; 用户点击向上箭头
  61.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos - 1)

  62.                 Case $SB_LINEDOWN ; 用户点击底部向下箭头
  63.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos + 1)

  64.                 Case $SB_PAGEUP ; 用户点击滚动框内滚动条的上面
  65.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos - $iPage)

  66.                 Case $SB_PAGEDOWN ; 用户点击滚动框内滚动条的下面
  67.                         DllStructSetData($tSCROLLINFO, 'nPos', $iPos + $iPage)

  68.                 Case $SB_THUMBTRACK ; 用户拖动滚动条
  69.                         DllStructSetData($tSCROLLINFO, 'nPos', $iTrackPos)
  70.         EndSwitch

  71.         ; // 设置的位置,然后检索它,
  72.         ; //   因 Windows 的原因,设定值可能不相同.

  73.         DllStructSetData($tSCROLLINFO, 'fMask', $SIF_POS)
  74.         _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  75.         _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  76.         ;// 如果位置发生了变化, 则滚动窗口并更新
  77.         $iPos = DllStructGetData($tSCROLLINFO, 'nPos')

  78.         If ($iPos <> $iPosY) Then
  79.                 _GUIScrollBars_ScrollWindow($hWnd, 0, $iCharY * ($iPosY - $iPos))
  80.                 $iPosY = $iPos
  81.         EndIf

  82.         Return $GUI_RUNDEFMSG
  83. EndFunc   ;==>WM_VSCROLL

  84. Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam) ;设置滚动条鼠标滑轮
  85.         #forceref $hWnd, $iMsg, $lParam
  86.         Local $updown = BitShift($wParam, 16)
  87.         $updown = $updown / 120
  88.         Local $iIndex = -1, $iCharY, $iPosY
  89.         Local $iMin, $iMax, $iPage, $iPos, $iTrackPos
  90.         For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
  91.                 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
  92.                         $iIndex = $x
  93.                         $iCharY = $__g_aSB_WindowInfo[$iIndex][3]
  94.                         ExitLoop
  95.                 EndIf
  96.         Next
  97.         If $iIndex = -1 Then Return 0
  98.         Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
  99.         $iMin = DllStructGetData($tSCROLLINFO, 'nMin')
  100.         $iMax = DllStructGetData($tSCROLLINFO, 'nMax')
  101.         $iPage = DllStructGetData($tSCROLLINFO, 'nPage')
  102.         $iPosY = DllStructGetData($tSCROLLINFO, 'nPos')
  103.         $iPos = $iPosY
  104.         $iTrackPos = DllStructGetData($tSCROLLINFO, 'nTrackPos')
  105.         DllStructSetData($tSCROLLINFO, 'nPos', $iPos - $updown)
  106.         DllStructSetData($tSCROLLINFO, 'fMask', $SIF_POS)
  107.         _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  108.         _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  109.         $iPos = DllStructGetData($tSCROLLINFO, 'nPos')
  110.         If ($iPos <> $iPosY) Then
  111.                 _GUIScrollBars_ScrollWindow($hWnd, 0, $iCharY * ($iPosY - $iPos))
  112.                 $iPosY = $iPos
  113.         EndIf
  114.         Return $GUI_RUNDEFMSG
  115. EndFunc   ;==>WM_MOUSEWHEEL
复制代码
发表于 2018-8-7 16:28:50 | 显示全部楼层
水木子 发表于 2018-8-7 16:15
前辈不好意思,怪我没把问题讲清楚,实际上是这样的。
我想要在有滚动条的窗口中交换多个控件的位置。代 ...

交换不是这样吗?
$aPos1 = ControlGetPos($hGui1, '', $Button1)
$aPos2 = ControlGetPos($hGui1, '', $Button2)
GUICtrlSetPos($Button1, Default, $aPos2[1])
GUICtrlSetPos($Button2, Default, $aPos1[1])
 楼主| 发表于 2018-8-7 16:32:59 | 显示全部楼层
afan 发表于 2018-8-7 16:28
交换不是这样吗?
$aPos1 = ControlGetPos($hGui1, '', $Button1)
$aPos2 = ControlGetPos($hGui1, '', ...

对呀!但是你把滚动条往下拉点,再交换试试。
发表于 2018-8-7 16:46:19 | 显示全部楼层
水木子 发表于 2018-8-7 16:32
对呀!但是你把滚动条往下拉点,再交换试试。

往下拉试了, 10#的是错位的。但是11#正常啊~
 楼主| 发表于 2018-8-7 16:50:10 | 显示全部楼层
afan 发表于 2018-8-7 16:46
往下拉试了, 10#的是错位的。但是11#正常啊~

我测试了 11#的方法,同样是错位的。
我想应该是 _GUIScrollBars_ScrollWindow 这个函数重新定义了窗口的客户区坐标。
发表于 2018-8-7 17:05:19 | 显示全部楼层
水木子 发表于 2018-8-7 16:50
我测试了 11#的方法,同样是错位的。
我想应该是 _GUIScrollBars_ScrollWindow 这个函数重新定义了窗口 ...

除非你的代码不是这样,GetPos 之后进行了滚动操作~  如果GetPos、SetPos是连续的,客户区坐标不管怎么变, GetPos 获取的已经是改变后的,SetPos 应该就是正常的。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|小黑屋|手机版|AUTOIT CN ( 鲁ICP备15028933号-3 )谷歌 百度

GMT+8, 2018-8-19 04:28 , Processed in 0.091717 second(s), 16 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表