Jump to content

Recommended Posts

Posted

Here is a script to show it:

GUICreate ("Testing tab switch", 400, 50, -1, -1)
   Global $hTab = GUICtrlCreateTab (2, 2, 396, 20)
      GUICtrlCreateTabItem ("1")
         GUICtrlCreateLabel ("You should only see me in tab 1.", 2, 24, 396, 20)

      GUICtrlCreateTabItem ("2")

   GUIRegisterMsg (0x020A, "_TabSwitch"); WM_MOUSEWHEEL

   GUISetState ()

   While 1
      Switch GUIGetMsg ()
         Case -3
            Exit
      EndSwitch
   WEnd

Func _TabSwitch ($hwnd, $msg, $l, $r)
   Local Const $TCM_SETCURSEL = 0x1300 + 12
   Local Const $TCM_GETCURSEL = 0x1300 + 11
   Local $nCur = GUICtrlSendMsg ($hTab, $TCM_GETCURSEL, 0, 0)

   If $l = 0xFF880000 Then; up
      If $nCur = 0 Then Return SetError (1)
      GUICtrlSendMsg ($hTab, $TCM_SETCURSEL, $nCur - 1, 0)
   Else; down
      If $nCur = 1 Then Return SetError (1)
      GUICtrlSendMsg ($hTab, $TCM_SETCURSEL, $nCur + 1, 0)
   EndIf
EndFunc; ==> _TabSwitch

The problem is that its not switching tabs as it would if done manually by me.

MDiesel

Posted

Try it with ControlClick and ItemGetRect :D

#Include <GuiTab.au3>
GUICreate ("Testing tab switch", 400, 50, -1, -1)
   Global $hTab = GUICtrlCreateTab (2, 2, 396, 20)
      GUICtrlCreateTabItem ("1")
         GUICtrlCreateLabel ("You should only see me in tab 1.", 2, 24, 396, 20)

      GUICtrlCreateTabItem ("2")

   GUIRegisterMsg (0x020A, "_TabSwitch"); WM_MOUSEWHEEL

   GUISetState ()

   While 1
      Switch GUIGetMsg ()
         Case -3
            Exit
      EndSwitch
   WEnd

Func _TabSwitch ($hwnd, $msg, $l, $r)
   Local Const $TCM_SETCURSEL = 0x1300 + 12
   Local Const $TCM_GETCURSEL = 0x1300 + 11
   Local $nCur = GUICtrlSendMsg ($hTab, $TCM_GETCURSEL, 0, 0)

   If $l = 0xFF880000 Then; up
      If $nCur = 0 Then Return SetError (1)
      ;GUICtrlSendMsg ($hTab, $TCM_SETCURSEL, $nCur - 1, 0)
      Local $aRect = _GUICtrlTab_GetItemRect($hTab, $nCur -1)
      ControlClick(GUICtrlGetHandle($hTab), "", "", "primary", 1, $aRect[0], $aRect[1])
   Else; down
      If $nCur = 1 Then Return SetError (1)
      ;GUICtrlSendMsg ($hTab, $TCM_SETCURSEL, $nCur + 1, 0)
      Local $aRect = _GUICtrlTab_GetItemRect($hTab, $nCur +1)
      ControlClick(GUICtrlGetHandle($hTab), "", "", "primary", 1, $aRect[0], $aRect[1])
   EndIf
EndFunc; ==> _TabSwitch

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Posted

Try it with ControlClick and ItemGetRect :D

Thats cheating!!

No, thanks. I was thinking about that, but thought it would be better to send the msg's.

Thats up and working, but unfortunately I don't like to use workarounds just becouse I failed (sore loser:)). Is it something to do with autoit intercepting the notifications? if so... how do I trigger those manually?

Thanks ProgAndy!!

MDiesel

Posted (edited)

Thats cheating!!

No, thanks. I was thinking about that, but thought it would be better to send the msg's.

Thats up and working, but unfortunately I don't like to use workarounds just becouse I failed (sore loser:)). Is it something to do with autoit intercepting the notifications? if so... how do I trigger those manually?

Thanks ProgAndy!!

MDiesel

There is more than one message involved. Changing it that way doesn't send $TCN_SELCHANGING or $TCN_SELCHANGE, to trigger redrawing the GUI.

:D

P.S. This ALMOST works:

#include <GuiTab.au3>

Global $hGUI = GUICreate("Testing tab switch", 400, 50, -1, -1)
Global $ctrlTab = GUICtrlCreateTab(2, 2, 396, 20)
Global $hTab = ControlGetHandle($hGUI, "", $ctrlTab)
For $n = 0 To 4
    GUICtrlCreateTabItem("Tab" & $n)
    GUICtrlCreateLabel("This is tab " & $n, 2, 24, 396, 20)
Next
GUICtrlCreateTabItem("")
GUIRegisterMsg(0x020A, "_TabSwitch"); WM_MOUSEWHEEL
GUISetState()

For $n = 0 To 4
; Demonstrate that all tabs CAN be selected
    Sleep(1000)
    _GUICtrlTab_ClickTab($hTab, $n)
    ConsoleWrite("Debug: $n = " & $n & @LF)
Next

While 1
    Switch GUIGetMsg()
        Case - 3
            Exit
    EndSwitch
WEnd

Func _TabSwitch($hwnd, $msg, $l, $r)
    Local Const $TCM_SETCURSEL = 0x1300 + 12
    Local Const $TCM_GETCURSEL = 0x1300 + 11
    Local $nCur = GUICtrlSendMsg($ctrlTab, $TCM_GETCURSEL, 0, 0)
    ConsoleWrite("Debug: $nCur = " & $nCur & @LF)

    If $l = 0xFF880000 Then; up
        If $nCur = 0 Then Return SetError(1)
        _GUICtrlTab_ClickTab($hTab, $nCur - 1)
    Else; down
        If $nCur = _GuiCtrlTab_GetItemCount($hTab) - 1 Then Return SetError(1)
        _GUICtrlTab_ClickTab($hTab, $nCur + 1)
    EndIf
EndFunc;==>_TabSwitch

It will move down just fine. Mouse wheel up hangs on tab 1, and I don't know why. If you manually select Tab 2 with a mouse click, it will go up from there with the mouse wheel, and it will go up from 0 to 1, but no further by mouse wheel.

???

;)

ReEdit: Doh! :D It was just the weird error return. Fixed it.

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Posted

There is more than one message involved. Changing it that way doesn't send $TCN_SELCHANGING or $TCN_SELCHANGE, to trigger redrawing the GUI.

... Is it something to do with autoit intercepting the notifications?...

:D

Is there a way I can manually trigger those notifications? Or is Progandys the best?

MDiesel

Posted

Done this way, it can scroll round-robin, and now it works:

#include <GuiTab.au3>

Global $hGUI = GUICreate("Testing tab switch", 400, 50, -1, -1)
Global $ctrlTab = GUICtrlCreateTab(2, 2, 396, 20)
Global $hTab = ControlGetHandle($hGUI, "", $ctrlTab)
For $n = 0 To 4
    GUICtrlCreateTabItem("Tab" & $n)
    GUICtrlCreateLabel("This is tab " & $n, 2, 24, 396, 20)
Next
GUICtrlCreateTabItem("")
GUIRegisterMsg(0x020A, "_TabSwitch"); WM_MOUSEWHEEL
GUISetState()

For $n = 0 To 4
; Demonstrate that all tabs CAN be selected
    Sleep(1000)
    _GUICtrlTab_ClickTab($hTab, $n)
    ConsoleWrite("Debug: $n = " & $n & @LF)
Next

While 1
    Switch GUIGetMsg()
        Case - 3
            Exit
    EndSwitch
WEnd

Func _TabSwitch($hwnd, $msg, $l, $r)
    Local Const $TCM_SETCURSEL = 0x1300 + 12
    Local Const $TCM_GETCURSEL = 0x1300 + 11
    Local $nCur = GUICtrlSendMsg($ctrlTab, $TCM_GETCURSEL, 0, 0)
    ConsoleWrite("Debug: $nCur = " & $nCur & @LF)

    If $l = 0xFF880000 Then
    ; Mouse wheel up
        If $nCur = 0 Then
            _GUICtrlTab_ClickTab($hTab, _GUICtrlTab_GetItemCount($hTab) - 1)
        Else
            _GUICtrlTab_ClickTab($hTab, $nCur - 1)
        EndIf
    Else
    ; Mouse wheel down
        If $nCur = _GUICtrlTab_GetItemCount($hTab) - 1 Then
            _GUICtrlTab_ClickTab($hTab, 0)
        Else
            _GUICtrlTab_ClickTab($hTab, $nCur + 1)
        EndIf
    EndIf
EndFunc  ;==>_TabSwitch

:D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Posted (edited)

Is there a way I can manually trigger those notifications? Or is Progandys the best?

MDiesel

Now i wrote the _GUICtrlTab__ActiavteTab wich sends all required Messages :D

#include <GuiTab.au3>

Global $hGUI = GUICreate("Testing tab switch", 400, 50, -1, -1)
Global $ctrlTab = GUICtrlCreateTab(2, 2, 396, 20)
Global $hTab = ControlGetHandle($hGUI, "", $ctrlTab)
For $n = 0 To 4
    GUICtrlCreateTabItem("Tab" & $n)
    GUICtrlCreateLabel("This is tab " & $n, 2, 24, 396, 20)
Next
GUICtrlCreateTabItem("")
GUIRegisterMsg(0x020A, "_TabSwitch"); WM_MOUSEWHEEL
GUISetState()



While 1
    Switch GUIGetMsg()
        Case - 3
            Exit
    EndSwitch
WEnd

Func _TabSwitch($hwnd, $msg, $l, $r)
    Local $nCur = GUICtrlSendMsg($ctrlTab, $TCM_GETCURSEL, 0, 0)
    ConsoleWrite("Debug: $nCur = " & $nCur & @LF)

    If $l = 0xFF880000 Then
    ; Mouse wheel up
        If $nCur = 0 Then
            _GUICtrlTab_ActivateTab($hTab, _GUICtrlTab_GetItemCount($hTab) - 1)
        Else
            _GUICtrlTab_ActivateTab($hTab, $nCur - 1)
        EndIf
    Else
    ; Mouse wheel down
        If $nCur = _GUICtrlTab_GetItemCount($hTab) - 1 Then
           _GUICtrlTab_ActivateTab($hTab, 0)
        Else
            _GUICtrlTab_ActivateTab($hTab, $nCur + 1)
        EndIf
    EndIf
EndFunc  ;==>_TabSwitch

; #FUNCTION# ====================================================================================================================
; Name...........: _GUICtrlTab_ActivateTab
; Description ...: Activates a tab by its index and sends all required messages
; Syntax.........: _GUICtrlTab_ActivateTab($hWnd, $iIndex)
; Parameters ....: $hWnd        - Handle to control
;                  $iIndex      - Specifies the zero based index of the item
; Return values .: Success      - The index of the previously selected tab
;                  Failure      - -1
; Author ........: Prog@ndy
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......;
; ===============================================================================================================================
Func _GUICtrlTab_ActivateTab($hWnd, $iIndex)
    Local $nIndX, $hParent, $NMHDR, $iRet
    ; first, get Handle and CtrlID of TabControl
    If $hWnd = -1 Then $hWnd = GUICtrlGetHandle(-1)
    If IsHWnd($hWnd) Then
        $nIndX = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hWnd)
        $nIndX = $nIndX[0]
    Else
        $nIndX = $hWnd
        $hWnd = GUICtrlGetHandle($hWnd)
    EndIf
    ; then get Parent
    Local $hParent = DllCall("user32.dll", "hwnd", "GetParent", "hwnd", $hWnd)
    If @error Then Return SetError(1,0,-1)
    $hParent = $hParent[0]
    ; create Struct for the Messages
    $NMHDR = DllStructCreate("HWND hwndFrom; UINT_PTR idFrom; UINT code;")
    DllStructSetData($NMHDR, 1, $hWnd)
    DllStructSetData($NMHDR, 2, $nIndX)
    DllStructSetData($NMHDR, 3, $TCN_SELCHANGING)
    ; send first message
    _SendMessage($hParent, 0x4E, $nIndX, DllStructGetPtr($NMHDR))
    ; select TabItem
    $iRet = _GUICtrlTab_SetCurSel($hWnd, $iIndex)
    ; send second message
    DllStructSetData($NMHDR, 3, $TCN_SELCHANGE)
    _SendMessage($hParent, 0x4E, $nIndX, DllStructGetPtr($NMHDR))
    Return $iRet
EndFunc

//Edit: Possibly it's worth to be added to GUITab.au3 :D

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Posted

I knew it was possible!! Thanks a lot prograndy, you just made my day. Definitely gets my vote!

Only one problem left... Edit controls swallow the windows message, you can no longer use the mouse scroll after clicking into an edit. even one with no styles... and even after you click off. do I need to trigger another msg when the edit control is clicked in, to revert back to normal?

CODE
#include <GuiTab.au3>

Global $hGUI = GUICreate("Testing tab switch", 400, 50, -1, -1)

Global $ctrlTab = GUICtrlCreateTab(2, 2, 396, 20)

Global $hTab = ControlGetHandle($hGUI, "", $ctrlTab)

For $n = 0 To 4

GUICtrlCreateTabItem("Tab" & $n)

GUICtrlCreateLabel ("This is tab " & $n, 2, 24, 396, 20)

Next

GUICtrlCreateTabItem ("Edit tab")

GUICtrlCreateEdit ("", 2, 24, 396, 20, 0, 0) ; no styles!

GUICtrlCreateTabItem("")

GUIRegisterMsg(0x020A, "_TabSwitch"); WM_MOUSEWHEEL

GUISetState()

While 1

Switch GUIGetMsg()

Case - 3

Exit

EndSwitch

WEnd

Func _TabSwitch($hwnd, $msg, $l, $r)

Local $nCur = GUICtrlSendMsg($ctrlTab, $TCM_GETCURSEL, 0, 0)

ConsoleWrite("Debug: $nCur = " & $nCur & @LF)

If $l = 0xFF880000 Then

; Mouse wheel up

If $nCur = 0 Then

_GUICtrlTab_ActivateTab($hTab, _GUICtrlTab_GetItemCount($hTab) - 1)

Else

_GUICtrlTab_ActivateTab($hTab, $nCur - 1)

EndIf

Else

; Mouse wheel down

If $nCur = _GUICtrlTab_GetItemCount($hTab) - 1 Then

_GUICtrlTab_ActivateTab($hTab, 0)

Else

_GUICtrlTab_ActivateTab($hTab, $nCur + 1)

EndIf

EndIf

EndFunc ;==>_TabSwitch

; #FUNCTION# ====================================================================================================

; Name...........: _GUICtrlTab_ActivateTab

; Description ...: Activates a tab by its index and sends all required messages

; Syntax.........: _GUICtrlTab_ActivateTab($hWnd, $iIndex)

; Parameters ....: $hWnd - Handle to control

; $iIndex - Specifies the zero based index of the item

; Return values .: Success - The index of the previously selected tab

; Failure - -1

; Author ........: Prog@ndy

; Modified.......:

; Remarks .......:

; Related .......:

; Link ..........;

; Example .......;

; ====================================================================================================

Func _GUICtrlTab_ActivateTab($hWnd, $iIndex)

Local $nIndX, $hParent, $NMHDR, $iRet

; first, get Handle and CtrlID of TabControl

If $hWnd = -1 Then $hWnd = GUICtrlGetHandle(-1)

If IsHWnd($hWnd) Then

$nIndX = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hWnd)

$nIndX = $nIndX[0]

Else

$nIndX = $hWnd

$hWnd = GUICtrlGetHandle($hWnd)

EndIf

; then get Parent

Local $hParent = DllCall("user32.dll", "hwnd", "GetParent", "hwnd", $hWnd)

If @error Then Return SetError(1,0,-1)

$hParent = $hParent[0]

; create Struct for the Messages

$NMHDR = DllStructCreate("HWND hwndFrom; UINT_PTR idFrom; UINT code;")

DllStructSetData($NMHDR, 1, $hWnd)

DllStructSetData($NMHDR, 2, $nIndX)

DllStructSetData($NMHDR, 3, $TCN_SELCHANGING)

; send first message

_SendMessage($hParent, 0x4E, $nIndX, DllStructGetPtr($NMHDR))

; select TabItem

$iRet = _GUICtrlTab_SetCurSel($hWnd, $iIndex)

; send second message

DllStructSetData($NMHDR, 3, $TCN_SELCHANGE)

_SendMessage($hParent, 0x4E, $nIndX, DllStructGetPtr($NMHDR))

Return $iRet

EndFunc

MDiesel

Posted

Now i wrote the _GUICtrlTab__ActiavteTab wich sends all required Messages :D

CODE
#include <GuiTab.au3>

Global $hGUI = GUICreate("Testing tab switch", 400, 50, -1, -1)

Global $ctrlTab = GUICtrlCreateTab(2, 2, 396, 20)

Global $hTab = ControlGetHandle($hGUI, "", $ctrlTab)

For $n = 0 To 4

GUICtrlCreateTabItem("Tab" & $n)

GUICtrlCreateLabel("This is tab " & $n, 2, 24, 396, 20)

Next

GUICtrlCreateTabItem("")

GUIRegisterMsg(0x020A, "_TabSwitch"); WM_MOUSEWHEEL

GUISetState()

While 1

Switch GUIGetMsg()

Case - 3

Exit

EndSwitch

WEnd

Func _TabSwitch($hwnd, $msg, $l, $r)

Local $nCur = GUICtrlSendMsg($ctrlTab, $TCM_GETCURSEL, 0, 0)

ConsoleWrite("Debug: $nCur = " & $nCur & @LF)

If $l = 0xFF880000 Then

; Mouse wheel up

If $nCur = 0 Then

_GUICtrlTab_ActivateTab($hTab, _GUICtrlTab_GetItemCount($hTab) - 1)

Else

_GUICtrlTab_ActivateTab($hTab, $nCur - 1)

EndIf

Else

; Mouse wheel down

If $nCur = _GUICtrlTab_GetItemCount($hTab) - 1 Then

_GUICtrlTab_ActivateTab($hTab, 0)

Else

_GUICtrlTab_ActivateTab($hTab, $nCur + 1)

EndIf

EndIf

EndFunc ;==>_TabSwitch

; #FUNCTION# ======================================================

; Name...........: _GUICtrlTab_ActivateTab

; Description ...: Activates a tab by its index and sends all required messages

; Syntax.........: _GUICtrlTab_ActivateTab($hWnd, $iIndex)

; Parameters ....: $hWnd - Handle to control

; $iIndex - Specifies the zero based index of the item

; Return values .: Success - The index of the previously selected tab

; Failure - -1

; Author ........: Prog@ndy

; Modified.......:

; Remarks .......:

; Related .......:

; Link ..........;

; Example .......;

; =================================================================

Func _GUICtrlTab_ActivateTab($hWnd, $iIndex)

Local $nIndX, $hParent, $NMHDR, $iRet

; first, get Handle and CtrlID of TabControl

If $hWnd = -1 Then $hWnd = GUICtrlGetHandle(-1)

If IsHWnd($hWnd) Then

$nIndX = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hWnd)

$nIndX = $nIndX[0]

Else

$nIndX = $hWnd

$hWnd = GUICtrlGetHandle($hWnd)

EndIf

; then get Parent

Local $hParent = DllCall("user32.dll", "hwnd", "GetParent", "hwnd", $hWnd)

If @error Then Return SetError(1,0,-1)

$hParent = $hParent[0]

; create Struct for the Messages

$NMHDR = DllStructCreate("HWND hwndFrom; UINT_PTR idFrom; UINT code;")

DllStructSetData($NMHDR, 1, $hWnd)

DllStructSetData($NMHDR, 2, $nIndX)

DllStructSetData($NMHDR, 3, $TCN_SELCHANGING)

; send first message

_SendMessage($hParent, 0x4E, $nIndX, DllStructGetPtr($NMHDR))

; select TabItem

$iRet = _GUICtrlTab_SetCurSel($hWnd, $iIndex)

; send second message

DllStructSetData($NMHDR, 3, $TCN_SELCHANGE)

_SendMessage($hParent, 0x4E, $nIndX, DllStructGetPtr($NMHDR))

Return $iRet

EndFunc

//Edit: Possibly it's worth to be added to GUITab.au3 ;)
Very cool to see all the messages sent, but they are all sent automatically by the Windows API for the Tab control when you click on a tab with _GuiCtrlTab_ClickTab(). What is the advantage to this method, besides the geeky-cool demo of how the messages work?

:D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Posted

I knew it was possible!! Thanks a lot prograndy, you just made my day. Definitely gets my vote!

Only one problem left... Edit controls swallow the windows message, you can no longer use the mouse scroll after clicking into an edit. even one with no styles... and even after you click off. do I need to trigger another msg when the edit control is clicked in, to revert back to normal?

CODE
#include <GuiTab.au3>

Global $hGUI = GUICreate("Testing tab switch", 400, 50, -1, -1)

Global $ctrlTab = GUICtrlCreateTab(2, 2, 396, 20)

Global $hTab = ControlGetHandle($hGUI, "", $ctrlTab)

For $n = 0 To 4

GUICtrlCreateTabItem("Tab" & $n)

GUICtrlCreateLabel ("This is tab " & $n, 2, 24, 396, 20)

Next

GUICtrlCreateTabItem ("Edit tab")

GUICtrlCreateEdit ("", 2, 24, 396, 20, 0, 0) ; no styles!

GUICtrlCreateTabItem("")

GUIRegisterMsg(0x020A, "_TabSwitch"); WM_MOUSEWHEEL

GUISetState()

While 1

Switch GUIGetMsg()

Case - 3

Exit

EndSwitch

WEnd

Func _TabSwitch($hwnd, $msg, $l, $r)

Local $nCur = GUICtrlSendMsg($ctrlTab, $TCM_GETCURSEL, 0, 0)

ConsoleWrite("Debug: $nCur = " & $nCur & @LF)

If $l = 0xFF880000 Then

; Mouse wheel up

If $nCur = 0 Then

_GUICtrlTab_ActivateTab($hTab, _GUICtrlTab_GetItemCount($hTab) - 1)

Else

_GUICtrlTab_ActivateTab($hTab, $nCur - 1)

EndIf

Else

; Mouse wheel down

If $nCur = _GUICtrlTab_GetItemCount($hTab) - 1 Then

_GUICtrlTab_ActivateTab($hTab, 0)

Else

_GUICtrlTab_ActivateTab($hTab, $nCur + 1)

EndIf

EndIf

EndFunc ;==>_TabSwitch

; #FUNCTION# ====================================================================================================

; Name...........: _GUICtrlTab_ActivateTab

; Description ...: Activates a tab by its index and sends all required messages

; Syntax.........: _GUICtrlTab_ActivateTab($hWnd, $iIndex)

; Parameters ....: $hWnd - Handle to control

; $iIndex - Specifies the zero based index of the item

; Return values .: Success - The index of the previously selected tab

; Failure - -1

; Author ........: Prog@ndy

; Modified.......:

; Remarks .......:

; Related .......:

; Link ..........;

; Example .......;

; ====================================================================================================

Func _GUICtrlTab_ActivateTab($hWnd, $iIndex)

Local $nIndX, $hParent, $NMHDR, $iRet

; first, get Handle and CtrlID of TabControl

If $hWnd = -1 Then $hWnd = GUICtrlGetHandle(-1)

If IsHWnd($hWnd) Then

$nIndX = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hWnd)

$nIndX = $nIndX[0]

Else

$nIndX = $hWnd

$hWnd = GUICtrlGetHandle($hWnd)

EndIf

; then get Parent

Local $hParent = DllCall("user32.dll", "hwnd", "GetParent", "hwnd", $hWnd)

If @error Then Return SetError(1,0,-1)

$hParent = $hParent[0]

; create Struct for the Messages

$NMHDR = DllStructCreate("HWND hwndFrom; UINT_PTR idFrom; UINT code;")

DllStructSetData($NMHDR, 1, $hWnd)

DllStructSetData($NMHDR, 2, $nIndX)

DllStructSetData($NMHDR, 3, $TCN_SELCHANGING)

; send first message

_SendMessage($hParent, 0x4E, $nIndX, DllStructGetPtr($NMHDR))

; select TabItem

$iRet = _GUICtrlTab_SetCurSel($hWnd, $iIndex)

; send second message

DllStructSetData($NMHDR, 3, $TCN_SELCHANGE)

_SendMessage($hParent, 0x4E, $nIndX, DllStructGetPtr($NMHDR))

Return $iRet

EndFunc

MDiesel
I think when the Edit control gets focus, it registers its own handler for WM_MOUSEWHEEL. So you have to re-register yours. I don't know if you can do that while the edit still has focus.

:D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Posted

I've been looking through the messages to see if there are any that trigger the edit gaining all losing focus, all I ended up with is putting ControlGetFocus in a loop.

I'm not sure how to solve it though...

Unless there is a way to find out what function is currently registered, which I can't find.

dodgy solution:

AdlibRegister ("_ResetMsg")

Func _ResetMsg ()
   GUIRegisterMsg (code, func)
EndFunc

MDiesel

Posted (edited)

I've been looking through the messages to see if there are any that trigger the edit gaining all losing focus, all I ended up with is putting ControlGetFocus in a loop.

I'm not sure how to solve it though...

Unless there is a way to find out what function is currently registered, which I can't find.

dodgy solution:

AdlibRegister ("_ResetMsg")

Func _ResetMsg ()
   GUIRegisterMsg (code, func)
EndFunc

MDiesel

Well, I posted the statement that I didn't know if you could do that after failing in my own attempt. I just put a check with ControlGetFocus() in the GuiGetMsg() While\WEnd loop that would re-register the WM_MOUSEWHEEL message whenever focus changed to the Tab or Edit controls. It did not appear to work while the Edit had focus.

That doesn't prove it can't be done, but it's at least not that simple.

:D

Edit: typo

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Posted (edited)

KK, maybe its possible then it'll only work when it loses focus.

I think thats as good as its going to get. Unless I can draw my own textbox... I saw someone linked to one, but the link was broken, and searching failed to produce any results either.

Thanks for your help.

MDiesel

Edit: Guys. are we missing something. Control command: :D:D;)

"CurrentTab", "" Returns the current Tab shown of a SysTabControl32

"TabRight", "" Moves to the next tab to the right of a SysTabControl32

"TabLeft", "" Moves to the next tab to the left of a SysTabControl32

Not tested... but i'm goig to now.

Edited by mdiesel
Posted (edited)

Edit: Guys. are we missing something. Control command: :D;):P

Not tested... but i'm goig to now.

Oops, but with ControlCommand you can't select a tab by its Index ;)

Very cool to see all the messages sent, but they are all sent automatically by the Windows API for the Tab control when you click on a tab with _GuiCtrlTab_ClickTab(). What is the advantage to this method, besides the geeky-cool demo of how the messages work?

:D

ClickTab is not a WinAPi-function, but it is user-defined. Did you look at the Code for ClickTab? it moves the mose and clicks. So the TabControl has to be visible and it will gain focus.

_GUICtrlTab_ActivateTab should work with hidden or minimized windows, too.

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Posted

Oops, but with ControlCommand you can't select a tab by its Index :D

Yer, I know, but it would have saved me a lot of trouble earlier. But I suppose its worthit when you end up with better code...

As your the expert here, how can I solve the problem with the edit control?

MDiesel

Posted (edited)

I don't know. Possibly subclass it, and then call DefWindowProc instead of the Original windowproc for this message.

At least MSDN mentions, DefWindowProc propagates the message to the parent.

http://msdn.microsoft.com/en-us/library/ms645617.aspx

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Posted (edited)

ClickTab is not a WinAPi-function, but it is user-defined. Did you look at the Code for ClickTab? it moves the mose and clicks. So the TabControl has to be visible and it will gain focus.

_GUICtrlTab_ActivateTab should work with hidden or minimized windows, too.

Good point. There is a MouseClick() at the heart of _GuiCtrlTab_ClickTab().

I'm surprised. I assumed (stupidly, without looking) that it used ControlClick() or the appropriate DLL vice MouseClick() because the default was not to move the mouse. Since ControlClick() has supported X/Y coordinates within the control for the last couple of Beta/Prod versions that change should be made. Then the existing UDF code would work without focus or worrying about moving the mouse.

:D

Edit: Here is a demo of what I'm suggesting. Each time you hit ESC it jumps two tabs to the right (round-robin), even if the window is minimized:

#include <GuiTab.au3>

HotKeySet("{ESC}", "_Demo"); Hit ESC to see tab + 2 change

Global $hGUI = GUICreate("Testing tab switch", 400, 100, -1, -1)
Global $ctrlTab = GUICtrlCreateTab(10, 10, 380, 50)
Global $hTab = ControlGetHandle($hGUI, "", $ctrlTab)
For $n = 0 To 4
    GUICtrlCreateTabItem("Tab" & $n)
    GUICtrlCreateLabel("This is tab " & $n, 12, 34, 300, 20)
Next
GUICtrlCreateTabItem("")
GUISetState()

While 1
    Switch GUIGetMsg()
        Case - 3
            Exit
    EndSwitch
WEnd

Func _Demo()
; Move the tab twice to the right (round-robin)
;   Can be done with window not active
    Local $nCur = GUICtrlSendMsg($ctrlTab, $TCM_GETCURSEL, 0, 0)
    Local $nCount = _GUICtrlTab_GetItemCount($hTab)
    Local $nNew = $nCur + 2
    If $nNew > ($nCount - 1) Then $nNew -= $nCount
    ConsoleWrite("Debug: $nCur = " & $nCur & ", $nNew = " & $nNew & @LF)
    __GUICtrlTab_ClickTab($hTab, $nNew); Modified version of _GuiCtrlTab_ClickTab()
EndFunc ;==>_Demo

; #FUNCTION# =====================================================
; Name...........: _GUICtrlTab_ClickTab
; Description ...: Clicks a tab
; Syntax.........: _GUICtrlTab_ClickTab($hWnd, $iIndex[, $sButton = "left"[, $fMove = False[, 
;               $iClicks = 1[, $iSpeed = 1]]]])
; Parameters ....: $hWnd        - Handle to control
;                 $iIndex     - Specifies the zero based index of the item
;                 $fButton   - Button to click with
;                 $fMove       - If True, the mouse will be moved. 
;                          - If False, the mouse does not move.
;                 $iClicks   - Number of clicks
;                 $iSpeed     - Mouse movement speed
; Return values .:
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
;               : PsaltyDS - Modified to use ControlClick() when $fMove = False so window
;                    does not have to be active
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; Yes
; ================================================================
Func __GUICtrlTab_ClickTab($hwnd, $iIndex, $sButton = "left", $fMove = False, $iClicks = 1, $iSpeed = 1)
    Local $iX, $iY, $tPoint, $tRect, $iMode, $aPos, $hWinParent, $avTabPos
    If $Debug_TAB Then _GUICtrlTab_ValidateClassName($hwnd)
    If Not IsHWnd($hwnd) Then $hwnd = GUICtrlGetHandle($hwnd)

    If Not $fMove Then
        ; Don't move mouse, use ControlClick()
        $hWinParent = _WinAPI_GetParent($hwnd)
        $avTabPos = _GUICtrlTab_GetItemRect($hwnd, $iIndex)
        $iX = $avTabPos[0] + (($avTabPos[2] - $avTabPos[0]) / 2)
        $iY = $avTabPos[1] + (($avTabPos[3] - $avTabPos[1]) / 2)
        ControlClick($hWinParent, "", $hwnd, $sButton, $iClicks, $iX, $iY)
    Else
        ; Original code to move mouse and click (requires active window)
        $tRect = _GUICtrlTab_GetItemRectEx($hwnd, $iIndex)
        $tPoint = _WinAPI_PointFromRect($tRect, True)
        $tPoint = _WinAPI_ClientToScreen($hwnd, $tPoint)
        _WinAPI_GetXYFromPoint($tPoint, $iX, $iY)
        $iMode = Opt("MouseCoordMode", 1)
        MouseClick($sButton, $iX, $iY, $iClicks, $iSpeed)
        Opt("MouseCoordMode", $iMode)
    EndIf
EndFunc ;==>__GUICtrlTab_ClickTab

If $fMove = False (the default) it will use ControlClick() and will change tabs correctly even if the window is inactive or minimized.

The method is unchanged where $fMove = True, and that might bear looking into.

:D

Edit: Tried to remove annoying line wrap.

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Posted

:D

surely its more efficient to use ctrl click anyhow, as then it will work whether the window is open or not... or use progandys script.

I can't get anywhere with the edit - I can't even seem to re-register the message after it loses focus.

MDiesel

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...