Jump to content

Make GUI Control (list of radio buttons) scrollable?


Recommended Posts

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:

#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 by emendelson
Added enough to make a standalone script.
Link to comment
Share on other sites

  • Moderators

emendelson,

This shows how to use my Scrollbar_Ex UDF in your script:

#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

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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 columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...