dnbj2010 发表于 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 < $nPos+ $nPos- 8) and ($MousePos > $nPos+ 8)
        $DDy = ($MousePos < $nPos+ $nPos- 8) and ($MousePos > $nPos+ 8)
        ; 以上是无边框窗体移动事件的发生条件

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

        $S5 = ($MousePos <= $nPos+ 8)      ; 左边
        $S6 = ($MousePos <= $nPos+ 8)      ; 顶边
        $S7 = ($MousePos >= $nPos + $nPos- 8)      ; 右边
        $S8 = ($MousePos >= $nPos + $nPos- 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个指令的触发条件就可以了。基本思路就这样。

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

xlcwxl 发表于 2010-3-5 09:36:29

谢谢分享:face (16):

alice148 发表于 2010-3-5 12:09:23

:face (22)::face (22):

jsgh1983 发表于 2011-10-19 10:50:45

抻拉可以为什么移动不行呢?{:face (382):}继续潜水学习吧!

menfan1 发表于 2011-10-19 12:27:23

收藏,备用。。

w55554 发表于 2011-11-5 17:41:55

挺好的,下载收藏了。

liyi-softs 发表于 2011-11-30 04:20:36

不错。谢谢分享!

yangyunbo 发表于 2011-12-16 16:10:52

挺好用的!

帆船 发表于 2017-2-18 23:01:17

非常感谢!AU3的帮助文档虽然很完备,但是关于DLL、Object、消息代码等内容还是难以涉及,始终不得要领。
页: [1]
查看完整版本: 一个无边框窗体随意移动并拉伸的实例