Jump to content

Enable Scrolling In ReadOnly Edit Control?


Recommended Posts

Hi all,

So, I found a great post that helped lead me in the right direction to generate line numbers for an edit control. It works great, but I want the edit control to be read-only. As soon as I add the $ES_READONLY style to the edit control, the numbers are no longer generated. Is there a way to use this code from the post to have the line numbers generate as well as having the edit control set as read only? Ultimately, I'm looking to be able to set read only on/off with a hotkey which is CTRL+E (in the replicator).

 

#include <GUIConstants.au3>
#Include <GUIEdit.au3>

$sStuff = "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF

$bEditMode = False

GUIRegisterMsg($WM_CTLCOLOREDIT, 'WM_CTLCOLOREDIT')

$Form1 = GUICreate("Form1", 123, 196, -1, -1, BitOR($WS_MAXIMIZEBOX, $WS_MINIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_SYSMENU, $WS_CAPTION, $WS_OVERLAPPEDWINDOW, $WS_TILEDWINDOW, $WS_POPUP, $WS_POPUPWINDOW, $WS_GROUP, $WS_TABSTOP, $WS_BORDER, $WS_CLIPSIBLINGS))
$cDummy = GUICtrlCreateDummy()
$Edit_Num = GUICtrlCreateEdit("", 0, 0, 25, 165, BitOR($ES_AUTOVSCROLL, $ES_READONLY), 0)
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetData(-1, "1")
GUICtrlSetBkColor(-1, 0xC0DCC0)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH)
GUICtrlCreateLabel("CTRL+E to to toggle read only", 0, 180, 123, 16)
$Edit_Main = GUICtrlCreateEdit($sStuff, 26, 0, 96, 175, BitOr($GUI_SS_DEFAULT_EDIT, $WS_VSCROLL), 0); This works great!! (but it's not read only)
;~ $Edit_Main = GUICtrlCreateEdit($sStuff, 26, 0, 96, 175, BitOr($GUI_SS_DEFAULT_EDIT, $WS_VSCROLL, $ES_READONLY), 0); This is what I want to work, but read only prevents the numbers from working
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
$Edit_Blank = GUICtrlCreateLabel("", 0, 164, 25, 11)
GUICtrlSetBkColor(-1, 0xC0DCC0)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKBOTTOM + $GUI_DOCKSIZE)

GUISetState(@SW_SHOW)

Local $aAccelKeys[1][2] = [["^e", $cDummy]]
GUISetAccelerators($aAccelKeys, $Form1)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $cDummy
            $bEditMode = Not $bEditMode
            If $bEditMode Then
                GUICtrlSetStyle($Edit_Main, BitOr($GUI_SS_DEFAULT_EDIT, $WS_VSCROLL))
            Else
                GUICtrlSetStyle($Edit_Main, BitOr($GUI_SS_DEFAULT_EDIT, $WS_VSCROLL, $ES_READONLY))
            EndIf
    EndSwitch
WEnd

Func WM_CTLCOLOREDIT($hWnd, $iMsg, $iWParam, $iLParam)
    If $iLParam = GUICtrlGetHandle($Edit_Main) Then
        Local $iCount = _GUICtrlEdit_GetLineCount ($Edit_Main)
        Local $iNumCount = _GUICtrlEdit_GetLineCount ($Edit_Num) - 2
        If $iCount <> $iNumCount Then
            Local $sNumContent = ''
            For $i = 1 To $iCount
                $sNumContent &= $i & @CRLF
            Next
            GUICtrlSetData($Edit_Num, $sNumContent & @CRLF)
        EndIf
        Local $iFirstVisMain = _GUICtrlEdit_GetFirstVisibleLine ($Edit_Main)
        Local $iFirstVisNum = _GUICtrlEdit_GetFirstVisibleLine ($Edit_Num)
        If $iFirstVisMain <> $iFirstVisNum Then
            _GUICtrlEdit_LineScroll($Edit_Num, 0, $iFirstVisMain - $iFirstVisNum)   
        EndIf
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc

 

Link to comment
Share on other sites

  • Moderators

buymeapc,

From MSDN:

An edit control that is not read-only or disabled sends the WM_CTLCOLOREDIT message to its parent window when the control is about to be drawn

so it looks as if you cannot use this method when the edit is read-only.

M23

Edit: I found this in my Snippets folder - any use?

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

#Include <GuiEdit.au3>

Global $bEditMode = True

Global $iLineCount = 0 ; Keep a global count so we can check if it has changed

$hGUI = GUICreate("Test", 200, 200)

$cEdit_Num = GUICtrlCreateEdit("", 10, 10, 25, 165, BitOR($ES_AUTOVSCROLL, $ES_READONLY), 0)
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetData(-1, "1")
GUICtrlSetBkColor(-1, 0xC0DCC0)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH)

$cEdit_Main = GUICtrlCreateEdit("", 36, 10, 96, 175)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
GUICtrlCreateLabel("", 10, 164, 25, 11)
GUICtrlSetBkColor(-1, 0xC0DCC0)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH)

$cDummy = GUICtrlCreateDummy()

GUISetState(@SW_SHOW)

AdlibRegister("_LineNum", 100)

Local $aAccelKeys[1][2] = [["^e", $cDummy]]
GUISetAccelerators($aAccelKeys, $hGUI)

$sStuff = ""
For $i = 1 To 20
    GUICtrlSetData($cEdit_Main, "Blah " & $i & @CRLF, 1)
    Sleep(250)
Next

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $cDummy

            $bEditMode = Not $bEditMode

            If $bEditMode Then
                ConsoleWrite("Edit mode" & @CRLF)
                GUICtrlSetStyle($cEdit_Main, $GUI_SS_DEFAULT_EDIT)
            Else
                ConsoleWrite("ReadOnly mode" & @CRLF)
                GUICtrlSetStyle($cEdit_Main, BitOr($GUI_SS_DEFAULT_EDIT, $ES_READONLY))
            EndIf

    EndSwitch



WEnd



Func _LineNum() ; line numbering
    Local $iCount = _GUICtrlEdit_GetLineCount ($cEdit_Main)

    ;Check if the number of lines has changed in $cEdit_Main
    ;since this function was last called
    If $iCount <> $iLineCount Then
        ;save the new count to the global variable
        $iLineCount = $iCount

        Local $iNumCount = _GUICtrlEdit_GetLineCount ($cEdit_Num)
        If $iLineCount > $iNumCount Then
            For $i = $iNumCount + 1 To $iLineCount

                _GUICtrlEdit_AppendText ($cEdit_Num, @CRLF & $i)
            Next
        ElseIf $iLineCount < $iNumCount Then
            $text = GUICtrlRead($cEdit_Num)
            For $i = $iNumCount To $iLineCount + 1 Step -1
                $text = StringReplace($text,@CRLF & $i,"")
            Next
            GUICtrlSetData($cEdit_Num, $text)
        EndIf

    EndIf

    Local $iFirstVisMain = _GUICtrlEdit_GetFirstVisibleLine ($cEdit_Main)
    Local $iFirstVisNum = _GUICtrlEdit_GetFirstVisibleLine ($cEdit_Num)
    If $iFirstVisMain <> $iFirstVisNum Then
        _GUICtrlEdit_LineScroll($cEdit_Num, 0, $iFirstVisMain - $iFirstVisNum)
    EndIf
EndFunc

 

Edited by Melba23

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

Well, that certainly stinks, but thank you for confirming my suspicions...

Is there a way around this? I've tried creating a transparent label that's the same size of the edit control (minus the width of the scroll bars) to overlay it, but it always ends up behind the edit control instead of on top even though I've stipulated the $GUI_ONTOP style.

Link to comment
Share on other sites

  • Moderators

buymeapc,

Did you see the code I added in the edit above?

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

Ah, just saw your edit now. Thank you for finding that.

I checked it out and it is useful, however it doesn't have the ability to make the line numbers scroll along with the edit scrolling unfortunately - that's why I loved the WM_CTLCOLOREDIT function.

I really hate to be that "have my cake and eat it, too" kind of guy, but there has to be a way around this......no?

Link to comment
Share on other sites

Thanks to you finding that MSDN quote, I stumbled across a way to eat that yummy cake ^_^

If I replicate the WM_CTLCOLOREDIT function with the name of WM_CTLCOLORSTATIC, that takes care of the read only scrolling as this new function will scroll the read only control. I'm not too fond of using the same code in two different areas, but heck, it gets the job done.

Thank you so much for the help!!

#include <GUIConstants.au3>
#Include <GUIEdit.au3>

$sStuff = "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF & _
            "Blah" & @CRLF

$bEditMode = False

GUIRegisterMsg($WM_CTLCOLOREDIT, 'WM_CTLCOLOREDIT')
GUIRegisterMsg($WM_CTLCOLORSTATIC, 'WM_CTLCOLORSTATIC')

$Form1 = GUICreate("Form1", 123, 196, -1, -1, BitOR($WS_MAXIMIZEBOX, $WS_MINIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_SYSMENU, $WS_CAPTION, $WS_OVERLAPPEDWINDOW, $WS_TILEDWINDOW, $WS_POPUP, $WS_POPUPWINDOW, $WS_GROUP, $WS_TABSTOP, $WS_BORDER, $WS_CLIPSIBLINGS))
$cDummy = GUICtrlCreateDummy()
$Edit_Num = GUICtrlCreateEdit("", 0, 0, 25, 165, BitOR($ES_AUTOVSCROLL, $ES_READONLY), 0)
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetData(-1, "1")
GUICtrlSetBkColor(-1, 0xC0DCC0)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH)
GUICtrlCreateLabel("CTRL+E to toggle read only", 0, 180, 123, 16)
$Edit_Main = GUICtrlCreateEdit($sStuff, 26, 0, 96, 175, BitOr($GUI_SS_DEFAULT_EDIT, $WS_VSCROLL), 0); This works great!! (but it's not read only)
;~ $Edit_Main = GUICtrlCreateEdit($sStuff, 26, 0, 96, 175, BitOr($GUI_SS_DEFAULT_EDIT, $WS_VSCROLL, $ES_READONLY), 0); This is what I want to work, but read only prevents the numbers from working
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
$Edit_Blank = GUICtrlCreateLabel("", 0, 164, 25, 11)
GUICtrlSetBkColor(-1, 0xC0DCC0)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKBOTTOM + $GUI_DOCKSIZE)

GUISetState(@SW_SHOW)

Local $aAccelKeys[1][2] = [["^e", $cDummy]]
GUISetAccelerators($aAccelKeys, $Form1)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $cDummy
            $bEditMode = Not $bEditMode
            If $bEditMode Then
                GUICtrlSetStyle($Edit_Main, BitOr($GUI_SS_DEFAULT_EDIT, $WS_VSCROLL))
            Else
                GUICtrlSetStyle($Edit_Main, BitOr($GUI_SS_DEFAULT_EDIT, $WS_VSCROLL, $ES_READONLY))
            EndIf
    EndSwitch
WEnd

Func GUICtrlEdit_Scroll($hWnd, $hWnd_Num)
    Local $iCount = _GUICtrlEdit_GetLineCount($hWnd)
    Local $iNumCount = _GUICtrlEdit_GetLineCount($hWnd_Num) - 2
    If $iCount <> $iNumCount Then
        Local $sNumContent = ''
        For $i = 1 To $iCount
            $sNumContent &= $i & @CRLF
        Next
        GUICtrlSetData($hWnd_Num, $sNumContent & @CRLF)
    EndIf
    Local $iFirstVisMain = _GUICtrlEdit_GetFirstVisibleLine($hWnd)
    Local $iFirstVisNum = _GUICtrlEdit_GetFirstVisibleLine($hWnd_Num)
    If $iFirstVisMain <> $iFirstVisNum Then
        _GUICtrlEdit_LineScroll($hWnd_Num, 0, $iFirstVisMain - $iFirstVisNum)
    EndIf
EndFunc

Func WM_CTLCOLOREDIT($hWnd, $iMsg, $iWParam, $iLParam)
    If $iLParam = GUICtrlGetHandle($Edit_Main) Then
        GUICtrlEdit_Scroll($Edit_Main, $Edit_Num)
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc

Func WM_CTLCOLORSTATIC($hWnd, $iMsg, $iWParam, $iLParam)
    If $iLParam = GUICtrlGetHandle($Edit_Main) Then
        GUICtrlEdit_Scroll($Edit_Main, $Edit_Num)
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc

 

Edited by buymeapc
Better function usage in code
Link to comment
Share on other sites

  • Moderators

buymeapc,

No need for 2 handlers - just register both messages to the same function.

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...