找回密码
 加入
搜索
查看: 170684|回复: 20

[GUI管理] 如何限制窗口界面移出屏幕边缘?

 火.. [复制链接]
发表于 2010-4-23 12:03:22 | 显示全部楼层 |阅读模式
比如说屏幕上有个窗口在屏幕上移动位置时,如何限制它不可移出屏幕的边缘?
发表于 2010-4-23 12:51:36 | 显示全部楼层
我也想知道......
发表于 2010-4-23 16:02:51 | 显示全部楼层
思路:循环判断窗口的位置,一旦发现超过屏幕,就马上移动回来。
发表于 2010-4-23 17:54:52 | 显示全部楼层
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$Form = GUICreate("My GUI") ; will create a dialog box that when displayed is centered
GUISetState(@SW_SHOW) ; will display an empty dialog box

While 1
        _GUILock($Form)
        $msg = GUIGetMsg()
        If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd

GUIDelete()

Func _GUILock($hGUI)
        Local $aPos = WinGetPos($hGUI), _
                        $iX = $aPos[0], $iY = $aPos[1], $iWidth = $aPos[2], $iHeight = $aPos[3]
        If $iX < 0 Then
                $iX = 0
        ElseIf $iX + $iWidth > @DesktopWidth Then
                $iX = @DesktopWidth - $iWidth
        EndIf
        If $iY < 0 Then
                $iY = 0
        ElseIf $iY + $iHeight > @DesktopHeight Then
                $iY = @DesktopHeight - $iHeight
        EndIf
        WinMove($hGUI, '', $iX, $iY, $iWidth, $iHeight)
EndFunc   ;==>_GUILock
发表于 2010-4-23 18:43:52 | 显示全部楼层
#include <StructureConstants.au3>
#include <WindowsConstants.au3>


Local $iWidth = 400, $iHeight = 300
Local $iStyle = BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_SIZEBOX)
$hGUI = GUICreate("Test", $iWidth, $iHeight, -1, -1, $iStyle)
GUISetState()

GUIRegisterMsg(0x216, "WM_MOVING")
GUIRegisterMsg($WM_SIZE, "WM_SIZE")

While GUIGetMsg() <> -3
WEnd

Func WM_SIZE($hWnd, $iMsg, $iwParam, $ilParam)
        $iWidth = BitAnd($ilParam, 0xFFFF)
        $iHeight = BitShift($ilParam, 0x10)
EndFunc        ;==>WM_SIZE

Func WM_MOVING($hWnd, $iMsg, $iwParam, $ilParam)
        Local $tBuffer, $iLeft, $iTop

        $tBuffer = DllStructCreate($tagRECT, $ilParam)
        $iLeft = DllStructGetData($tBuffer, "Left")
        $iTop = DllStructGetData($tBuffer, "Top")
        $iRight = DllStructGetData($tBuffer, "Right")
        $iBottom = DllStructGetData($tBuffer, "Bottom")

        If ($iLeft < 0) Then
                DllStructSetData($tBuffer, "Left", 0)
        ElseIf ($iRight > @DesktopWidth) Then
                DllStructSetData($tBuffer, "Left", @DesktopWidth - $iWidth)
                DllStructSetData($tBuffer, "Right", @DesktopWidth)
        EndIf
        If ($iTop < 0) Then
                DllStructSetData($tBuffer, "Top", 0)
        ElseIf ($iBottom > @DesktopHeight) Then
                DllStructSetData($tBuffer, "Top", @DesktopHeight - $iHeight)
                DllStructSetData($tBuffer, "Bottom", @DesktopHeight)
        EndIf
        $tBuffer = 0
EndFunc        ;==>WM_MOVING
 楼主| 发表于 2010-4-23 18:52:59 | 显示全部楼层
谢谢,就是想这样的效果!!!
发表于 2010-4-23 20:10:36 | 显示全部楼层
超版就是超版~~境界不同!
发表于 2010-4-23 20:23:07 | 显示全部楼层
回复 7# zjimmy


    - -||| 谢谢赞同,5#的代码只适用于AutoIt自身进程的窗口,对于其他进程,就无能为力了,这是5#的代码缺陷所在。对于外部进程,就不得不使用zjimmy兄的方法了。或者,可以把那个外部程序破解,把自己控制窗口边界的代码嵌入进去,但这个实在太高深,要用到反汇编了,不懂~
发表于 2010-4-23 20:55:23 | 显示全部楼层
以前没注意这个,学习了
发表于 2010-4-23 21:01:05 | 显示全部楼层
本帖最后由 lainline 于 2010-4-23 21:07 编辑

详情参考http://www.autoitx.com/thread-14446-1-1.html
;#include <ACC_Const.au3>
$EVENT_SYSTEM_MOVESIZEEND = 0x000B;窗口移动结束事件
Global $hWinEventProc = DllCallbackRegister("WinEventProc", "none", "hwnd;int;hwnd;long;long;int;int");注册回调函数
_Acc_SetWinEventHook($hWinEventProc,$EVENT_SYSTEM_MOVESIZEEND,$EVENT_SYSTEM_MOVESIZEEND);设置“最小化事件”钩子

OnAutoItExitRegister("_Exit");注册退出函数
While 1
        Sleep(200)
WEnd

Func _Exit();退出程序
        _Acc_UnhookWinEvent($hWinEventProc);释放钩子
        Exit
EndFunc

;回调函数
Func WinEventProc($hHook, $iEvent, $hWnd, $idObject, $idChild, $iEventThread, $iEventTime);钩子,事件,句柄,对象,子ID,事件追逐,事件事件
        If $iEvent = $EVENT_SYSTEM_MOVESIZEEND Then
       MsgBox (0,"","窗口移动完成事件")
        EndIf
EndFunc   ;==>WinEventProc

Func _Acc_SetWinEventHook($hWinEvent,$event_start,$event_end,$mode=2);设置事件钩子
    Local $aRet,$modeget
    Local Const $WINEVENT_OUTOFCONTEXT = 0x0
        Local Const $WINEVENT_SKIPOWNTHREAD = 0x1
        Local Const $WINEVENT_SKIPOWNPROCESS = 0x2
        Local Const $WINEVENT_INCONTEXT = 0x4
        Select
                Case $mode=1
                        $modeget=$WINEVENT_OUTOFCONTEXT;0
                Case $mode=2
                        $modeget=$WINEVENT_SKIPOWNTHREAD;1
                Case $mode=3
                        $modeget=$WINEVENT_SKIPOWNPROCESS;2
                Case $mode=4
                        $modeget=$WINEVENT_INCONTEXT;4
                Case $mode=5
                        $modeget=BitOR($WINEVENT_INCONTEXT , $WINEVENT_SKIPOWNTHREAD);5
                Case $mode=6
                        $modeget=BitOR($WINEVENT_INCONTEXT , $WINEVENT_SKIPOWNPROCESS);6
                Case Else
                        $modeget=2
        EndSelect
    $aRet = DllCall("User32.dll", "hwnd", "SetWinEventHook","uint",$event_start, _
                                        "uint", $event_end, "hwnd", 0, "ptr", DllCallbackGetPtr($hWinEvent), _
                                        "int", 0, "int", 0, "uint", $modeget)
        If @error Or $aRet=0 Then Return SetError(1,0,0)
    Return $aRet[0]
EndFunc

Func _Acc_UnhookWinEvent($hHook);解除事件钩子
        DllCall("User32.dll", "int", "UnhookWinEvent", "hwnd", $hHook)
EndFunc

Func _Acc_CoInitializeEx();初始化
        $aRet = DllCall("Ole32.dll", "long", "CoInitializeEx", "ptr", 0, "dword", 2)
EndFunc

评分

参与人数 1金钱 +30 收起 理由
pusofalse + 30 感谢分享

查看全部评分

发表于 2010-4-23 21:28:22 | 显示全部楼层
回复 10# lainline


    请教一下,我下载了lainline兄发表的【Accessible 技术实例集】中的附件,发现其中的API调用中有idispatch*这样一个写法,请教这是什么意思?谢谢~
发表于 2010-4-23 21:38:49 | 显示全部楼层
不清楚呢
例子没吃透
好像是新语法
另外有时RtlMoveMemory 要改成RtlCopyMemory
要不然程序内存会不断增加
发表于 2010-4-23 21:41:16 | 显示全部楼层
看了下帮助
* 传递一个其它类型(添加一个*到末尾.) 例如 "int*" 传递一个指针到 "int" 类型.
发表于 2010-4-23 22:06:09 | 显示全部楼层
API调用中,星号*的作用我知道,多数情况下是用于不超过8字节的输出型参数,只是不明白idispatch是什么类型。
发表于 2010-4-23 22:20:10 | 显示全部楼层
搜下帮助里面 com参考里面有大片的英文 没有仔细看应该是com 接口
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-5-12 10:12 , Processed in 0.092679 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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