flat assembler
Message board for the users of flat assembler.
Index
> Windows > EDIT with nonclient(NC) area for linenumbers |
Author |
|
ProMiNick 29 Mar 2023, 21:06
for example horizontal scroll of Scintilla is a kind of mess (when all lines could fit client area scroll is allowed and scrolls).
moreover in scintilla linenumbers are in margin of client textarea, not in NC area because of that user mispredicted that scroll will scroll linenumbers to, it not happend but looks very ugly. How to look on scintilla in minipad example? Code: ; Simple text editor - fasm example program format PE GUI 4.0 entry start include 'win32a.inc' IDR_ICON = 17 IDR_MENU = 37 IDM_NEW = 101 IDM_EXIT = 102 IDM_ABOUT = 901 SCI_SETMARGINTYPEN = 2240 SCI_SETMARGINWIDTHN = 2242 SCI_GETDIRECTFUNCTION = 2184 SCI_GETDIRECTPOINTER = 2185 SC_MARGIN_NUMBER = 1 section '.text' code readable executable start: RTL_C invoke GetModuleHandle,0 mov [wc.hInstance],eax invoke LoadIcon,eax,IDR_ICON mov [wc.hIcon],eax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],eax invoke RegisterClass,wc test eax,eax jz error invoke LoadMenu,[wc.hInstance],IDR_MENU invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW,144,128,256,256,NULL,eax,[wc.hInstance],NULL test eax,eax jz error msg_loop: invoke GetMessage,msg,NULL,0,0 cmp eax,1 jb end_loop jne msg_loop invoke TranslateMessage,msg invoke DispatchMessage,msg jmp msg_loop error: invoke MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK end_loop: invoke ExitProcess,[msg.wParam] invoke Scintilla_DirectFunction flush_locals WindowProc: RTL_C hwnd,wmsg,wparam,lparam frame ebp push ebx esi edi mov eax,[wmsg] cmp eax,WM_CREATE je .wmcreate cmp eax,WM_SIZE je .wmsize cmp eax,WM_SETFOCUS je .wmsetfocus cmp eax,WM_COMMAND je .wmcommand cmp eax,WM_DESTROY je .wmdestroy .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp .finish .wmcreate: invoke GetClientRect,[hwnd],client invoke CreateWindowEx,WS_EX_CLIENTEDGE,_edit,0,WS_VISIBLE+WS_CHILD+WS_HSCROLL+WS_VSCROLL+ES_AUTOHSCROLL+ES_AUTOVSCROLL+ES_MULTILINE,[client.left],[client.top],[client.right],[client.bottom],[hwnd],0,[wc.hInstance],NULL or eax,eax jz .failed mov [edithwnd],eax ;invoke SendMessage,eax,SCI_GETDIRECTFUNCTION ,0,0 ;mov [mfp],eax invoke SendMessage,[edithwnd],SCI_GETDIRECTPOINTER ,0,0 mov [ptr_hndl],eax invoke Scintilla_DirectFunction,[ptr_hndl],SCI_SETMARGINTYPEN,1,SC_MARGIN_NUMBER invoke Scintilla_DirectFunction,[ptr_hndl],SCI_SETMARGINWIDTHN,1,40 invoke CreateFont,16,0,0,0,0,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_RASTER_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL or eax,eax jz .failed mov [editfont],eax invoke SendMessage,[edithwnd],WM_SETFONT,eax,FALSE xor eax,eax jmp .finish .failed: or eax,-1 jmp .finish .wmsize: invoke GetClientRect,[hwnd],client invoke MoveWindow,[edithwnd],[client.left],[client.top],[client.right],[client.bottom],TRUE xor eax,eax jmp .finish .wmsetfocus: invoke SetFocus,[edithwnd] xor eax,eax jmp .finish .wmcommand: mov eax,[wparam] and eax,0FFFFh cmp eax,IDM_NEW je .new cmp eax,IDM_ABOUT je .about cmp eax,IDM_EXIT je .wmdestroy jmp .defwndproc .new: invoke SendMessage,[edithwnd],WM_SETTEXT,0,0 jmp .finish .about: invoke MessageBox,[hwnd],_about_text,_about_title,MB_OK jmp .finish .wmdestroy: invoke DeleteObject,[editfont] invoke PostQuitMessage,0 xor eax,eax .finish: pop edi esi ebx exitf stack_cleanup callee flush_locals section '.data' data readable writeable _title TCHAR 'ScintillaPad',0 _about_title TCHAR 'About MiniPad',0 _about_text TCHAR 'This is Win32 example program created with flat assembler.',0 _error TCHAR 'Startup failed.',0 _class TCHAR 'MINIPAD32',0 _edit TCHAR 'Scintilla',0 wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class edithwnd dd ? editfont dd ? mfp dd ? ptr_hndl dd ? msg MSG client RECT section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL',\ gdi,'GDI32.DLL',\ scilexer,'SCILEXER.DLL' import kernel,\ GetModuleHandle,'GetModuleHandleA',\ ExitProcess,'ExitProcess' import user,\ RegisterClass,'RegisterClassA',\ CreateWindowEx,'CreateWindowExA',\ DefWindowProc,'DefWindowProcA',\ SetWindowLong,'SetWindowLongA',\ RedrawWindow,'RedrawWindow',\ GetMessage,'GetMessageA',\ TranslateMessage,'TranslateMessage',\ DispatchMessage,'DispatchMessageA',\ SendMessage,'SendMessageA',\ LoadCursor,'LoadCursorA',\ LoadIcon,'LoadIconA',\ LoadMenu,'LoadMenuA',\ GetClientRect,'GetClientRect',\ MoveWindow,'MoveWindow',\ SetFocus,'SetFocus',\ MessageBox,'MessageBoxA',\ PostQuitMessage,'PostQuitMessage' import gdi,\ CreateFont,'CreateFontA',\ DeleteObject,'DeleteObject' import scilexer,\ Scintilla_DirectFunction,'_Scintilla_DirectFunction@16' section '.rsrc' resource data readable ; resource directory directory RT_MENU,menus,\ RT_ICON,icons,\ RT_GROUP_ICON,group_icons,\ RT_VERSION,versions ; resource subdirectories resource menus,\ IDR_MENU,LANG_ENGLISH+SUBLANG_DEFAULT,main_menu resource icons,\ 1,LANG_NEUTRAL,icon_data resource group_icons,\ IDR_ICON,LANG_NEUTRAL,main_icon resource versions,\ 1,LANG_NEUTRAL,version menu main_menu menuitem '&File',0,MFR_POPUP menuitem '&New',IDM_NEW menuseparator menuitem 'E&xit',IDM_EXIT,MFR_END menuitem '&Help',0,MFR_POPUP + MFR_END menuitem '&About...',IDM_ABOUT,MFR_END icon main_icon,icon_data,'minipad.ico' versioninfo version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLANG_DEFAULT,0,\ 'FileDescription','MiniPad - example program',\ 'LegalCopyright','No rights reserved.',\ 'FileVersion','1.0',\ 'ProductVersion','1.0',\ 'OriginalFilename','MINIPAD.EXE' I used old scintilla version (it is smaller). In new ones exported symbol 'Scintilla_DirectFunction' not '_Scintilla_DirectFunction@16'
_________________ I don`t like to refer by "you" to one person. My soul requires acronim "thou" instead. |
||||||||||
29 Mar 2023, 21:06 |
|
bitRAKE 30 Mar 2023, 11:50
EM_GETLINEHEIGHT, looks like a custom edit control message.
What is gained by this sub-class? Without it the code would need to paint on the parent window. Might be better just to let the edit control do what it does. The most dynamic way to obtain the line height is to subtract consecutive lines with EM_LINEINDEX / EM_POSFROMCHAR - just force an extra line at end of text. This technique adapts to varied fonts (per line, different font size in line could throw off number alignment). Responding to EN_UPDATE might be sufficient to synchronize numbers to lines. Support for word wrap would need additional end-of-line detection if there was a desire to not number wrapped fragments. _________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
|||
30 Mar 2023, 11:50 |
|
bitRAKE 01 Apr 2023, 20:05
The longer I thought about it, the more sure I was there would be additional complexities. Maybe, EN_UPDATE and EN_VSCROLL would need to be handled - I didn't know. Also, how bad is it going to look with different line heights? Perhaps just let the gaps happen - no need to calculate the line height then.
There are other problems in the general solution though. What if the edit font is too small, and the number turns to mush. So, the size of the numbering font needs to match the line height. Then the column width is broken, too. Imagine a line of very large text - massive line numbers as well. These massive line numbers could be wider than the largest line number! Dynamic general solution is not possible. So, we fall back to what everyone else does: user sets the numbering font/size and it's constant - regardless of the line height. In this senerio we need the line height only to center the number to the line. But we can be even lazier - just align the numbering with top of line. Here is my first draft. I know there are still errors to resolve and I've not tested it much.
_________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
||||||||||||||||||||
01 Apr 2023, 20:05 |
|
ProMiNick 01 Apr 2023, 23:52
thanks for solution, bitRAKE.
how bad is it going to look with different line heights? - for formated text there is significant how beauty it looks: different fonts, line heights other formating stuff but there are needless linenumbers. from other side for code text linenumbers are significant, other stuff specific for formated text in case of code only decrease readability. So if we in case of needance in linenumbers we could be sure that font would be only one & and it would be monospaced. However in code there other specialities: Code: 312 IDM_ABOUT := 901 313 314 directory \ 314 RT_MENU, menus,\ 314 RT_VERSION, versions,\ 314 RT_MANIFEST, manifests 318 logicaly there are 4 lines with number 314 because of line continuation symbol. But as basic solution above one is perfect. |
|||
01 Apr 2023, 23:52 |
|
bitRAKE 02 Apr 2023, 00:46
My preference is for the line number on the status line - for the rare times when it's needed. What purpose does it serve? Decoration for the selection bar. Long days have me wanting the active line highlighted - to find the damn caret. Do line numbers really help navigation in some way?
If you make the window small the line wrapping can be seen increasing the line numbers as well. Line continuations offer a special complexity, example: Code: 312 IDM_ABOUT := 901 313 314 directory \ 314 RT_MENU, menus,\; comment can follow 314 RT_VERSION, versions,\; line continuation! 314 RT_MANIFEST, manifests 318 Then for fasmg, comment characters are not always pruned. Many cases exist where it can only be known at compiler time what is what. It's the same way for high-lighting. We choose some lesser representation to approximate the actual parsing. Another approach is to develop an "online" algorithm that compiles during editing. So, all the information is present. My understanding is that all Windows edit controls have errors which can result in lines of different heights - definitely something to test. _________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
|||
02 Apr 2023, 00:46 |
|
revolution 02 Apr 2023, 00:57
I know of no other editors or tools that count continuation lines as the same line number. It would be very disorientating to have grep report something on line 456 only to have the editor say it is line 321. Yuck.
I also find line numbers in the side bar to be, not just nice, but essential. We have tools that output lists of line numbers that it identifies, and then being able to have those same line numbers shown to me for quickly locating each line during editing is a huge time saver. Many editors also use the line number sidebar as a clickable target to select whole lines quickly, and/or to move lines around by dragging them, etc. |
|||
02 Apr 2023, 00:57 |
|
revolution 02 Apr 2023, 04:02
Line numbers also allow an unambiguous view of wrapped lines.
|
||||||||||
02 Apr 2023, 04:02 |
|
Roman 02 Apr 2023, 07:44
Apply + in number line close\open this line.
Hidden unhidden line. |
|||
02 Apr 2023, 07:44 |
|
ProMiNick 05 Apr 2023, 13:39
Atleast my own working example.
On repaint I caught 3 messages WM_NCPAINT (here is hiding part of area with context menu, actualy repaint itself),WM_PAINT (here is scrolling, hiding part of area with context menu),WM_KEYDOWN (all the rest not caused repaint, for example making new line that still fit client area) Code a bit ugly: in WM_KEYDOWN processing invoke InvalidateRect,[hwnd],0,FALSE - mean repaint of whole area even where client already successfuly painted once because of 0 instead of ptr to repaint RECT. line numbers are limitid in size for 4 digits (enought for any practical code, that is practical, but not looks like general solution), and they are with leading zeroes. in my code to many constants: Code: .make_ncarea: mov eax,[lparam] add dword[eax],40 ... add [client.left],3 add [client.top],3 mov [client.right],40-3 ... invoke TextOut,[NC_DC], 3, 3, ntext, 4 40 - is value that fit 4 digits of default font with default size 3 - is standard 3d-look bordering - 2 pix, plus internal EDIT spacing - 1 pix (may be both controlled by themes, and must be grabbed from value of some windows environment vars). moreover repaint of NC caused even it not needed (must be tracked shift of first visible line, tracked change of count of displayed lines) should work on win32 subsys with user32.dll (win98..win10, wine, reactos). [EDIT] How to cut off couple of constants by win environment variables: Code: .make_ncarea: mov eax,[lparam] add dword[eax],40 ... invoke GetClientRect,[hwnd],client invoke GetSystemMetrics,SM_CYEDGE add [client.left],eax add [client.top],eax mov [client.right],40 sub [client.right],eax invoke GetSystemMetrics,SM_CYHSCROLL add [client.bottom],eax ... invoke GetSystemMetrics,SM_CYEDGE invoke TextOut,[NC_DC], eax, eax, ntext, 4 [EDIT2] not in attachment Code: NewEditProc.wmpaint: RTL_C hwnd,wmsg,wparam,lparam frame ebp invoke BaseEditProc,[hwnd],WM_PAINT,0,0 invoke GetWindowRgn,[hwnd],[wparam] mov [wmsg],WM_NCPAINT ; this one added,that is very significant, without it appear graphical artifacts in client area, scroll areas, and in border exitf flush_locals for erasing whole custom NC area (client.height+scroll.height was not enought): Code: invoke GetClientRect,[hwnd],client invoke GetSystemMetrics,SM_CYEDGE add [client.left],eax add [client.top],eax mov [client.right],40 sub [client.right],eax add [client.bottom],eax ;after window resizing left graphical artifacts 1-2 pix width, this line fix it. invoke GetSystemMetrics,SM_CYHSCROLL add [client.bottom],eax invoke SelectObject,[NC_DC], [editfont] invoke FillRect,[NC_DC],client,HOLLOW_BRUSH
_________________ I don`t like to refer by "you" to one person. My soul requires acronim "thou" instead. Last edited by ProMiNick on 06 Apr 2023, 12:21; edited 2 times in total |
||||||||||||||||||||
05 Apr 2023, 13:39 |
|
bitRAKE 05 Apr 2023, 15:39
Handling the messages the way you suggest seems to solve a flicking problem present in my approach.
Also, when dragging the scrollbar 'THUMB' no messages are sent to the parent. This means the scrollbars would need to be external from the edit control. Sub-classing reduces the complexity. _________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
|||
05 Apr 2023, 15:39 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.