找回密码
 加入
搜索
查看: 6194|回复: 9

[AU3基础] 一个无边框窗体随意移动并拉伸的实例

  [复制链接]
发表于 2010-3-5 08:53:44 | 显示全部楼层 |阅读模式
头些天弄一个锁定的窗口,搞不定,来论坛得到了帮助。这些天我又加了些功能,这个无边框窗口不仅可以随意的拖动,还可以随意的拉伸。当然这对于高手和行家来说,实在不算什么。可自已在做的过程中,还是经历了多次的失败。虽说网络很方便,可是很多介绍却是含糊而简略的。这里我将这个做出的代码贴出来与大家分享,说不准能够帮到一些人。

发送$HTCAPTION指令移动窗体后,窗体大小就无法伸缩了。网上有很多方法,AU3的却很少。而那些方法,要么含糊不清,要么云山雾罩,贴来贴来,未经验实的居多。令我等凡人,头疼不已。试想微软也提供消息接口参数,让大家可以利用。而这么一个简单的功能,却没人提供现成的代码,对于这些,高手们完全可以无偿提供代码及注解,让后学者不至于做无谓的付出。

窗体不能伸缩后,通过做窗体移动,发送$HTCAPTION消息的经验,想到,也许可以通过向系统发送某个消息来使窗体伸缩。就去查,但只查WM_NCHITTEST。又到网上查,看了许多别人各式各样的代码,总算知道了HTBOTTOMRIGHT这几个指令。然后摸索着在AU3中写。想到一定还有一样的朋友在找这样的代码,所以干脆贴出来,方便大家直接使用,各取所需。
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>

$Form1 = GUICreate("无边框窗体移动拉伸", 600, 400, 200, 100, BitOR($WS_POPUP,$WS_CLIPSIBLINGS)) 
$Button1 = GUICtrlCreateButton("退出", 250, 300, 75, 25, 0)

GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_NCHITTEST, "topbottom")

While 1
$nMsg = GUIGetMsg()
Switch $nMsg
   Case $GUI_EVENT_CLOSE
    Exit
   Case $Button1
        Exit
EndSwitch
WEnd

Func topbottom($hWnd, $iMsg, $iwParam, $ilParam)
        $MousePos = MouseGetPos()
        $nPos = WinGetPos("")
        $DT = ($hWnd = $Form1 and $iMsg = $WM_NCHITTEST)
        $DDx = ($MousePos[0] < $nPos[0]+ $nPos[2]- 8) and ($MousePos[0] > $nPos[0]+ 8) 
        $DDy = ($MousePos[1] < $nPos[1]+ $nPos[3]- 8) and ($MousePos[1] > $nPos[1]+ 8)
        ; 以上是无边框窗体移动事件的发生条件

        $S1x = ($MousePos[0] >= $nPos[0]+ $nPos[2]- 8)  ; 右下角x
        $S1y = ($MousePos[1] >= $nPos[1]+ $nPos[3]- 8)  ; 右下角y
        $S2x = ($MousePos[0] <= $nPos[0]+ 8)            ; 左上角x
        $S2y = ($MousePos[1] <= $nPos[1]+ 8)            ; 左上角y
        $S3x = ($MousePos[0] <= $nPos[0]+8)             ; 左下角x
        $S3y = ($MousePos[1] >= $nPos[1]+ $nPos[3]- 8)  ; 左下角y
        $S4x = ($MousePos[0] >= $nPos[0]+ $nPos[2]- 8)  ; 右上角x
        $S4y = ($MousePos[1] <= $nPos[1]+ 8)            ; 右上角y
        ;以上是四角拉伸事件的发生条件

        $S5 = ($MousePos[0] <= $nPos[0]+ 8)      ; 左边
        $S6 = ($MousePos[1] <= $nPos[1]+ 8)      ; 顶边
        $S7 = ($MousePos[0] >= $nPos[0] + $nPos[2]- 8)      ; 右边
        $S8 = ($MousePos[1] >= $nPos[1] + $nPos[3]- 8)      ; 底边
        ;以上是四边拉伸事件的发生条件

        If $DT and $DDx and $DDy then Return $HTCAPTION  ;移动
        If $S1x and $S1y Then Return $HTBOTTOMRIGHT   ;右下角拉伸
        If $S2x and $S2y Then Return $HTTOPLEFT       ;左上角拉伸
        If $S3x and $S3y Then Return $HTBOTTOMLEFT    ;左下角拉伸
        If $S4x and $S4y Then Return $HTTOPRIGHT      ;右上角拉伸
        If $S5 Then Return $HTLEFT       ;左边拉伸
        If $S6 Then Return $HTTOP        ;上边拉伸
        If $S7 Then Return $HTRIGHT      ;右边拉伸
        If $S8 Then Return $HTBOTTOM     ;下边拉伸
EndFunc        
代码的思路:
无边框窗体的移动,利用GUIRegisterMsg 注册的自定义函数向系统发送 HTCAPTION 指令,使窗体的非客户区与标题栏客户区一样移动。达到窗口移动的目的。但发送$HTCAPTION指令后,窗体大小无法伸缩了。但是正常情况下,鼠标在窗体边缘是可以拉伸窗体的,这证明,鼠标移动到窗体边缘附近时,会发送某个消息指令给系统,系统接收后,便允许鼠标拉伸。这个消息就是WM_NCHITTEST。其实这个消息与移动时发送的消息是一致的,只不过具体指令不一样而已。而鼠标具体在窗体边缘的哪一个方位将会发出对应的不同的指令。这就是代码中的八个指令$HTBOTTOMRIGHT,$HTTOPLEFT,$HTBOTTOMLEFT,$HTTOPRIGHT,$HTLEFT,$HTTOP,$HTRIGHT,$HTBOTTOM。只要定义好这8个指令的触发条件就可以了。基本思路就这样。

条件判断写的时候费点时间,测试了好多次,因为不是经常写代码的人。不过写好了就没必要都再写一次了。也不想看第二次。
不认为让每一个人都来折腾一番是一种好的锻炼方法。个人认为,对于普及者爱好者来说,引用与操作是更重要的,很多事见多了,做多了,自然也就有了经验与思路。

评分

参与人数 2金钱 +60 贡献 +10 收起 理由
帆船 + 20 非常感谢
gapkiller + 40 + 10 谢谢分享

查看全部评分

发表于 2010-3-5 09:36:29 | 显示全部楼层
谢谢分享
发表于 2010-3-5 12:09:23 | 显示全部楼层
发表于 2011-10-19 10:50:45 | 显示全部楼层
抻拉可以为什么移动不行呢?继续潜水学习吧!
发表于 2011-10-19 12:27:23 | 显示全部楼层
收藏,备用。。
发表于 2011-11-5 17:41:55 | 显示全部楼层
挺好的,下载收藏了。
发表于 2011-11-30 04:20:36 | 显示全部楼层
不错。谢谢分享!
发表于 2011-12-16 16:10:52 | 显示全部楼层
挺好用的!
发表于 2017-2-18 23:01:17 | 显示全部楼层
非常感谢!AU3的帮助文档虽然很完备,但是关于DLL、Object、消息代码等内容还是难以涉及,始终不得要领。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-12-25 02:23 , Processed in 0.080542 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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