News:

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

Main Menu

Event-driven programming

Started by jj2007, January 28, 2017, 08:51:02 PM

Previous topic - Next topic

jj2007

There is a remarkably poor Wikipedia page on Event-driven programming, therefore here a few examples on how it can be done in assembly, using the MasmBasic library.

Example #0: a full-fledged window with a menu, its event handler, and a message monitor
GuiParas equ "Event-driven programming in Assembly", x500, y20, w200, h200, cblack, b00FFFFD0h
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste
include \masm32\MasmBasic\Res\MbGui.asm

Event Menu ; this event returns MenuID
  Switch_ MenuID
  Case_ 0
MsgBox 0, "You clicked Open", "Hi", MB_OK ; first menu item has MenuID 0
  Default_
MsgBox 0, Str$("You clicked menu #%i", MenuID), "Hi", MB_OK ; MenuID=0, 1, 2, ...
  Endsw_

Event Message ; this event returns hWnd, uMsg, lParam, wParam
  inc msgCount ; if the internal msgCount variable
  deb 4, "msg", chg:msgCount ; changes, deb shows the current uMsg

GuiEnd


The code above creates a small window (w200, h200) with a menu. Every message passing the Event Message handler is being displayed in the console. As the screenshot below shows, in this specific moment mainly menu messages appeared.

jj2007

Example #1 uses simple handlers for the WM_PAINT and WM_KEYDOWN messages:
include \masm32\MasmBasic\Res\MbGui.asm ; no GuiParas, no GuiMenu: defaults will be used
SetGlobals lastkey ; define a global variable

Event Key ; returns VKey, e.g. VK_A, VK_DOWN, ...
  mov lastkey, VKey
  If_ VKey==VK_F1 Then call You_Hit_F1
  GuiRefresh ; force a Paint event

Event Paint ; returns PtDC (=esi)
  invoke TextOut, PtDC, 20, 20, chr$("size the window or press a key to see how the ticks change"), 58
  invoke TextOut, PtDC, 20, 50, str$(rv(GetTickCount)), 10 ; str$ is a standard Masm32 macro; length 10 is guessed
  GuiText 20, 80, Str$("The last key was %i ", lastkey)         ; the GuiText macro provides more features then TextOut
  GuiText 150, 80, Chr$(" or rather: ", lastkey, " ") ; display the char pressed (may not work for special keys)
EndOfEvents ; put user procs below this line

You_Hit_F1:
  MsgBox 0, "No help, sorry...", "Hi", MB_OK
  ret
GuiEnd


When the user presses any key, the key event is triggered; if the key happens to be F1, an "external" routine placed after the events but before the end of the program (GuiEnd) is called.

During Event Key, the variable VKey (internally: edi), plus the booleans KeyCtrl, KeyAlt and KeyShift are available for the coder to decide any specific action, such as calling You_Hit_F1.

In the example above, the Paint event is being used to display the current ticks and the last pressed key, using both the standard Windows API TextOut and the GuiText macro.

jj2007

Example #3 creates a window with a listbox and a richedit control that accepts dropped files and displays their content:
GuiParas equ "Dropping files is simple"
include \masm32\MasmBasic\Res\MbGui.asm

  GuiControl FilesBox, "listbox", w=200, x1000-175, +WS_BORDER
  GuiControl Content, "richedit", w=800

Event DropFiles
  SetListbox Files$()
  wMsgBox 0, wCat$(wStr$("%i files dropped, first one is\n[", Files$(?))+wRec$(Files$(0))+"], last one is "+CrLf$+"["+wRec$(Files$(Files$(?)-1))+"]"), "Event Dropfiles:", MB_OK or MB_TOPMOST

Event Notify
  .if NotifyCode==LBN_SELCHANGE
mov ecx, Files$(LbSel) ; get the name of the selected file
SetWin$ hContent=FileRead$(ecx) ; put its content into the richedit control
  .endif
GuiEnd


As the screenshot demonstrates, Unicode file names are no problem.

Attached is a single source with all examples. Open in RichMasm, select GuiParas and hit F6 to build them.

hutch--

Its an old terminology for a UI application that sets up a window, a message loop to dispatch system messages and a message processing procedure. The message handling procedure "WndProc" is the gate to manage "events" to which an action (click on a button etc ...) produces an event which you write code to respond to. It is the architecture of Windows 3.0 and later UI code.

The layout of a basic window is an application that sits idling until the system sends it a message to which it can respond. If the system sends a message to a window the message loop activates, passes the message to the WndProc which funnels it to the processing code.

TWell

WndProc was since Windows 1.0 ;)

BlameTroi

Right after structures/pointers (dsects in my world), event-driven programming seemed to be the most difficult thing for new programmers to grasp. "Where's the mainline?"
"God made the integers, all else is the work of man." -- Leopold Kronecker.

jj2007

Quote from: hutch-- on January 28, 2017, 10:44:47 PM
Its an old terminology for a UI application that sets up a window, a message loop to dispatch system messages and a message processing procedure. The message handling procedure "WndProc" is the gate to manage "events" to which an action (click on a button etc ...) produces an event which you write code to respond to. It is the architecture of Windows 3.0 and later UI code

Right. See e.g. Events (Visual Basic) of July 2015. Why it has to be so horribly complicated in VB, no idea. Micros**t 8)

GuiParas equ "Key events only", x50, y50, w100, h60, s0
include \masm32\MasmBasic\Res\MbGui.asm

GuiControl MyStatic, "static"

Event Key
  mov esi, VKey
  SetWin$ hMyStatic=Chr$("You pressed ", esi)
GuiEnd

jj2007

New beta version of the Gui** macros attached, replacing \Masm32\MasmBasic\Res\MbGui.asm
Building the attached SkelGuiGroup.asc requires a) the new macros and b) a current MasmBasic installation, i.e. version 19 December 2017 or later.

Tested so far on Win7-64, it looks OK. I know the colours can cause eye cancer, but the red & green is meant to check if the margins are OK. Grateful for feedback on other systems, especially fonts, margins, behaviour when resizing etc...

The timer event shows the current time with millisecond precision. Check with Task Manager if that causes a high cpu usage.

hutch--

Looks fine here on my Win10 Pro. I don't mind the colours, in small areas is looks fine. One whinge, put a manifest in the resources, gives you the later appearance and gives crappy AV scanners less reason to squark about your exe.

Siekmanski

Works perfect on Win 8.1, smoothly resizing the windows and fonts are perfect too.
Task manager shows 0.0% cpu load.
Creative coders use backward thinking techniques as a strategy.

LiaoMi

Hi,

if you type a string with a space, then the selection of the full line doesnt work, only a part before the space is selected. Maybe it was so programmed, the rest works  :t

jj2007

#11
Thanks, Marinus :icon14:

Quote from: hutch-- on December 21, 2017, 07:54:17 AMput a manifest in the resources, gives you the later appearance

Can you see any difference?? The progressbar behaves differently, see attachment, but the rest looks identical to me ::)

Quote from: LiaoMi on December 21, 2017, 10:59:51 AMif you type a string with a space, then the selection of the full line doesnt work, only a part before the space is selected.

I tried that now, but if I click left of the string, the whole line gets selected. No such problem here, or do you mean something else?

One thing that puzzles me is the look of the progressbar. With manifest (version 6.16), it has always the PBS_SMOOTH look, whether the style is specified or not ::)

hutch--

>  it has always the PBS_SMOOTH look, whether the style is specified or not

You can thank Microsoft for this loss of choice. I prefer the later one but its typical Microsoft.

jj2007

#13
Quote from: hutch-- on December 21, 2017, 01:56:57 PM
>  it has always the PBS_SMOOTH look, whether the style is specified or not

You can thank Microsoft for this loss of choice. I prefer the later one but its typical Microsoft.

The old 'blocky' progressbar is somewhat clearer - if it advances, you recognise immediately what it is. But you are right that choices are really limited here. What did you mean with "newer look & feel"? Even with a Win7 manifest, I can't see a difference on Win7, while a test on Win10 shows tiny differences:
- the reset button changes colour when hovering over it
- same for the MsgBox OK button (press 'A' to see it)
- the progressbar is green and continuous

I vaguely remember that I once saw MsgBox buttons that had a gradient fill, but no idea how to arrive there :(

P.S.: I found the culprit - apparently the newer styles are visible in Win7 only when you enable that ugly "Aero" thing!
See How To Get Windows 7 Look For Controls? and the messy MSDN article Enabling Visual Styles.

jj2007

New version attached, including a date & time picker and a trackbar. Code is now a whopping 75 lines long ;-)