Editorgadget line numbers possible??

Just starting out? Need help? Post your questions and find answers here.
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post by utopiomania »

Maybe I'm running with some Vista 'eye-candy' enabled that I'm not aware of that makes it slow. It runs ok on XP at work, but it should
run fine on the Lenovo too to be useful, because the PC is generally quite responsive.

I also have a problem with cut/paste where the linenumbering fails on the inserted text. This works fine with Trond's code. I'll check out if
the latter works ok in Vista, if not, the scintilla gadget seems to be the way to go.
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post by utopiomania »

I'm trying to PureBasic-ify Tronds post, but the linenumbers are seriously out of sync here on my Vista machine, can you spot the problem????

Code: Select all

enumeration
  #WIN: #EDIT
endEnumeration

declare openMainWindow()
declare drawLinenumbers()
declare editCallback(hWnd, uMsg,  wParam, lParam)

global editProc, winW = 800, winH = 600, leftM = 64

openMainWindow()

repeat
  select waitWindowEvent()
    case #PB_EVENT_SIZEWINDOW
       winW = windowWidth(#WIN)
       winH = windowHeight(#WIN)
       resizeGadget(#EDIT, 0, 0, winW, winH)
    case #PB_EVENT_CLOSEWINDOW
      end
  endSelect
forever

procedure openMainWindow()
  if openWindow(#WIN, 0, 0, winW, winH, "Linenumbers", $CF0001)
    if createGadgetList(windowID(#WIN))
      editorGadget(#EDIT, 0, 0, winW, winH)
      ;margins
      editRect.RECT\left = leftM
      editRect\right = winW 
      editRect\bottom = winH
      sendMessage_(gadgetId(#EDIT), #EM_SETRECT, 0, editRect) 
      ;subclass the editorgadget
      editProc = setWindowLong_(gadgetID(#EDIT), #GWL_WNDPROC, @editCallback()) 
    endIf
  endIf
endProcedure

procedure editCallback(hWnd, uMsg, wParam, lParam) 
  select uMsg 
    case #WM_PAINT 
      callWindowProc_(editProc, hWnd, uMsg, wParam, lParam) 
      drawLineNumbers() 
      procedurereturn 0 
  endSelect 
  procedureReturn callWindowProc_(editProc, hWnd, uMsg, wParam, lParam) 
endProcedure

procedure drawLinenumbers()
  id = gadgetId(#EDIT)
  hDC = getDC_(id)
  
  getTextExtentPoint32_(hDC, "1", 1, sz.SIZE) 
  fontH = sz\cy
  ;oldObject = selectObject_(hDC, 0) 
  
  getClientRect_(id, rc.RECT) 
  rc\right = leftM - 8
  fillRect_(hDC, rc, getStockObject_(#WHITE_BRUSH))
  setBkMode_(hDC, #TRANSPARENT)
  setTextColor_(hDC, $C0C0C0) 

  line = sendMessage_(id, #EM_GETFIRSTVISIBLELINE, 0, 0) + 1 
  last = line + winH / FontH
  while line < last  
    drawText_(hDC, str(line), -1, rc, #DT_RIGHT) 
    rc\top + FontH
    line + 1 
  wend 
  
  ;selectObject_(hDC, OldObject) 
  releaseDC_(id, hDC)
endProcedure
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Out of sync on my XP machine as well.

Looks like a totally different font height.

Changing the procedure to this shows the problem

Code: Select all

Procedure openMainWindow() 
  If OpenWindow(#WIN, 0, 0, winW, winH, "Linenumbers", $CF0001) 
    If CreateGadgetList(WindowID(#WIN)) 
      EditorGadget(#EDIT, 0, 0, winW, winH) 
      LoadFont(0,"Times",11)
      SetGadgetFont(#edit,FontID(0))
      ;margins 
      editRect.RECT\left = leftM 
      editRect\right = winW 
      editRect\bottom = winH 
      SendMessage_(GadgetID(#EDIT), #EM_SETRECT, 0, editRect) 
      ;subclass the editorgadget 
      editProc = SetWindowLong_(GadgetID(#EDIT), #GWL_WNDPROC, @editCallback()) 
    EndIf 
  EndIf 
EndProcedure 
So obviously the linenumbers aren't using the same font height as the gadget and are going out of sync.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

See if this works any better...

Code: Select all

Enumeration 
  #WIN: #EDIT
EndEnumeration 

Declare openMainWindow() 
Declare drawLinenumbers() 
Declare editCallback(hwnd, uMsg,  wParam, lParam) 

Global editProc, winW = 800, winH = 600, leftM = 64 

;...Sparkie was here.............
#PASTE = 1
Global EditorFont
;................................


openMainWindow() 

Repeat 
  Select WaitWindowEvent() 
    
    ;...Sparkie was here..........................
    Case #PB_Event_Menu
      If EventMenu() = #PASTE
        ;...Remove any text formatting for our paste
        SendMessage_(GadgetID(#EDIT), #EM_PASTESPECIAL, #CF_TEXT, 0)
      EndIf
    ;..............................................
      
    Case #PB_Event_SizeWindow 
      winW = WindowWidth(#WIN) 
      winH = WindowHeight(#WIN) 
      ResizeGadget(#EDIT, 0, 0, winW, winH) 
    Case #PB_Event_CloseWindow 
      End 
  EndSelect 
ForEver 

Procedure openMainWindow() 
  If OpenWindow(#WIN, 0, 0, winW, winH, "Linenumbers", $CF0001) 
    If CreateGadgetList(WindowID(#WIN)) 
      EditorGadget(#EDIT, 0, 0, winW, winH) 
      
      ;...Sparkie was here........................
      ;...set our font - (Optional)
      EditorFont = LoadFont(0, "Courier New", 12)
      SetGadgetFont(#EDIT, EditorFont)
      ;...We need to intercept paste to remove any text formatting
      AddKeyboardShortcut(0, #PB_Shortcut_Control | #PB_Shortcut_V, #PASTE)
      ;...........................................
      
      ;margins 
      editRect.RECT\left = leftM 
      editRect\right = winW 
      editRect\bottom = winH 
      SendMessage_(GadgetID(#EDIT), #EM_SETRECT, 0, editRect) 
      ;subclass the editorgadget 
      editProc = SetWindowLong_(GadgetID(#EDIT), #GWL_WNDPROC, @editCallback()) 
    EndIf 
  EndIf 
EndProcedure 

Procedure editCallback(hwnd, uMsg, wParam, lParam) 
  Select uMsg 
    Case #WM_PAINT 
      CallWindowProc_(editProc, hwnd, uMsg, wParam, lParam) 
      drawLinenumbers() 
      ProcedureReturn 0 
  EndSelect 
  ProcedureReturn CallWindowProc_(editProc, hwnd, uMsg, wParam, lParam) 
EndProcedure 

Procedure drawLinenumbers() 
  id = GadgetID(#EDIT) 
  hdc = GetDC_(id) 
  
  ;...Sparkie was here........................
  ;...make sure we are using the same font metrics
  ;...for our numbers/text
  hfont = EditorFont
  If EditorFont = 0
    hfont = getStockObject_(#DEFAULT_GUI_FONT)
  EndIf
  hOldFont = SelectObject_(hdc, hfont);
  GetTextMetrics_(hdc, @tMet.TEXTMETRIC)
  fontH = tMet\tmHeight
  ;...........................................
  
  GetClientRect_(id, rc.RECT) 
  rc\right = leftM - 8 
  FillRect_(hdc, rc, getStockObject_(#WHITE_BRUSH)) 
  setBkMode_(hdc, #TRANSPARENT) 
  setTextColor_(hdc, $C0C0C0) 
  line = SendMessage_(id, #EM_GETFIRSTVISIBLELINE, 0, 0) + 1 
  last = line + winH / fontH 
  While line < last  
    drawText_(hdc, Str(line), -1, rc, #DT_RIGHT) 
    rc\top + fontH
    line + 1 
  Wend 
  
  ;...Sparkie was here........................
  SelectObject_(hdc, hOldFont) 
  ;..........................................
  
  ;selectObject_(hDC, OldObject) 
  ReleaseDC_(id, hdc) 
EndProcedure
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Works fine on my Vista machine, Sparkie.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

It think it still gets out of sync when you use mousewheel:

Image
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post by utopiomania »

Thanks Sparkie! :)

I've modified my code sample, included your changes and simplified it a bit, and tested it out in the editor it is meant for, and
it works fine, except for drag/drop, and for using the scrollbar to move the text a few pixels up/down
at a time. If I do that the linenumbers moves slowly out of sync again by almost a line, which doesn't look too professional..

Can the editorgadget be set up to scroll a line at a time?

Code: Select all

enumeration
  #WIN: #EDIT: #EDIT_PASTE
endEnumeration

declare openMainWindow()
declare drawLinenumbers()
declare editCallback(hWnd, uMsg,  wParam, lParam)

global editProc, leftM = 64

openMainWindow()

repeat
  select waitWindowEvent()
    case #PB_EVENT_MENU
      select eventMenu()
        case #EDIT_PASTE
          sendMessage_(gadgetId(#EDIT), #EM_PASTESPECIAL, #CF_TEXT, 0)
      endSelect
    case #PB_EVENT_SIZEWINDOW
       winW = windowWidth(#WIN)
       winH = windowHeight(#WIN)
       resizeGadget(#EDIT, 0, 0, winW, winH)
    case #PB_EVENT_CLOSEWINDOW
      end
  endSelect
forever

procedure openMainWindow()
  if openWindow(#WIN, 0, 0, 800, 600, "Linenumbers", $CF0001)
    if createGadgetList(windowID(#WIN))
      editorGadget(#EDIT, 0, 0, 800, 600)
      ;font
      hFont = loadFont(0, "calibri", 10)
      setGadgetFont(#EDIT, hFont)
      addKeyboardShortcut(#WIN, #PB_SHORTCUT_CONTROL | #PB_SHORTCUT_V, #EDIT_PASTE)
      ;margins
      getClientRect_(gadgetId(#EDIT), rc.RECT)
      rc\left = leftM
      sendMessage_(gadgetId(#EDIT), #EM_SETRECT, 0, rc) 
      ;subclass the editorgadget
      editProc = setWindowLong_(gadgetID(#EDIT), #GWL_WNDPROC, @editCallback()) 
    endIf
  endIf
endProcedure

procedure editCallback(hWnd, uMsg, wParam, lParam) 
  select uMsg 
    case #WM_PAINT 
      callWindowProc_(editProc, hWnd, uMsg, wParam, lParam) 
      drawLineNumbers() 
      procedurereturn 0 
  endSelect 
  procedureReturn callWindowProc_(editProc, hWnd, uMsg, wParam, lParam) 
endProcedure

procedure drawLinenumbers()
  id = gadgetId(#EDIT)
  hDC = getDC_(id)
  
  hFont = fontId(getGadgetFont(#EDIT))
  prevObj = selectObject_(hDC, hFont) 

  getTextMetrics_(hDC, @tm.TEXTMETRIC) 
  fontH = tm\tmHeight
  
  getClientRect_(id, rc.RECT) 
  rc\right = leftM - 8
  fillRect_(hDC, rc, getStockObject_(#WHITE_BRUSH))
  setBkMode_(hDC, #TRANSPARENT)
  setTextColor_(hDC, $C0C0C0) 

  line = sendMessage_(id, #EM_GETFIRSTVISIBLELINE, 0, 0) + 1 
  last = line + (rc\bottom - rc\top + 1) / FontH
  while line < last  
    drawText_(hDC, str(line), -1, rc, #DT_RIGHT) 
    rc\top + FontH
    line + 1 
  wend 
  
  selectObject_(hDC, prevObj) 
  releaseDC_(id, hDC)
endProcedure
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Try this one. I've tweaked this code to death and I don't know who to thank for the original code. Was it Trond :?: or maybe zapman* :?:

Code: Select all

Enumeration 
  #WIN: #EDIT 
EndEnumeration 

Declare openMainWindow() 
Declare drawLinenumbers() 
Declare editCallback(hwnd, uMsg,  wParam, lParam) 

Global editProc, winW = 800, winH = 600, leftM = 64 

;...Sparkie was here............. 
#PASTE = 1 
Global EditorFont 
;................................ 


openMainWindow() 

Repeat 
  Select WaitWindowEvent() 
    
    ;...Sparkie was here.......................... 
    Case #PB_Event_Menu 
      If EventMenu() = #PASTE 
        ;...Remove any text formatting for our paste 
        SendMessage_(GadgetID(#EDIT), #EM_PASTESPECIAL, #CF_TEXT, 0) 
      EndIf 
      ;.............................................. 
      
    Case #PB_Event_SizeWindow 
      winW = WindowWidth(#WIN) 
      winH = WindowHeight(#WIN) 
      ResizeGadget(#EDIT, 0, 0, winW, winH) 
    Case #PB_Event_CloseWindow 
      End 
  EndSelect 
ForEver 

Procedure openMainWindow() 
  If OpenWindow(#WIN, 0, 0, winW, winH, "Linenumbers", $CF0001) 
    If CreateGadgetList(WindowID(#WIN)) 
      EditorGadget(#EDIT, 0, 0, winW, winH) 
      
      ;...Sparkie was here........................ 
      ;...set our font - (Optional) 
      EditorFont = LoadFont(0, "Courier New", 12) 
      SetGadgetFont(#EDIT, EditorFont) 
      ;...We need to intercept paste to remove any text formatting 
      AddKeyboardShortcut(0, #PB_Shortcut_Control | #PB_Shortcut_V, #PASTE) 
      ;........................................... 
      
      ;margins 
      editRect.RECT\left = leftM 
      editRect\right = winW 
      editRect\bottom = winH 
      SendMessage_(GadgetID(#EDIT), #EM_SETRECT, 0, editRect) 
      ;subclass the editorgadget 
      editProc = SetWindowLong_(GadgetID(#EDIT), #GWL_WNDPROC, @editCallback()) 
    EndIf 
  EndIf 
EndProcedure 

Procedure editCallback(hwnd, uMsg, wParam, lParam) 
  Select uMsg 
    Case #WM_PAINT 
      CallWindowProc_(editProc, hwnd, uMsg, wParam, lParam) 
      drawLinenumbers() 
      ProcedureReturn 0 
  EndSelect 
  ProcedureReturn CallWindowProc_(editProc, hwnd, uMsg, wParam, lParam) 
EndProcedure 

Procedure drawLinenumbers() 
  id = GadgetID(#EDIT) 
  hdc = GetDC_(id) 
  
  ;...Sparkie was here........................ 
  ;...make sure we are using the same font metrics 
  ;...for our numbers/text 
  hFont = EditorFont 
  If EditorFont = 0 
    hFont = getStockObject_(#DEFAULT_GUI_FONT) 
  EndIf 
  hOldFont = SelectObject_(hdc, hFont); 
  GetTextMetrics_(hdc, @tMet.TEXTMETRIC) 
  fontH = tMet\tmHeight 
  ;........................................... 
  
  GetClientRect_(id, rc.RECT) 
  ;Debug rc\right 
  rc\right = leftM - 8 
  FillRect_(hdc, rc, getStockObject_(#WHITE_BRUSH)) 
  setBkMode_(hdc, #TRANSPARENT) 
  setTextColor_(hdc, $C0C0C0) 
  
  ;...Sparkie was here........................ 
  ;...Get the first line 
  topLine = SendMessage_(id, #EM_GETFIRSTVISIBLELINE, 0, 0) 
  ;...Fill a POINT structure for use with EM_CHARFROMPOS 
  pt.POINT 
  pt\x = rc\left 
  pt\y = rc\bottom 
  ;...Get the bottommost character position 
  bottomChar = SendMessage_(id, #EM_CHARFROMPOS, 0, pt) 
  ;...Get the last line 
  bottomLine = SendMessage_(id, #EM_LINEFROMCHAR, bottomChar, 0) 
  ;...Fill a POINT structure for use with EM_CHARFROMPOS 
  pt\x = rc\left 
  pt\y = rc\top 
  ;...Get the topmost character position 
  topChar = SendMessage_(id, #EM_CHARFROMPOS, 0, pt) 
  ;...Get the client coordinates fo the topmost character 
  SendMessage_(id, #EM_POSFROMCHAR, @tChar.POINT, topChar) 
  ;...Adjust our RECT accordingly as scrolling occurs 
  rc\top = tChar\y 
  If tChar\y < 0 
    rc\top + -tChar\y 
  EndIf 
  For drawline = topLine To bottomLine 
    number$ = Str(drawline + 1) 
    drawText_(hdc, @number$, Len(number$), rc, #DT_RIGHT) 
    rc\top + fontH 
  Next drawline 
  SelectObject_(hdc, hOldFont) 
  ;.......................................... 
  
  ReleaseDC_(id, hdc) 
EndProcedure
***Edited to make some repairs***
Last edited by Sparkie on Sun Oct 28, 2007 4:00 pm, edited 1 time in total.
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post by utopiomania »

Well, what can I say.. WOW! :)

This looks awesome! Many thanks man! I've tested it as far as I can right now, and it seems to be just what the doctor ordered. Thanks again!
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post by utopiomania »

I've just tested the code in the larger program, and the only remaining problem I've found with it is that it draws on my toolbar.

The testcode under shows this. DrawText_() clips the text if #DT_NOCLIP isn't specified, but as the rectangle is adjusted outside
the editorgadghet at the top, it draws there too.

The problem can be lessened a bit :oops: by the unrem'ed code in the for/next loop.

Code: Select all

enumeration
  #WIN: #EDIT: #EDIT_PASTE
endEnumeration

declare openMainWindow()
declare drawLinenumbers()
declare editCallback(hWnd, uMsg,  wParam, lParam)

global editProc, leftM = 64

openMainWindow()

repeat
  select waitWindowEvent()
    case #PB_EVENT_MENU
      select eventMenu()
        case #EDIT_PASTE
          sendMessage_(gadgetId(#EDIT), #EM_PASTESPECIAL, #CF_TEXT, 0)
      endSelect
    case #PB_EVENT_SIZEWINDOW
       winW = windowWidth(#WIN)
       winH = windowHeight(#WIN)
       resizeGadget(#EDIT, 0, 25, winW, winH - 50)
    case #PB_EVENT_CLOSEWINDOW
      end
  endSelect
forever

procedure openMainWindow()
  if openWindow(#WIN, 0, 0, 800, 600, "Linenumbers", $CF0001)
    if createGadgetList(windowID(#WIN))
      editorGadget(#EDIT, 0, 25, 800, 600 - 50)
      ;font
      hFont = loadFont(0, "calibri", 14)
      setGadgetFont(#EDIT, hFont)
      addKeyboardShortcut(#WIN, #PB_SHORTCUT_CONTROL | #PB_SHORTCUT_V, #EDIT_PASTE)
      ;margins
      getClientRect_(gadgetId(#EDIT), rc.RECT)
      rc\left = leftM
      sendMessage_(gadgetId(#EDIT), #EM_SETRECT, 0, rc) 
      ;remove the editorgadget border
      style = getWindowLong_(gadgetId(#EDIT), #GWL_EXSTYLE)
      newstyle = style & (~#WS_EX_CLIENTEDGE)
      setWindowLong_(gadgetId(#EDIT), #GWL_EXSTYLE, newstyle)
      setWindowPos_(gadgetId(#EDIT), 0, 0, 0, 0, 0, #SWP_SHOWWINDOW | #SWP_NOSIZE | #SWP_NOMOVE | #SWP_FRAMECHANGED)
      ;subclass the editorgadget
      editProc = setWindowLong_(gadgetID(#EDIT), #GWL_WNDPROC, @editCallback()) 
    endIf
  endIf
endProcedure

procedure editCallback(hWnd, uMsg, wParam, lParam) 
  select uMsg 
    case #WM_PAINT 
      callWindowProc_(editProc, hWnd, uMsg, wParam, lParam) 
      drawLineNumbers() 
      procedurereturn 0 
  endSelect 
  procedureReturn callWindowProc_(editProc, hWnd, uMsg, wParam, lParam) 
endProcedure

procedure drawLinenumbers()
  id = gadgetId(#EDIT)
  hDC = getDC_(id)
  
  hFont = fontId(getGadgetFont(#EDIT))
  prevObj = selectObject_(hDC, hFont) 

  getTextMetrics_(hDC, @tm.TEXTMETRIC) 
  fontH = tm\tmHeight
  
  getClientRect_(id, rc.RECT) 
  rc\right = leftM - 8
  fillRect_(hDC, rc, getStockObject_(#WHITE_BRUSH))
  setBkMode_(hDC, #TRANSPARENT)
  setTextColor_(hDC, $C0C0C0) 

  ;get the first line 
  first = SendMessage_(id, #EM_GETFIRSTVISIBLELINE, 0, 0) 

  ;get the last character/line  
  pt.POINT\x = rc\left 
  pt\y = rc\bottom 
  lastChar = sendMessage_(id, #EM_CHARFROMPOS, 0, pt) 
  last = sendMessage_(id, #EM_LINEFROMCHAR, lastChar, 0) 
  ; get the first character
  pt\y = rc\top
  firstChar = sendMessage_(id, #EM_CHARFROMPOS, 0, pt) 

  ;get the client coordinates fo the first character 
  sendMessage_(id, #EM_POSFROMCHAR, @tChar.POINT, firstChar) 
  ;adjust linenumber RECT
  rc\top = tChar\y  

  for line = first to last
    ;if rc\top >= -fontH / 4
      drawText_(hDc, str(line + 1), -1, rc, #DT_RIGHT)
    ;endIf 
    rc\top + fontH
  next

  selectObject_(hDC, prevObj) 
  releaseDC_(id, hDC)
endProcedure
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

I'll take a closer look later today when I have more time. :)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

***Edited to try a new fix one more time***

I changed line 64 from

Code: Select all

hdc = GetDC_(id)
to this

Code: Select all

hdc = GetDCEx_(id, 0, #DCX_CACHE)
and it seems to work ok now.

Code: Select all

Enumeration 
  #WIN: #EDIT: #EDIT_PASTE 
endEnumeration 

declare openMainWindow() 
declare drawLinenumbers() 
declare editCallback(hWnd, uMsg,  wParam, lParam) 

global editProc, leftM = 64 

openMainWindow() 

repeat 
  select waitWindowEvent() 
    case #PB_EVENT_MENU 
      select eventMenu() 
        case #EDIT_PASTE 
          sendMessage_(gadgetId(#EDIT), #EM_PASTESPECIAL, #CF_TEXT, 0) 
      endSelect 
    case #PB_EVENT_SIZEWINDOW 
      winW = windowWidth(#WIN) 
      winH = windowHeight(#WIN) 
      resizeGadget(#EDIT, 0, 25, winW, winH - 50) 
    case #PB_EVENT_CLOSEWINDOW 
      end 
  endSelect 
forever 

procedure openMainWindow() 
  if openWindow(#WIN, 0, 0, 800, 600, "Linenumbers", $CF0001) 
    if createGadgetList(windowID(#WIN)) 
      editorGadget(#EDIT, 0, 25, 800, 600 - 50) 
      ;font 
      hFont = loadFont(0, "calibri", 14) 
      setGadgetFont(#EDIT, hFont) 
      addKeyboardShortcut(#WIN, #PB_SHORTCUT_CONTROL | #PB_SHORTCUT_V, #EDIT_PASTE) 
      ;margins 
      getClientRect_(gadgetId(#EDIT), rc.RECT) 
      rc\left = leftM 
      sendMessage_(gadgetId(#EDIT), #EM_SETRECT, 0, rc) 
      ;remove the editorgadget border 
      style = getWindowLong_(gadgetId(#EDIT), #GWL_EXSTYLE) 
      newstyle = style & (~#WS_EX_CLIENTEDGE) 
      setWindowLong_(gadgetId(#EDIT), #GWL_EXSTYLE, newstyle) 
      setWindowPos_(gadgetId(#EDIT), 0, 0, 0, 0, 0, #SWP_SHOWWINDOW | #SWP_NOSIZE | #SWP_NOMOVE | #SWP_FRAMECHANGED) 
      ;subclass the editorgadget 
      editProc = setWindowLong_(gadgetID(#EDIT), #GWL_WNDPROC, @editCallback()) 
    endIf 
  endIf 
endProcedure 

procedure editCallback(hWnd, uMsg, wParam, lParam) 
  select uMsg 
    case #WM_PAINT 
      callWindowProc_(editProc, hWnd, uMsg, wParam, lParam) 
      drawLineNumbers() 
      procedurereturn 0 
  endSelect 
  procedureReturn callWindowProc_(editProc, hWnd, uMsg, wParam, lParam) 
endProcedure 

procedure drawLinenumbers() 
  id = gadgetId(#EDIT) 
  hdc = GetDCEx_(id, 0, #DCX_CACHE)
  
  hFont = fontId(getGadgetFont(#EDIT)) 
  prevObj = selectObject_(hDC, hFont) 
  
  getTextMetrics_(hDC, @tm.TEXTMETRIC) 
  fontH = tm\tmHeight 
  
  getClientRect_(id, rc.RECT) 
  rc\right = leftM - 8 
  fillRect_(hDC, rc, getStockObject_(#WHITE_BRUSH)) 
  setBkMode_(hdc, #TRANSPARENT) 
  setTextColor_(hdc, $C0C0C0) 
  
  ;get the first line 
  first = SendMessage_(id, #EM_GETFIRSTVISIBLELINE, 0, 0) 
  
  ;get the last character/line  
  pt.POINT\x = rc\left 
  pt\y = rc\bottom 
  lastChar = SendMessage_(id, #EM_CHARFROMPOS, 0, pt) 
  last = SendMessage_(id, #EM_LINEFROMCHAR, lastChar, 0) 
  ; get the first character 
  pt\y = rc\top 
  firstChar = SendMessage_(id, #EM_CHARFROMPOS, 0, pt) 
  
  ;get the client coordinates fo the first character 
  SendMessage_(id, #EM_POSFROMCHAR, @tChar.POINT, firstChar) 
  ;adjust linenumber RECT 
  rc\top = tChar\y  
  
  For line = first To last 
    ;if rc\top >= -fontH / 4 
    drawText_(hdc, Str(line + 1), -1, rc, #DT_RIGHT) 
    ;endIf 
    rc\top + fontH 
  Next 
  
  SelectObject_(hdc, prevObj) 
  ReleaseDC_(id, hdc) 
EndProcedure 
Last edited by Sparkie on Wed Oct 31, 2007 12:27 am, edited 1 time in total.
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post by utopiomania »

Sparkie, your hack brings back the linenumber sync problem obviously! but your previous code works very well with a small change, so many
thanks for your help! :)
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Damn :x ....

Ok, I tried more more time if you'd like to back ^ up there ^ to the last code snippet and see what happens now.
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post by utopiomania »

Thanks for trying one more time.. :) It works perfect now.
Post Reply