emendelson Posted June 19, 2020 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.
faustf Posted June 20, 2020 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
Moderators Melba23 Posted June 20, 2020 Moderators 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
emendelson Posted June 20, 2020 Author 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!
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