PsychodelEKS Posted March 27, 2010 Posted March 27, 2010 (edited) Hi everyone,I'm trying to automate some action in Creative Audio Control Panel (sound card control applet).Currently I want my script to change speakers configuration.This is the main window:And here comes trouble, as you can see there is no Apply/Ok buttons, so changing value in combobox switches the mode instantly.ComboBox info:The problem is that its callback is not triggered by:ControlCommand($winid, '', 1004, 'SelectString', '2/2.1 Speakers')orControlCommand($winid, '', 1004, 'SetCurrentSelection', 0)The value inside combobox is changed, but it does not actually change the settings =(I've sniffed the combobox commands sent/recieved with Winspector Spy:and tried:$speakers_combobox = ControlGetHandle($winid, "", 1004) DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', $speakers_combobox, 'uint', 0x0131, 'wParam', 0x02, 'lParam', 0x002000e5)but no luck, neither combobox value, nor settings change.If I try:$CB_SETCURSEL = 0x14E $speakers_combobox = ControlGetHandle($winid, "", 1004) DllCall("user32.dll", "int", "SendMessage", "hwnd", $speakers_combobox, "int", $CB_SETCURSEL, "int", 0, "int", 0)it changes current selection, but not settings.Any help/advice would be appreciated.PS: I do not wnt to emulate mouse clicks, as I want to run the applet in hidden mode with Control Panel window also hidden. Edited March 27, 2010 by PsychodelEKS
PsaltyDS Posted March 27, 2010 Posted March 27, 2010 Send CBN_SELCHANGE by a WM_COMMAND message. 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
PsychodelEKS Posted March 27, 2010 Author Posted March 27, 2010 (edited) Send CBN_SELCHANGE by a WM_COMMAND message. I know it's ignorant, but could you be more specific? I've done a lot searching recently, but it seems to be too advanced for me right now Those are my first steps in low-level gui manipulation. I came up with this code (I'm not even sure it's not total crap), but it only switches the state of combobox, not the actual settings: #include <GuiConstantsEx.au3> #include <GuiComboBox.au3> $WM_COMMAND = 0x0111 $winid = "Audio Control Panel" Run("C:\Program Files (x86)\Creative\AudioCS\CTAudCS.exe", "C:\Program Files (x86)\Creative\AudioCS\") WinWaitActive($winid, '', 20) $hCntl = ControlGetHandle($winid, "", 1004) _GUICtrlComboBox_SetCurSel($hCntl, 0) $iCode = $CBN_SELCHANGE $val = BitShift($iCode, -16) $handle = WinGetHandle($winid, "") _SendMessage($handle, $WM_COMMAND, $val, $hCntl) Thanks for your help in advance. Edited March 27, 2010 by PsychodelEKS
Ascend4nt Posted March 27, 2010 Posted March 27, 2010 Try this, it works for me: #include <WinAPI.au3> Local $hWnd,$ctSpeakerSel,$iControlID $hWnd=WinGetHandle("[TITLE:Audio Control Panel; CLASS:#32770]") If $hWnd=0 Then Exit $ctSpeakerSel=ControlGetHandle($hWnd,"","[CLASS:ComboBox; INSTANCE:1]") ConsoleWrite("Control Handle:"&$ctSpeakerSel) ; Get the Control ID # (GWL_ID = -12) $iControlID=_WinAPI_GetWindowLong($ctSpeakerSel,-12) ConsoleWrite(" Control ID:"&$iControlID&@CRLF) ControlCommand($hWnd,"",$ctSpeakerSel,"SelectString","2/2.1 Speakers") ;WM_COMMAND = 0x111, CBN_SELCHANGE 1 (upper word) + Control ID _WinAPI_PostMessage($hWnd,0x0111,0x00010000+$iControlID,$ctSpeakerSel) My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code)
PsychodelEKS Posted March 27, 2010 Author Posted March 27, 2010 Try this, it works for meAwesome, man, thx a lot. At least it switches the mode, hopefully I'll be able to fully understand it and add everything else =)
PsychodelEKS Posted March 27, 2010 Author Posted March 27, 2010 (edited) Try this, it works for meI've faced another problem, as I understand, GUI is created with all objects (by IDs) available, but seems like it is not - if the window is switched to another tab (as it is by default), the ComboBox can not be found =(Is there any way to overcome this, or should I manually switch the tab each time? Are there any dummy-guides on how to do this (not through TabRight/TabLeft)?Here goes, tab info:Also, the window is not hidden by @SW_HIDE, does it have any limitations? Edited March 27, 2010 by PsychodelEKS
Ascend4nt Posted March 27, 2010 Posted March 27, 2010 (edited) This is a way to set the tab: $ctTabControl=ControlGetHandle($hWnd,"","[CLASS:SysTabControl32; INSTANCE:1]") ;#define TCM_FIRST 0x1300 // Tab control messages ;#define TCM_SETCURFOCUS (TCM_FIRST + 48) _SendMessage($ctTabControl,0x1300+48,1,0) Note that the wParam parameter (2nd to last) of SendMessage/PostMessage is the index of the Tab. I've assumed for you it is 1, but it might be another number (it was 2 on my Creative Audio Control Panel, but its layout is different). So you'll have to experiment a bit to see which one is the correct one. (They start at index #0) This gives me an idea to create an enumeration function for a Tab control.. it looks possible, so I will have to try my luck at it... Edited March 27, 2010 by Ascend4nt My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code)
PsychodelEKS Posted March 27, 2010 Author Posted March 27, 2010 This is a way to set the tabThank Ascend4nt, works nice, but my version seems to be written by some hardcore coders, seems like it needs some event triggered or command sent to get and render the info. Now it just renders empty tab after switching =(The ComboBox is empty and other controls (radiobuttons) are missing from it.
Fubarable Posted March 27, 2010 Posted March 27, 2010 I'm just curious, what Creative SB X-Fi are you using, which drivers, and what OS? I wonder if it would be simpler to call the drivers directly without messing with the Creative Audio Control Panel GUI.
PsychodelEKS Posted March 27, 2010 Author Posted March 27, 2010 I'm just curious, what Creative SB X-Fi are you using, which drivers, and what OS? I wonder if it would be simpler to call the drivers directly without messing with the Creative Audio Control Panel GUI.It is X-Fi Titanium PCI-E version. Under Win7 x64. Actually using drivers directly would've been perfect, but I have totally no idea on how and where to start from. I'm more of a web coder, not C/C++ =)But as far as I know, windows, starting from vista, does not provide any simple built in interface for this.
PsaltyDS Posted March 28, 2010 Posted March 28, 2010 Thank Ascend4nt, works nice, but my version seems to be written by some hardcore coders, seems like it needs some event triggered or command sent to get and render the info. Now it just renders empty tab after switching =(The ComboBox is empty and other controls (radiobuttons) are missing from it. Same problem as before, but different message. From the help file under _GuiCtrlTab_SetCurSel(): RemarksA tab control does not send a $TCN_SELCHANGING or $TCN_SELCHANGE notification message when a tab is selected using this function. 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
Ascend4nt Posted March 28, 2010 Posted March 28, 2010 (edited) PsaltyDS, that's actually exactly how its listed on the MSDN page (without the $'s). Even with those messages though, it doesn't seem to do any good, probably because of the pointers being passed.I found code that attempts to activate the tab using the messages here: _GUICtrlTab_ActivateTab Problem is - GUI isn't updated, just the button. I'm guess its got to do with the pointers..Oh, and PsychodelEKS - you are absolutely right, I didn't realize that TCM_SETCURFOCUS leaves the form empy. The problem was that I was testing an already-open Control Panel where I had clicked the 'Speakers' tab myself, then clicked another tab. But I started it up from scratch and got the same problem you did.So after looking at the options, I figure the easiest method, though it looks like a sort of hack, is to cycle through the tabs one-by one until we get to the right one. We'll grab the current tab, knowing already what the target tab is ($iSpeakerTab, index #1?), and 'spin' the tabs in the right direction using ControlCommand() until we are on the right tab. Notice that "CurrentTab" through ControlCommand is 1-based, whereas getting it through Windows methods is 0-based (hence my -1 on the first line):$iCurSelTab=ControlCommand($hWnd,"",$ctTabControl,"CurrentTab","")-1 If $iSpeakerTab>$iCurSelTab Then $sControlDir="TabRight" $iDiff=$iSpeakerTab-$iCurSelTab Else $sControlDir="TabLeft" $iDiff=$iCurSelTab-$iSpeakerTab EndIf ConsoleWrite("Current tab#"&$iCurSelTab&" Target Tab #"&$iSpeakerTab&" Tab Dir:"&$sControlDir&" Difference:"&$iDiff&@CRLF) For $i=1 To $iDiff ControlCommand($hWnd,"",$ctTabControl,$sControlDir,"") NextOh - and my idea on enumerating tabs.. that's another problem dealing with pointers. All info passed through messages to other processes expects pointers to be accessing its own memory space (TCN_SEL* messages require pointers).My thinking on this wasn't clear until I got a grip on that - DLL calls with pointers work because DLL's are mapped into the address space of the given process. But separate processes - the same memory pointer will mean something completely different since each process lives in its own virtual bubble and can only see 'out' of it through calls to Windows to read other process's memory..*edit: up too late, not thinking straight. gotta go now, mate Edited March 28, 2010 by Ascend4nt My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code)
Ascend4nt Posted March 29, 2010 Posted March 29, 2010 (edited) Well, as expected, by writing to the process memory, I was able to enumerate the tabs and send the necessary messages. Even though I simplified it a lot in my code (_DLLStructInject/Sync functions), there's still a lot of steps to go through to get simple text, indexes, or to select a tab. For these purposes, I think my 'hack' solution is actually the best method for what we need it for. It works quickly enough, and doesn't require the screen to have focus (it can even be minimized). However, something like the enumeration of Tabs could be incorporated into say, the AutoIT Window Info Tool. The problem of course would be the applications that need higher access privileges to write to their process memory. Its certainly been enlightening for me in messing around with this stuff. Edited March 29, 2010 by Ascend4nt My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code)
PsychodelEKS Posted March 29, 2010 Author Posted March 29, 2010 Its certainly been enlightening for me in messing around with this stuff.Glad to here that Wish Creative support were half that responsive in this problem resolution I`ll definitely give your solution a try.Some things in AutoIt are really for pros only PsaltyDS,Your ""s make me shy
Ascend4nt Posted March 30, 2010 Posted March 30, 2010 (edited) omg, don't get me started on Creative support! I identified a real bug in their drivers but they gave me a huge run-around and treated me as though someone like me couldn't possibly find a bug. But hey.. I've been toying around with this new functionality I have due to this mess, and I'm wondering if there can be some cool practical uses for it.. I just activated your tab another way using this code utilizing my _DllStructInject functions: Func _TabClick($hProcess,$ctTabControl,$iIndex=0) If Not IsHWnd($ctTabControl) Or Not IsPtr($hProcess) Or $hProcess=0 Then Return SetError(1,0,"") Local $stRect,$pRemoteRect,$bSuccess Dim $aTabRect[4] $stRect=DllStructCreate("long;long;long;long") $pRemoteRect=_DLLStructInject($hProcess,$stRect) ; TCM_GETITEMRECT (TCM_FIRST + 10) ; #define TCM_FIRST 0x1300 // Tab control messages $bSuccess=_SendMessage($ctTabControl,0x1300+10,$iIndex,$pRemoteRect) _DllStructInjectSyncDown($hProcess,$pRemoteRect,$stRect) _DllStructUnInject($hProcess,$pRemoteRect) If Not $bSuccess Then Return SetError(5,0,"") For $i=1 To 4 $aTabRect[$i-1]=DllStructGetData($stRect,$i) Next ControlClick($ctTabControl,"","","primary",1,$aTabRect[0]+1,$aTabRect[1]+1) Return True EndFunc The code for enumerating is a bit confusing to post, as it deals with pointers to buffers inside the structure, but its pretty neat now using this interface. I'm such a geek *edit: found out there are already data-injection functions in the standard UDF's which can be used for these things! d'oh.. gotta know where to look. But FYI - those particular injection functions can potentially crash AutoIT due to the lack of proper error checking (as of v3.3.6.0) Edited April 1, 2010 by Ascend4nt My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code)
schtroumph Posted October 25, 2011 Posted October 25, 2011 Hi guys, I'm trying to do exactly the same here and I was trying to make this work. Im not familliar with all this, have you been succesful with the tab selection?? Is it possible to have this part of your code??
Ascend4nt Posted October 26, 2011 Posted October 26, 2011 Check the help guide for _GUICtrlTab* functions. (_GUICtrlTab_FindTab, _GUICtrlTab_GetItemCount, _GUICtrlTab_SetCurSel/Focus, etc etc) My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code)
schtroumph Posted October 27, 2011 Posted October 27, 2011 (edited) Check the help guide for _GUICtrlTab* functions. (_GUICtrlTab_FindTab, _GUICtrlTab_GetItemCount, _GUICtrlTab_SetCurSel/Focus, etc etc) I'm not familliar with the handle thing, Im looking in winspector spy but Im not shure how to find or where to find the handle of the tab for those function. Can you help me with this? Thank you. Edited October 27, 2011 by schtroumph
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