找回密码
 加入
搜索
查看: 3488|回复: 8

[AU3基础] 请问怎么在Tab标签的页面增加一个关闭按扭,实现像浏览器关闭标签页一样的效果?

  [复制链接]
发表于 2011-9-28 10:25:54 | 显示全部楼层 |阅读模式
本帖最后由 chenzhi1210 于 2011-9-28 10:27 编辑

请问怎么在Tab标签的页面增加一个关闭按扭,实现像浏览器关闭标签页一样的效果?
#include <GUIConstantsEx.au3>
#include <TabConstants.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 633, 454, 192, 114)
$Tab1 = GUICtrlCreateTab(8, 8, 617, 433)
GUICtrlSetResizing(-1, $GUI_DOCKWIDTH+$GUI_DOCKHEIGHT)
$TabSheet1 = GUICtrlCreateTabItem("第一页    [×]")
$TabSheet2 = GUICtrlCreateTabItem("第二页    [×]")
$TabSheet3 = GUICtrlCreateTabItem("第三页    [×]")
GUICtrlCreateTabItem("")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

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

        EndSwitch
WEnd

请高手帮忙,请问怎么在Tab标签上放置一个关闭分页的按扭?像多标签的浏览器一样。

本帖子中包含更多资源

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

×
发表于 2011-9-28 14:38:01 | 显示全部楼层
请问怎么在Tab标签的页面增加一个关闭按扭,实现像浏览器关闭标签页一样的效果?

请高手帮忙,请问怎么在 ...
chenzhi1210 发表于 2011-9-28 10:25



   这个是非常麻烦的事,最好就是用多Gui去模拟多tab来实现这样的功能。
硬要用GUICtrlCreateTab来做,就是添加$TCS_OWNERDRAWFIXED,然后注册WM_DRAWITEM消息的函数,在这个函数里做。就是这样,你用删除_GUICtrlTab_DeleteItem删除某个Tab,它并不会删除上面的任何控件,你还得一个个手工写代码删除。

下面是改变tab颜色的代码,你看看就知道了

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiTab.au3>

Global Const $ODT_TAB = 101
Global Const $ODS_SELECTED = 0x0001
Global Const $ODA_DRAWENTIRE = 0x1

Global Const $ODS_FOCUS = 0x0010

$hGUI = GUICreate("Draw Tab", 300, 200)

$hTab = GUICtrlCreateTab(10, 10, 280, 180, $TCS_OWNERDRAWFIXED)

$TabItem_1 = GUICtrlCreateTabItem("TabItem 1")
GUICtrlCreateLabel("", 10, 33, 277, 155)
GUICtrlSetBkColor(-1, 0xDDAA11)
GUICtrlSetState(-1, $GUI_DISABLE)

$TabItem_2 = GUICtrlCreateTabItem("TabItem 2")
GUICtrlCreateLabel("", 10, 33, 277, 155)
GUICtrlSetBkColor(-1, 0x99BBEE)

GUICtrlSetState(-1, $GUI_DISABLE)

GUICtrlCreateTabItem("")

GUISetState()

GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")

_GUICtrlTab_SetCurSel($hTab, 1)
_GUICtrlTab_SetCurSel($hTab, 0)

Do
Until GUIGetMsg() = -3

Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
    Local $DRAWITEMSTRUCT

    $DRAWITEMSTRUCT = DllStructCreate("uint cType;uint cID;uint itmID;uint itmAction;uint itmState;" & _
            "hwnd hItm;hwnd hDC;dword itmRect[4];dword itmData", $lParam)

    If DllStructGetData($DRAWITEMSTRUCT, "cType") <> $ODT_TAB Then Return $GUI_RUNDEFMSG

    Local $cID = DllStructGetData($DRAWITEMSTRUCT, "cID")
    Local $itmID = DllStructGetData($DRAWITEMSTRUCT, "itmID")
    Local $itmAction = DllStructGetData($DRAWITEMSTRUCT, "itmAction")
    Local $itmState = DllStructGetData($DRAWITEMSTRUCT, "itmState")
    Local $hItm = DllStructGetData($DRAWITEMSTRUCT, "hItm")
    Local $hDC = DllStructGetData($DRAWITEMSTRUCT, "hDC")

    If $itmAction <> $ODA_DRAWENTIRE Then Return $GUI_RUNDEFMSG

    Local $iTextColor, $itmText
    $iTextColor = 0xFFFFFF
        
    Switch $itmID
        Case 0
            $iBrushColor = 0x11AADD
        Case 1
            $iBrushColor = 0xEEBB99
    EndSwitch

    DllCall("gdi32.dll", "int", "SetBkMode", "hwnd", $hDC, "int", 1)

    Local $iBrush = DllCall("gdi32.dll", "hwnd", "CreateSolidBrush", "int", $iBrushColor)
    $iBrush = $iBrush[0]

    Local $iBrushOld = _WinAPI_SelectObject($hDC, $iBrush)

    DllCall("user32.dll", "int", "FillRect", "hwnd", $hDC, "ptr", DllStructGetPtr($DRAWITEMSTRUCT, "itmRect"), "hwnd", $iBrush)

    Local $tBuffer = DllStructCreate("char[256]")
    DllStructSetData($tBuffer, 1, "Item" & $itmID)
    $itmText = DllStructGetData($tBuffer, 1)

    DllStructSetData($DRAWITEMSTRUCT, "itmRect", DllStructGetData($DRAWITEMSTRUCT, "itmRect", 1) + 10, 1)
    DllStructSetData($DRAWITEMSTRUCT, "itmRect", DllStructGetData($DRAWITEMSTRUCT, "itmRect", 2) + 5, 2)
    _WinAPI_SetTextColor($hDC, $iTextColor)

    DllCall("user32.dll", "int", "DrawText", "hwnd", $hDC, "str", $itmText, "int", StringLen($itmText), _
            "ptr", DllStructGetPtr($DRAWITEMSTRUCT, "itmRect"), "int", $DT_LEFT)

    _WinAPI_SelectObject($hDC, $iBrushOld)
    _WinAPI_DeleteObject($iBrush)

    Return $GUI_RUNDEFMSG
EndFunc ;==>WM_DRAWITEM
 楼主| 发表于 2011-9-28 14:58:17 | 显示全部楼层
非常感谢楼上的朋友回复!如果难实现,我再另想办法。谢谢!
发表于 2011-9-28 15:26:06 | 显示全部楼层
也可以简单点,先创建一个按钮隐藏之,在鼠标移动到标签上时移位+显示
 楼主| 发表于 2011-9-28 16:01:12 | 显示全部楼层
也可以简单点,先创建一个按钮隐藏之,在鼠标移动到标签上时移位+显示
afan 发表于 2011-9-28 15:26



    请问afan,可以写一个事例代码吗?麻烦你了。
发表于 2011-9-28 16:30:58 | 显示全部楼层
回复 4# afan


你想用Button去覆盖住Tab头,    效果肯定很差, 一则你得把Tab头宽度固定宽度,就是用了$TCS_FIXEDWIDTH,就是这样,在不同DPI或系统主题下,还是很容易露馅的。
发表于 2011-9-28 17:10:14 | 显示全部楼层
简单弄了个
#include <GuiTab.au3>
#include <GuiConstantsEx.au3>

Local $mflag = 0, $hflag = 0, $ti = -1
Local $hGui = GUICreate('Tab 标签划过显示删除按钮 By afan')
Local $Bt_tab = GUICtrlCreateButton('×', 100, 100, 15, 15)
GUICtrlSetCursor(-1, 0)
GUICtrlSetBkColor(-1, 0xFF00)
GUICtrlSetState(-1, $gui_Hide)
Local $tab = GUICtrlCreateTab(5, 5, 390, 390)
_GUICtrlTab_InsertItem($tab, 0, '标签页 -- 0')
_GUICtrlTab_InsertItem($tab, 1, '标签页 -- 1')
_GUICtrlTab_InsertItem($tab, 2, '标签页 -- 2')
GUICtrlCreateTabItem('')

GUISetState()

While 1
        $msInfo = GUIGetCursorInfo($hGui)
        If Not @error And $msInfo[4] = $tab Then
                Local $ms_x = $msInfo[0], $ms_y = $msInfo[1]
                $Now_i = _GUICtrlTab_HitTest($tab, $ms_x, $ms_y - 5)

                If ($Now_i[0] <> $ti) Then
                        Local $p_tab = _GUICtrlTab_GetItemRect($tab, $Now_i[0])
                        If Not $mflag Then
                                GUICtrlSetPos($Bt_tab, $p_tab[2] - 17, $p_tab[1])
                                GUICtrlSetState($Bt_tab, $gui_Show)
                                $mflag = 1
                                $hflag = 0
                        Else
                                $mflag = 0
                                $ti = $Now_i[0]
                        EndIf
                ElseIf $Now_i[0] = -1 Then
                        $mflag = 0
                        If Not $hflag Then
                                GUICtrlSetState($Bt_tab, $gui_Hide)
                                $hflag = 1
                        EndIf
                EndIf
        Else
                $mflag = 0
                If $mflag And $msInfo[4] <> $Bt_tab Then
                        $ti = -1
                        GUICtrlSetState($Bt_tab, $gui_Hide)
                EndIf
        EndIf

        $msg = GUIGetMsg()
        Switch $msg
                Case -3
                        Exit
                Case $Bt_tab
                        GUICtrlSetState($Bt_tab, $gui_Hide)
                        _GUICtrlTab_DeleteItem($tab, $ti)
        EndSwitch
WEnd
发表于 2011-9-28 17:19:11 | 显示全部楼层
回复  afan


你想用Button去覆盖住Tab头,    效果肯定很差, 一则你得把Tab头宽度固定宽度,就是用了 ...
happytc 发表于 2011-9-28 16:30



    我只是一个未入门的菜鸟,能达到目的就不深究了。不过也不是你所说的“露馅”情况~
这个问题据我所知,P版可以轻松做到。3m可能也可以做到。不过,他们不在线,也不一定有时间~
发表于 2011-9-28 17:52:32 | 显示全部楼层
我只是一个未入门的菜鸟,能达到目的就不深究了。不过也不是你所说的“露馅”情况~
这个问题据我 ...
afan 发表于 2011-9-28 17:19


呵,之所以对这个帖子有点兴趣,就是因为我也曾经问过
http://www.autoitx.com/forum.php ... 6553&highlight=
我最后还是用多个gui来模拟实现的,别的效果总有不如意的情形。
最初提出这个问题,我也象你一样,想用Button盖住tab头来做,但难在各种情况下都完美盖住,感觉有点丑。于是开始研究WM_DRAWITEM,给它定义个函数里来加个X,这个实现了,但最后还是得一个个对Tab里的控件一个个手工删除,若Tab里的控件多,不同的Tab里的控件还不一样,于是想着把一个Tab里的控件变量全部放入一个一维数组里,这样删除时就一个循环了,但写的时候得不停地记住那个元素代表那个控件,也是麻烦,于是最后还是采用多个GUI来模拟了。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-9-21 00:39 , Processed in 0.151026 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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