The MASM Forum

General => The Workshop => Topic started by: zedd151 on October 04, 2022, 05:27:13 AM

Title: SimplEd - a simple richedit editor
Post by: zedd151 on October 04, 2022, 05:27:13 AM
A dialog box based richedit editor. Very basic functionality in this version. Posted by request.
Menu bar access to Cut - "X"; Copy - "C"; Paste - "V", Select All - "A". Undo - "U" Redo "R"
Some menu items not functiong as they are not implemented here in this stripped down version.
They are:
"<<" shift selection 4 spaces left
"<"  shift selection one space left
">"  shift selection one space right
">>" shift selection four spaces right
"Test Plugin" tests plugin code
"Back Color" - under Edit->Settings
"Text Color" - under Edit -> Settings
These functions were removed as they were poorly written and clumsy.
The 'Test Plugin' function is proprietary.   Just kidding.  :tongue:
All of these can be reintroduced (after rewrite) if their is any interest. But will take a little time.
Code below slightly modified. Thanks to bluedevil.
Code: [Select]
    ; This source code written by zedd151 @ masm32.com


    include \masm32\include\masm32rt.inc
 ;     include plugin.inc


    DlgProc         proto :dword, :dword, :dword, :dword
    CenterMain      proto :dword, :dword, :dword
    streamin        proto :dword
    streamout       proto :dword
    savfile         proto :dword
   
    bakcolor        equ 00400020h
    txtcolor        equ 00FFCFEFh
    cwidth          equ 800
    cheight         equ 600
   
  .data
    hWnd            dd 0
    hInstance       dd 0
    hRich           dd 0
    cfm CHARFORMAT  <0>
   
  .code
start:
    fn LoadLibrary, "riched20.dll"
    invoke DialogBoxParamA, 0, 1000, 0, addr DlgProc, 0
    invoke ExitProcess, eax
    DlgProc proc hWin:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
    local hfont:dword, rct:RECT, Cr:CHARRANGE, Wtx:dword
    local memsize, outsize, srcmem, dstmem
      .if uMsg == WM_INITDIALOG
        invoke GetDlgItem, hWin, 1001
        mov hRich, eax
        invoke SendMessage, hRich, EM_EXLIMITTEXT, 0, 1000000000
        invoke SendMessage, hRich, EM_SETOPTIONS, ECOOP_XOR, ECO_SELECTIONBAR
        invoke SendMessage, hRich, EM_SETMARGINS, EC_LEFTMARGIN, 16
        mov cfm.cbSize, SIZEOF CHARFORMAT
        mov cfm.dwMask, CFM_COLOR
        mrm cfm.crTextColor, txtcolor
        invoke PostMessage, hRich, EM_SETCHARFORMAT, SCF_ALL, ADDR cfm
        invoke SendMessage, hRich, EM_SETBKGNDCOLOR, 0, bakcolor
        invoke LoadMenu, 0, 600
        invoke SetMenu, hWin, eax
        invoke CenterMain, hWin, cheight, cwidth
      .elseif uMsg == WM_COMMAND
        .if wParam == 101
          invoke streamin, hRich
        .elseif wParam == 102
          invoke savfile, hRich
        .elseif wParam == 103
          invoke streamout, hRich
        .elseif wParam == 104
          invoke EndDialog, hWin, 0
        .elseif wParam == 201
          invoke SendMessage, hRich, EM_UNDO, 0, 0
        .elseif wParam == 202
          invoke SendMessage, hRich, EM_REDO, 0, 0
        .elseif wParam == 203
          invoke SendMessage, hRich, WM_CUT, 0, 0
        .elseif wParam == 204
          invoke SendMessage, hRich, WM_COPY, 0, 0
        .elseif wParam == 205
          invoke SendMessage, hRich, EM_PASTESPECIAL, CF_TEXT, 0
        .elseif wParam == 207
          mov Cr.cpMin, 0
          invoke GetWindowTextLength, hRich
          inc eax
          mov Cr.cpMax, eax
          invoke SendMessage, hRich, EM_EXSETSEL, 0, ADDR Cr
        .elseif wParam ==777
 ;           invoke SendMessage, hRich, EM_EXGETSEL, 0, ADDR Cr
 ;           mov eax, Cr.cpMax
 ;           sub eax, Cr.cpMin
 ;           inc eax
 ;           mov memsize, eax
 ;           invoke GlobalAlloc, GPTR, memsize
 ;           mov srcmem, eax
 ;           mov eax, memsize
 ;           shl eax, 1
 ;           mov outsize, eax
 ;           invoke GlobalAlloc, GPTR, outsize
 ;           mov dstmem, eax
 ;           invoke SendMessage, hRich, EM_GETSELTEXT, 0, srcmem
 ;           
 ;           invoke plugin, srcmem, dstmem
 ;           
 ;           invoke SendMessage, hRich, EM_REPLACESEL, 1, dstmem
 ;           invoke lstrlen, dstmem
 ;           add eax, Cr.cpMin
 ;           mov Cr.cpMax, eax
 ;           invoke SendMessage, hRich, EM_EXSETSEL, 0, ADDR Cr
 ;           invoke GlobalFree, srcmem
 ;           invoke GlobalFree, dstmem
        .endif
      .elseif uMsg == WM_SIZE
        invoke GetClientRect, hWin, addr rct
        invoke MoveWindow, hRich, rct.left, rct.top, rct.right, rct.bottom, TRUE
      .elseif uMsg == WM_CLOSE
        invoke EndDialog, hWin, 0
      .endif
        xor eax, eax
        ret
    DlgProc endp
   
    CenterMain proc hWin:dword, wd:dword, ht:dword
    local rct:RECT, h:dword, w:dword, x:dword, y:dword
        mov x, 0
        mov y, 0
      @@: ; dynamically adjusting width of the window for proper client rect size
        invoke MoveWindow, hWin, x, y, wd, ht, 0
        invoke GetClientRect, hWin, addr rct
        mov eax, rct.right
        sub eax, rct.left
      .if eax > cwidth ; desired client rect width
        dec wd
        jmp @b
      .elseif eax < cwidth
        inc wd
        jmp @b
      .endif
      @@: ; dynamically adjusting height of the window for proper client rect size
        invoke MoveWindow, hWin, x, y, wd, ht, 0
        invoke GetClientRect, hWin, addr rct
        mov eax, rct.bottom
        sub eax, rct.top
      .if eax > cheight ; desired client rect height
        dec ht
        jmp @b
      .elseif eax < cheight
        inc ht
        jmp @b
      .endif
        invoke GetSystemMetrics, SM_CYMENU
        add ht, eax
        invoke SystemParametersInfoA, SPI_GETWORKAREA, 0, addr rct, 0
        mov eax, rct.right
        sub eax, wd
        sar eax, 1
        mov x, eax
        mov eax, rct.bottom
        sub eax, ht
        sar eax, 1
        mov y, eax
        invoke MoveWindow, hWin, x, y, wd, ht, TRUE
        ret
    CenterMain endp
   
    savfile proc hEdit:dword
    local hWin:dword, ofs:OFSTRUCT, wTxt:dword, hFile:dword
    local WndText[256]:byte, bWrit:dword, tSiz:dword
        invoke GetParent, hEdit
        mov hWin, eax
        invoke GetWindowText, hWin, addr WndText, 256
        invoke OpenFile, addr WndText, ADDR ofs, OF_CREATE
        mov hFile, eax
        invoke GetWindowTextLength, hEdit
        inc eax
        mov tSiz, eax
        invoke GlobalAlloc, GPTR, tSiz
        mov wTxt, eax
        invoke GetWindowText, hEdit, wTxt, tSiz
        invoke WriteFile, hFile, wTxt, tSiz, addr bWrit, 0
        invoke GlobalFree, wTxt
        ret
    savfile endp
   
    streamin proc hriched:dword
    local hFile:DWORD, ofs:OFSTRUCT, est:EDITSTREAM, hPa:dword
    local ttl[16]:byte, flt[16]:byte, ofb[256]:byte, ofn:OPENFILENAME
        mov ecx, sizeof OPENFILENAME
        add ecx, sizeof ofb
        add ecx, sizeof flt
        add ecx, sizeof ttl
        shr ecx, 2
        mov eax, 0
        lea edi, ofn
        rep stosd
        lea eax, ttl
        mov ofn.lpstrTitle, eax
        mov dword ptr [eax], "nepO" ; putting our strings on the stack
        mov dword ptr [eax+4], "liF "
        mov word ptr [eax+8], "e"
        lea eax, flt
        mov ofn.lpstrFilter, eax
        mov dword ptr [eax], " llA"
        mov dword ptr [eax+4], "eliF"
        mov word ptr [eax+8], "s"
        mov dword ptr [eax+10], "*.*"
        mov ofn.lStructSize, sizeof OPENFILENAME
        lea eax, ofb
        mov ofn.lpstrFile, eax
        mov ofn.nMaxFile, sizeof ofb
        mov ofn.Flags, OFN_EXPLORER
        or ofn.Flags, OFN_FILEMUSTEXIST
        or ofn.Flags, OFN_LONGNAMES
        or ofn.Flags, OFN_HIDEREADONLY
        invoke GetOpenFileName, ADDR ofn
        invoke OpenFile, addr ofb, ADDR ofs, OF_READ
        mov hFile, eax
        mov est.dwCookie, eax
        mov est.dwError, 0
        mov eax, offset ofCallBack
        mov est.pfnCallback, eax
        invoke GetParent, hriched
        mov hPa, eax
        invoke SetWindowText, hPa, addr ofb
        invoke SendMessage, hriched, EM_STREAMIN, SF_TEXT, ADDR est
        invoke SendMessage, hriched, EM_SETMODIFY, 0, 0
        mov eax, 0
        ret
    streamin endp
   
    ofCallBack proc dwCookie:DWORD, pbBuff:DWORD, cb:DWORD, pcb:DWORD
        invoke ReadFile, dwCookie, pbBuff, cb, pcb, NULL
        mov eax, 0
        ret
    ofCallBack endp
   
    streamout proc hriched:dword
    local hFile:DWORD, ofs:OFSTRUCT, est:EDITSTREAM
    local ttl[16]:byte, flt[16]:byte, ofb[256]:byte, ofn:OPENFILENAME
        mov ecx, sizeof OPENFILENAME
        add ecx, sizeof ofb
        add ecx, sizeof flt
        add ecx, sizeof ttl
        shr ecx, 2
        mov eax, 0
        lea edi, ofn
        rep stosd
        lea eax, ttl
        mov ofn.lpstrTitle, eax
        mov dword ptr [eax], "evaS" ; putting our strings on the stack
        mov dword ptr [eax+4], "liF "
        mov word ptr [eax+8], "e"
        lea eax, flt
        mov ofn.lpstrFilter, eax
        mov dword ptr [eax], " llA"
        mov dword ptr [eax+4], "eliF"
        mov word ptr [eax+8], "s"
        mov dword ptr [eax+10], "*.*"
        mov ofn.lStructSize, sizeof OPENFILENAME
        lea eax, ofb
        mov ofn.lpstrFile, eax
        mov ofn.nMaxFile, sizeof ofb
        mov ofn.Flags, OFN_EXPLORER
        or ofn.Flags, OFN_OVERWRITEPROMPT
        or ofn.Flags, OFN_LONGNAMES
        or ofn.Flags, OFN_HIDEREADONLY
        invoke GetSaveFileName, ADDR ofn
        invoke OpenFile, addr ofb, ADDR ofs, OF_CREATE
        mov hFile, eax
        mov est.dwCookie, eax
        mov est.dwError, 0
        mov eax, offset sfCallBack
        mov est.pfnCallback, eax
        invoke SendMessage, hriched, EM_STREAMOUT, SF_TEXT, ADDR est
        invoke CloseHandle, hFile
        invoke SendMessage, hriched, EM_SETMODIFY, 0, 0
        mov eax, 0
        ret
    streamout endp
   
    sfCallBack proc dwCookie:DWORD, pbBuff:DWORD, cb:DWORD, pcb:DWORD
        invoke WriteFile, dwCookie, pbBuff, cb, pcb, NULL
        mov eax, 0
        ret
    sfCallBack endp


end start
a slightly updated version now attached.  :cool:
Title: Re: SimplEd - a simple editor
Post by: NoCforMe on October 04, 2022, 05:41:00 AM
So what do "plugins" do and how do they work?
Title: Re: SimplEd - a simple editor
Post by: zedd151 on October 04, 2022, 05:46:20 AM
Plugins here have two parameters. They are two buffers, one containing selected text the other for the result of manipulating that text. For reformatting, remove empty lines, uncapitalize keywords etc, are some uses.
This plugin interface is not the same as for qeditor which has two entirely different interfaces. Does this answer the question satisfactorily?


I can supply a version that uses the commented plugin interface but will be later on some time, as I've other projects to tend to at the moment.
Title: Re: SimplEd - a simple editor
Post by: NoCforMe on October 04, 2022, 05:53:47 AM
Well, yes, I was just curious as to what a plugin would do in your simple editor. Makes sense with 2 buffers.

Maybe I'll have to add that capability to my assembler editor ...
Title: Re: SimplEd - a simple editor
Post by: zedd151 on October 04, 2022, 05:57:27 AM
I highly recommend that you do. You can use a similar method to reformat others' code to your liking. I often do, using my plugins for qe. (I have similar versions of those for working with a version of this editor somewhere)
If you do add that, remember how richedit handles CR and not CRLF to avoid issues later on. (from experience)
Also, if you add to the text use a larger buffer as the destination. I generally use twice the size, but at times more than that depending on what the plugin is designed for.
One of the best advantages of using plugins is that they can be self contained in a dll, hence reusable. A rewrite of an editor would have much less code to deal with especially if their are many functions handled by plugins or dlls in general.
Title: Re: SimplEd - a simple richedit editor
Post by: jj2007 on October 04, 2022, 08:55:48 AM
I built it at 5120 bytes, that's shorter than my TinyIDE at 7168 :thumbsup:
Title: Re: SimplEd - a simple richedit editor
Post by: bluedevil on October 04, 2022, 09:20:23 AM
Where do we issue bugs :D

1. SimpleEd is not closing file, when user clicks "Close File".
2. There is no "Exit" menu item
Title: Re: SimplEd - a simple richedit editor
Post by: zedd151 on October 04, 2022, 09:49:16 AM
1. SimpleEd is not closing file, when user clicks "Close File".
You're right!  :thumbsup:
Quote
2. There is no "Exit" menu item
But the Big Red "X" works.  :badgrin:
Fixed!  :biggrin:  Both code above and attached source + exe
This is a simple editor after all. Kind of a WIP still.  :mrgreen:
Title: Re: SimplEd - a simple richedit editor
Post by: zedd151 on October 04, 2022, 09:57:26 AM
I built it at 5120 bytes, that's shorter than my TinyIDE at 7168 :thumbsup:
With todays hard drive sizes, the executables size hardly matters. But being a dialog box does make it a slim editor.




and btw Thats what she said.  :joking:
Title: Re: SimplEd - a simple richedit editor
Post by: learn64bit on October 04, 2022, 11:29:15 AM
 :thumbsup:

Test report

utf8 auto detection
 utf8withBOM works
  utf8 automagic guess works
   accuracy 100%
 utf8withoutBOM No!
utf16 No!
Title: Re: SimplEd - a simple richedit editor
Post by: zedd151 on October 04, 2022, 11:44:07 AM
utf8withoutBOM No!
utf16 No!
Intended as a plain text, ascii only editor.
Title: Re: SimplEd - a simple richedit editor
Post by: zedd151 on October 05, 2022, 02:22:52 AM
:thumbsup:

Test report

utf8 auto detection
 utf8withBOM works
  utf8 automagic guess works
   accuracy 100%
 utf8withoutBOM No!
utf16 No!
No, my program here is not notepad.  :tongue:  Thank you for confirming what I already knew.  :biggrin:
Now maybe I should put a plugin interface into notepad myself and add colors for background and text.  :eusa_naughty:
Not. I would rather distribute programs of my own creation verified by supplying source code.
Now I shall crawl back under my rock and never speak of this again.  :toothy:  Besides I've got more urgent matters to deal with. If I can only remember where I left off.  :tongue:
Title: Re: SimplEd - a simple richedit editor
Post by: zedd151 on October 05, 2022, 02:36:38 AM
Quote from: zedd151?
If I can only remember where I left off.  :tongue:
Oh yeah, just remembered. As a sideline project am planning a rewrite of SimplEd with more functionality. Possibly a 64 bit version as well this time since I now have windows7 64 bit installed on this machine.  :biggrin:  But first, I have to finish my main current project.
Title: Re: SimplEd - a simple richedit editor
Post by: TimoVJL on October 05, 2022, 02:59:11 AM
There are so many good editors based in richedit/mftedit components to choose.
For example MetaPad users knows, with source code, how to make a good notepad replacements.



Title: Re: SimplEd - a simple richedit editor
Post by: hutch-- on October 05, 2022, 10:26:04 AM
If you are into 64 bit "Notepad" style editors, have a look at the examples in the 64 bit version of the MASM SDK for "TheGun". Pure ASCII, search and replace, very large capacity and its just as ugly as the original Notepad of long ago.
Title: Re: SimplEd - a simple richedit editor
Post by: zedd151 on October 06, 2022, 02:51:42 AM
I am currently undertaking the merging of several functions from my various editor projects, plus bits and pieces from the Masm32 SDK and the current Masm64 beta SDK. (Downconverting from 64 to 32 bit code  :tongue: )
Will post the project as soon as I have it up and running (A rather basic editor at first, to be added to over time).
 :biggrin:
No print functions will be used and no toolbar. I do plan on having a plugin interface (compatible with old style (legacy) qeditor plugins), colored text and background, search and replace, sorting capabilities, separate ascending sort with removal of duplicates, and other features commonly expected in an editor.
Title: Re: SimplEd - a simple richedit editor
Post by: zedd151 on October 11, 2022, 01:22:59 PM

I am currently undertaking the merging of several functions from my various editor projects, plus bits and pieces from the Masm32 SDK and the current Masm64 beta SDK. (Downconverting from 64 to 32 bit code  :tongue: )
Will post the project...
  here: my editor project (http://masm32.com/board/index.php?topic=10411.0)