找回密码
 加入
搜索
查看: 10435|回复: 19

[GUI管理] [已解决]如何让子窗体最小化到父窗体的下方的状态栏上面

 火.. [复制链接]
发表于 2012-4-2 10:14:29 | 显示全部楼层 |阅读模式
本帖最后由 xms77 于 2012-4-5 12:37 编辑

RT,如果用WinMove函数应该可以做到,但是用消息注册模式不知道怎么实现了?
特别要感谢298311657 兄弟高人!!!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×

评分

参与人数 1金钱 +20 收起 理由
afan + 20 感谢主动将修改帖子分类为[已解决],请继续 ...

查看全部评分

发表于 2012-4-2 11:25:42 | 显示全部楼层
原来那贴不是已经解决了吗,设为子窗口直接就是最小化到状态栏上面的啊
 楼主| 发表于 2012-4-2 12:38:44 | 显示全部楼层
回复 2# seniors
我怎么试了是最小化窗体被状态栏遮住了?
发表于 2012-4-2 22:15:45 | 显示全部楼层
本帖最后由 298311657 于 2012-4-2 22:26 编辑



#include <GuiConstants.au3>
#include <WindowsConstants.au3>
#Include <GuiStatusBar.au3>
#include <winapi.au3>
Global Const $SC_CLOSE = 0xF060
Global Const $SC_MINIMIZE = 0xF020
Global $MoveForm, $MoveY = 0
Local $ChildForm[1] = [0], $ChildBtn[1] = [0]

$MainForm = GUICreate("Main", 500, 500)
$menu = GUICtrlCreateMenu("窗口")
$new1 = GUICtrlCreateMenuItem("新建", $menu)
$new2 = GUICtrlCreateMenuItem("批量新建", $menu)
GUICtrlCreateMenuItem("", $menu)
$mini = GUICtrlCreateMenuItem("全部最小化", $menu)
GUICtrlCreateMenuItem("", $menu)
$RESTORE = GUICtrlCreateMenuItem("全部还原", $menu)
GUICtrlCreateMenuItem("", $menu)
$close = GUICtrlCreateMenuItem("全部关闭", $menu)
Local $aText[2] = ["AU3子窗口最小化", @TAB & "Crossdoor"]
Local $aParts[2] = [170, -1]
$hStatus = _GUICtrlStatusBar_Create($MainForm, $aParts, $aText,0x54000000,0x00000000)
GUISetState(@SW_SHOW, $MainForm)
$iStatusHeight = _GUICtrlStatusBar_GetHeight($hStatus)

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND")
GUIRegisterMsg($WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING")

While 1
        Sleep(2500)
WEnd

Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
        $iControl = BitAND($iwParam, 0xFFFF)
        $iMsg = BitShift($iwParam, 16)
        Switch $iControl
                Case $new1;新建子窗口
                        _CreateChildForm()
                Case $new2;批量新建子窗口
                        For $i = 0 To Random(3,10,1)
                                _CreateChildForm()
                        Next
                Case $close;关闭全部子窗口
                        _CloseChildForm()
                Case $mini;最小化全部子窗口
                        For $i = 0 To UBound($ChildForm) - 1
                                GUISetState(@SW_MINIMIZE, $ChildForm[$i])
                        Next
                Case $RESTORE
                        For $i = 0 To UBound($ChildForm) - 1
                                GUISetState(@SW_RESTORE, $ChildForm[$i])
                        Next
                Case Else;子窗口按钮点击
                        For $i = 0 To UBound($ChildBtn) - 1
                                If $iMsg = 0 And $iControl = $ChildBtn[$i] Then
                                        Return MsgBox(0,WinGetTitle($hWnd) & " 提示", "我是[" & $i & "]窗口。" & @CRLF & "我的句柄是:" & $ChildForm[$i], 0, $ChildForm[$i])
                                EndIf
                        Next
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func WM_SYSCOMMAND($hWnd, $Msg, $wParam, $lParam)
        Local $iID = BitAND($wParam, 0x0000FFFF)
        Switch $iID
                Case $SC_CLOSE
                        If $hWnd = $MainForm Then
                                _CloseChildForm()
                                Exit
                        Else
                                For $i = 0 To UBound($ChildForm) - 1
                                        If $ChildForm[$i] = $hWnd Then
                                                GUIDelete($ChildForm[$i])
                                                $ChildForm[$i] = 0
                                                ExitLoop
                                        EndIf
                                Next
                        EndIf
                Case $SC_MINIMIZE
                        If $hWnd <> $MoveForm Then
                                $MoveForm = $hWnd
                        EndIf
        EndSwitch
EndFunc   ;==>WM_SYSCOMMAND

Func WM_WINDOWPOSCHANGING($hWnd, $Msg, $wParam, $lParam)
        If $hWnd == $MoveForm Then
                Local $rect, $x, $y, $width, $height
                $rect = DllStructCreate($tagWINDOWPOS, $lParam)
                $x = DllStructGetData($rect, "X")
                $y = DllStructGetData($rect, "Y")
                $width = DllStructGetData($rect, "CX")
                $height = DllStructGetData($rect, "CY")
                If $x = 0 Then
                        If $MoveY = 0 Then
                                $MoveY = $y - $iStatusHeight
                        Else
                                $MoveY -= $height
                        EndIf
                EndIf
                DllStructSetData($rect, "Y", $MoveY)
                $MoveForm = 0
        EndIf
EndFunc   ;==>WM_WINDOWPOSCHANGING

Func _CreateChildForm()
        Local $j = 0
        For $i = 0 To UBound($ChildForm) - 1
                If Not IsHWnd($ChildForm[$i]) Then
                        $j = $i
                        ExitLoop
                EndIf
        Next
        If $j < 1 Then
                $j = $i
                ReDim $ChildForm[$j + 1]
                ReDim $ChildBtn[$j + 1]
        EndIf

        $ChildForm[$j] = GUICreate("Child" & $j, 200, 100, 10 + $j * 10, 10 + $j * 15, BitOR($WS_CHILD, $WS_MINIMIZEBOX, $WS_CAPTION, $WS_SYSMENU), -1, $MainForm)
        GUICtrlCreateLabel("我的句柄:" & $ChildForm[$j], 10, 10, 200, 60)
        $ChildBtn[$j] = GUICtrlCreateButton("点我", 10, 70, 75, 25)
        GUISetBkColor("0x" & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2), $ChildForm[$j])
        _WinAPI_SetParent($ChildForm[$j], $MainForm)
        GUISetState(@SW_SHOW, $ChildForm[$j])
EndFunc

Func _CloseChildForm()
        For $i = 0 To UBound($ChildForm) - 1
                GUIDelete($ChildForm[$i])
                $ChildForm[$i] = 0
        Next
        $MoveY = 0
EndFunc

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×

评分

参与人数 4威望 +2 金钱 +178 贡献 +25 收起 理由
lynfr8 + 48 + 5
xms77 + 60 + 15 真的感谢,你很强大!
afan + 2 + 50 + 5 学习了
happytc + 20 写了这么长的code,就得赞下!

查看全部评分

 楼主| 发表于 2012-4-2 22:55:23 | 显示全部楼层
回复 4# 298311657
好好学习一下你的代码,并表示衷心的感谢,真汗颜自己像个身手党了
发表于 2012-4-2 23:08:41 | 显示全部楼层
回复 5# xms77
修改了2个地方,之前的代码批量最小化时还是会遮挡住状态栏,这个不会了
#include <GuiConstants.au3>
#include <WindowsConstants.au3>
#Include <GuiStatusBar.au3>
#include <winapi.au3>
Global Const $SC_CLOSE = 0xF060
Global Const $SC_MINIMIZE = 0xF020
Global Const $SC_RESTORE = 0xF120
Global $MoveForm, $MoveY = 0
Local $ChildForm[1] = [0], $ChildBtn[1] = [0]

$MainForm = GUICreate("Main", 500, 500)
$menu = GUICtrlCreateMenu("窗口")
$new1 = GUICtrlCreateMenuItem("新建", $menu)
$new2 = GUICtrlCreateMenuItem("批量新建", $menu)
GUICtrlCreateMenuItem("", $menu)
$mini = GUICtrlCreateMenuItem("全部最小化", $menu)
GUICtrlCreateMenuItem("", $menu)
$RESTORE = GUICtrlCreateMenuItem("全部还原", $menu)
GUICtrlCreateMenuItem("", $menu)
$close = GUICtrlCreateMenuItem("全部关闭", $menu)
Local $aText[2] = ["AU3子窗口最小化", @TAB & "Crossdoor"]
Local $aParts[2] = [170, -1]
$hStatus = _GUICtrlStatusBar_Create($MainForm, $aParts, $aText,0x54000000,0x00000000)
GUISetState(@SW_SHOW, $MainForm)
$iStatusHeight = _GUICtrlStatusBar_GetHeight($hStatus)

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND")
GUIRegisterMsg($WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING")

While 1
        Sleep(2500)
WEnd

Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
        $iControl = BitAND($iwParam, 0xFFFF)
        $iMsg = BitShift($iwParam, 16)
        Switch $iControl
                Case $new1;新建子窗口
                        _CreateChildForm()
                Case $new2;批量新建子窗口
                        For $i = 0 To Random(3,10,1)
                                _CreateChildForm()
                        Next
                Case $close;关闭全部子窗口
                        _CloseChildForm()
                Case $mini;最小化全部子窗口
                        For $i = 0 To UBound($ChildForm) - 1
                                _SendMessageA($ChildForm[$i], $WM_SYSCOMMAND, $SC_MINIMIZE)
;~                                 GUISetState(@SW_MINIMIZE, $ChildForm[$i])
                        Next
                Case $RESTORE
                        For $i = 0 To UBound($ChildForm) - 1
                                _SendMessageA($ChildForm[$i], $WM_SYSCOMMAND, $SC_RESTORE)
;~                                 GUISetState(@SW_RESTORE, $ChildForm[$i])
                        Next
                Case Else;子窗口按钮点击
                        For $i = 0 To UBound($ChildBtn) - 1
                                If $iMsg = 0 And $iControl = $ChildBtn[$i] Then
                                        Return MsgBox(0,WinGetTitle($hWnd) & " 提示", "我是[" & $i & "]窗口。" & @CRLF & "我的句柄是:" & $ChildForm[$i], 0, $ChildForm[$i])
                                EndIf
                        Next
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func WM_SYSCOMMAND($hWnd, $Msg, $wParam, $lParam)
        Local $iID = BitAND($wParam, 0x0000FFFF)
        Switch $iID
                Case $SC_CLOSE
                        If $hWnd = $MainForm Then
                                _CloseChildForm()
                                Exit
                        Else
                                For $i = 0 To UBound($ChildForm) - 1
                                        If $ChildForm[$i] = $hWnd Then
                                                GUIDelete($ChildForm[$i])
                                                $ChildForm[$i] = 0
                                                ExitLoop
                                        EndIf
                                Next
                        EndIf
                Case $SC_MINIMIZE
                        If $hWnd <> $MoveForm Then
                                $MoveForm = $hWnd
                        EndIf
        EndSwitch
EndFunc   ;==>WM_SYSCOMMAND

Func WM_WINDOWPOSCHANGING($hWnd, $Msg, $wParam, $lParam)
        If $hWnd == $MoveForm Then
                Local $rect, $x, $y, $width, $height
                $rect = DllStructCreate($tagWINDOWPOS, $lParam)
                $x = DllStructGetData($rect, "X")
                $y = DllStructGetData($rect, "Y")
                $width = DllStructGetData($rect, "CX")
                $height = DllStructGetData($rect, "CY")
                If $x = 0 Then
                        If $MoveY = 0 Then
                                $MoveY = $y - $iStatusHeight
                        Else
                                $MoveY -= $height
                        EndIf
                EndIf
                DllStructSetData($rect, "Y", $MoveY)
                $MoveForm = 0
        EndIf
EndFunc   ;==>WM_WINDOWPOSCHANGING

Func _CreateChildForm()
        Local $j = 0
        For $i = 0 To UBound($ChildForm) - 1
                If Not IsHWnd($ChildForm[$i]) Then
                        $j = $i
                        ExitLoop
                EndIf
        Next
        If $j < 1 Then
                $j = $i
                ReDim $ChildForm[$j + 1]
                ReDim $ChildBtn[$j + 1]
        EndIf

        $ChildForm[$j] = GUICreate("Child" & $j, 200, 100, 10 + $j * 10, 10 + $j * 15, BitOR($WS_CHILD, $WS_MINIMIZEBOX, $WS_CAPTION, $WS_SYSMENU), -1, $MainForm)
        GUICtrlCreateLabel("我的句柄:" & $ChildForm[$j], 10, 10, 200, 60)
        $ChildBtn[$j] = GUICtrlCreateButton("点我", 10, 70, 75, 25)
        GUISetBkColor("0x" & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2), $ChildForm[$j])
        _WinAPI_SetParent($ChildForm[$j], $MainForm)
        GUISetState(@SW_SHOW, $ChildForm[$j])
EndFunc

Func _CloseChildForm()
        For $i = 0 To UBound($ChildForm) - 1
                GUIDelete($ChildForm[$i])
                $ChildForm[$i] = 0
        Next
        $MoveY = 0
EndFunc

评分

参与人数 3金钱 +107 贡献 +16 收起 理由
lynfr8 + 22 + 1
xms77 + 60 + 15 感谢逐步完善
user3000 + 25 还是对你说: Cool~!

查看全部评分

发表于 2012-4-2 23:18:55 | 显示全部楼层
汗, 看来是我理解有误, 我以为是子窗口像常见的窗口最小化到任务栏'里' 一样最小化到那个状态栏'里'!
原来是最小化到该状态栏的上方!
发表于 2012-4-3 14:02:52 | 显示全部楼层
回复 6# 298311657
最小化、还原后,再最小化不能到准确位置了
发表于 2012-4-3 20:31:47 | 显示全部楼层
回复 8# seniors
不好意思,还原之后变量$MoveY忘记置0了,改了下代码,这次没问题了

#include <GuiConstants.au3>
#include <WindowsConstants.au3>
#Include <GuiStatusBar.au3>
#include <winapi.au3>
Global Const $SC_CLOSE = 0xF060
Global Const $SC_MINIMIZE = 0xF020
Global Const $SC_RESTORE = 0xF120
Global $MoveForm, $MoveY = 0
Local $ChildForm[1] = [0], $ChildBtn[1] = [0]

$MainForm = GUICreate("Main", 500, 500)
$menu = GUICtrlCreateMenu("窗口")
$new1 = GUICtrlCreateMenuItem("新建", $menu)
$new2 = GUICtrlCreateMenuItem("批量新建", $menu)
GUICtrlCreateMenuItem("", $menu)
$mini = GUICtrlCreateMenuItem("全部最小化", $menu)
GUICtrlCreateMenuItem("", $menu)
$RESTORE = GUICtrlCreateMenuItem("全部还原", $menu)
GUICtrlCreateMenuItem("", $menu)
$close = GUICtrlCreateMenuItem("全部关闭", $menu)
Local $aText[2] = ["AU3子窗口最小化", @TAB & "Crossdoor"]
Local $aParts[2] = [170, -1]
$hStatus = _GUICtrlStatusBar_Create($MainForm, $aParts, $aText,0x54000000,0x00000000)
GUISetState(@SW_SHOW, $MainForm)
$iStatusHeight = _GUICtrlStatusBar_GetHeight($hStatus)

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND")
GUIRegisterMsg($WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING")

While 1
        Sleep(2500)
WEnd

Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
        $iControl = BitAND($iwParam, 0xFFFF)
        $iMsg = BitShift($iwParam, 16)
        Switch $iControl
                Case $new1;新建子窗口
                        _CreateChildForm()
                Case $new2;批量新建子窗口
                        For $i = 0 To Random(3,10,1)
                                _CreateChildForm()
                        Next
                Case $close;关闭全部子窗口
                        _CloseChildForm()
                Case $mini;最小化全部子窗口
                        For $i = 0 To UBound($ChildForm) - 1
                                _SendMessageA($ChildForm[$i], $WM_SYSCOMMAND, $SC_MINIMIZE)
;~                                 GUISetState(@SW_MINIMIZE, $ChildForm[$i])
                        Next
                Case $RESTORE
                        For $i = 0 To UBound($ChildForm) - 1
                                _SendMessageA($ChildForm[$i], $WM_SYSCOMMAND, $SC_RESTORE)
;~                                 GUISetState(@SW_RESTORE, $ChildForm[$i])
                        Next
                        $MoveY = 0
                Case Else;子窗口按钮点击
                        For $i = 0 To UBound($ChildBtn) - 1
                                If $iMsg = 0 And $iControl = $ChildBtn[$i] Then
                                        Return MsgBox(0,WinGetTitle($hWnd) & " 提示", "我是[" & $i & "]窗口。" & @CRLF & "我的句柄是:" & $ChildForm[$i], 0, $ChildForm[$i])
                                EndIf
                        Next
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func WM_SYSCOMMAND($hWnd, $Msg, $wParam, $lParam)
        Local $iID = BitAND($wParam, 0x0000FFFF)
        Switch $iID
                Case $SC_CLOSE
                        If $hWnd = $MainForm Then
                                _CloseChildForm()
                                Exit
                        Else
                                For $i = 0 To UBound($ChildForm) - 1
                                        If $ChildForm[$i] = $hWnd Then
                                                GUIDelete($ChildForm[$i])
                                                $ChildForm[$i] = 0
                                                ExitLoop
                                        EndIf
                                Next
                        EndIf
                Case $SC_MINIMIZE
                        If $hWnd <> $MoveForm Then
                                $MoveForm = $hWnd
                        EndIf
        EndSwitch
EndFunc   ;==>WM_SYSCOMMAND

Func WM_WINDOWPOSCHANGING($hWnd, $Msg, $wParam, $lParam)
        If $hWnd == $MoveForm Then
                Local $rect, $x, $y, $width, $height
                $rect = DllStructCreate($tagWINDOWPOS, $lParam)
                $x = DllStructGetData($rect, "X")
                $y = DllStructGetData($rect, "Y")
                $width = DllStructGetData($rect, "CX")
                $height = DllStructGetData($rect, "CY")
                If $x = 0 Then
                        If $MoveY = 0 Then
                                $MoveY = $y - $iStatusHeight
                        Else
                                $MoveY -= $height
                        EndIf
                EndIf
                DllStructSetData($rect, "Y", $MoveY)
                $MoveForm = 0
        EndIf
EndFunc   ;==>WM_WINDOWPOSCHANGING

Func _CreateChildForm()
        Local $j = 0
        For $i = 0 To UBound($ChildForm) - 1
                If Not IsHWnd($ChildForm[$i]) Then
                        $j = $i
                        ExitLoop
                EndIf
        Next
        If $j < 1 Then
                $j = $i
                ReDim $ChildForm[$j + 1]
                ReDim $ChildBtn[$j + 1]
        EndIf

        $ChildForm[$j] = GUICreate("Child" & $j, 200, 100, 10 + $j * 10, 10 + $j * 15, BitOR($WS_CHILD, $WS_MINIMIZEBOX, $WS_CAPTION, $WS_SYSMENU), -1, $MainForm)
        GUICtrlCreateLabel("我的句柄:" & $ChildForm[$j], 10, 10, 200, 60)
        $ChildBtn[$j] = GUICtrlCreateButton("点我", 10, 70, 75, 25)
        GUISetBkColor("0x" & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2), $ChildForm[$j])
        _WinAPI_SetParent($ChildForm[$j], $MainForm)
        GUISetState(@SW_SHOW, $ChildForm[$j])
EndFunc

Func _CloseChildForm()
        For $i = 0 To UBound($ChildForm) - 1
                GUIDelete($ChildForm[$i])
                $ChildForm[$i] = 0
        Next
        $MoveY = 0
EndFunc

评分

参与人数 1金钱 +20 收起 理由
seniors + 20

查看全部评分

发表于 2012-4-3 20:43:28 | 显示全部楼层
回复 9# 298311657
高手知道WM_WINDOWPOSCHANGING消息中的Y值是从哪儿来的吗?如果有来处的话就不需要MOVEY这个变量了。
我发现这个Y值是窗口高度减下边框高度,也就是状态栏放上去以后,窗口不知道状态栏哪里不能放最小化的窗口了,可能要在WM_NCCALCSIZE里改变下边框高度,就不需要WM_WINDOWPOSCHANGING
 楼主| 发表于 2012-4-3 21:44:35 | 显示全部楼层
回复 9# 298311657
高手,好像再次最小后位置还是变啊!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2012-4-3 23:48:04 | 显示全部楼层
回复 10# seniors
我一开始也是想用$y值,但是不准确,估计有哪里没照顾到,没时间去查资料,就弄了个变量来变通一下,拐了个弯
发表于 2012-4-3 23:49:06 | 显示全部楼层
回复 11# xms77
我的系统是windows2008 X64版本,9楼的代码,还原之后再次最小化测试没问题
lz说下你的系统和操作步骤,我再看看吧
 楼主| 发表于 2012-4-4 07:05:09 | 显示全部楼层
回复 13# 298311657
操作系统是window 7,新建三个子窗体,然后一个一个最小化,然后最大化,再次最小化,位置就变了,愈来愈高。
 楼主| 发表于 2012-4-4 07:45:22 | 显示全部楼层
本帖最后由 xms77 于 2012-4-4 07:46 编辑

回复 9# 298311657
正在好好研究注册Windows消息的代码,请教高手下面蓝框的两句是什么作用,好像没有这两句,直接调用$iwParam参数,也是可以的,不知道这两句是对什么做了限制?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-4-27 00:19 , Processed in 0.086199 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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