az2000 Posted June 17, 2009 Share Posted June 17, 2009 How can I detect that the user went to a different tab? (I am interested in the tab they departed from.). I searched the forum and found an example of detecting focus change for input fields: $wProcNew = DllCallbackRegister("_FocusWindowProc", "ptr", "hwnd;uint;long;ptr") $wProcOld = _WinAPI_SetWindowLong(GUICtrlGetHandle($cInput), $GWL_WNDPROC, DllCallbackGetPtr($wProcNew)) But, that uses GUICtrlGetHandle. It doesn't seem like tab *items* have a handle. Could someone point me in the right direction? Thanks Link to comment Share on other sites More sharing options...
nguyenbason Posted June 17, 2009 Share Posted June 17, 2009 GuiCtrlRead($Tab) will return index of selected tab (0,1,2,....) UnderWorldVN- Just play the way you like it Link to comment Share on other sites More sharing options...
az2000 Posted June 17, 2009 Author Share Posted June 17, 2009 GuiCtrlRead($Tab) will return index of selected tab (0,1,2,....)Thanks. But, I want to be notified when the tab focus changes (the user left the tab). I think I know how to do that using the dll example. But, it requires a control handle which doesn't seem to be available for tab items.(?) Link to comment Share on other sites More sharing options...
nguyenbason Posted June 17, 2009 Share Posted June 17, 2009 ; Get handle to Tab control $hTab = ControlGetHandle($hWnd, "", "SysTabControl321") If @error Then _Exitonerror("Failed to get handle to TAB control.") UnderWorldVN- Just play the way you like it Link to comment Share on other sites More sharing options...
az2000 Posted June 17, 2009 Author Share Posted June 17, 2009 ; Get handle to Tab control $hTab = ControlGetHandle($hWnd, "", "SysTabControl321") If @error Then _Exitonerror("Failed to get handle to TAB control.") Tab "items" are what I can't get a handle to. I believe your example only returns the handle to the Tab control (not the Tab items within it). I have something partially working with GUIRegisterMsg using system message 0x0008 (kill focus). It calls my registered function when I change tabs after changing data in any control on the tab item. But, I don't know how to determine which tab item it is losing focus from. I'll post an example shortly. Mark Link to comment Share on other sites More sharing options...
nguyenbason Posted June 17, 2009 Share Posted June 17, 2009 Why don't you write a variable that store current selected index tab, then when new tab is selected you did something with it and change value to new tab index? UnderWorldVN- Just play the way you like it Link to comment Share on other sites More sharing options...
DCCD Posted June 17, 2009 Share Posted June 17, 2009 While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop If $msg = $tab Then ; display the clicked tab If GUICtrlRead($tab) = 0 Then WinSetTitle("My GUI Tab", "", "My GUI Tab0") If GUICtrlRead($tab) = 1 Then WinSetTitle("My GUI Tab", "", "My GUI Tab1") If GUICtrlRead($tab) = 2 Then WinSetTitle("My GUI Tab", "", "My GUI Tab2") EndIf WEnd [u][font=Arial Black]M[/font]y Blog, AVSS Parts[/u][font=Arial Black]Else[/font][font=Arial Black]L[/font]ibya Linux Users Group Link to comment Share on other sites More sharing options...
az2000 Posted June 17, 2009 Author Share Posted June 17, 2009 While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop If $msg = $tab Then ; display the clicked tab If GUICtrlRead($tab) = 0 Then WinSetTitle("My GUI Tab", "", "My GUI Tab0") If GUICtrlRead($tab) = 1 Then WinSetTitle("My GUI Tab", "", "My GUI Tab1") If GUICtrlRead($tab) = 2 Then WinSetTitle("My GUI Tab", "", "My GUI Tab2") EndIf WEnd I need to know when the user *LEAVES* a tab item. I don't need to know when they arrived on a tab item. Also, I'm using "onEvent" mode. I can't poll the GUI trying to track the user's movements. The following works somewhat. The "WM_KILLFOCUS" message works perfectly. I'm notified when the user left a *control* (with changed data) on the tab item. But, I can't figure out how to determine which control triggered the message. The "WM_MESSAGE" message tells me which control triggered the message. But, it triggers for a lot of other stuff too. I just want WM_KILLFOCUS. This gives me an idea that maybe I could go back to the DLL example I found and setup events for all the controls on each tab item. Maybe that would tell me the same thing as WM_KILLFOCUS. But, I'd know which control caused it. expandcollapse popup#include <GuiConstants.au3> Opt('GUIOnEventMode', 1); Event mode, not message mode. ; This reports only killfocus events, but I don't know how to determine ; the control that caused the event. ;Global Const $WM_KILLFOCUS = 0x0008; killfocus event ; Or, use this. It seems to report more events. The $nID bits indicate ; if it was a set focus or kill focus. Global Const $WM_COMMAND = 0x0111; wmcommand events? Global Const $EN_SETFOCUS = 0x100 Global Const $EN_KILLFOCUS = 0x200 _Main() ;********************************************************************* ;********************************************************************* Func _Main() Global $hWnd, $tab, $tab0, $tab0OK, $tab0input Local $tab1, $tab1combo, $tab1OK Local $tab2, $tab2OK, $msg $hWnd = GUICreate("My GUI Tab") GUISetBkColor(0x00E0FFFF) GUISetFont(9, 300) $tab = GUICtrlCreateTab(10, 10, 200, 100) $tab0 = GUICtrlCreateTabItem("tab0") GUICtrlCreateLabel("label0", 30, 80, 50, 20) $tab0OK = GUICtrlCreateButton("OK0", 20, 50, 50, 20) $tab0input = GUICtrlCreateInput("default", 80, 50, 70, 20) $tab1 = GUICtrlCreateTabItem("tab----1") GUICtrlCreateLabel("label1", 30, 80, 50, 20) $tab1combo = GUICtrlCreateCombo("", 20, 50, 60, 120) GUICtrlSetData(-1, "Trids|CyberSlug|Larry|Jon|Tylo", "Jon"); default Jon $tab1OK = GUICtrlCreateButton("OK1", 80, 50, 50, 20) $tab2 = GUICtrlCreateTabItem("tab2") GUICtrlSetState(-1, $GUI_SHOW) ; will be display first GUICtrlCreateLabel("label2", 30, 80, 50, 20) $tab2OK = GUICtrlCreateButton("OK2", 140, 50, 50) GUICtrlCreateTabItem("") ; end tabitem definition GUISetState() ;GUIRegisterMsg($WM_KILLFOCUS, "MY_KILLFOCUS") GUIRegisterMsg($WM_COMMAND, "MY_WMCOMMAND") While 1 Sleep(5000); or, change the eventMode, comment out this line, and decomment the following. ; Switch GUIGetMsg() ; Case $ExitButton, $GUI_EVENT_CLOSE; You'll need to add an exit button to the form. ; ExitLoop ; EndSwitch WEnd EndFunc ;==>_Main ;********************************************************************* ;********************************************************************* Func MY_KILLFOCUS($hWnd, $msg, $wParam, $lParam) Local $nNotifyCode = BitShift($wParam, 16); high word Local $nID = BitAND($wParam, 0xFFFF); low word Local $hCtrl = $lParam MsgBox(64, "In MY_KILLFOCUS", '$nID=' & $nID) ; Proceed the default Autoit3 internal message commands. ; You also can complete let the line out. ; !!! But only 'Return' (without any value) will not proceed ; the default Autoit3-message in the future !!! Return $GUI_RUNDEFMSG EndFunc ;==>MY_WM_COMMAND ;********************************************************************* ;********************************************************************* Func MY_WMCOMMAND($hWnd, $msg, $wParam, $lParam) Local $nNotifyCode = BitShift($wParam, 16); high word Local $nID = BitAND($wParam, 0xFFFF); low word Local $hCtrl = $lParam If $nNotifyCode = $EN_KILLFOCUS Then MsgBox(64, "In MY_WMCOMMAND with killfocus message", '$nID=' & $nID) EndIF ; Proceed the default Autoit3 internal message commands. ; You also can complete let the line out. ; !!! But only 'Return' (without any value) will not proceed ; the default Autoit3-message in the future !!! Return $GUI_RUNDEFMSG EndFunc ;==>MY_WM_COMMAND Mark Link to comment Share on other sites More sharing options...
az2000 Posted June 17, 2009 Author Share Posted June 17, 2009 Also, browsing the TabConstants.au3 I see a section called "Notifications" containing the following: Global Const $TCN_FOCUSCHANGE = ($TCN_FIRST - 4) That sounds like what I want. But, I don't know where I would use it. Mark Link to comment Share on other sites More sharing options...
az2000 Posted June 17, 2009 Author Share Posted June 17, 2009 (edited) This gives me an idea that maybe I could go back to the DLL example I found and setup events for all the controls on each tab item. Maybe that would tell me the same thing as WM_KILLFOCUS. But, I'd know which control caused it.Just a follow up. What I described is working well. I register the controls on each tab using the DLL shown in my first post. In the registered function, I can 1) tell that it was called because the control lost focus, 2) which control caused it, 3) I know which tab that control is on4) I can determine if the focus loss was due to the user clicking on a different control on the same tabItem, or going to a different tabItem. If the user clicked a different tabItem, GUICtrlRead($tab) will return that tabItem number (or controlID). I can compare this with what I know from #3.I like this better than WM_FOCUSKILL or WM_MESSAGE (with the registerMsg function). That called my registered function for every control on the GUI. The DLL lets me specify which controls I want to receive messages for. This is useful if I'm only concerned that a user would lose changes to a text control by going to a different tab before "applying" the change. I can keep them on the tab and prompt them to confirm abandoning changes.I'll update this thread with an example later. Edited June 17, 2009 by az2000 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now