I have continued to work on the syntax highlighter that I previously posted. Please try and make suggestions for improvements.
very nice! go on. :t
Works fine, except that pasting a long text (in this case: the MasmBasic source :P) causes an exception at 403E0d (and tilts the system-wide clipboard on that occasion :().
Check also your handling of tabs.
Besides, I prefer individual colouring - it helps when you are in line 14,500 of a source you wrote months ago, and you can't remember what you did there. Same code seen with two editors:
Thank you.
Quote
Works fine, except that pasting a long text
How long text is MasmBasic? I copied 1MB and pasted. It took some time but did work.
Quote
Check also your handling of tabs.
What about tabs. I change
invoke SendMessage,hRED1,EM_SETTABSTOPS,12,offset TabStopArray
to
invoke SendMessage,hRED1,EM_SETTABSTOPS,1,offset TabStopArray
Was that the meaning of your comment or is it how indent works?
Quote
Besides, I prefer individual colouring
I am not sure I understand. Do you mean a different way to do highlighting or
do you mean to do a selection and color it with a separate color and be able
to save it?
Quote from: minor28 on June 11, 2014, 04:42:32 PM
How long text is MasmBasic? I copied 1MB and pasted. It took some time but did work.
MB is 580k, but try \Masm32\include\windows.inc, it crashes at the same address.
Quote
What about tabs. I change
invoke SendMessage,hRED1,EM_SETTABSTOPS,12,offset TabStopArray
to
invoke SendMessage,hRED1,EM_SETTABSTOPS,1,offset TabStopArray
Was that the meaning of your comment or is it how indent works?
Compare the screenshots above - which one looks better? It's a very tricky issue, though. Assembler is a "vertical" language, many small strings (mov eax, ecx) distributed over many lines. But some coders, me included, also use multiple .if .elseif etc constructs. That makes the choice of the "right" TabStopArray difficult. RichMasm has three different arrays, one for "vertical" code, one for multiple indents, and one for the .data section. This makes sense only if you can
save the formatting, of course.
QuoteQuote
Besides, I prefer individual colouring
I am not sure I understand. Do you mean a different way to do highlighting or do you mean to do a selection and color it with a separate color and be able to save it?
The latter. Automatic highlighting is one thing, saving individual formatting is another. I have lived a long time with automatic highlighting, my favourite Basic dialect had it (Gfa), but for assembler I went the other road, simply because you often have code sections that are extremely difficult to read; and these benefit from highly selective colouring. For example, this code is size-efficient but you would be completely lost in a normal editor:
mov eax, [esp+4+4] ; #n, Basic file number
mov eax, [MbFH+4*eax] ; Windows handle
push edx ; create the bytes read slot
mov edx, esp ; pointer to the slot
; five bytes shorter, and returns bytes read
invoke ReadFile, eax, [esp+28], [esp+28], edx, 0
; invoke ReadFile, eax, tgt, bytes, addr locBytes, 0
call TestRetVal ; throw an error if needed
pop eax
mov edx, [esp+4+8] ; return target buffer
Neither coping/pasting nor opening windows.inc will cause an exception on my computer (Win7 32).
But the time to load the text is very long. Also problem with line numbering when scrolling.
The margin must also be flexible.
I have skiped the tab array and only use the first element as distance between all tabs. Multiple
indents, OK the first EM_SETTABSTOPS line limited the multiple to 12 but not with the wParam set to 1.
Besides I use rtf code and tabstop is set to deftab480 which overrides the EM_SETTABSTOPS when
opening or pasting text. The other two tab types I'll think about. However as for now I save the
text as plain text.
Quote
Compare the screenshots above
I agree that the RichMasm pic is better readable as the code is written. I don't know how other write
code but with my style I think RichEd_minor pic suits me better. I like line numbering.
Quote
Besides, I prefer individual colouring - it helps when you are in line 14,500 of a source you wrote months ago, and you can't remember what you did there.
To remeber what I did there I usally use comments and and special marking like
;##################################
I must admit that my intentions are not to write a new editor. It was originally intended as a
demo to show how to use the dictionary in the static library. For fun, I worked on with the
demonstration project.
Quote from: minor28 on June 11, 2014, 07:30:05 PM
Neither coping/pasting nor opening windows.inc will cause an exception on my computer (Win7 32).
Opening works, pasting doesn't - tested on XP SP3 and Win7-32. Anybody else having that problem?
Quote
Opening works, pasting doesn't -
It's weird pasting and opening use the same streaming code. The difference is that one reads
the characters from memory and the other from the file.
I see "downloaded 15 times" in reply #1 - nobody else wants to report if pasting Windows.inc content makes it crash or not?
Quote from: jj2007 on June 12, 2014, 03:24:51 AM
I see "downloaded 15 times" in reply #1 - nobody else wants to report if pasting Windows.inc content makes it crash or not?
Hi,
Does not appear to do anything here. (Does not run, and
just returns to the prompt.) P-III and Win2k. Will try later with
Win XP, but that will require a bit of setup to move Windows.inc.
Steve
Hi,
Setting things up was easier than I thought, or at least faster.
It worked on the XP computer. Loading from -> File -> Open,
was very slow and showed some odd behavior (name changed).
Loading from the clipboard was fast and did not crash.
HTH,
Steve N.
After many attempts best solution seems to be to use the DrawText in a compatible bitmap.
So far I have not adjusted the code for other versions of RichEdit than version 3.0
Remaining work that I would appreciate comments on is
- how to solve selection of text. See code below (file Scanner.asm line 176)
- commented text block with comment keyword. Only OK if comment is visible. Test on windows.inc
- any other comments
invoke SendMessage,hWin,EM_EXGETSEL,0,addr txtrange.chrg
mov eax,txtrange.chrg.cpMin
.if eax<txtrange.chrg.cpMax
lea eax,buffer
mov txtrange.lpstrText,eax
invoke SendMessage,hWin,EM_GETTEXTRANGE,0,addr txtrange
invoke SetBkMode,cDC,OPAQUE
invoke SetBkColor,cDC,0FF0000h
invoke SetTextColor,cDC,0FFFFFFh
invoke SendMessage,hWin,EM_GETRECT,0,addr rect
invoke SendMessage,hRED1,EM_POSFROMCHAR,addr rect,txtrange.chrg.cpMin
mov eax,3 ;why 3, I want 4.
shl eax,8
add eax,DT_LEFT or DT_NOCLIP or DT_EXPANDTABS or DT_TABSTOP
invoke DrawText,cDC,addr buffer,-1,addr rect,eax
.endif
Pasting windows.inc does no longer crash the app :t
After some playing with the pasted wininc, the highlighting stops working, and instead I see the original formatting of the pasted code.
I also pasted wininc and played around without highlighting stops working. Do you remember what you did when it stopped working?
The application from reply #11 does have a GDI handle leak.
The GDI handle leak is fixed but I have abandoned the solution to paint the client rect with text. It is a fast way of loading files or paste text to an empty richedit. But that's it.
I have concluded that the best solution is to use RTF syntax. The solution works well for documents of less than about 1000 rows.
I use windows.inc as a yardstick. To scan through the file and convert it to rtf takes less than 2 seconds, but RichEdit need at least 30 seconds to paint the converted text. RichEdit20 control is extremely slow to load files.
If you instead use RichEdit50W (msftedit.dll) the whole procedure will be executed in about 2 sec. It is an acceptable time to load windows.inc.
Undo and Redo are problems remaining to work with.
Hi,
When trying to save the colour options, it crashes in ntdll.dll. I tried to rebuild it but get "fatal error A1000: cannot open file : Automation.inc".
Lines 29+30 in RichEditor.inc can be commented out, but still, while building succeeds then, the dialog does not show up under WinXP SP3. Your original exe works, though.
When saving, be aware that EM_STREAMOUT is broken (http://www.masmforum.com/board/index.php?topic=13089.0) ("disk space saving feature"). Use EM_GETTEXTEX instead.
Re speed, see http://www.masmforum.com/board/index.php?topic=13089.0
RichMasm loads Windows.inc in 0.55 seconds on my trusty old Celeron.
Quote from: minor28 on July 13, 2014, 06:43:36 PM
The GDI handle leak is fixed
it is not fixed - you can check that (for example) with the program GDIView (http://www.nirsoft.net/utils/gdi_handles.html).
You should remarks that you can delete GDI object only if they are currently not selected into a DC. Also DeleteDC does not destroy selected objects. For that reason:
- create the GDI object
- select it into the DC and save the returned handle
- do the drawing operation/s
- select the previously returned handle back in the DC and delete(if wished) the returned object
(Furthermore there are the functions SaveDC and RestoreDC, which might be used for simplification under certain circumstances)
Thank you both for testing.
About the leakage. I do not understand what you mean. In my previous version, I noted that more memory was used when the client rect was repainted. I checked all gdi handles was deleted and after that there was no increase in memory usage.
I this new version there is no increase of memory. I downloaded GDIView but I can not interpret the results. I can not see that my program differs from any of the other running programs. Please could you explain how to detect the leakage.
not sure about how to use that tool
rather than messing with that, heed qWord's notes about how to avoid GDI handle leaks :t
generally, when i create a GDI object, i do so in the WM_CREATE code
and - i "mirror" that creation with a DeleteObject call in WM_DESTROY
there are exceptions to this
one exception might be that i want the handle for window class registration
in that case, i mirror the creation with a DeleteObject in WinMain (before ExitProcess)
another exception is that i might create a GDI object during WM_PAINT
i generally try to avoid this, but a compatible HBITMAP meets this requirement
in such a case, i mirror the creation with a DeleteObject in WM_PAINT
in order for a GDI object to be deleted, it must not be currently selected into a DC
also, when you create a memory DC (applies to any DC, for that matter), you should restore the
originally selected objects before deleting or releasing the DC
if you follow those rules, you shouldn't have any GDI leaks
typically, i notice a GDI leaks by running a program several times (assemble/test/assemble/test, etc)
after a while, windows runs out of GDI handle space and funky things start happening - lol
things like windows not redrawn correctly or at all,
maybe windows explorer not working correctly, desktop icons not redrawn, and so on
Quote
1. create the GDI object
2. select it into the DC and save the returned handle
3. do the drawing operation/s
4. select the previously returned handle back in the DC and delete(if wished) the returned object
Isn't this what I do?
MainDlgProc proc:
.if uMsg==WM_INITDIALOG
invoke CreateFontIndirect,offset CodeFont
mov hCodeFont,eax
invoke SendMessage,hRED1,WM_SETFONT,eax,TRUE
.elseif uMsg==WM_CLOSE
invoke DeleteObject,hCodeFont
DrawLineNumbers proc: call from richedit WM_PAINT
invoke GetDC,hRED1
mov hDC,eax
invoke CreateCompatibleDC,hDC
mov mDC,eax
invoke CreateCompatibleBitmap,hDC,rect.right,rect.bottom
mov hBitmap,eax
invoke SelectObject,mDC,hBitmap
mov hBitmapObj,eax
invoke CreateFontIndirect,offset NumFont
push eax
invoke SelectObject,mDC,eax
mov hFontObj,eax
invoke CreateSolidBrush,numBKcolor
push eax
invoke FillRect,mDC,addr rect,eax
;solid brush
pop eax
invoke DeleteObject,eax
;numbers font
pop eax
invoke DeleteObject,eax ;This object was not deleted!!!
invoke DeleteObject,hFontObj
invoke DeleteObject,hBitmapObj
invoke DeleteObject,hBitmap ;This object was not deleted!!!
invoke DeleteDC,mDC
invoke ReleaseDC,hRED1,hDC
ColorsTabProc proc:
.elseif uMsg == WM_CTLCOLORSTATIC
invoke GetClassName,lParam,addr buffer,sizeof buffer
invoke lstrcmp,addr buffer,offset szColorStatic
.if eax==0
.if OptionColor==-1
invoke GetDlgCtrlID,lParam
mov eax,optTbl[eax*4]
mov edx,colToken[eax*4]
invoke CreateSolidBrush,edx
.else
invoke CreateSolidBrush,OptionColor
mov OptionColor,-1
.endif
ret
.endif
FillFontData proc:
invoke GetDC,hRED1
mov hDC,eax
invoke GetDeviceCaps,hDC,LOGPIXELSY
invoke ReleaseDC,hRED1,hDC
I'm still interested in how GDIView should be interpreted. I would appreciate if someone could enlighten me.
Minor28
from maindialog. Perhaps you are missing create a Dc for the main window handle to the hCodeFont be properly selected (then after using it you may delete the object)
Didn“t saw your code, but, perhaps something like this will avoid the GDI leaking you are facing:
.if uMsg==WM_INITDIALOG
invoke CreateFontIndirect,offset CodeFont
mov hCodeFont,eax
-------------------------------------------------------------------------------
invoke GetDC YourMainWindow
mov hEditFontDC, eax
invoke SetMapMode eax, MM_TEXT <---If you need it)
invoke SelectObject hEditFontDC, hCodeFont
invoke SendMessage,hRED1,WM_SETFONT, hCodeFont,TRUE
-------------------------------------------------------------------------------
.elseif uMsg==WM_CLOSE
invoke DeleteObject,hCodeFont
SelectObject returns the previously selected object. Before deleting the new one, you must de-select it by selecting the old one:
invoke CreateFontIndirect,offset NumFont
push eax
invoke SelectObject,mDC,eax
mov hFontObj,eax ; OLD font
...
;numbers font
invoke SelectObject, mDC, hFontObj ; re-select OLD font, thus freeing new font
pop eax ; NEW font
invoke DeleteObject,eax ;This object was not deleted!!!
; NO, it's not yours: invoke DeleteObject,hFontObj
minor28,
GDIView shows you what kind and how many GDI object a process currently use. To detected a handle leak, enable auto refresh due to the menu, start your program and take a look at the handle counts of the corresponding process. When scrolling loaded text you will see that the count continually increase.
Quote from: minor28 on July 14, 2014, 05:50:49 PM
Quote
1. create the GDI object
2. select it into the DC and save the returned handle
3. do the drawing operation/s
4. select the previously returned handle back in the DC and delete(if wished) the returned object
Isn't this what I do?
no, you don't deselect the objects. For example, see DrawLineNumbers:
invoke CreateCompatibleDC,hDC
mov mDC,eax
invoke CreateCompatibleBitmap,hDC,rect.right,rect.bottom
mov hBitmap,eax
invoke SelectObject,mDC,hBitmap
mov hBitmapObj,eax
invoke CreateFontIndirect,offset NumFont
invoke SelectObject,mDC,eax
mov hFontObj,eax
; ...
invoke DeleteObject,hFontObj
invoke DeleteObject,hBitmapObj
invoke DeleteDC,mDC
invoke ReleaseDC,hRED1,hDC
it should be:
invoke CreateCompatibleDC,hDC
mov mDC,eax
invoke CreateCompatibleBitmap,hDC,rect.right,rect.bottom
invoke SelectObject,mDC,eax
mov hBitmapObj,eax
invoke CreateFontIndirect,offset NumFont
invoke SelectObject,mDC,eax
mov hFontObj,eax
; ...
invoke SelectObject,mDC,hFontObj ; deselect (restore default object)
invoke DeleteObject,eax
invoke SelectObject,mDC,hBitmapObj ; deselect (restore default object)
invoke DeleteObject,eax
invoke DeleteDC,mDC
invoke ReleaseDC,hRED1,hDC
BTW: the windows task manger can also show the total GDI handle count...
BTW2: jj was a bit faster :-D
| Brush | bitmap | font | total | |
Open app | 2 | 1 | 4 | 11 | |
file loaded | 17 | 13 | 8 | 62 | Scrolling, resizing no change |
Open option dlg | 18 | 14 | 11 | 67 | |
Close option | 18 | 14 | 11 | 67 | why not decreasing? |
Open again | 18 | 14 | 14 | 70 | |
Close again | 18 | 14 | 14 | 70 | |
Open again | 18 | 14 | 17 | 73 | increases with 3 each opening |
The only font I use is hCodeFont created in MainDlgProc and deleted in MainDlgProc WM_CLOSE event.
The font is sent to 22 richedit control in option dlg. Is it OK when font is increasing each time the option dlg is opened and why remains the GDI handles after closing the option dlg?
ColorsTabProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.if uMsg==WM_INITDIALOG
;...
xor ecx,ecx
mov eax,7
.while ecx<23
inc colorindex
invoke CreateWindowEx,0,offset szColorStatic,0,50800000h,80,eax,40,12,hWin,colorindex,hInstance,0
mov edx,colorindex
add edx,100
pop eax
invoke CreateWindowEx,0,ASTR("RichEdit50W"),0,50010800h,125,eax,150,12,hWin,edx,hInstance,0
mov hRtf,eax
invoke SendMessage,hRtf,EM_SETBKGNDCOLOR,0,codeBKcolor
invoke SendMessage,hRtf,WM_SETFONT,hCodeFont,TRUE
;.....
.endw
.elseif uMsg==WM_LBUTTONUP
it's ok to create and destroy the font object over and over
but - if it's something that's used a lot, i would create and delete it in WndMain
that means it uses some memory during the life of the process instance - that's ok
Quote
When trying to save the colour options, it crashes in ntdll.dll. I tried to rebuild it but get
"fatal error A1000: cannot open file : Automation.inc".
Lines 29+30 in RichEditor.inc can be commented out ..
I did some testings with IRichEdit interface and belonging dispinterfaces. I forgot to delete
those lines.
Quote
, but still, while building succeeds then, the dialog does not show up under WinXP SP3.
Your original exe works, though.
I don't have WinXP so I cannot test why the dialog not show up.
Quote
When saving, be aware that EM_STREAMOUT is broken ("disk space saving feature").
Use EM_GETTEXTEX instead.
This only happens if you save your text in RTF mode, isn't it? I save in plan text mode.
Quote
RichMasm loads Windows.inc in 0.55 seconds on my trusty old Celeron.
It is difficult to compare the speeds when you do not know the circumstances. In my case
each token will be compared in the dictionary that consists of words (keys) with the total
amount of about 1.5 MBytes. This and converting to RTF takes about two seconds. Loading the
converted text takes "no time".
Quote
it's ok to create and destroy the font object over and over
but - if it's something that's used a lot, i would create and delete it in WndMain
The code font I create in MainDlg proc and delete it when the app is closed. The number font is
created and deleted one time on each richedit WM_PAINT message. No increase of font handles here.
But when I open option dialog the font handles increases every time I open the dialog, even though
I do not create a font but use the font created in MainDlgProc. Isn't this a leak?
Quote from: minor28 on July 17, 2014, 02:16:23 AMBut when I open option dialog the font handles increases every time I open the dialog, even though
I do not create a font but use the font created in MainDlgProc. Isn't this a leak?
yes, it is a leak. The problem is that you use EndDilaog for modeless dialog boxes, whereas DestroyWindow is required. The result of this is that the option-dialog is only hidden, but not destroyed.
To fix that, replace the code in OptionsDlgProc->WM_CLOSE with a single call to DestroyWindow(hWin) and change WM_CLOSE to WM_DESTROY in ColorsTabProc.
Thanks qWord. Now it seems to be without any GDI leakage.
Quote from: minor28 on July 17, 2014, 02:16:23 AM
Quote
When saving, be aware that EM_STREAMOUT is broken ("disk space saving feature").
Use EM_GETTEXTEX instead.
This only happens if you save your text in RTF mode, isn't it? I save in plan text mode.
I discovered this "feature" because the assembler threw errors. So it was plain text.
However, it only happens for medium-sized sources, i.e. several thousand lines.
jj2007,
Quote
, but still, while building succeeds then, the dialog does not show up under WinXP SP3.
Your original exe works, though.
Now I have reinstalled WinXP and for me the dialog is showing up. This is odd.
I have not been able to stop working with the program before it works reasonably. Now it works also when typing and pasting text. The comment keyword was tricky.
Very good work
Hi Gustavo,
you've changed your signature and personal text. Cool. :icon_cool:
Gunther
Hi Gunther, many tks :bgrin:
I had forgotten to change it before.
I have added tab marker lines. My problem is that the lines are not visible when a file is opened but only after scrolling. These are the functions for this.
The subclassed richedit process
.if uMsg==WM_PAINT
invoke HideCaret,hWin
invoke GetUpdateRect,hWin,addr rect,FALSE
mov eax,margin
sub eax,5
.if rect.left<eax
mov rect.right,eax
invoke ValidateRect,hWin,addr rect
.endif
invoke DrawLineNumbers
invoke ShowCaret,hWin
and
DrawLineNumbers proc
LOCAL hDC:dword
LOCAL mDC:dword
LOCAL hBitmapObj:dword
LOCAL hFontObj:dword
LOCAL buffer[32]:BYTE
LOCAL hBitmap:dword
local rect:RECT
local h:dword
local linecount:dword
;----------------------------
local linebuf[256]:byte
local rect2:RECT
LOCAL stride:dword
local ppTabLine:dword
local ppGraphics:dword
local fValue:real4
LOCAL ppBrush:dword
local ppPen:dword
LOCAL rectF:RECTF
local ppTabLineBitmap:dword
;----------------------------
;Touching the stack frame
mov eax,ebp
.while eax>esp
dec eax
mov byte ptr [eax],0
.endw
invoke GetClientRect,hRED1,addr rect
mov eax,margin
mov rect.right,eax
mov eax,rect.bottom
add eax,codeFontHeight
mov h,eax
invoke GetDC,hRED1
mov hDC,eax
invoke CreateCompatibleDC,hDC
mov mDC,eax
invoke CreateCompatibleBitmap,hDC,rect.right,rect.bottom
mov hBitmap,eax
invoke SelectObject,mDC,hBitmap
mov hBitmapObj,eax
invoke CreateFontIndirect,offset NumFont
invoke SelectObject,mDC,eax
mov hFontObj,eax
invoke CreateSolidBrush,numBKcolor
push eax
invoke FillRect,mDC,addr rect,eax
sub rect.right,5
pop eax
invoke DeleteObject,eax
invoke SetBkMode,mDC,TRANSPARENT
invoke SetTextColor,mDC,numTXTcolor
;----------------------------
;Draw indent lines
invoke SendMessage,hRED1,EM_GETRECT,0,addr rect2
mov eax,rect2.right
shl eax,2
mov stride,eax
mov eax,rect2.right
sub eax,rect2.left
mov edx,rect2.bottom
sub edx,rect2.top
invoke GdipCreateBitmapFromScan0,rect2.right,rect2.bottom,stride,PixelFormat32bppARGB,0,addr ppTabLineBitmap
.if eax==0
invoke GdipGetImageGraphicsContext,ppTabLineBitmap,addr ppGraphics
invoke GdipSetSmoothingMode,ppGraphics,SmoothingModeAntiAlias
invoke GdipCreateSolidFill,_ARGB(0,0,0,0),addr ppBrush
invoke GdipFillRectangleI,ppGraphics,ppBrush,0,0,rect2.right,rect2.bottom
invoke GdipSetSolidFillColor,ppBrush,_ARGB(255,255,150,150)
finit
pushd 1
fild dword ptr [esp]
fst fValue
add esp,4
invoke GdipCreatePen2,ppBrush,fValue,UnitPixel,addr ppPen
invoke GdipSetPenDashArray,ppPen,offset dashArray,2
invoke GdipSetPenDashStyle,ppPen,DashStyleCustom
.endif
;----------------------------
sub rect.right,5
invoke SendMessage,hRED1,EM_GETLINECOUNT,0,0
mov linecount,eax
invoke SendMessage,hRED1,EM_GETFIRSTVISIBLELINE,0,0
inc eax
xor ecx,ecx
.while eax<=linecount
push ecx
push eax
push ecx
;----------------------
push eax
;----------------------
push eax
;Draw line number
invoke wsprintf,addr buffer,ASTR("%d"),eax
pop eax
dec eax
invoke SendMessage,hRED1,EM_LINEINDEX,eax,0
invoke SendMessage,hRED1,EM_POSFROMCHAR,addr rect,eax
mov rect.left,0
invoke DrawText,mDC,addr buffer,-1,addr rect,DT_RIGHT
mov numLineHeight,eax
;----------------------------------
;Draw indent lines
pop eax
dec eax
lea edi,linebuf
mov word ptr [edi],sizeof linebuf
invoke SendMessage,hRED1,EM_GETLINE,eax,edi
.if eax
mov eax,1
.while byte ptr [edi]==9 && (byte ptr [edi + 1]==9 || byte ptr [edi + 1]==13 || \
byte ptr [edi + 1]==0)
add eax,TabSize
add eax,TabSize
push eax
mov ecx,rect.top
mov edx,ecx
add edx,codeLineHeight
invoke GdipDrawLineI,ppGraphics,ppPen,eax,ecx,eax,edx
pop eax
inc edi
.endw
.endif
;-------------------------------------
pop eax
mul numLineHeight
.if sdword ptr eax>h
add esp,8
.break
.endif
pop eax
inc eax
pop ecx
inc ecx
.endw
invoke GetClientRect,hRED1,addr rect
mov eax,margin
sub eax,5
mov rect.right,eax
mov edi,eax
dec edi
invoke MoveToEx,mDC,edi,rect.top,0
invoke LineTo,mDC,edi,rect.bottom
invoke BitBlt,hDC,0,0,rect.right,rect.bottom,mDC,0,0,SRCCOPY
;-------------------------
invoke GdipCreateFromHWND,hRED1,addr ppTabLine
invoke GdipDrawImageI,ppTabLine,ppTabLineBitmap,margin,1
;-------------------------
;numbers font
invoke SelectObject,mDC,hFontObj
invoke DeleteObject,eax
invoke DeleteObject,hBitmapObj
invoke DeleteObject,hBitmap
invoke DeleteDC,mDC
;--------------------------
;gdiplus
invoke GdipDeleteBrush,ppBrush
invoke GdipDeletePen,ppPen
invoke GdipDeleteGraphics,ppGraphics
invoke GdipDisposeImage,ppTabLineBitmap
invoke GdipDeleteGraphics,ppTabLine
;--------------------------
invoke ReleaseDC,hRED1,hDC
ret
DrawLineNumbers endp
What should I do to make the lines visible all the time? Any suggestions?
I attach the exe.
If I draw the line numbers in WM_PAINT message and the tab marker lines in WM_PRINTCLIENT it works fairly will. Some flickering though.
Without having any real goal, I continue with the project. If anyone is interested in following the project, I will from time to tim update my website regularly (http://minor28.divdev.se (http://minor28.divdev.se)).
Hi minor28,
Quote from: minor28 on October 06, 2014, 07:14:25 AM
Without having any real goal, I continue with the project. If anyone is interested in following the project, I will from time to tim update my website regularly (http://minor28.divdev.se (http://minor28.divdev.se)).
interesting web site. You're a hard working man. :t
Gunther
Now I have added outlinings to the editor (http://minor28.divdev.se (http://minor28.divdev.se)).
Quote from: minor28 on December 17, 2014, 08:36:05 PM
Now I have added outlinings to the editor (http://minor28.divdev.se (http://minor28.divdev.se)).
Well done. :t
Gunther
Quote from: minor28 on December 17, 2014, 08:36:05 PM
Now I have added outlinings to the editor (http://minor28.divdev.se (http://minor28.divdev.se)).
What do you mean with outlinings?
Apparently, you don't process all paint messages. Try the following:
- go to the end of a very long line
- press arrow right to advance to the start of the next line
- you'll probably see something like this:
QuoteWhat do you mean with outlinings?
Outlining is hiding/showing certain codelines.
The richedit doesn't trigger the WM_HSCROLL when scrolling with arrow keys but ENM_SCROLL to main window does. The EN_HSCROLL notification may do the invalidation instead.
About big files as windows.inc I have done nothing yet.