emendelson Posted June 19, 2020 Share Posted June 19, 2020 (edited) Short version: I've been using some superb code (from this forum) that creates a list of installed printers, with a radio button next to each one, so a user can select a printer. Problem: These days, the list can be too long to fit on screen, and I'm trying to make the list scrollable. Here is a short version of my code, based on the code in the message listed on the second comment line: expandcollapse popup#include <GUIConstantsEx.au3> #include <Array.au3> #include <Constants.au3> #include <WinAPI.au3> #include <APIErrorsConstants.au3> Global $gh $ptrselmsg = "Select a printer for this document:" $printername = 0 GetPrinter($ptrselmsg) Do Sleep(100) Until $printername Exit Func GetPrinter($ptrselmsg) ; based on the excellent code by mfectau at ; https://www.autoitscript.com/forum/topic/40388-printer-selector-gui/?do=findComment&comment=869533 Global $printer_list[1] Global $printer_list_ext[1] Global $printer_radio_array[1] ; $printer_list = 0 ; $printer_list_ext = 0 ; $printer_radio_array = 0 $regprinters = "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices" $currentprinter = RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows\", "Device") $defaultprinter = StringLeft($currentprinter, StringInStr($currentprinter, ",") - 1) Dim $i = 1 Dim $erreur_reg = False While Not $erreur_reg $imprimante = RegEnumVal($regprinters, $i) $erreur_reg = @error If Not $erreur_reg Then _ArrayAdd($printer_list, $imprimante) _ArrayAdd($printer_list_ext, $imprimante & "," & RegRead($regprinters, $imprimante)) EndIf $i = $i + 1 WEnd _ArrayDelete($printer_list, 0) _ArrayDelete($printer_list_ext, 0) If UBound($printer_list) >= 2 Then ;if 2 or more printers available, we show the dialog Dim $groupheight = (UBound($printer_list) + 1) * 25 ;30 Dim $guiheight = $groupheight + 50 Dim $buttontop = $groupheight + 20 Opt("GUIOnEventMode", 1) $gh = GUICreate($ptrselmsg, 400, $guiheight) Dim $font = "Verdana" GUISetFont(10, 400, 0, $font) GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked") GUISetFont(10, 400, 0, $font) GUICtrlCreateGroup("Available printers:", 10, 10, 380, $groupheight) Dim $position_vertical = 5 ; 0 For $i = 0 To UBound($printer_list) - 1 Step 1 GUISetFont(10, 400, 0, $font) $position_vertical = $position_vertical + 25 ;30 $radio = GUICtrlCreateRadio($printer_list[$i], 20, $position_vertical, 350, 20) _ArrayAdd($printer_radio_array, $radio) If $currentprinter = $printer_list_ext[$i] Then GUICtrlSetState($radio, $GUI_CHECKED) EndIf Next _ArrayDelete($printer_radio_array, 0) GUISetFont(10, 400, 0, $font) $okbutton = GUICtrlCreateButton("OK", 10, $buttontop, 50, 25) GUICtrlSetOnEvent($okbutton, "OKButton") Local $AccelKeys[2][2] = [["{ENTER}", $okbutton], ["^O", $okbutton]] GUISetAccelerators($AccelKeys) GUISetState() EndIf EndFunc ;==>GetPrinter Func OKButton() For $i = 0 To UBound($printer_radio_array) - 1 Step 1 If GUICtrlRead($printer_radio_array[$i]) = 1 Then $printername = StringLeft($printer_list_ext[$i], StringInStr($printer_list_ext[$i], ",") - 1) EndIf Next GUIDelete($gh) ConsoleWrite($printername & @LF) EndFunc ;==>OKButton Func CLOSEClicked() ;$printername = $defaultprinter GUIDelete($gh) ; Cancelled() ; MsgBox(0, "", $printername) ; Return $printername ; next two added 8 Dec 2012 $printername = "nul" ConsoleWrite($printername & @LF) EndFunc ;==>CLOSEClicked One solution to making the list scrollable seems to be here: But after spending a few hours making a hopeless mess, I can't figure out how to put these two things together - starting with the problem that the menu created by my printer list doesn't have a preset size, only a preset width. What I would like to do is limit the height of my printer list to something like 800 pixels, and then add a scrollbar if the height is anything greater than that. Has anyone already solved this problem? Is there code that I haven't found that does the job? Edited June 19, 2020 by emendelson Added enough to make a standalone script. Link to comment Share on other sites More sharing options...
faustf Posted June 20, 2020 Share Posted June 20, 2020 you can use a listview with checkbutton (andset a control only one check is flagged work ), or if you want only radio button controll here emendelson 1 Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted June 20, 2020 Moderators Share Posted June 20, 2020 emendelson, This shows how to use my Scrollbar_Ex UDF in your script: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <Array.au3> #include "GUIScrollbars_Ex.au3" Opt("GUIOnEventMode", 1) Global $gh, $hAperture $ptrselmsg = "Select a printer for this document:" $printername = 0 Global $printer_list_ext[1] Global $printer_radio_array[1] GetPrinter($ptrselmsg) Do Sleep(100) Until $printername Exit Func GetPrinter($ptrselmsg) ; based on the excellent code by mfectau at ; https://www.autoitscript.com/forum/topic/40388-printer-selector-gui/?do=findComment&comment=869533 Local $printer_list[1] Local $regprinters = "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices" Local $currentprinter = RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows\", "Device") Local $defaultprinter = StringLeft($currentprinter, StringInStr($currentprinter, ",") - 1) Local $i = 1 Local $erreur_reg = False While 1 $imprimante = RegEnumVal($regprinters, $i) If @error Then ExitLoop Else _ArrayAdd($printer_list, $imprimante) $printer_list[0] += 1 _ArrayAdd($printer_list_ext, $imprimante & "," & RegRead($regprinters, $imprimante)) $printer_list_ext[0] += 1 EndIf $i += 1 WEnd ; Just for test ################################################################################# For $i = 1 To 0 ; Increase this number to get a longer list _ArrayAdd($printer_list, "Test printer " & $i) $printer_list[0] += 1 _ArrayAdd($printer_list_ext, "Test printer " & $i & "," & "RegRead " & $i) $printer_list_ext[0] += 1 Next ; ############################################################################################### If UBound($printer_list) >= 2 Then ; if 2 or more printers available, we show the dialog Local $font = "Verdana" Local $position_vertical = 5 ; 0 $gh = GUICreate($ptrselmsg, 400, 400) GUISetFont(10, 400, 0, $font) GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked") $okbutton = GUICtrlCreateButton("OK", 10, 365, 50, 25) GUICtrlSetOnEvent($okbutton, "OKButton") Local $AccelKeys[2][2] = [["{ENTER}", $okbutton], ["^O", $okbutton]] GUISetAccelerators($AccelKeys) GUISetState(@SW_SHOW, $gh) Local $groupheight = (UBound($printer_list) + 1) * 25 ;30 Local $hCurrent_GUI = $gh If $groupheight > 335 Then ; Height chosen according to the size of the main GUI of course ; We need scrollbars, so create a child GUI $hAperture = GUICreate("", 380, 335, 10, 10, $WS_POPUP, $WS_EX_MDICHILD, $gh) ; Generate the scrollbars $aAperture = _GUIScrollbars_Generate($hAperture, 0, $groupheight) ; Show the GUI GUISetState(@SW_SHOW, $hAperture) ; Set handle of GUI in which to create the controls $hCurrent_GUI = $hAperture Else ; No scroll bars GUICtrlCreateGroup("Available printers:", 10, 10, 380, $groupheight) EndIf GUISwitch($hCurrent_GUI) For $i = 1 To $printer_list[0] $position_vertical = $position_vertical + 25 ;30 $radio = GUICtrlCreateRadio($printer_list[$i], 20, $position_vertical, 350, 20) _ArrayAdd($printer_radio_array, $radio) $printer_radio_array[0] += 1 If $currentprinter = $printer_list_ext[$i] Then GUICtrlSetState($radio, $GUI_CHECKED) EndIf Next EndIf EndFunc ;==>GetPrinter Func OKButton() For $i = 1 To $printer_radio_array[0] If GUICtrlRead($printer_radio_array[$i]) = $GUI_CHECKED Then $printername = StringLeft($printer_list_ext[$i], StringInStr($printer_list_ext[$i], ",") - 1) EndIf Next GUIDelete($gh) GUIDelete($hAperture) ConsoleWrite($printername & @LF) EndFunc ;==>OKButton Func CLOSEClicked() GUIDelete($gh) GUIDelete($hAperture) $printername = "nul" ConsoleWrite($printername & @LF) EndFunc ;==>CLOSEClicked I made a few other changes too - such as why not use the [0] element of your arrays to hold the count. Please ask if you have any questions. M23 emendelson 1 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
emendelson Posted June 20, 2020 Author Share Posted June 20, 2020 @Melba23 This is perfect, and looks far better than my older code. I can't thank you enough. Now that you've shown me how to do it, it seems very straightforward, but I could never have figured it out for myself. A thousand thanks! Also @faustf Thank you also for that alternate solution! 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