pixelsearch Posted October 1, 2019 Posted October 1, 2019 Hi everybody I would like to share with you the way I made many controls "untabbable" in a GUI, without adding dozen of lines to the code. In my case, I wanted only the Input controls to be tabbable, while all others controls (radio buttons, check boxes and buttons) would be untabbable. As style $WS_TABSTOP is forced during the creation of radio buttons, check boxes and buttons, then here is a common way for removing this style just after a control creation : #include <WindowsConstants.au3> #include <WinAPISysWin.au3> ... $idButton_Close = GUICtrlCreateButton("my closing button", 64, 160, 175, 25) $hButton_Close = GUICtrlGetHandle($idButton_Close) $iStyle_Button_Close = _WinAPI_GetWindowLong($hButton_Close, $GWL_STYLE) If BitAND($iStyle_Button_Close, $WS_TABSTOP) = $WS_TABSTOP Then _WinAPI_SetWindowLong($hButton_Close, $GWL_STYLE, BitXOR($iStyle_Button_Close, $WS_TABSTOP)) Endif The problem is that if you have to do same on several controls, then there will be plenty of lines added to your code. So I created a function to reduce the code size, let's see how it was applied to the following GUI, where the only tabbable controls are the 7 Input controls on the right side of the GUI : Here is the line of code that removes $WS_TABSTOP style from 9 controls : Remove_Style($WS_TABSTOP, $idRadio_1, $idRadio_2, $idRadio_3, $idRadio_4, _ $idRadio_11, $idRadio_12, $idCheckbox_CropOnly, $idButton_OK, $idButton_Cancel) And here is the associated function (which can also be used to remove any style) : Func Remove_Style($iStyleToRemove, $id1, $id2 = 0, $id3 = 0, $id4 = 0, $id5 = 0, _ $id6 = 0, $id7 = 0, $id8 = 0, $id9 = 0, $id10 = 0) Local $hControl, $iStyle For $i = 1 To @NumParams - 1 ; @NumParams between 2 and 11. 1st parameter is the style to remove. $hControl = GUICtrlGetHandle(Eval("id" & $i)) $iStyle = _WinAPI_GetWindowLong($hControl, $GWL_STYLE) If BitAND($iStyle, $iStyleToRemove) = $iStyleToRemove Then _WinAPI_SetWindowLong($hControl, $GWL_STYLE, BitXOR($iStyle, $iStyleToRemove)) Endif Next EndFunc ; Remove_Style() What about the 8 checkboxes corresponding to the 8 Image types ? Well, you can : * Call the Remove_Style() function a 2nd time, including their 8 id's * Or tweak the Remove_Style() function to have it accept more than 10 id's per call * As these 8 checkboxes were created within a loop, then it has been scripted differently : For $i = 0 To $iMaxImageTypes - 1 $idCheckbox[$i] = GUICtrlCreateCheckbox(...) Remove_Style($WS_TABSTOP, $idCheckbox[$i]) Next I hope this function will help users facing the same situation "I think you are searching a bug where there is no bug... don't listen to bad advice."
spudw2k Posted October 2, 2019 Posted October 2, 2019 (edited) I'm a keyboard kind of operator (prefer keyboard shortcuts to using the mouse). I can and do appreciate the tab scenario you solved, but I would also employ Accelerators to enable keyboard interaction with the other controls as well. Looks like it'd be a fairly easy to add that to your controls without much compromise. i.e. Choose a &folder Choose a folder + all &subfolders Pick them &individually &Drag them here &New names (ex..._resized.jpg) &Overwrite E&xit Script &JPG &PNG &GIF &TIFF &EXIF &WMF E&MF &check if yes Maybe you already did this but it's not obvious from the screenshot as the underscores are hidden by default until you press alt. Edited October 2, 2019 by spudw2k Spoiler Things I've Made: Always On Top Tool ◊ AU History ◊ Deck of Cards ◊ HideIt ◊ ICU ◊ Icon Freezer ◊ Ipod Ejector ◊ Junos Configuration Explorer ◊ Link Downloader ◊ MD5 Folder Enumerator ◊ PassGen ◊ Ping Tool ◊ Quick NIC ◊ Read OCR ◊ RemoteIT ◊ SchTasksGui ◊ SpyCam ◊ System Scan Report Tool ◊ System UpTime ◊ Transparency Machine ◊ VMWare ESX Builder Misc Code Snippets: ADODB Example ◊ CheckHover ◊ Detect SafeMode ◊ DynEnumArray ◊ GetNetStatData ◊ HashArray ◊ IsBetweenDates ◊ Local Admins ◊ Make Choice ◊ Recursive File List ◊ Remove Sizebox Style ◊ Retrieve PNPDeviceID ◊ Retrieve SysListView32 Contents ◊ Set IE Homepage ◊ Tickle Expired Password ◊ Transpose Array Projects: Drive Space Usage GUI ◊ LEDkIT ◊ Plasma_kIt ◊ Scan Engine Builder ◊ SpeeDBurner ◊ SubnetCalc Cool Stuff: AutoItObject UDF ◊ Extract Icon From Proc ◊ GuiCtrlFontRotate ◊ Hex Edit Funcs ◊ Run binary ◊ Service_UDF
pixelsearch Posted October 6, 2019 Author Posted October 6, 2019 (edited) Just now, spudw2k said: I can and do appreciate the tab scenario you solved, but I would also employ Accelerators to enable keyboard interaction with the other controls as well. Hi spudw2k, glad you appreciated the tab scenario I haven't done it yet [the keyboard shortcuts] but I will certainly consider it in the future, thanks for your idea. As we are in the example sections, I would like to explain some specific parts of the script, for example the "enlarged landing zone for dropped files" that I added since my precedent post, it may be useful if any reader needs to do same. I wanted this "green landing zone" to be bigger than the one you can see in the diagram of my 1st post above, to make the drag and drop process easier (it sure is easier to drop on a larger zone than on a smaller one) As I didn't want the GUI to be wider, then I found a way of enlarging the landing zone, having all 4 radio buttons participating (in the same Group control). It works great, here is the result : 1) Diagram on the left shows how the GUI appears immediately after you launch the script : * 1st radio button in the group is selected ("Choose a folder") and button "Ok" is enabled * The background of all 4 radio buttons is grey on my computer (it's the gui background color, untouched) 2) Diagram on the right shows how the GUI appears when you check the 4th radio button ("Drag them here") * 4th radio button in the group is selected and button "Ok" is now disabled * The background of all 4 radio buttons is now light green and you can drop your files anywhere in the enlarged green zone. To achieve this, I was very lucky to find 3 posts from guinness, here, there and everywhere (that's a Beatles song title lol). But after having read (and tested) what KaFu replied in the "here" link, then I preferred not to use the "here" function, you'll understand why it you read KaFu's comment. Guinness "there" link worked fine : keep the original background color of the GUI in a variable, so you can re-apply it to a control in case you need to change the background color of the control (from grey to green in our case, then back to grey) Here are the 2 corresponding parts of the script. 1st part when GUI is created : $hGUI_main = GUICreate("Resize image files (v3)", 493, 290, -1, -1, _ -1, BitOr($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST)) GUICtrlCreateGroup(" How to select image files ? ", 13, 8, 193, 129) $idRadio_1 = GUICtrlCreateRadio("Choose a folder", 29, 27, 170, 25) GUICtrlSetState(-1, $GUI_CHECKED) $idRadio_2 = GUICtrlCreateRadio("Choose a folder + all subfolders", 29, 52, 170, 25) $idRadio_3 = GUICtrlCreateRadio("Pick them individually", 29, 77, 170, 25) $idRadio_4 = GUICtrlCreateRadio("Drag them here", 29, 102, 170, 25) GUICtrlCreateGroup("", -99, -99, 1, 1) ... GUISetState(@SW_SHOW, $hGUI_main) ; ++++++++++++ Guinness "there" ; Keep the GUI original background color in a variable Local $hDC = _WinAPI_GetDC($hGUI_main) $iGuiBackColor = _WinAPI_GetBkColor($hDC) ; Gui MUST be visible (not hidden or minimized) _WinAPI_ReleaseDC($hGUI_main, $hDC) ; ++++++++++++ $bDropColorVisible = False ... Now the 2nd part of the script, within the While... Wend loop : expandcollapse popupWhile 1 If $bDropColorVisible = True And GUICtrlRead($idRadio_4) = $GUI_UNCHECKED Then For $i = 1 To 4 $idVar = Eval("idRadio_" & $i) GUICtrlSetBkColor($idVar, $iGuiBackColor) GUICtrlSetState($idVar, $GUI_NODROPACCEPTED + (($i < 4) ? (0) : ($GUI_UNCHECKED))) Next $bDropColorVisible = False GUIRegisterMsg($WM_DROPFILES, "") GUICtrlSetState($idButton_OK, $GUI_ENABLE) EndIf $iGetMsg = GUIGetMsg() Switch $iGetMsg Case $GUI_EVENT_CLOSE, $idButton_Cancel ; or Esc ... Case $idRadio_1 $iHow_Choose_img = 1 ; a whole folder (no recursion) using FileSelectFolder() Case $idRadio_2 $iHow_Choose_img = 2 ; a whole folder + subfolders, using FileSelectFolder() Case $idRadio_3 $iHow_Choose_img = 3 ; pick files individually, using FileOpenDialog() Case $idRadio_4 $iHow_Choose_img = 4 ; drag 'n drop files from any Explorer, ACDSee... For $i = 1 To 4 $idVar = Eval("idRadio_" & $i) GUICtrlSetBkColor($idVar, 0xDDFFE0) ; light green. 0xC0FFFF (light blue) is ok too GUICtrlSetState($idVar, $GUI_DROPACCEPTED + (($i < 4) ? (0) : ($GUI_CHECKED))) Next $bDropColorVisible = True GUIRegisterMsg($WM_DROPFILES, "WM_DROPFILES") GUICtrlSetState($idButton_OK, $GUI_DISABLE) ... Case $idButton_OK, $GUI_EVENT_DROPPED $idBad_Control = Check_Control() ; check if all controls got correct values ... EndSwitch WEnd Func WM_DROPFILES() can be found at guinness "everywhere" link. So thank you guys, UEZ for all your GDI+ examples, guinness for your 3 posts, Melba23 ("don't ever color buttons !"), BrewManNH "It appears that the window and control have to be visible to be detected by this function", KaFu "So depending on the control type this one still needs more tweaking." etc... etc... Really a great community with helpful people Edited October 6, 2019 by pixelsearch "I think you are searching a bug where there is no bug... don't listen to bad advice."
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