The MASM Forum
General => The Workshop => Topic started 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.
; 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:
-
So what do "plugins" do and how do they work?
-
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.
-
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 ...
-
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.
-
I built it at 5120 bytes, that's shorter than my TinyIDE at 7168 :thumbsup:
-
Where do we issue bugs :D
1. SimpleEd is not closing file, when user clicks "Close File".
2. There is no "Exit" menu item
-
1. SimpleEd is not closing file, when user clicks "Close File".
You're right! :thumbsup:
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:
-
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:
-
:thumbsup:
Test report
utf8 auto detection
utf8withBOM works
utf8 automagic guess works
accuracy 100%
utf8withoutBOM No!
utf16 No!
-
utf8withoutBOM No!
utf16 No!
Intended as a plain text, ascii only editor.
-
: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:
-
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.
-
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.
-
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.
-
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.
-
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)