News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Rapid Application Development in Assembly

Started by jj2007, December 13, 2019, 11:04:47 PM

Previous topic - Next topic

jj2007

See also GUI programming with events

This three-liner assembles to a full-fledged Windows application that displays plain text or rich text format (rtf) files:

include \masm32\MasmBasic\Res\MbGui.asm         ; yep, MasmBasic is required to build this!
  GuiControl MyRichEdit, "richedit", wCL$()
EndOfCode


Drag any *.txt, *.inc, *.rtf or *.asc file over the exe to see the result. Of course, under the hood are lots of things going on, the exe has a whopping 48,640 bytes; which is a lot for an assembly application but still less than 1% of what an equivalent QT executable would need to do the job.

Why would any assembly programmer use this approach? Simply because it saves time. It is a rapid way to develop an application with a lot of functionality. In addition to the 400+ MasmBasic macros, the full Masm32 library is available, but you can also use whatever closest-to-the-metal assembly code as you wish. Plus, the deb macro can help you a lot with low level code.

Attached is a more advanced example. With 30 lines of source code (the *.asc file opens in RichMasm), you can generate a window with edit, static, richedit and statusbar controls (see GuiControl), plus a background image (see GuiImage) which monitors the WM_** messages produced by the OS e.g. when clicking on a menu:


hutch--

Sounds like you are building "objects" which can be useful in design terms.

mineiro

GTK has the same approach, reusable code, but type massification.
If I do not know which parameters a function needs, it is necessary to question the function that returns the types, or size in bytes required. It's a great idea.
Setbacks often happen in my tests with memory allocation. If a huge file is opened in the editor and after the text is deleted, the allocated memory continues to consume resources. I tried several ways in vain; dissatisfied, I looked at the source code of 3 IDE's made with gtk and found faults; even if the edit control is closed.
QT is higher than gtk in this scenario.
Good luck, good work.
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

jj2007

@mineiro: thanks :thup:

Quote from: hutch-- on December 13, 2019, 11:48:28 PM
Sounds like you are building "objects" which can be useful in design terms.

Yes, kind of. I don't call them objects because they are really just standard Windows controls. Here is a 10-liner with a minimum of functionality:

include \masm32\MasmBasic\Res\MbGui.asm
  GuiControl MyRichEd, "richedit", "Pick a file in the listbox", w800   ; create a RichEdit control, width 80%
  GuiControl MyList, "listbox", x800, w200      ; create a listbox at x=80%, width 20%
  GetFiles *.as?|*.inc|*.rc|*.rtf
  SetListbox Files$()

Event Command
  .if word ptr wParam_+2==LBN_SELCHANGE
        SetWin$ hMyRichEd=FileRead$(Cat$(CurDir$()+LbSel$))
  .endif
EndOfCode


The RAD point here is that you can quickly design an application just by specifying x, y, w and h using a simple code:
GuiControl "...", x500+20, w500-20  ; put x at 50%+20px, width 50%-20px

The first number means n/1000*client rect width, the second number is a fixed amount of pixels. The underlying engine takes care of all calculations, and updates the whole UI when resizing the window.

Event can be:
Message (generic event, uses hWnd_, uMsg_, wParam_, lParam_)
Paint (put GuiImage, ArrayPlot etc there)
Menu (returns MenuID from 0...n)
Command and Notify (both return NotifyID)
Key (returns VKey, e.g. VK_ESCAPE)
Data (creates and returns CopyData$ in response to a WM_COPYDATA message)
DropFiles (creates the Files$() array in responses to WM_DROPFILES)
and a few others like Close, Timer, Size, Download, CanvasPaint (for the special "canvas" control).

It takes one line before the include... to add a menu:

GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste

The corresponding handler (short version - it can look very different, of course, e.g. using Switch_ MenuID):

Event Menu
  If_ MenuID==3 Then MsgBox 0, "This is Undo", "Hi", MB_OK

LiaoMi

Hi jj2007,

in your cool RadDemo example there is no double buffering  :rolleyes:, when you change the red window, you can see a flickering area, this is the main background of the window. If there wasn't flicker, it would be perfect  :thumbsup: :azn:

Don't Flicker! Double Buffer! (Demonstrates several ways to overcome the annoying flickering problem.) - https://www.codeproject.com/Articles/12870/Don-t-Flicker-Double-Buffer

Double Buffering With GDI+ (C++) - https://www.codeproject.com/Articles/1819/Double-Buffering-With-GDI
C++ & WinAPI: Double Buffering https://ksgamedev.wordpress.com/2010/01/11/c-winapi-double-buffering/

P.S. examples demonstrate the effect of flicker and absence.

jj2007

Thanks, LiaoMi. You are right, the background flickers. Attached two versions, let me know what you think about the difference.

LiaoMi

Quote from: jj2007 on December 14, 2019, 01:24:06 PM
Thanks, LiaoMi. You are right, the background flickers. Attached two versions, let me know what you think about the difference.

Hi jj2007,

SimpleGuiFlicker.exe - at first glance, everything looks very good, but if you increase the speed of movement, or hold the mouse button to resize for 5 seconds, then the old effect reappears.
SimpleGuiMsgMonitor.exe - there is no problem with this example, what the moment of redrawing looks like can be seen here (120 FPS) - https://i.imgur.com/QsQXkge.png, on the second frame, the picture looks already redrawn. I used a free utility for recording - ScreenToGif 2.19.3 - https://github.com/NickeManarin/ScreenToGif/releases/tag/2.19.3

jj2007

Thanks a lot for the feedback :thup:

Under the hood, I do use a compatible bitmap etc, but the first example had a main window background, and that caused problems. The second example has bnone in the first line, i.e. background: none, and behaves much better. In both cases, however, the RichEdit control shows no flicker at all, while the edit control shows strong flicker when resizing the main window.

ScreenToGif looks very useful, but it was extremely slow to start, and the UI is confusing. I have not yet found out how to save a series of frames. I can see the frames, and scroll through them with the arrow keys, but it keeps telling me that I first have to pick a folder for saving a project. And there is no button that would allow me to pick one :cool:

I also wonder why the UI is in Italian. Is it translated, or is the author Italian?

P.S.: I attach another demo. On my machine, it's very smooth except for the edit control, in particular its scrollbar. When sizing, I also noted that the menu headings (File, Edit) flicker slightly. I wonder if the text rendering is the culprit.

LiaoMi

The picture shows the cause of the flicker, exactly the same effect as in this thread - http://masm32.com/board/index.php?topic=6483.msg90177#msg90177 ..

Reducing the size of the window while holding the left side of the window violates some logic, but on the right side this effect does not occur at all  :azn:

LiaoMi

Quote from: jj2007 on December 15, 2019, 05:07:00 AM

ScreenToGif looks very useful, but it was extremely slow to start, and the UI is confusing. I have not yet found out how to save a series of frames. I can see the frames, and scroll through them with the arrow keys, but it keeps telling me that I first have to pick a folder for saving a project. And there is no button that would allow me to pick one :cool:

I also wonder why the UI is in Italian. Is it translated, or is the author Italian?

Hi jj2007,

ScreenToGif - it seems to be written in .net, so it probably slows down due to windows 7, to make a series of frames, you need to activate recording for a short moment, record the selected area, perform actions on the program, stop recording. Multiple pictures will open, from which you can select the ones you need. Then right-click the "explorer" menu key, a folder with all recorded pictures will open, you can select the desired one by number. The program has a large data stream, in a couple of seconds, it records up to 400 mb of data. Therefore, you need to stop recording as soon as the test is completed. Maybe there are alternative programs that may be faster, languages are built into the program, the language switches during the system language check. I have a portable version, everything is saved in the temporary directory. In the settings there should be a folder for saving or just save the project to the desktop separately.

LiaoMi

Quote from: jj2007 on December 15, 2019, 05:07:00 AM
but the first example had a main window background

WM_ERASEBKGND message
Sent when the window background must be erased (for example, when a window is resized). The message is sent to prepare an invalidated portion of a window for painting.
https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-erasebkgnd

jj2007

Another little demo, 24 lines of code: Extract all files to a folder, then run the exe and select a file in the listbox to see its content.



GuiParas equ "Dynamic Layout Demo", y100, w900, h400, m9, bGrey        ; y at 100px, width 900px, margin 9px, grey background
GuiMenu equ @File, &Open, &Save, -, E&xit, @Whatever, Добро пожаловать, مرحبا بكم, Functions not implemented   ; creates a menu -> Event Menu
include \masm32\MasmBasic\Res\MbGui.asm
  GuiControl MyLink, "syslink", "Download the MasmBasic library", w0+200, y0+100, h0+20
  GuiControl MySBar, "statusbar", "Добро пожаловать"                     ; all GuiControls understand Unicode
  GuiGroupGroupbox (functions not implemented):", w0+266, h0+75, bcol LiteYellow
    GuiControl StatFind, "static", "Find:",        h0+22, w0+50            ; general syntax:
    GuiControl StatRepl, "static", "Replace:",         h0+22, w0+50, y0+32             ; guicontrol ID, "class", args "text", x, y, w, h, style
    GuiControl EditFind, "edit", "Gui", x0+62, w0+100, h0+22, WS_EX_CLIENTEDGE         ; args have a variable part plus an optional fixed one, example:
    GuiControl EditRepl, "edit", x0+62, w0+100, h0+22, WS_EX_CLIENTEDGE, y 0+30        ; x1000-90 means "at right border, i.e. 100.0%, minus 90 pixels"
    GuiControl Cis, "button", BS_AUTOCHECKBOX, h0+22, x0+170, w0+60, "Case"    ; args may appear in no particular order, e.g. "Case" at the end
    GuiControl Fw, "button", "Full word", h0+22, x0+170, w0+64, y0+28, BS_AUTOCHECKBOX
  GuiGroup end
  GetFiles *.as?|*.rc|*.rtf     ; collect asm, asc & rc sources, plus rich text files
  SortFiles date       ; latest first
  GuiControl MyList, "listbox", Files$(), x0+288, w1000-288, h0+100    ; right-aligned, height 100px
  GuiControl BigEdit, "richedit", y0+120, h1000-120, bcol RgbCol(222, 255, 255), font -14       ; *)
Event Menu
  SetWin$ hMySBar=Str$("You clicked menu #%i", MenuID)
Event Notify
  If_ word ptr wParam_==MyLink && NotifyCode==NM_CLICK Then <ShEx "http://masm32.com/board/index.php?topic=94.0">
Event Command
  If_ word ptr wParam_==MyList && LbSel>=0 Then <SetWin$ hBigEdit=FileRead$(LbSel$)>
GuiEnd XP                      ; OPT_Icon Smiley       ; Calc, Eye, Disk, Editor, Globe, Keys, Plot, Smiley, Timer
*)
BigEdit specs:
x and width not specified -> 100% of client rect width
y is 0% of client rect height plus 120px
height is 1000 (=100% of rect height) minus 120px
background colour is turquoise, font -16 px

jj2007

Attached a demo with a set of 6 controls - work in progress. Grateful for feedback on major display problems :cool:

All controls are sizeable. For example, you can enlarge the upper left control, and then click into the map to select other countries.