TheAutomator Posted March 20 Posted March 20 (edited) I'm looking for a way to programatically scroll a rich edit control to a specific line (range = first line to last line). The edit has no scrollbar and that should stay that way, the cursor and selection sould also keep unmodified, is that even possible? I know about _GUICtrlRichEdit_GetScrollPos but it works with pixels and has no clear way of finding the min and max range.. The goal here is to create a custom scrollbar, made from a label. Ideally it would also move the scrollbar thumb if I scroll the edit or change the cursor position of the edit. I have some code, but it's unfinished, it's quite a workaround but the best I can do at the moment (sorry if it looks a little dirty)... any help or better ideas would be appriciated! Contributors to this code also get credits on the code of this program in the example script section: See part of code under here, and for the graphics I'll upload a zip file expandcollapse popup; colors const $color_text_white = 0x00ffffff const $color_text_gray = 0x00C0C0C0 const $color_element_gray = 0x606060 const $color_control_gray = 0x404040 const $color_border_gray = 0x202020 const $color_text_red = 0x006600ff const $color_text_green = 0x0000ff66 const $color_text_blue = 0x00ff6600 const $color_transparent_background = 0xff00ff ; font names const $font_handel_gothic_bt = 'handelgothic bt' const $font_lucida_console = 'lucida console' ; sound effects const $sound_start = @scriptdir & '\sounds\start.wav' const $sound_click = @scriptdir & '\sounds\click.wav' const $sound_alert = @scriptdir & '\sounds\alert.wav' const $sound_stop = @scriptdir & '\sounds\stop.wav' ; user interface images const $image_alert = @scriptdir & '\images\alert.bmp' const $image_blue = @scriptdir & '\images\blue.bmp' const $image_bold = @scriptdir & '\images\bold.bmp' const $image_case_off = @scriptdir & '\images\case_off.bmp' const $image_case_on = @scriptdir & '\images\case_on.bmp' const $image_close = @scriptdir & '\images\close.bmp' const $image_exit = @scriptdir & '\images\exit.bmp' const $image_find = @scriptdir & '\images\find.bmp' const $image_gray = @scriptdir & '\images\gray.bmp' const $image_green = @scriptdir & '\images\green.bmp' const $image_info = @scriptdir & '\images\info.bmp' const $image_install = @scriptdir & '\images\install.bmp' const $image_italic = @scriptdir & '\images\italic.bmp' const $image_link = @scriptdir & '\images\link.bmp' const $image_minimark = @scriptdir & '\images\minimark.bmp' const $image_no = @scriptdir & '\images\no.bmp' const $image_ok = @scriptdir & '\images\ok.bmp' const $image_open = @scriptdir & '\images\open.bmp' const $image_options = @scriptdir & '\images\options.bmp' const $image_red = @scriptdir & '\images\red.bmp' const $image_remove = @scriptdir & '\images\remove.bmp' const $image_replace = @scriptdir & '\images\replace.bmp' const $image_replace_all = @scriptdir & '\images\replace_all.bmp' const $image_reset = @scriptdir & '\images\reset.bmp' const $image_save = @scriptdir & '\images\save.bmp' const $image_scroll = @scriptdir & '\images\scroll.bmp' const $image_scroll_down = @scriptdir & '\images\scroll_down.bmp' const $image_scroll_up = @scriptdir & '\images\scroll_up.bmp' const $image_search = @scriptdir & '\images\search.bmp' const $image_searcher = @scriptdir & '\images\searcher.bmp' const $image_settings = @scriptdir & '\images\settings.bmp' const $image_setup = @scriptdir & '\images\setup.bmp' const $image_size = @scriptdir & '\images\size.bmp' const $image_size_down = @scriptdir & '\images\size_down.bmp' const $image_size_up = @scriptdir & '\images\size_up.bmp' const $image_sound_off = @scriptdir & '\images\sound_off.bmp' const $image_sound_on = @scriptdir & '\images\sound_on.bmp' const $image_strike = @scriptdir & '\images\strike.bmp' const $image_underline = @scriptdir & '\images\underline.bmp' const $image_white = @scriptdir & '\images\white.bmp' const $image_word_off = @scriptdir & '\images\word_off.bmp' const $image_word_on = @scriptdir & '\images\word_on.bmp' const $image_yes = @scriptdir & '\images\yes.bmp' ; intro file const $file_manual = @scriptdir & '\data\MiniMark.mnm' #notrayicon #include <guirichedit.au3> #include <guiconstants.au3> #include <winapisyswin.au3> local $x for $i = 1 to 300 $x &= $i & @CRLF Next $minimark_form = guicreate('MiniMark', 380, 380, default, default, $ws_popup, $ws_ex_layered) guisetbkcolor($color_transparent_background) $minimark_background = guictrlcreatepic($image_minimark, 0, 0, 380, 380) guictrlsetstate(default, $gui_disable) $minimark_title = guictrlcreatelabel('the title.....', 5, 5, 370, 20, bitor($ss_centerimage, $ss_center), $gui_ws_ex_parentdrag) ; use label to drag form guictrlsettip(default, 'full path') ; display full path on mouse over guictrlsetfont(default, 12, 400, 0, $font_handel_gothic_bt) guictrlsetcolor(default, $color_text_gray) guictrlsetbkcolor(default, $gui_bkcolor_transparent) $minimark_edit = _guictrlrichedit_create($minimark_form, $x, 10, 35, 270, 335, bitor($es_multiline, $es_autovscroll, $es_nohidesel), 0) ; $es_nohidesel for visible selection when using search function _guictrlrichedit_setbkcolor($minimark_edit, $color_control_gray) ;~ load_file() guiregistermsg($wm_command, wm_command) func wm_command($hwnd, $imsg, $wparam, $lparam) ; we need this becouse rich edit keeps changing to default style if $minimark_edit <> $lparam then return $gui_rundefmsg if _guictrlrichedit_istextselected($minimark_edit) then return $gui_rundefmsg if _guictrlrichedit_getfont($minimark_edit)[1] <> $font_lucida_console then _guictrlrichedit_setfont($minimark_edit, 9, $font_lucida_console) _guictrlrichedit_setcharcolor($minimark_edit, $color_text_gray) endif return $gui_rundefmsg endfunc $button_options = guictrlcreatepic($image_options, 305, 30, 70, 20) guictrlsettip(default, 'Open settings.', 'ctrl + o') $button_open = guictrlcreatepic($image_open, 305, 55, 70, 20) guictrlsettip(default, 'Open a new *.mnm file.', 'ctrl + o') $button_bold = guictrlcreatepic($image_bold, 305, 80, 70, 20) guictrlsettip(default, 'Make selection bold.', 'ctrl + b') $button_italic = guictrlcreatepic($image_italic, 305, 105, 70, 20) guictrlsettip(default, 'Make selection italic.', 'ctrl + i') $button_strike = guictrlcreatepic($image_strike, 305, 130, 70, 20) guictrlsettip(default, 'Make selection struck.', 'ctrl + t') $button_underline = guictrlcreatepic($image_underline, 305, 155, 70, 20) guictrlsettip(default, 'Make selection underlined.', 'ctrl + u') $button_red = guictrlcreatepic($image_red, 305, 180, 70, 20) guictrlsettip(default, 'Make selection red.', 'shift + ctrl + r') $button_green = guictrlcreatepic($image_green, 305, 205, 70, 20) guictrlsettip(default, 'Make selection green.', 'shift + ctrl + g') $button_blue = guictrlcreatepic($image_blue, 305, 230, 70, 20) guictrlsettip(default, 'Make selection blue.', 'shift + ctrl + b') $button_white = guictrlcreatepic($image_white, 305, 255, 70, 20) guictrlsettip(default, 'Make selection white.', 'shift + ctrl + w') $button_gray = guictrlcreatepic($image_gray, 305, 280, 70, 20) guictrlsettip(default, 'Make selection default style and gray.', 'shift + ctrl + d') $button_search = guictrlcreatepic($image_search, 305, 305, 70, 20) guictrlsettip(default, 'Find and replace text.', 'ctrl + f') $button_save = guictrlcreatepic($image_save, 305, 330, 70, 20) guictrlsettip(default, 'Save file / save file as.', 'ctrl + s / shift + ctrl + s') $button_exit = guictrlcreatepic($image_exit, 305, 355, 70, 20) guictrlsettip(default, 'Quit the program.', 'escape') $minimark_scroll_up = GUICtrlCreatePic($image_scroll_up, 290, 30, 10, 10) $minimark_scroll_thumb = GUICtrlCreatePic($image_scroll, 290, 45, 10, 20) ; scroll background: 290, 45, 10, 315 $minimark_scroll_down = GUICtrlCreatePic($image_scroll_down, 290, 365, 10, 10) _guictrlrichedit_seteventmask($minimark_edit, $enm_scrollevents) guiregistermsg($wm_notify, wm_notify) func wm_notify($hwnd, $imsg, $wparam, $lparam) local $tfilter = dllstructcreate($tagmsgfilter, $lparam) if $tfilter.hwndfrom = $minimark_edit then _guictrlrichedit_scrolllines($tfilter.hwndfrom, $tfilter.wparam ? 1 : -1) return $gui_rundefmsg endfunc _winapi_setlayeredwindowattributes($minimark_form, $color_transparent_background) ;set the transparant gui color guisetstate(@SW_SHOW, $minimark_form) #Region scrollbar $scroll_drag = False ; are we dragging the scroll button? local $scroll_selection, $scroll_new_pos ; remember cursor and selection Func check_scroll_clicked() Local $scroll_cursor = GUIGetCursorInfo($minimark_form) If _ $scroll_cursor[0] >= 290 And _ $scroll_cursor[0] <= 300 And _ $scroll_cursor[1] >= 45 And _ $scroll_cursor[1] <= 360 _ Then $scroll_drag = True $scroll_selection = _GUICtrlRichEdit_GetSel($minimark_edit) EndIf EndFunc Func scroll() Local $scroll_x = 290 ; x of $scroll control at all times Local $scroll_min_y = 55, $scroll_max_y = 350 ; range of y movement for $scroll (top of frame till bottom - height) Local $scroll_cursor = GUIGetCursorInfo($minimark_form)[1] ; get y position of cursor if $scroll_cursor < $scroll_min_y then $scroll_cursor = $scroll_min_y if $scroll_cursor > $scroll_max_y then $scroll_cursor = $scroll_max_y GUICtrlSetPos($minimark_scroll_thumb, $scroll_x, $scroll_cursor-10) ; drag scroll button within range of background bar $scroll_ratio = ($scroll_cursor - $scroll_min_y) / ($scroll_max_y - $scroll_min_y) ; calculate scroll position percentage between 0 and 1 $scroll_last = _GUICtrlRichEdit_GetLineCount($minimark_Edit) local $scroll_calculate = $scroll_ratio * $scroll_last ; calculate where to walk to local $scroll_line = _GUICtrlRichEdit_GetFirstCharPosOnLine($minimark_Edit, $scroll_calculate) _GUICtrlRichEdit_SetSel($minimark_edit, $scroll_line, $scroll_line) consolewrite(_GUICtrlRichEdit_GetLineCount($minimark_Edit) & '---' & $scroll_calculate & '---' & $scroll_ratio & @CRLF) EndFunc #endregion While 1 switch guigetmsg() case $gui_event_close soundplay($sound_stop, 1) _guictrlrichedit_destroy($minimark_edit) guidelete() exit case $GUI_EVENT_PRIMARYDOWN check_scroll_clicked() Case $GUI_EVENT_MOUSEMOVE If $scroll_drag Then scroll() Case $GUI_EVENT_PRIMARYUP if $scroll_drag Then $scroll_new_pos = _GUICtrlRichEdit_GetScrollPos($minimark_edit) _GUICtrlRichEdit_SetSel($minimark_edit, $scroll_selection[0], $scroll_selection[1]) _GUICtrlRichEdit_SetScrollPos($minimark_edit, $scroll_new_pos[0], $scroll_new_pos[1]) $scroll_drag = False EndIf case $minimark_scroll_up _guictrlrichedit_scrolllines($minimark_edit, -1) case $minimark_scroll_down _guictrlrichedit_scrolllines($minimark_edit, 1) EndSwitch WEnd scroller.zip Edited March 20 by TheAutomator Retro Console, NestedArrayDisplay UDF foldermaker-pro-clone MiniMark Editor
junkew Posted March 20 Posted March 20 (edited) https://www.autoitscript.com/autoit3/docs/libfunctions/_GUICtrlRichEdit_FindText.htm https://www.autoitscript.com/autoit3/docs/libfunctions/_GUICtrlRichEdit_GotoCharPos.htm Goto 0 and in a loop find carriage return Probably with those messages you will be able to do this EM_POSFROMCHAR EM_CHARFROMPOS EM_LINEFROMCHAR EM_LINEINDEX EM_LINESCROLL And the editcontrol functions should work also otherwise you need sendmessage function with windows messages https://learn.microsoft.com/en-us/windows/win32/controls/about-rich-edit-controls https://www.autoitscript.com/autoit3/docs/libfunctions/_GUICtrlEdit_LineScroll.htm Edited March 20 by junkew TheAutomator 1 FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets
junkew Posted March 20 Posted March 20 (edited) This seems to work for both controls but you have to set the rich text box first to point 0,0 The reverse order is not working expandcollapse popup#include <EditConstants.au3> #include <GuiEdit.au3> #include <GuiRichEdit.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Example() Func Example() Local $hGui=GUICreate("My GUI edit and rich edit") ; will create a dialog box that when displayed is centered local $someTextLines=stringreplace("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","x", "line" & @crlf) Local $idMyedit = GUICtrlCreateEdit($someTextLines & @CRLF, 10, 10, 350, 180, $ES_MULTILINE+$ES_AUTOVSCROLL + $WS_VSCROLL) Local $hRichEdit = _GUICtrlRichEdit_Create($hGui, $someTextLines, 10, 210, 350, 180, bitor($ES_MULTILINE, $ES_AUTOVSCROLL, $WS_VSCROLL)) ;~ Important line _GUICtrlRichEdit_SetSel($hRichEdit, 0, 0) GUISetState(@SW_SHOW) ;~ GUICtrlSendMsg ($hRichEdit, $EM_LINESCROLL, 0, 0) local $i For $i=10 to 20 ;~ _GUICtrlEdit_LineScroll($idMyedit, 0, _GUICtrlEdit_GetLineCount($idMyedit)) ;~ _GUICtrlEdit_LineScroll($hRichEdit, 0, _GUICtrlEdit_GetLineCount($hRichEdit)) _GUICtrlEdit_LineScroll($idMyedit, 0, $i) _GUICtrlEdit_LineScroll($hRichEdit, 0, $i) ;~ GUICtrlSendMsg ($hRichEdit, $EM_LINESCROLL, 0, $i) ;~ Local $nIndex = GUICtrlSendMsg ($hRichEdit, $EM_LINEINDEX, $i, 0) ;~ GUICtrlSendMsg ($hRichEdit, $EM_SETSEL, $nIndex, 0) ;~ ControlCommand ($hGUI, "", $hRichEdit, "SetCurrentSelection", @CRLF) ;~ $iCharPosition = _GUICtrlRichEdit_GetFirstCharPosOnLine($hRichEdit, $i) ;~ _GUICtrlRichEdit_SetSel($hRichEdit, $iCharPosition, $iCharPosition + 4) sleep(250) next ;~ Important line ;~ _GUICtrlEdit_SetSel($idMyedit, -1, -1) ;~ _GUICtrlRichEdit_SetSel($hRichEdit, -1,-1) For $i=10 to 0 step -1 _GUICtrlEdit_LineScroll($idMyedit, 0, $i) _GUICtrlEdit_LineScroll($hRichEdit, 0, $i) sleep(250) next ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete() EndFunc ;==>Example Edited March 20 by junkew TheAutomator 1 FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets
pixelsearch Posted March 21 Posted March 21 (edited) On 3/20/2025 at 3:07 AM, TheAutomator said: The edit has no scrollbar and that should stay that way Maybe you will tell us why you don't want to use a native vertical scrollbar in your richedit control, is it simply its color you don't like, or something else ? Because, as you already know, a simple $WS_SCROLL style would solve it all. Anyway, as you prefer to mimic the scrollbar (by using a vertical movable/resizable label control) , then imho the 1st step should be to constantly check what is the last visible line in your richedit control. Knowing the 1st visible line is easy, as there is a native windows message EM_GETFIRSTVISIBLELINE which indicates this. With AutoIt, the message is found in the function _GUICtrlRichEdit_GetNumberOfFirstVisibleLine() But unfortunately there is no "EM_GETLASTVISIBLELINE" Windows message (and it's a pity) but you can calculate it, using a couple of other messages, as shown in the script below. Now, when you got these 2 variables (1st and last visible lines) then it should be possible to mimic a vertical scrollbar, by comparing constantly the value of the 2 variables to the total number of lines in your richedit control, then move/resize accordingly your vertical label (the "scrollbar thumb") The script below got a scrollable richedit control (using mousewheel, without scrollbar) as discussed in our preceding posts. The purpose of the script is simply to indicate how to calculate the last visible line of a richedit control, which is (imho) the 1st step that could help to achieve your goal. Good luck expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiRichEdit.au3> #include <WindowsConstants.au3> Opt("MustDeclareVars", 1) ;0=no, 1=require pre-declaration Global $g_hRichEdit Example() Func Example() Local $hGui, $idLblMsg, $idBtnNext, $aRect, $iCharIndex, $iLastVisibleLine $hGui = GUICreate("Last visible line richedit", 320, 320) $g_hRichEdit = _GUICtrlRichEdit_Create($hGui, "Line # 01", 5, 5, 310, 214, _ BitOR($ES_MULTILINE, $ES_AUTOVSCROLL)) $idLblMsg = GUICtrlCreateLabel("", 5, 225, 310, 50) GUICtrlSetBkColor(-1, 0xFFFF00) ; yellow $idBtnNext = GUICtrlCreateButton("Scroll then Check last visible line", 70, 280, 180, 30) GUISetState(@SW_SHOW) _GUICtrlRichEdit_AppendText($g_hRichEdit, @CRLF & "Line # 02") For $i = 3 To 40 _GUICtrlRichEdit_AppendText($g_hRichEdit, @CRLF & "Line # " & StringFormat("%02i", $i)) Next _GUICtrlRichEdit_SetSel($g_hRichEdit, 0, 129) _GUICtrlRichEdit_SetCharAttributes($g_hRichEdit, "+bo") _GUICtrlRichEdit_SetEventMask($g_hRichEdit, $ENM_SCROLLEVENTS) GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _GUICtrlRichEdit_Destroy($g_hRichEdit) Exit Case $idBtnNext $aRect = _GUICtrlRichEdit_GetRECT($g_hRichEdit) ; ConsoleWrite("Formatting rectangle : " & $aRect[0] & " " & $aRect[1] & " " & $aRect[2] & " " & $aRect[3] & @crlf) $iCharIndex = _GUICtrlRichEdit_GetCharPosFromXY($g_hRichEdit, $aRect[0] + 2, $aRect[3] - 2) ; ConsoleWrite("$iCharIndex : " & $iCharIndex & @crlf) $iLastVisibleLine = _GUICtrlRichEdit_GetLineNumberFromCharPos($g_hRichEdit, $iCharIndex) ; ConsoleWrite("$iLastVisibleLine : " & $iLastVisibleLine & @crlf & "=================" & @crlf) GUICtrlSetData($idLblMsg, "First Visible Line : " & _GUICtrlRichEdit_GetNumberOfFirstVisibleLine($g_hRichEdit) & @crlf & _ "Last Visible Line : " & $iLastVisibleLine & @crlf & _ "Count of all lines : " & _GUICtrlRichEdit_GetLineCount($g_hRichEdit)) ControlFocus($hGUI, "", $g_hRichEdit) EndSwitch WEnd EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tFilter = DllStructCreate($tagMSGFILTER, $lParam) If $tFilter.hwndFrom = $g_hRichEdit Then _GUICtrlRichEdit_ScrollLines($g_hRichEdit, $tFilter.wParam ? 1 : -1) Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Edited March 25 by pixelsearch added "count of all lines" TheAutomator 1 "I think you are searching a bug where there is no bug..."
TheAutomator Posted March 26 Author Posted March 26 (edited) Hi everyone, thanks for the replys! Normally I reply whitin a day, but I have been sick the last few days.. junkew, Thanks, it's a good start for me to experiment with The messages you listed are the ones that should work somehow if I combine them the right way yes. pixelsearch, Thanks for the effort I want a custom colored scrollbar is the reason, not the ugly white standart one that hurts your eyes when using a dark gui (like in my project). Your code has no scrollbar at all but the code can be helpfull for calculations! I already made the graphics to fit the dark theme, but the code is still a bit buggy and not completely working: I wish i could just hide the default one but send messages to it and get from it instead of reinventing the wheel to have a custom color... I'm gonna experiment a little more with the code and see how good i can get it for general use, for now my bar just moves the cursor and resets the selection when done scrolling (it works pretty well too but you can see the cursor move when you scroll and the bar stays on the same spot when you change the text). So what I already have now: - an image for the background and one for the thumb - the ability to drag the thumb image over the background and get the result als a value between 0 and 1 according to the position dragged - some code that works a bit but not fully as i would like (like a real scrollbar) When I have a few finished scripts i'll post them here Edited Wednesday at 09:29 PM by TheAutomator edit for pixelsearch pixelsearch 1 Retro Console, NestedArrayDisplay UDF foldermaker-pro-clone MiniMark Editor
pixelsearch Posted Wednesday at 09:29 PM Posted Wednesday at 09:29 PM Just now, TheAutomator said: Your code has no scrollbar at all Yes I know The purpose of my preceding post was just to indicate how to calculate precisely the number of the last visible line, which seems to me a very important step before doing anything else : remember the height of the scroll thumb should be recalculated when comparing the number of visible lines to the number of total lines, which will constantly change while the user adds/removes lines. In a 2nd step, I went a bit further, adding a registered WM_COMMAND message to take care of $EN_CHANGE or $EN_UPDATE, which could call a function dedicated to resize/move the scroll thumb (or hide it when all lines are visible in the richedit area) Maybe $EN_UPDATE is a better choice than $EN_CHANGE because the scrolling function will be called only from this place ($EN_UPDATE) . Because if you choose instead to monitor $EN_CHANGE, then you'll have to call the scrolling function from several other places (for example from inside WM_NOTIFY while you're using the mouse wheel to scroll [this triggers $EN_UPDATE but not $EN_CHANGE], or from a resize function, in case one day you allow the richedit control to be resized while you resize the GUI etc...) The annoyance with $EN_UPDATE is that it's called more often than $EN_CHANGE, which means the scrolling function will also be called more often when using $EN_UPDATE (compared to $EN_CHANGE) Anyway, all this is challenging for educational purpose. If I succeed achieving some working code, I"ll post it here. 21 minutes ago, TheAutomator said: Normally I reply whitin a day, but I have been sick the last few days.. Glad to know you're feeling better TheAutomator 1 "I think you are searching a bug where there is no bug..."
TheAutomator Posted Wednesday at 09:48 PM Author Posted Wednesday at 09:48 PM (edited) 39 minutes ago, pixelsearch said: Yes I know The purpose of my preceding post was just to indicate how to calculate precisely the number of the last visible line, which seems to me a very important step before doing anything else : remember the height of the scroll thumb should be recalculated when comparing the number of visible lines to the number of total lines, which will constantly change while the user adds/removes lines. In a 2nd step, I went a bit further, adding a registered WM_COMMAND message to take care of $EN_CHANGE or $EN_UPDATE, which could call a function dedicated to resize/move the scroll thumb (or hide it when all lines are visible in the richedit area) Maybe $EN_UPDATE is a better choice than $EN_CHANGE because the scrolling function will be called only from this place ($EN_UPDATE) . Because if you choose instead to monitor $EN_CHANGE, then you'll have to call the scrolling function from several other places (for example from inside WM_NOTIFY while you're using the mouse wheel to scroll [this triggers $EN_UPDATE but not $EN_CHANGE], or from a resize function, in case one day you allow the richedit control to be resized while you resize the GUI etc...) The annoyance with $EN_UPDATE is that it's called more often than $EN_CHANGE, which means the scrolling function will also be called more often when using $EN_UPDATE (compared to $EN_CHANGE) Anyway, all this is challenging for educational purpose. If I succeed achieving some working code, I"ll post it here. Glad to know you're feeling better the code you provided is already helpfull for calculations, but seeing all this makes me think if it's worth all the trouble.. if _GUICtrlRichEdit_ScrollLines($hWnd, $iQlines) would have the ability to work in a non relative way, the problem would be a lot more easy! I don't get why such functionality does'nt exist.. Maybe I need to keep it basic and just save the current selection, move the cursor to the targetline and when done dragging the scroller restore the selection (like I already have code for) and to set the scroll thumb to the right place while editing -> check if cursorpos is changed in the gui loop? other alternative: somehow change transparancy of the real scrollbar Edited Wednesday at 10:09 PM by TheAutomator Retro Console, NestedArrayDisplay UDF foldermaker-pro-clone MiniMark Editor
WildByDesign Posted Thursday at 12:07 AM Posted Thursday at 12:07 AM 3 hours ago, TheAutomator said: I want a custom colored scrollbar is the reason, not the ugly white standart one that hurts your eyes when using a dark gui (like in my project). If it's running on Windows 10 or 11, you can add a win32-darkmode scrollbar. It isn't quite the same aesthetic as your custom-made scrollbar, but it likely wont have all of the other issues that you are experiencing with your custom scrollbar that you mentioned. I added one to your MiniMark.au3 and it works really well. I've added a video within a spoiler so that you can see. Spoiler video.mp4 TheAutomator 1
Solution argumentum Posted Thursday at 01:57 AM Solution Posted Thursday at 01:57 AM (edited) Spoiler expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiRichEdit.au3> #include <WindowsConstants.au3> #include "GUIDarkMode_v0.02mod.au3" ; https://www.autoitscript.com/forum/applications/core/interface/file/attachment.php?id=76109&key=ecd9ab7288a19d16e4d006193fba0763 Example() Func Example() Local $hGui, $hRichEdit, $iMsg, $iW = 400, $iH = 200 $hGui = GUICreate("Example (" & StringTrimRight(@ScriptName, StringLen(".exe")) & ")", $iW, $iH, -1, -1) $hRichEdit = _GUICtrlRichEdit_Create($hGui, "", 0, 0, $iW, $iH, _ BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL), 0) _GUICtrlRichEdit_SetBkColor($hRichEdit, 0x212121) _GUICtrlRichEdit_SetCharColor($hRichEdit, 0xFFFFFF) set_W11GuiColor($hGUI, 0x121212, 35) ; for Win 11 22H2 onwards ; Caption background GuiDarkmodeApply($hGUI) GUISetState(@SW_SHOW) Local $sText = "" For $n = 1 To 40 $sText &= "This is appended text." & @CRLF Next _GUICtrlRichEdit_AppendText($hRichEdit, $sText) While True $iMsg = GUIGetMsg() Select Case $iMsg = $GUI_EVENT_CLOSE _GUICtrlRichEdit_Destroy($hRichEdit) ; needed unless script crashes ; GUIDelete() ; is OK too Exit EndSelect WEnd EndFunc ;==>Example ;~ set_W11GuiColor($gui_hwnd, 0x00ff00) ; for Win 11 22H2 onwards Func set_W11GuiColor($hwnd, $iBorderColor = 0xFFffffff, $DWMWA_BORDER_COLOR = 34) ; default is 0xffFFFFFF ; else use 0x00rrggbb ;~ $DWMWA_BORDER_COLOR = 34 ; https://www.purebasic.fr/english/viewtopic.php?t=78732 ;~ Enumeration DWMWINDOWATTRIBUTE ;~ #DWMWA_USE_IMMERSIVE_DARK_MODE = 20 ;~ #DWMWA_BORDER_COLOR = 34 ;~ #DWMWA_CAPTION_COLOR = 35 ;~ #DWMWA_TEXT_COLOR = 36 ;~ EndEnumeration dllcall( _ 'dwmapi.dll', _ 'long', 'DwmSetWindowAttribute', _ 'hwnd', $hwnd, _ 'dword', $DWMWA_BORDER_COLOR, _ 'dword*', $iBorderColor, _ 'dword', 4 ) EndFunc Edited Thursday at 02:00 AM by argumentum TheAutomator and WildByDesign 2 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
TheAutomator Posted Thursday at 06:23 PM Author Posted Thursday at 06:23 PM 18 hours ago, WildByDesign said: If it's running on Windows 10 or 11, you can add a win32-darkmode scrollbar. It isn't quite the same aesthetic as your custom-made scrollbar, but it likely wont have all of the other issues that you are experiencing with your custom scrollbar that you mentioned. I added one to your MiniMark.au3 and it works really well. I've added a video within a spoiler so that you can see. Reveal hidden contents video.mp4 1.05 MB · 1 download How did you do that? That's a huge improvement! Retro Console, NestedArrayDisplay UDF foldermaker-pro-clone MiniMark Editor
TheAutomator Posted Thursday at 06:45 PM Author Posted Thursday at 06:45 PM 16 hours ago, argumentum said: Reveal hidden contents expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiRichEdit.au3> #include <WindowsConstants.au3> #include "GUIDarkMode_v0.02mod.au3" ; https://www.autoitscript.com/forum/applications/core/interface/file/attachment.php?id=76109&key=ecd9ab7288a19d16e4d006193fba0763 Example() Func Example() Local $hGui, $hRichEdit, $iMsg, $iW = 400, $iH = 200 $hGui = GUICreate("Example (" & StringTrimRight(@ScriptName, StringLen(".exe")) & ")", $iW, $iH, -1, -1) $hRichEdit = _GUICtrlRichEdit_Create($hGui, "", 0, 0, $iW, $iH, _ BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL), 0) _GUICtrlRichEdit_SetBkColor($hRichEdit, 0x212121) _GUICtrlRichEdit_SetCharColor($hRichEdit, 0xFFFFFF) set_W11GuiColor($hGUI, 0x121212, 35) ; for Win 11 22H2 onwards ; Caption background GuiDarkmodeApply($hGUI) GUISetState(@SW_SHOW) Local $sText = "" For $n = 1 To 40 $sText &= "This is appended text." & @CRLF Next _GUICtrlRichEdit_AppendText($hRichEdit, $sText) While True $iMsg = GUIGetMsg() Select Case $iMsg = $GUI_EVENT_CLOSE _GUICtrlRichEdit_Destroy($hRichEdit) ; needed unless script crashes ; GUIDelete() ; is OK too Exit EndSelect WEnd EndFunc ;==>Example ;~ set_W11GuiColor($gui_hwnd, 0x00ff00) ; for Win 11 22H2 onwards Func set_W11GuiColor($hwnd, $iBorderColor = 0xFFffffff, $DWMWA_BORDER_COLOR = 34) ; default is 0xffFFFFFF ; else use 0x00rrggbb ;~ $DWMWA_BORDER_COLOR = 34 ; https://www.purebasic.fr/english/viewtopic.php?t=78732 ;~ Enumeration DWMWINDOWATTRIBUTE ;~ #DWMWA_USE_IMMERSIVE_DARK_MODE = 20 ;~ #DWMWA_BORDER_COLOR = 34 ;~ #DWMWA_CAPTION_COLOR = 35 ;~ #DWMWA_TEXT_COLOR = 36 ;~ EndEnumeration dllcall( _ 'dwmapi.dll', _ 'long', 'DwmSetWindowAttribute', _ 'hwnd', $hwnd, _ 'dword', $DWMWA_BORDER_COLOR, _ 'dword*', $iBorderColor, _ 'dword', 4 ) EndFunc This is the best solution so far, i'll think i'm gonna stick with this one I'll have to extract out of the udf only what is needed, but the original udf gets credits (if that's an ok way to burrow code on this forum) Retro Console, NestedArrayDisplay UDF foldermaker-pro-clone MiniMark Editor
WildByDesign Posted Thursday at 08:06 PM Posted Thursday at 08:06 PM 1 hour ago, TheAutomator said: How did you do that? That's a huge improvement! Mine is the same as argumentum’s, so I would follow that code. That one also has the advantage of making the titlebar dark as well but I believe that part only works on Windows 11.
TheAutomator Posted Thursday at 08:13 PM Author Posted Thursday at 08:13 PM 7 minutes ago, WildByDesign said: Mine is the same as argumentum’s, so I would follow that code. That one also has the advantage of making the titlebar dark as well but I believe that part only works on Windows 11. ok, thanks for letting me know WildByDesign 1 Retro Console, NestedArrayDisplay UDF foldermaker-pro-clone MiniMark Editor
Nine Posted Thursday at 10:21 PM Posted Thursday at 10:21 PM Here another approach using my latest UDF : You can scroll with mouse wheel and kb arrows. See the example posted in my thread. BTW, with my UDF, you don't need all those tens of images, you can do everything with it. TheAutomator 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy
WildByDesign Posted Thursday at 10:40 PM Posted Thursday at 10:40 PM 16 minutes ago, Nine said: BTW, with my UDF, you don't need all those tens of images, you can do everything with it. Your UDF is quite literally perfect for the curved design here. Nine 1
argumentum Posted Thursday at 10:41 PM Posted Thursday at 10:41 PM (edited) 4 hours ago, TheAutomator said: ...but the original udf gets credits (if that's an ok way to burrow code on this forum) I very much doubt that you'll stop the copy'n'paste because is not yours Spoiler PS: I don't care much about credits Edited Thursday at 10:52 PM by argumentum image Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
Nine Posted Thursday at 10:58 PM Posted Thursday at 10:58 PM 16 minutes ago, argumentum said: I don't care much about credits Ya of course, aren't we all ? “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy
KaFu Posted Friday at 09:56 AM Posted Friday at 09:56 AM 13 hours ago, WildByDesign said: That one also has the advantage of making the titlebar dark as well but I believe that part only works on Windows 11. Works fine on my Win10 too. WildByDesign 1 OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
TheAutomator Posted Friday at 10:45 PM Author Posted Friday at 10:45 PM On 3/27/2025 at 11:21 PM, Nine said: Here another approach using my latest UDF : You can scroll with mouse wheel and kb arrows. See the example posted in my thread. BTW, with my UDF, you don't need all those tens of images, you can do everything with it. Dude...! This would be perfect! Tomorrow i'm gonna have a look at your udf, thanks for posting! Retro Console, NestedArrayDisplay UDF foldermaker-pro-clone MiniMark Editor
TheAutomator Posted Saturday at 10:14 PM Author Posted Saturday at 10:14 PM (edited) On 3/27/2025 at 11:21 PM, Nine said: Here another approach using my latest UDF : You can scroll with mouse wheel and kb arrows. See the example posted in my thread. BTW, with my UDF, you don't need all those tens of images, you can do everything with it. Hi Nine, Would it be to much to ask to show us a trimmed down version / function just to make a label behave like a thumb, like in this example? I tried to do it myself, but i'm afraid i'm messing up inportant calls and create memory leaks ... What I understand about your code is that it makes use of _WinAPI_SetWindowSubclass to hook the RichEdit control to handle custom scrollbar behavior? $hProc is a callback function (RichEditProc), which processes scroll messages right? Local $hProc = DllCallbackRegister(__RGUI_ScrollBarProc, 'lresult', 'hwnd;uint;wparam;lparam;uint_ptr;dword_ptr') _WinAPI_SetWindowSubclass(GUICtrlGetHandle($idScroll), DllCallbackGetPtr($hProc), $idScroll, $idCtrl) Local $aScroll = [$fCall, $hProc, $iTop + 5, $iSize - 54] $mScroll[$idScroll] = $aScroll Return $idScroll This is like chinese to me. Noob asking for help here, I know (no pressure tho). Edited Saturday at 10:22 PM by TheAutomator Retro Console, NestedArrayDisplay UDF foldermaker-pro-clone MiniMark Editor
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