Terenz Posted February 5, 2016 Author Share Posted February 5, 2016 I have made an attempt with RichEdit, the scrollbar aren't syncronized...some pixel of difference without any reason and sometime not work expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GuiRichEdit.au3> Global $sText = "", $hGUI, $hRichEdit1, $hRichEdit2 For $i = 1 To 50 $sText &= "TEST_" & $i & @CRLF Next $hGUI = GUICreate("TEST", 350, 300, -1, -1) $hRichEdit1 = __GUICtrlRichEdit_Create($hGUI, $sText, 10, 10, 160, 220, BitOR($ES_MULTILINE, $WS_VSCROLL, $WS_HSCROLL)) _GUICtrlRichEdit_SetEventMask($hRichEdit1, BitOR($ENM_KEYEVENTS, $ENM_SCROLL, $ENM_SCROLLEVENTS)) $hRichEdit2 = __GUICtrlRichEdit_Create($hGUI, $sText, 180, 10, 160, 220, BitOR($ES_MULTILINE, $WS_VSCROLL, $WS_HSCROLL)) _GUICtrlRichEdit_SetEventMask($hRichEdit2, BitOR($ENM_KEYEVENTS, $ENM_SCROLL, $ENM_SCROLLEVENTS)) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") _GUICtrlRichEdit_SetScrollPos($hRichEdit1, 0, 0) _GUICtrlRichEdit_SetScrollPos($hRichEdit2, 0, 0) While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _GUICtrlRichEdit_Destroy($hRichEdit1) _GUICtrlRichEdit_Destroy($hRichEdit2) Exit EndSwitch WEnd Func WM_NOTIFY($hWnd, $iMsg, $iWparam, $iLparam) #forceref $iMsg, $iWparam Local $hWndFrom, $iCode, $tNMHDR, $tMsgFilter, $hMenu, $tagEN_MSGFILTER = $tagNMHDR & ";uint msg;int wParam;int lParam;" $tNMHDR = DllStructCreate($tagNMHDR, $iLparam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hRichEdit1 Select Case $iCode = $EN_MSGFILTER $tMsgFilter = DllStructCreate($tagEN_MSGFILTER, $iLparam) Switch DllStructGetData($tMsgFilter, "msg") Case 256, 257, 258 _GUICtrlRichEdit_SetText($hRichEdit2, _GUICtrlRichEdit_GetText($hRichEdit1)) Case 276 $aPos = _GUICtrlRichEdit_GetScrollPos($hRichEdit1) _GUICtrlRichEdit_SetScrollPos($hRichEdit2, $aPos[0], $aPos[1]) Case 277 $aPos = _GUICtrlRichEdit_GetScrollPos($hRichEdit1) _GUICtrlRichEdit_SetScrollPos($hRichEdit2, $aPos[0], $aPos[1]) EndSwitch EndSelect Case $hRichEdit2 Select Case $iCode = $EN_MSGFILTER $tMsgFilter = DllStructCreate($tagEN_MSGFILTER, $iLparam) $aPos = _GUICtrlRichEdit_GetScrollPos($hRichEdit2) Switch DllStructGetData($tMsgFilter, "msg") Case 256, 257, 258 _GUICtrlRichEdit_SetText($hRichEdit2, _GUICtrlRichEdit_GetText($hRichEdit1)) Case 276 _GUICtrlRichEdit_SetScrollPos($hRichEdit1, $aPos[0], $aPos[1]) Case 277 _GUICtrlRichEdit_SetScrollPos($hRichEdit1, $aPos[0], $aPos[1]) EndSwitch EndSelect EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func __GUICtrlRichEdit_Create($hWnd, $sText, $iLeft, $iTop, $iWidth = 150, $iHeight = 150, $iStyle = -1, $iExStyle = -1) If Not IsHWnd($hWnd) Then Return SetError(1, 0, 0) ; Invalid Window handle for _GUICtrlRichEdit_Create 1st parameter If Not IsString($sText) Then Return SetError(2, 0, 0) ; 2nd parameter not a string for _GUICtrlRichEdit_Create If Not __GCR_IsNumeric($iWidth, ">0,-1") Then Return SetError(105, 0, 0) If Not __GCR_IsNumeric($iHeight, ">0,-1") Then Return SetError(106, 0, 0) If Not __GCR_IsNumeric($iStyle, ">=0,-1") Then Return SetError(107, 0, 0) If Not __GCR_IsNumeric($iExStyle, ">=0,-1") Then Return SetError(108, 0, 0) If $iWidth = -1 Then $iWidth = 150 If $iHeight = -1 Then $iHeight = 150 If $iStyle = -1 Then $iStyle = BitOR($ES_WANTRETURN, $ES_MULTILINE) If BitAND($iStyle, $ES_MULTILINE) <> 0 Then $iStyle = BitOR($iStyle, $ES_WANTRETURN) If $iExStyle = -1 Then $iExStyle = 0x200 ; $DS_FOREGROUND $iStyle = BitOR($iStyle, $__UDFGUICONSTANT_WS_CHILD, $__UDFGUICONSTANT_WS_VISIBLE) If BitAND($iStyle, $ES_READONLY) = 0 Then $iStyle = BitOR($iStyle, $__RICHEDITCONSTANT_WS_TABSTOP) Local $nCtrlID = __UDF_GetNextGlobalID($hWnd) If @error Then Return SetError(@error, @extended, 0) __GCR_Init() Local $hRichEdit = _WinAPI_CreateWindowEx($iExStyle, $_GRE_sRTFClassName, "", $iStyle, $iLeft, $iTop, $iWidth, _ $iHeight, $hWnd, $nCtrlID) If $hRichEdit = 0 Then Return SetError(700, 0, False) __GCR_SetOLECallback($hRichEdit) _SendMessage($hRichEdit, $__RICHEDITCONSTANT_WM_SETFONT, _WinAPI_GetStockObject($DEFAULT_GUI_FONT), True) _GUICtrlRichEdit_AppendText($hRichEdit, $sText) Return $hRichEdit EndFunc ;==>__GUICtrlRichEdit_Create I am just about to leave and I'd hate to see it. I don't have the technical knowledge to continue with this... Nothing is so strong as gentleness. Nothing is so gentle as real strength  Link to comment Share on other sites More sharing options...
LarsJ Posted February 6, 2016 Share Posted February 6, 2016 You implement the C# code (link in post 8) in this way: expandcollapse popup#include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPIShellEx.au3> Example() Func Example() GUICreate( "My GUI edit", 400, 200 ) GUISetState( @SW_SHOW ) Local $s = 1 For $i = 2 To 100 $s &= @CRLF & $i Next Local $idEdit1 = GUICtrlCreateEdit( $s, 10, 10, 185, 180, $ES_AUTOVSCROLL + $ES_WANTRETURN + $WS_VSCROLL ) Local $hEdit1 = GUICtrlGetHandle( $idEdit1 ) Send("{END}") Local $idEdit2 = GUICtrlCreateEdit( $s, 205, 10, 185, 180, $ES_AUTOVSCROLL + $ES_WANTRETURN + $WS_VSCROLL ) Local $hEdit2 = GUICtrlGetHandle( $idEdit2 ) Send("{END}") Local $pEditProc = DllCallbackGetPtr( DllCallbackRegister( "EditProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) ) _WinAPI_SetWindowSubclass( $hEdit1, $pEditProc, 1, $idEdit2 ) ; $iSubclassId = 1, $pData = $idEdit2 _WinAPI_SetWindowSubclass( $hEdit2, $pEditProc, 1, $idEdit1 ) ; $iSubclassId = 1, $pData = $idEdit1 While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _WinAPI_RemoveWindowSubclass( $hEdit1, $pEditProc, 1 ) _WinAPI_RemoveWindowSubclass( $hEdit2, $pEditProc, 1 ) GUIDelete() EndFunc Func EditProc( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData ) Local Static $bScrolling If Not $bScrolling And $iMsg = $WM_VSCROLL Then $bScrolling = True GUICtrlSendMsg( $pData, $iMsg, $wParam, $lParam ) $bScrolling = False EndIf ; Call next function in subclass chain Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] #forceref $iSubclassId EndFunc  Controls,  File Explorer,  ROT objects,  UI Automation,  Windows Message MonitorCompiled code: Accessing AutoIt variables,  DotNet.au3 UDF,  Using C# and VB codeShell menus: The Context menu,  The Favorites menu. Shell related: Control Panel,  System Image ListsGraphics related: Rubik's Cube,  OpenGL without external libraries,  Navigating in an image,  Non-rectangular selectionsListView controls: Colors and fonts,  Multi-line header,  Multi-line items,  Checkboxes and icons,  Incremental searchListView controls: Virtual ListViews,  Editing cells,  Data display functions Link to comment Share on other sites More sharing options...
Terenz Posted February 6, 2016 Author Share Posted February 6, 2016 (edited) Lars...My Hero! Works very well! I have changes some things to make it compatible with my autoit version, added the wheel constant, horizontal scroll and _WinAPI_DefSubclassProc instead of the DllCall expandcollapse popup#include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <GuiEdit.au3> Global $MOUSE_WHEELSCROLL_EVENT = 0x20A Example() Func Example() GUICreate("My GUI edit", 400, 200) GUISetState(@SW_SHOW) Local $s = "THIS_IS_A_LONG_LINE_FOR_ENABLE_HORIZONTAL_SCROLLING" For $i = 2 To 100 $s &= @CRLF & $i Next Local $idEdit1 = GUICtrlCreateEdit($s, 10, 10, 185, 180, $ES_AUTOVSCROLL + $ES_AUTOHSCROLL + $ES_WANTRETURN + $WS_VSCROLL + $WS_HSCROLL) Local $hEdit1 = GUICtrlGetHandle($idEdit1) Local $idEdit2 = GUICtrlCreateEdit($s, 205, 10, 185, 180, $ES_AUTOVSCROLL + $ES_AUTOHSCROLL + $ES_WANTRETURN + $WS_VSCROLL + $WS_HSCROLL) Local $hEdit2 = GUICtrlGetHandle($idEdit2) Local $pEditProc = DllCallbackGetPtr(DllCallbackRegister("EditProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr")) _WinAPI_SetWindowSubclass($hEdit1, $pEditProc, 1, $idEdit2) ; $iSubclassId = 1, $pData = $idEdit2 _WinAPI_SetWindowSubclass($hEdit2, $pEditProc, 1, $idEdit1) ; $iSubclassId = 1, $pData = $idEdit1 While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _WinAPI_RemoveWindowSubclass($hEdit1, $pEditProc, 1) _WinAPI_RemoveWindowSubclass($hEdit2, $pEditProc, 1) GUIDelete() EndFunc ;==>Example Func EditProc($hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData) #forceref $iSubclassId Local Static $bScrolling If Not $bScrolling Then Switch $iMsg Case 257, 258, $WM_VSCROLL, $WM_HSCROLL, $MOUSE_WHEELSCROLL_EVENT $bScrolling = True ;~ $aPos = _GUICtrlEdit_GetSel($pData-1) ;~ ConsoleWrite("POS: " & $aPos[0] & $aPos[1] & @CRLF) ;~ _GUICtrlEdit_SetSel($pData, $aPos[0], $aPos[1]) GUICtrlSendMsg($pData, $iMsg, $wParam, $lParam) $bScrolling = False EndSwitch EndIf ; Call next function in subclass chain Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>EditProc Func _WinAPI_SetWindowSubclass($hWnd, $pSubclassProc, $idSubClass, $pData = 0) Local $aRet = DllCall('comctl32.dll', 'bool', 'SetWindowSubclass', 'hwnd', $hWnd, 'ptr', $pSubclassProc, 'uint_ptr', $idSubClass, _ 'dword_ptr', $pData) If @error Then Return SetError(@error, @extended, 0) Return $aRet[0] EndFunc ;==>_WinAPI_SetWindowSubclass Func _WinAPI_RemoveWindowSubclass($hWnd, $pSubclassProc, $idSubClass) Local $aRet = DllCall('comctl32.dll', 'bool', 'RemoveWindowSubclass', 'hwnd', $hWnd, 'ptr', $pSubclassProc, 'uint_ptr', $idSubClass) If @error Then Return SetError(@error, @extended, False) Return $aRet[0] EndFunc ;==>_WinAPI_RemoveWindowSubclass Func _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) Local $aRet = DllCall('comctl32.dll', 'lresult', 'DefSubclassProc', 'hwnd', $hWnd, 'uint', $iMsg, 'wparam', $wParam, _ 'lparam', $lParam) If @error Then Return SetError(@error, @extended, 0) Return $aRet[0] EndFunc ;==>_WinAPI_DefSubclassProc I have a couple of question: Did you know how i can use _GetSel and _SetSel for syncronize the selection of both editbox? Or maybe the SendMsg? Did you know why if i'm scroll with the down-up arrow or with the mouse selection the scrollbar is not updated? Thanks again Edited February 6, 2016 by Terenz Nothing is so strong as gentleness. Nothing is so gentle as real strength  Link to comment Share on other sites More sharing options...
LarsJ Posted February 6, 2016 Share Posted February 6, 2016 The code in post 22 works only if you use the mouse on one of the scrollbars. If you want to scroll an edit box with the arrow keys, you have to implement the synchronization yourself. That is, you have to look for $EN_VSCROLL notifications and synchronize the other edit box with _GUICtrlEdit_Scroll. You also need to know if you are scrolling up or down. You can use _GetSel and _SetSel to synchronize selections. You need to be able to detect when the user has finished his  selection. You can probably check for a mouse up event and a non-empty selection. Then you can get the selection with _GetSel and synchronize the other edit box with _SetSel. Controls,  File Explorer,  ROT objects,  UI Automation,  Windows Message MonitorCompiled code: Accessing AutoIt variables,  DotNet.au3 UDF,  Using C# and VB codeShell menus: The Context menu,  The Favorites menu. Shell related: Control Panel,  System Image ListsGraphics related: Rubik's Cube,  OpenGL without external libraries,  Navigating in an image,  Non-rectangular selectionsListView controls: Colors and fonts,  Multi-line header,  Multi-line items,  Checkboxes and icons,  Incremental searchListView controls: Virtual ListViews,  Editing cells,  Data display functions Link to comment Share on other sites More sharing options...
Terenz Posted February 7, 2016 Author Share Posted February 7, 2016 (edited) I have try LarsJ and partially work but sometime the line using arrow is not update with the current, i think i have make some mistake. About the mouse i don't know if the scrolling goes up or down so i don't have implementated yet. Please check it: expandcollapse popupFunc EditProc($hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData) #forceref $iSubclassId Local Static $bScrolling, $VScrollPos = _GetScroll($hWnd, 1), $hGetSel = _GUICtrlEdit_GetSel($hWnd) ;ConsoleWrite($wParam & @CRLF) If Not $bScrolling Then Switch $wParam Case 38 ; ARROW UP If $VScrollPos <> _GetScroll($hWnd, 1) Then $VScrollPos = _GetScroll($hWnd, 1) _GUICtrlEdit_Scroll($pData, 0) ; $SB_LINEUP EndIf Case 40 ; ARROW DOWN If $VScrollPos <> _GetScroll($hWnd, 1) Then $VScrollPos = _GetScroll($hWnd, 1) _GUICtrlEdit_Scroll($pData, 1) ; $SB_LINEDOWN EndIf EndSwitch Switch $iMsg Case 257, 258, $WM_VSCROLL, $WM_HSCROLL, $MOUSE_WHEELSCROLL_EVENT If $hGetSel <> _GUICtrlEdit_GetSel($hWnd) Then $hGetSel = _GUICtrlEdit_GetSel($hWnd) _GUICtrlEdit_SetSel($pData, $hGetSel[0], $hGetSel[1]) EndIf $bScrolling = True GUICtrlSendMsg($pData, $iMsg, $wParam, $lParam) $bScrolling = False EndSwitch EndIf ; Call next function in subclass chain Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>EditProc Func _GetScroll($hFrom, $iType) ; 0 horiziontal, 1 vertical Local $iGetInfo, $iSetInfo, $tSCROLLINFO = DllStructCreate($tagSCROLLINFO) DllStructSetData($tSCROLLINFO, "cbSize", DllStructGetSize($tSCROLLINFO)) DllStructSetData($tSCROLLINFO, "fMask", $_SCROLLBARCONSTANTS_SIF_ALL) $iGetInfo = _GUIScrollBars_GetScrollInfo($hFrom, $iType, $tSCROLLINFO) If $iGetInfo = False Then Return SetError(1, 0, 0) Return DllStructGetData($tSCROLLINFO, "nTrackPos") EndFunc ;==>_GetScroll  Edited February 7, 2016 by Terenz Nothing is so strong as gentleness. Nothing is so gentle as real strength  Link to comment Share on other sites More sharing options...
Gianni Posted February 7, 2016 Share Posted February 7, 2016 (edited) a way using _WinAPI_SetTimer I think it's a worst way, anyway here it is: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPISys.au3> #include <GuiEdit.au3> Global $hMyGUI = GUICreate("My GUI edit", 400, 200) Local $s = "THIS_IS_A_LONG_LINE_FOR_ENABLE_HORIZONTAL_SCROLLING" For $i = 2 To 100 $s &= @CRLF & $i Next Global $idEdit1 = GUICtrlCreateEdit($s, 10, 10, 185, 180, $ES_AUTOVSCROLL + $ES_AUTOHSCROLL + $ES_WANTRETURN + $WS_VSCROLL + $WS_HSCROLL) Global $idEdit2 = GUICtrlCreateEdit($s, 205, 10, 185, 180, $ES_AUTOVSCROLL + $ES_AUTOHSCROLL + $ES_WANTRETURN + $WS_VSCROLL + $WS_HSCROLL) GUISetState(@SW_SHOW) Local $hTimerProc = DllCallbackRegister('_CheckAlign', 'none', 'hwnd;uint;uint_ptr;dword') Local $iTimerID = _WinAPI_SetTimer(0, 0, 100, DllCallbackGetPtr($hTimerProc)) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _WinAPI_KillTimer(0, $iTimerID) DllCallbackFree($hTimerProc) GUIDelete() Func _CheckAlign($hWnd, $Msg, $iIDTimer, $dwTime) #forceref $hWnd , $Msg , $iIDTimer , $dwTime Local Static $iFirstVis1_old = 0 Local Static $iFirstVis2_old = 0 Local $iFirstVis1 = _GUICtrlEdit_GetFirstVisibleLine($idEdit1) Local $iFirstVis2 = _GUICtrlEdit_GetFirstVisibleLine($idEdit2) If $iFirstVis1 <> $iFirstVis1_old Then $iFirstVis1_old = $iFirstVis1 $iFirstVis2_old = $iFirstVis1 _GUICtrlEdit_LineScroll($idEdit2, 0, $iFirstVis1 - $iFirstVis2) ; EndIf ElseIf $iFirstVis2 <> $iFirstVis2_old Then $iFirstVis1_old = $iFirstVis2 $iFirstVis2_old = $iFirstVis2 _GUICtrlEdit_LineScroll($idEdit1, 0, $iFirstVis2 - $iFirstVis1) EndIf EndFunc ;==>_CheckAlign  Edited February 7, 2016 by Chimp  Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
TheSaint Posted February 8, 2016 Share Posted February 8, 2016 All very interesting, so I will be keeping a copy of this. I once synced three list controls, and it works reasonably well, but all you guys seem to be well in advance of my meager talent and knowledge. It was an attempt at a pretend three column Listview ... only because I didn't feel like reworking a whole lot of code for a genuine Listview, and the exercise interested me. Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage) 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