Author Topic: Event-driven programming  (Read 5128 times)

jj2007

  • Member
  • *****
  • Posts: 8503
  • Assembler is fun ;-)
    • MasmBasic
Event-driven programming
« on: January 28, 2017, 08:51:02 PM »
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
Code: [Select]
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

  • Member
  • *****
  • Posts: 8503
  • Assembler is fun ;-)
    • MasmBasic
Event-driven programming
« Reply #1 on: January 28, 2017, 08:53:58 PM »
Example #1 uses simple handlers for the WM_PAINT and WM_KEYDOWN messages:
Code: [Select]
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

  • Member
  • *****
  • Posts: 8503
  • Assembler is fun ;-)
    • MasmBasic
Event-driven programming
« Reply #2 on: January 28, 2017, 09:26:16 PM »
Example #3 creates a window with a listbox and a richedit control that accepts dropped files and displays their content:
Code: [Select]
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--

  • Administrator
  • Member
  • ******
  • Posts: 5472
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Event-driven programming
« Reply #3 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.

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.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

TWell

  • Member
  • ****
  • Posts: 748
Re: Event-driven programming
« Reply #4 on: January 29, 2017, 12:05:20 AM »
WndProc was since Windows 1.0 ;)

BlameTroi

  • Regular Member
  • *
  • Posts: 11
  • Blame me, everyone does
Re: Event-driven programming
« Reply #5 on: January 29, 2017, 12:27:26 AM »
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

  • Member
  • *****
  • Posts: 8503
  • Assembler is fun ;-)
    • MasmBasic
Re: Event-driven programming
« Reply #6 on: January 29, 2017, 02:41:41 AM »
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)

Code: [Select]
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

  • Member
  • *****
  • Posts: 8503
  • Assembler is fun ;-)
    • MasmBasic
Re: Event-driven programming
« Reply #7 on: December 21, 2017, 02:30:50 AM »
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--

  • Administrator
  • Member
  • ******
  • Posts: 5472
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Event-driven programming
« Reply #8 on: December 21, 2017, 07:54:17 AM »
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.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

Siekmanski

  • Member
  • *****
  • Posts: 1548
Re: Event-driven programming
« Reply #9 on: December 21, 2017, 09:15:06 AM »
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 their strategy.

LiaoMi

  • Member
  • **
  • Posts: 242
Re: Event-driven programming
« Reply #10 on: December 21, 2017, 10:59:51 AM »
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

  • Member
  • *****
  • Posts: 8503
  • Assembler is fun ;-)
    • MasmBasic
Re: Event-driven programming
« Reply #11 on: December 21, 2017, 11:16:43 AM »
Thanks, Marinus :icon14:

put 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 ::)

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.

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 ::)
« Last Edit: December 21, 2017, 12:41:36 PM by jj2007 »

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5472
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Event-driven programming
« Reply #12 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.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

jj2007

  • Member
  • *****
  • Posts: 8503
  • Assembler is fun ;-)
    • MasmBasic
Re: Event-driven programming
« Reply #13 on: December 21, 2017, 05:42:19 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.
« Last Edit: December 21, 2017, 07:25:39 PM by jj2007 »

jj2007

  • Member
  • *****
  • Posts: 8503
  • Assembler is fun ;-)
    • MasmBasic
Re: Event-driven programming
« Reply #14 on: December 22, 2017, 07:13:36 AM »
New version attached, including a date & time picker and a trackbar. Code is now a whopping 75 lines long ;-)