Что нового

Вкладки в окне с дополнительным элементом в заголовке

zert88

Новичок
Сообщения
14
Репутация
0
Здравствуйте, хотел узнать имеется ли возможность, добавить в заголовок вкладки элемент позволяющий закрывать вкладку, что-то типа крестика "X"
Сообщение автоматически объединено:

Полу-понимая, скрестил 2 алгоритма и получил нечто похожее на то, что хотел, но без крестиков, просто правой кнопкой при щелчке по вкладке выводит имя текущей вкладки(ну а из этого можно уже допилить закрытие вкладки по щелчку правой кнопки).
Код:
#include <GUIConstantsEx.au3>
#include <GuiTab.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

$gui = GUICreate("My GUI Context Menu", 400, 300)

$Tab1 = GUICtrlCreateTab(100, 10, 129, 200)

$buttoncontext2 = GUICtrlCreateContextMenu($Tab1)

;$buttonitem = GUICtrlCreateMenuItem("Close Tab", $buttoncontext2)

$item1 = GUICtrlCreateTabItem("Tab 1")

$item2 = GUICtrlCreateTabItem("Tab 2")

GUICtrlCreateTabItem("")

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

GUISetState()

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

GUIDelete()

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR, $iIDFrom, $iCode
; consolewrite(@crlf&"hWnd="&$hWnd&" "&"Msg="&$Msg&" wParam="&$wParam&" lParam="&$lParam)
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
;consolewrite(@crlf&"tNMHDR="&$tNMHDR&" "&"iIDFrom ="&$iIDFrom &" iCode="&$iCode)
    Switch $iIDFrom
        Case $Tab1
            Switch $iCode
                Case $NM_RCLICK
                    consolewrite(@crlf&"tNMHDR="&$tNMHDR&" "&"iIDFrom ="&$iIDFrom &" iCode="&$iCode)
                    consolewrite(@crlf&"hWnd="&$hWnd&" "&"Msg="&$Msg&" wParam="&$wParam&" lParam="&$lParam)
                    $tPOINT = _WinAPI_GetMousePos(True, $gui)
                    Local $iX = DllStructGetData($tPOINT, "X")
                    Local $iY = DllStructGetData($tPOINT, "Y")

                    Local $aPos = ControlGetPos($gui, "", $Tab1)

                    Local $aHit = _GUICtrlTab_HitTest($Tab1, $iX - $aPos[0], $iY - $aPos[1])
                    If $aHit[0] <> -1 Then
                        _GUICtrlTab_SetCurSel($Tab1, $aHit[0])
                    ;$hItem=__TV_GetItemHandle($iIDFrom)
                    $sText=_GUICtrlTab_GetItemText($Tab1, $aHit[0])
                    MsgBox(64, "", $sText)
                    endif
                    Return 0
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc
 
Последнее редактирование:

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Как вы понимаете "закрыть вкладку" ? Что должно произойти ?
 
Автор
Z

zert88

Новичок
Сообщения
14
Репутация
0
Guictrldelet()
Я делаю чат, взял шаблон чата, там уже реализована часть с удалением вкладки с текстом - это дело выведено в функцию, я просто хотел запустить данную функцию нажатием по крестику(в заголовке вкладки), а не вызовом контекстного меню с строкой "Закрыть вкладку", но думаю сойдет и просто клик правой кнопкой мышки по вкладке.
Плюс добавил сейчас функционала к коду выше:
Код:
#include <GUIConstantsEx.au3>
#include <GuiTab.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <GuiTreeView.au3>
Global $hTreeView
Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)
$gui = GUICreate("My GUI Context Menu", 400, 300)

$Tab1 = GUICtrlCreateTab(200, 10, 129, 100)

$buttoncontext2 = GUICtrlCreateContextMenu($Tab1)

;$buttonitem = GUICtrlCreateMenuItem("Close Tab", $buttoncontext2)

$item1 = GUICtrlCreateTabItem("Tab 1")

$item2 = GUICtrlCreateTabItem("Tab 2")

GUICtrlCreateTabItem("")
$hTreeView = _GUICtrlTreeView_Create($gui, 2, 2, 150, 268, $iStyle, $WS_EX_CLIENTEDGE)
    GUISetState()

    _GUICtrlTreeView_BeginUpdate($hTreeView)
        $hItem = _GUICtrlTreeView_Add($hTreeView, 0, "New")
            _GUICtrlTreeView_AddChild($hTreeView, $hItem, "New_Child")
            _GUICtrlTreeView_AddChild($hTreeView, $hItem, "New_Child_2")
            _GUICtrlTreeView_AddChild($hTreeView, $hItem, "New_Child_3")
    _GUICtrlTreeView_EndUpdate($hTreeView)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

GUISetState()

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

GUIDelete()

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    ;#forceref $hWnd, $Msg, $wParam
    Local $hWndFrom, $tNMHDR, $iIDFrom, $iCode, $hWndTreeview
    $hWndTreeview = $hTreeView
    If Not IsHWnd($hTreeView) Then $hWndTreeview = GUICtrlGetHandle($hTreeView)
; consolewrite(@crlf&"hWnd="&$hWnd&" "&"Msg="&$Msg&" wParam="&$wParam&" lParam="&$lParam)
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
;consolewrite(@crlf&"tNMHDR="&$tNMHDR&" "&"iIDFrom ="&$iIDFrom &" iCode="&$iCode)
    Switch $hWndFrom
        Case $hWndTreeview
            Switch $iCode
                Case $NM_DBLCLK
                    ConsoleWrite(@crlf&"Tatu"&@Crlf)
                     $hItem=__TV_GetItemHandle($hWndFrom)
                    $sText=_GUICtrlTreeView_GetText($hWndFrom, $hItem)
                    MsgBox(64, "", $sText)
                    Return 0
            EndSwitch
EndSwitch
Switch $iIDFrom
        Case $Tab1
            Switch $iCode
                Case $NM_RCLICK
                    consolewrite(@crlf&"tNMHDR="&$tNMHDR&" "&"iIDFrom ="&$iIDFrom &" iCode="&$iCode)
                    consolewrite(@crlf&"hWnd="&$hWnd&" "&"Msg="&$Msg&" wParam="&$wParam&" lParam="&$lParam)
                    $tPOINT = _WinAPI_GetMousePos(True, $gui)
                    Local $iX = DllStructGetData($tPOINT, "X")
                    Local $iY = DllStructGetData($tPOINT, "Y")

                    Local $aPos = ControlGetPos($gui, "", $Tab1)

                    Local $aHit = _GUICtrlTab_HitTest($Tab1, $iX - $aPos[0], $iY - $aPos[1])
                    If $aHit[0] <> -1 Then
                        _GUICtrlTab_SetCurSel($Tab1, $aHit[0])
                    ;$hItem=__TV_GetItemHandle($iIDFrom)
                    $sText=_GUICtrlTab_GetItemText($Tab1, $aHit[0])
                    MsgBox(64, "", $sText)
                    endif
                    Return 0
            EndSwitch

EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc
Func __TV_GetItemHandle($hTV)
  $tPoint = _WinAPI_GetMousePos(1, $hTV)
  $tTVHTI = _GUICtrlTreeView_HitTestEx($hTV, DllStructGetData($tPoint, 1), DllStructGetData($tPoint, 2))
  $hItem = DllStructGetData($tTVHTI, 'Item')
  Return $hItem
EndFunc
Получился чатик у меня, где в treeview список контактов, двойное нажатие левой кнопки вызывает создание вкладки с конкретным пользователем. А одинарный клик по вкладке(заголовку вкладки), правой кнопки, закрывает вкладку с пользователем. Код чата я не стал выкладывать он гигантский. Да код наверное местами избыточен и наверное можно проще, но может вдруг кому нужно будет.

PS хотя крестик наверное можно добавить, изгаляясь тем что можно просто сбоку от вкладки добавить микрокнопку с буквой "X", если конечно между заголовками вкладок можно сделать зазор
 
Последнее редактирование модератором:

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
сбоку от вкладки добавить микрокнопку с буквой "X"
Можно добавить и прямо на вкладку, сделав таб родителем кнопки. Но тогда обрабатывать нажатия кнопки придётся в самом табе через сабклассинг
Код:
#include <GUIConstants.au3>
#include <GuiTab.au3>
#include <WinAPI.au3>

GUICreate("My GUI", 400, 300)
GUISetState()

$Tab1 = GUICtrlCreateTab(200, 10, 129, 100)
$item1 = GUICtrlCreateTabItem("Tab 1     ")
$item2 = GUICtrlCreateTabItem("Tab 2     ")
GUICtrlCreateTabItem("")
$hTab1 = GUICtrlGetHandle($Tab1)

$Btn1 = GUICtrlCreateButton("x", 40, 3, 15, 15)
$hBtn1 = GUICtrlGetHandle($Btn1)
_WinAPI_SetParent($hBtn1, $hTab1)

$Btn2 = GUICtrlCreateButton("x", 95, 3, 15, 15)
$hBtn2 = GUICtrlGetHandle($Btn2)
_WinAPI_SetParent($hBtn2, $hTab1)

$hDll = DllCallbackRegister('_TabSubclassProc', 'lresult', 'hwnd;uint;wparam;lparam;uint_ptr;dword_ptr')
$pDll = DllCallbackGetPtr($hDll)
_WinAPI_SetWindowSubclass($hTab1, $pDll, 1000, 0)

While GUIGetMsg() <> $GUI_EVENT_CLOSE
WEnd

_WinAPI_RemoveWindowSubclass($hTab1, $pDll, 1000)
DllCallbackFree($hDll)

Func _TabSubclassProc($hWnd, $iMsg, $wParam, $lParam, $ID, $pData)
  Switch $iMsg
    Case $WM_COMMAND
      Switch $lParam
        Case $hBtn1
          ConsoleWrite("Button 1" & @CRLF)
        Case $hBtn2
          ConsoleWrite("Button 2" & @CRLF)
      EndSwitch
  EndSwitch
  Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam)
EndFunc
 
Верх