I've adapted it to PB 4 and improved to allow zoom in and out whith CTRL + MouseWheel
With this version, the line numbers also move better when scrolling the text.
Code: Select all
Global hLnFont,OldRedProc,mzoom,mspos,mlineno
Procedure FindInRichEdit(REGadgetID.l,SearchString$,startPos.l,MATCHCASE.l,WHOLEWORD.l,UP.l)
; By Zapman
FindParam.findtext\chrg\cpMin = startPos -1
FindParam.findtext\chrg\cpMax = -1
FindParam\lpstrText = @SearchString$
Flags = (MatchCase*#FR_MATCHCASE) | (WHOLEWORD*#FR_WHOLEWORD)
If UP = 0 : Flags | #FR_DOWN : EndIf
Res = SendMessage_(REGadgetID, #EM_FINDTEXT , Flags, FindParam)
ProcedureReturn Res + 1
EndProcedure
;
mspos = -1
;
Procedure DrawLineNumbers(REGadgetID)
hDC = GetDC_(REGadgetID)
GetClientRect_(REGadgetID, rc.RECT)
rc\right = 33
OldObject = SelectObject_(hDC, hLnFont)
p.point\x = 0:p\y = 0
nchar=SendMessage_(REGadgetID, #EM_CHARFROMPOS, 0, @p)
FillRect_(hDC, rc, 0)
SetBkMode_(hDC, #TRANSPARENT)
SetTextColor_(hDC, $A0A0A0)
HRGN = CreateRectRgn_(rc\left,rc\top,rc\right,rc\bottom)
SelectClipRgn_(hDC,HRGN)
rc\right -4
mrctop = rc\top
SendMessage_(REGadgetID, #EM_GETZOOM, @Zoomnumerator, @Zoomdenominator)
If Zoomnumerator>200
mrctop + (5*Zoomnumerator/Zoomdenominator)
ElseIf Zoomnumerator>150
mrctop + (3*Zoomnumerator/Zoomdenominator)
ElseIf Zoomnumerator>110
mrctop + (2*Zoomnumerator/Zoomdenominator)
EndIf
ypos = -1
LengthParam.GETTEXTLENGTHEX\flags = 0
LengthParam.GETTEXTLENGTHEX\codepage = 1200
length = SendMessage_(REGadgetID, #EM_GETTEXTLENGTHEX,LengthParam,0)
;
p.point\x = 0:p\y = 0
nchar=SendMessage_(REGadgetID, #EM_CHARFROMPOS, 0, @p)
If nchar<>mspos
mspos = nchar
;
; Tips to quickly count how much carriage returns are before the current position
lineno = 1
If nchar>0
*txbuffer = GlobalAlloc_(0,(nchar*2)+2)
If *txbuffer
txRange.textrange\chrg\cpMin = 0
txRange\chrg\cpMax = nchar
txRange\lpstrText = *txbuffer
SendMessage_(REGadgetID, #EM_GETTEXTRANGE,0,txRange)
PrecText$ = PeekS(*txbuffer)
GlobalFree_(*txbuffer)
lineno=Len(PrecText$)-Len(ReplaceString(PrecText$,Chr(13),""))
EndIf
EndIf
; That's all folks!
mlineno = lineno
Else
lineno = mlineno
EndIf
;
Repeat
ypos = SendMessage_(REGadgetID, #EM_POSFROMCHAR , nchar,0) &$FFFF0000
ypos/$10000
If ypos>-20 And ypos<(rc\bottom+20)
buffer.s = Str(lineno)
rc\top= mrctop + ypos
DrawText_(hDC, @buffer, -1, rc, #DT_RIGHT)
EndIf
nchar = FindInRichEdit(REGadgetID,Chr(13),nchar+1,0,0,0)
lineno+1
Until nchar = 0 Or nchar >length Or ypos>=(rc\bottom+20)
MoveToEx_(hDC, rc\right+3, 0, #Null)
Pen = CreatePen_(#PS_SOLID,1,$D0D0D0)
SelectObject_(hdc,Pen)
LineTo_(hDC, rc\right+3, rc\bottom)
DeleteObject_(pen)
ReleaseDC_(REGadgetID, hDC)
EndProcedure
Procedure RedProc(hWnd, uMsg, wParam, lParam)
Select uMsg
Case #WM_PAINT
SendMessage_(hWnd, #EM_GETZOOM, @Zoomnumerator, @Zoomdenominator)
If Zoomnumerator
If mzoom<>Zoomnumerator
mzoom=Zoomnumerator
GetClientRect_(hWnd, rc.RECT)
If Zoomnumerator>100
Zoomnumerator/1.2
EndIf
rc\left+(40 *Zoomdenominator/Zoomnumerator)
SendMessage_(hWnd, #EM_SETRECT, 0, rc)
EndIf
EndIf
CallWindowProc_(OldRedProc, hWnd, uMsg, wParam, lParam)
DrawLineNumbers(hWnd)
result = 0
Default
result = CallWindowProc_(OldRedProc, hWnd, uMsg, wParam, lParam)
EndSelect
ProcedureReturn result
EndProcedure
hWindow = OpenWindow(0, 0, 0, 640, 480 ,"RichEdit line numbers example", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget)
If hWindow
SetClassLong_(hWindow, #GCL_HBRBACKGROUND, 0) ; remove resize flicker
WindowWidth = WindowWidth(0)
WindowHeight = WindowHeight(0)
If CreateGadgetList(hWindow)
PB_REGadgetID = EditorGadget(#PB_Any, 0,0, WindowWidth, WindowHeight)
SendMessage_(GadgetID(PB_REGadgetID), #EM_SETTARGETDEVICE, #Null, 0) ; <<-- Set wrapping style (retour à la ligne automatique)
SendMessage_(GadgetID(PB_REGadgetID), #EM_LIMITTEXT, -1, 0) ; set unlimited content size
GetClientRect_(GadgetID(PB_REGadgetID), rc.RECT)
rc\left+40
SendMessage_(GadgetID(PB_REGadgetID), #EM_SETRECT, 0, rc)
lfnt.LOGFONT
FontName.s = "Courier"
lstrcpy_(@lfnt\lfFaceName[0], @FontName)
lfnt\lfHeight = -12
lfnt\lfWeight = 400
hLnFont = CreateFontIndirect_(lfnt)
OldRedProc = SetWindowLong_(GadgetID(PB_REGadgetID), #GWL_WNDPROC, @RedProc())
Repeat
EventID = WaitWindowEvent()
If EventID=#WM_SIZE
WindowWidth = WindowWidth(0)
WindowHeight = WindowHeight(0)
ResizeGadget(PB_REGadgetID,#PB_Ignore,#PB_Ignore ,WindowWidth,WindowHeight)
EndIf
Until EventID = #PB_Event_CloseWindow
EndIf
EndIf
End