News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

new to asm (simple question)

Started by Troy Lundin, June 03, 2006, 10:33:24 AM

Previous topic - Next topic

Troy Lundin

I am a vb programmer and am trying to get into asm. I have some code put together but cannot figure out one thing.
How do I detect events? Like a button is clicked or the check state of a checkbox.
My form only has two buttons and three checkboxes.
I need to detect when the check state of a checkbox has changed and what the current state is. Also I need to detect when a button is clicked.

Thank you.

Shantanu Gadgil

Wow! Short question, long answer possible.  :P But...how to explain this simply...ok...here goes...things happen differently in VB, i.e. if you are using assembly, you would work with window handles and the messages that would be received, sent, etc rather than the way it behaves in VB.

This being said, there is no one line answer to your question!!!  :P (Is there ever?) Iczelion tutorials would be the correct place to start as to how to code in Win32 assembly.

Some time in the tutorials you would be working with buttons...and there is where the solution to your question lies. But I would say...start with the tutorials...and all shall be revealed!!! :)  :lol :lol
To ret is human, to jmp divine!

dsouza123

If your main window is a dialogbox here is an example with two buttons.


; #########################################################################

      .386
      .model flat, stdcall
      option casemap :none   ; case sensitive

; #########################################################################

      include \masm32\include\windows.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc

      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib

; #########################################################################

    ;=================
    ; Local prototypes
    ;=================
    DlgProc    PROTO :DWORD,:DWORD,:DWORD,:DWORD

.data
    dlgname       db "DLG0",0
    hInstance     dd 0
    hProcess      dd 0
    hIcon         dd 0
    szTitle0      db "The MessageBox Title",0
    szMsg0        db "You clicked on the CALC button.",0

.const
    IDC_BUTTON0  equ    3000
    IDC_BUTTON1  equ    3001
    EXAMPLE      equ    4001

.code

start:

; #########################################################################

        invoke GetModuleHandle, NULL
        mov    hInstance, eax

        ; -------------------------------------------
        ; Call the dialog box stored in resource file
        ; -------------------------------------------
        invoke DialogBoxParam,hInstance,ADDR dlgname,0,ADDR DlgProc,NULL

        invoke ExitProcess,eax

; #########################################################################

DlgProc proc hWin   :DWORD,
             uMsg   :DWORD,
             wParam :DWORD,
             lParam :DWORD

      .if uMsg == WM_INITDIALOG
         invoke LoadIcon,hInstance,EXAMPLE
         mov hIcon, eax
         invoke SendMessage,hWin,WM_SETICON,1,hIcon

      .elseif uMsg==WM_COMMAND
        mov  eax,wParam
        mov  edx,eax
        shr  edx,16
  .if dx==BN_CLICKED
.if eax==IDC_BUTTON0        ; the CALC button clicked now do stuff
                   nop
                   invoke MessageBox, NULL,addr szMsg0, addr szTitle0, MB_OK

.elseif eax==IDC_BUTTON1    ; the EXIT button will be an EXIT
   invoke SendMessage,hWin,WM_CLOSE,NULL,NULL

.endif
        .endif

      .elseif uMsg == WM_CLOSE
        invoke EndDialog,hWin,0

      .endif

    xor eax, eax
    ret

DlgProc endp

; ########################################################################

end start



and the resource file  rsrc.inc


// constants for dialog box
#define IDC_BUTTON0    3000
#define IDC_BUTTON1    3001
#define EXAMPLE        4001

#define DS_MODALFRAME       0x80L
#define DS_3DLOOK           0x0004L
#define DS_CENTER           0x0800L
#define WS_CAPTION          0xC00000L
#define WS_SYSMENU          0x00080000L
#define WS_VISIBLE          0x10000000L
#define WS_POPUP            0x80000000L

#define SS_ICON             0x00000003L

EXAMPLE ICON MOVEABLE PURE LOADONCALL DISCARDABLE "Example.ico"

DLG0 DIALOGEX MOVEABLE IMPURE LOADONCALL DISCARDABLE 10, 10, 256, 128, 0
STYLE DS_MODALFRAME | DS_3DLOOK  | DS_CENTER  |
      WS_CAPTION    | WS_SYSMENU | WS_VISIBLE | WS_POPUP
CAPTION "Example"
FONT 8, "MS Sans Serif", 700, 0 /*FALSE*/
BEGIN
    DEFPUSHBUTTON   "CALC",                     IDC_BUTTON0, 180, 7, 41,12, 0, , 0
    PUSHBUTTON      "EXIT",                     IDC_BUTTON1, 180,21, 41,12, 0, , 0
END

[attachment deleted by admin]

hutch--

Troy,

If you can slightly rewire your head for this stuff, a VB "event" can usually be translated to processing a message in a normal win32 program which is what you write in assembler. In any win32 program, you have a seperate procedure that the OS send messages to which is normally called a WndProc() and it is here that you respond to messages that are sent to the window that has this WndProc.

To proerly get this stuff you need to understand some basic win32 architecture which is a message driven windowing system but once you get some basics, you can translate the concepts of much of VB to the matching win32 messaging system. It sounds messy and it can look a bit that way while you are learning this stuff but its basics are reasonably straight forwarde once you understand the architecture properly.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Mark Jones

Quote from: dsouza123 on June 03, 2006, 11:56:58 AM
      .elseif uMsg==WM_COMMAND
        mov  eax,wParam
        mov  edx,eax
        shr  edx,16
     .if dx==BN_CLICKED
      .if eax==IDC_BUTTON0        ; the CALC button clicked now do stuff
                   nop
                   invoke MessageBox, NULL,addr szMsg0, addr szTitle0, MB_OK

      .elseif eax==IDC_BUTTON1    ; the EXIT button will be an EXIT
         invoke SendMessage,hWin,WM_CLOSE,NULL,NULL

      .endif
        .endif

Hi Troy, welcome to the group! :bg

Along with what Hutch said, the above is the meat-and-potatoes of how windows control messages are parsed. To help explain it a little, every window has a WndProc() and any time you click (or even move the mouse over a window) Windows sends that procedure various immediate "messages" such as mouse cursor position, mouse button state, etc. Windows also sends messages autonomously such as shutdown and hibernate, etc. The point is that when it comes to intercepting clicks or state changes in your app, this is done inside the WndProc. (This is assuming you are writing a GUI app... it is possible to build console-mode apps which do not have a WndProc and behave quite differenty.)

Some great resources for you to persue would be the Iczelion tutorials and searching the WIN32.HLP file (guised as "Extended Win32 API Reference and CNT Files", thanks Ghirai!) :U In there search for WM_COMMAND and SendMessage to get started.
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

Ossa

I wrote a small tutorial (not especially brilliant IMHO) as a "quick and dirty" way to get to ASM from an HLL. Some people liked it though... I'm currently redoing my website (and the DNS entry only went in yesterday for the new location)... but it is here: http://ossa.the-wot.co.uk/tutorial_asm1_tex.htm

It only covers the very basics, but it might be good to read alongside Iczelion's tutorials.

Don't know whether it will help at all, but as I said, some people liked it.

Ossa
Website (very old): ossa.the-wot.co.uk

dsouza123

The example modified, now with two buttons and a checkbox.

[attachment deleted by admin]

Troy Lundin

Thank you all for your help. I took at look at those tuts the other day and I thought "wow, i am never going to learn this" then I remembered I thought the same thing when learning vb and html. So i'll keep poking at it.

Congrats on such a comfortable forum.

Enjoy!

Troy Lundin

Ok so I am still having some troubles. I have the following code.

DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

   mov eax,uMsg
   .if eax==WM_INITDIALOG

   .elseif eax==WM_COMMAND
      mov  eax,wParam
        mov  edx,eax
        shr  edx,16
        .if BN_CLICKED
           .if eax==chkTurns
              invoke SendMessage, 0, BM_GETCHECK, 0, 0
              .if ( eax!=0 )
              invoke MessageBox,0,'rew','ret',MB_OK
                 ;invoke Poke,aTurns,uTurns, 3
              .else
                 ;invoke Poke,aTurns,nopit, 3
              .endif
           .endif
        .endif
   .elseif eax==WM_CLOSE
      invoke EndDialog,hWin,0
   .else
      mov      eax,FALSE
      ret
   .endif
   mov      eax,TRUE
   ret

DlgProc endp

and the following declaration:

DlgProc         PROTO   :HWND,:UINT,:WPARAM,:LPARAM


Now, my problem is the messagebox will not show whether the checkbox (chkTurns) is checked or not. Any suggestions?
Also, I do have the checkbox declared like so: chkTurns   equ 1001


Thanks.

dsouza123

invoke MessageBox,0,'rew','ret',MB_OK

should be

invoke MessageBox,0,addr rew,addr ret,MB_OK

with
.data
  rew db "rew",0
  ret  db "ret",0

invoke MessageBox is expecting addresses (pointers) of zero terminated strings
for the message and caption.

Troy Lundin

Is there a way to invoke MessageBox and use strings as arguments? Or do they have to be predefined?

EDIT: I tried your suggestion and I still cannot get it to work. Would you like me to post my project?

hutch--

Troy,

Yes, masm32 has a set of macros that will do this for you.


fn MessageBox,hWnd,"Text Message","Title",MB_OK


The macro put the text into the .DATA section.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Troy Lundin

hmmm...this is getting frustrating.

This is what I have.

   .if eax==WM_INITDIALOG
         invoke  GetDlgItem,hWin,chkTurns  ; CheckBox0
         mov hChkTurns, eax
   .elseif eax==WM_COMMAND
      mov  eax,wParam
        mov  edx,eax
        shr  edx,16
        .if dx==BN_CLICKED
           .if eax==chkTurns
              invoke SendMessage, hChkTurns, BM_GETCHECK, 0, 0
              .if ( eax!=0 )
                 invoke MessageBox,0,addr rew,addr rew,MB_OK
                 ;invoke Poke,aTurns,uTurns, 3
              .endif
           .endif
        .endif
   .elseif eax==WM_CLOSE
      invoke EndDialog,hWin,0
   .endif
   xor eax,eax
   ret

That is my entire DlgProc procedure. It gives an error on the bold line. It gives no description just the error number A2001.
chkTurns is declared (chkTurns equ 1001), hChkTurns is declared (hChkTurns equ 0)

I have no idea what is wrong. Also, where can I find out what the error numbers mean? I am using RadASM with MASM.
Thank you.

Ossa

Error numbers: http://msdn2.microsoft.com/en-us/library/6kzwh998(VS.80).aspx

You can also use MASM Error Lookup Tool a.k.a. MELT (can't remember where I downloaded it from - but it was about 5 years ago that I got it).

You are trying to move eax into an equate or immediate value:

mov 1001, eax

You must define chkTurns differently:

chkTurns dd ?

in the .data? (or .data) section.

Ossa
Website (very old): ossa.the-wot.co.uk

Ossa

Anyway, here is MELT after googling: http://members.tripod.com/semper.fi/melt/index.htm

If you have further problems, it might be better to post your full source (or a stripped down version if you want to keep any of it private, etc) in a zip.

Ossa
Website (very old): ossa.the-wot.co.uk