Author Topic: character values?  (Read 12089 times)

jannes braet

  • Guest
character values?
« on: June 19, 2012, 01:49:13 AM »
hello everyone,
i have made a code but it doesn't quite work as expected. so the main intention of the program is to output  the x-coordinate if you click after pressing 1,to output the y-coordinate if you click after pressing 2 and both after pressing 3.
if none of these keys was pressed it should output press 1,2 or 3.
this is the code i have now:
i have chosen the values for 1,2 and 3 with an ascii table but i'm not sure if it is the same for asm. i believe it is since 20h in ascii is also space.

Code: [Select]
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

.IF uMsg==WM_DESTROY
        invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_CHAR
push wParam
pop char ;char starts with value of 20h (=space)
.ELSEIF uMsg==WM_LBUTTONDOWN
mov eax,lParam
and eax,0FFFFh
mov hitpoint.x,eax
mov eax,lParam
shr eax,16
mov hitpoint.y,eax
mov MouseClick,TRUE
invoke InvalidateRect,hWnd,NULL,TRUE
.ELSEIF uMsg==WM_PAINT
invoke BeginPaint,hWnd,ADDR ps
mov hdc,eax
invoke CreateFont,24,16,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT,ADDR FontName
invoke SelectObject,hdc,eax
mov hfont,eax
.IF char==31h ;1
invoke TextOut,hdc,hitpoint.x,hitpoint.y,hitpoint.x,SIZEOF hitpoint.x
.ELSEIF char==32h;2
invoke TextOut,hdc,hitpoint.x,hitpoint.y,hitpoint.y,SIZEOF hitpoint.y
.ELSEIF char==33h ;3
invoke lstrlen,ADDR hitpoint
invoke TextOut,hdc,hitpoint.x,hitpoint.y,ADDR hitpoint,eax
.ELSE
invoke TextOut,hdc,hitpoint.x,hitpoint.y,ADDR text,SIZEOF text ;press 1,2 or 3
.ENDIF
        invoke SelectObject,hdc,hfont
invoke EndPaint,hWnd,ADDR ps
.ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
    .ENDIF
the output i get is always press 1,2 or 3
so could someone tell me what i am doing wrong?

dedndave

  • Member
  • *****
  • Posts: 8828
  • Still using Abacus 2.0
    • DednDave
Re: character values?
« Reply #1 on: June 19, 2012, 02:15:09 AM »
you will probably want to reboot   :P

you create a new font every time your window gets a WM_PAINT message
better to create a font in WM_CREATE and save the handle in a var like hFont
then, use DeleteObject in WM_DESTROY to delete the hFont
these are GDI objects, and the system only has so much space allocated for them
the way your program is currently written, as you run it more times, the system will act screwier   :biggrin:

as for it not working...
i would construct a string in a buffer when mouse buttons are pressed
when the string changes, use InvalidateRect and UpdateWindow to force an update
then, in WM_PAINT, all you have to do is select hFont and display the string

jannes braet

  • Guest
Re: character values?
« Reply #2 on: June 20, 2012, 02:03:45 AM »
after following your tips i have something like this now but i'm not sure on how to work with a buffer. so can someone explain me that ? or how to store data in a buffer. and i'm also not sure on the way i display my data.
Code: [Select]
.data?
buffer db 512 dup(?)
...
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hdc:HDC
LOCAL ps:PAINTSTRUCT
LOCAL hfont:HFONT

    .IF uMsg==WM_DESTROY
invoke DeleteObject,hfont
invoke EndPaint,hWnd,ADDR ps
        invoke PostQuitMessage,NULL
.ELSEIF uMsg=WM_CREATE
invoke BeginPaint,hWnd,ADDR ps
mov hdc,eax
invoke CreateFont,24,16,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT,ADDR FontName
invoke SelectObject,hdc,eax
mov hfont,eax
    .ELSEIF uMsg==WM_COMMAND
        mov eax,wParam
        .IF ax==IDM_TEST
            invoke MessageBox,NULL,ADDR Test_string,OFFSET AppName,MB_OK
        .ELSEIF ax==IDM_HELLO
            invoke MessageBox, NULL,ADDR Hello_string, OFFSET AppName,MB_OK
        .ELSEIF ax==IDM_GOODBYE
            invoke MessageBox,NULL,ADDR Goodbye_string, OFFSET AppName, MB_OK
        .ELSE
            invoke DestroyWindow,hWnd
        .ENDIF
.ELSEIF uMsg==WM_CHAR
push wParam
pop char
.ELSEIF uMsg==WM_LBUTTONDOWN
mov eax,lParam
and eax,0FFFFh
mov hitpoint.x,eax
mov eax,lParam
shr eax,16
mov hitpoint.y,eax
mov MouseClick,TRUE
invoke InvalidateRect,hWnd,NULL,TRUE
.ELSEIF uMsg==WM_PAINT
.IF char==31h ;1
invoke lstrlen,ADDR buffer
invoke TextOut,hdc,hitpoint.x,hitpoint.y,ADDR buffer,eax
.ELSEIF char==32h;2
invoke lstrlen,ADDR buffer
invoke TextOut,hdc,hitpoint.x,hitpoint.y,ADDR buffer,eax
.ELSEIF char==33h ;3
invoke lstrlen,ADDR buffer
invoke TextOut,hdc,hitpoint.x,hitpoint.y,ADDR buffer,eax
.ELSE
invoke lstrlen,ADDR buffer
invoke TextOut,hdc,hitpoint.x,hitpoint.y,ADDR buffer,eax
.ENDIF
.ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
    .ENDIF
    xor    eax,eax
    ret
WndProc endp
« Last Edit: June 20, 2012, 03:15:41 AM by jannes braet »

dedndave

  • Member
  • *****
  • Posts: 8828
  • Still using Abacus 2.0
    • DednDave
Re: character values?
« Reply #3 on: June 20, 2012, 03:57:24 AM »
ouch !

BeginPaint should not be in WM_CREATE
EndPaint should not be in WM_DESTROY
put them back in WM_PAINT

i assume you want to display the string at the same location each time
let's use the upper left corner of the client area - not the hitpoint   :P

to handle the buffer, you need to convert the binary values into ASCII strings and place them in the buffer

EDIT: code removed (syntax errors) - see attachment below
« Last Edit: June 20, 2012, 07:47:32 AM by dedndave »

dedndave

  • Member
  • *****
  • Posts: 8828
  • Still using Abacus 2.0
    • DednDave
Re: character values?
« Reply #4 on: June 20, 2012, 07:48:59 AM »
ok - i played with it a little bit   :P

keys 0 to 3 work (0 turns both off)

jannes braet

  • Guest
Re: character values?
« Reply #5 on: June 20, 2012, 07:46:08 PM »
thank you very much i will take a look at these codes and i hope i will learn alot from it ;p
but one thing i was wondering is how did you make your own icon and how did you add it to the program?

dedndave

  • Member
  • *****
  • Posts: 8828
  • Still using Abacus 2.0
    • DednDave
Re: character values?
« Reply #6 on: June 20, 2012, 08:02:28 PM »
there are a number of free icon editors out there
but, i use Axialis IconWorkshop, which is not free
http://speckyboy.com/2008/05/03/top-5-free-icon-editors-for-the-pro-designer/
http://filehippo.com/download_icofx/

to add the icon to the program, you add it to the resource file
in this case, it's named SmallWin.rc - a text file that can open with NotePad
Code: [Select]
#define  IDI_ICON               501

IDI_ICON  ICON  DISCARDABLE  "SmallWin.ico"
look at the batch files to see how the resource file is added to the program

then, in the SmallWin.inc file...
Code: [Select]
IDI_ICON    EQU 501and in the program...
Code: [Select]
        INVOKE  LoadIcon,hInstance,IDI_ICONLoadIcon returns a handle that may be used in the WNDCLASSEX.hIcon and hIconSm members
(when the window class is registered)
LoadImage can also be used
another way to set a window icon is to send it a WM_SETICON message
Code: [Select]
        INVOKE  SendMessage,hWnd,WM_SETICON,ICON_BIG,hIcon
        INVOKE  SendMessage,hWnd,WM_SETICON,ICON_SMALL,hIcon
ICON_BIG is used when icon view is used in explorer (and other places) (32x32)
ICON_SMALL is used in the window title bar (and other places) (16x16)
if you send the message in WM_CREATE of the same window, use PostMessage

i usually try to make them 16-color icons, but 256-color is ok, too
more colors than that is silly for such a small image - and it makes for larger files

jannes braet

  • Guest
Re: character values?
« Reply #7 on: June 20, 2012, 08:21:48 PM »
uhm can you tell me what the intention of the copystring is and what is that ustr$(eax) ?

dedndave

  • Member
  • *****
  • Posts: 8828
  • Still using Abacus 2.0
    • DednDave
Re: character values?
« Reply #8 on: June 20, 2012, 08:35:06 PM »
well - it's just a little subroutine to fill the buffer with ASCII decimal numbers and/or spaces
it always sets 11 characters into the buffer
the buffer is 22 characters long (11 for X, 11 for Y)

ustr$ is a macro in the masm32 package for converting unsigned binary values to ASCII decimal
i probably should have used str$ - for signed values
but...
Code: [Select]
        mov     eax,str$(eax)doesn't work
this would probably work
Code: [Select]
        push    str$(eax)
        pop     eax
the macros are described in \masm32\help\hlhelp.chm
and defined in \masm32\macros\macros.asm

jj2007

  • Member
  • *****
  • Posts: 13957
  • Assembly is fun ;-)
    • MasmBasic
Re: character values?
« Reply #9 on: June 21, 2012, 01:36:55 AM »
this would probably work
Code: [Select]
        push    str$(eax)
        pop     eax

Unfortunately not. You can replace the
      EXITM <ADDR rvstring>
in macros.asm with
      EXITM <OFFSET rvstring>

Otherwise, for geniuses who like it a bit more complicated, here is a workaround :biggrin:

include \masm32\include\masm32rt.inc

mov_eax MACRO arg
ifndef maDummy
   maDummy PROTO :DWORD
   .if 0
      maDummy proc maArg
      mov eax, maArg
      ret
      maDummy endp
   .endif
  endif
   invoke maDummy, arg
   exitm <>
endm


.code
start:   mov eax, 123
   mov_eax(str$(eax))
   MsgBox 0, eax, "Hi", MB_OK
   exit

end start

jannes braet

  • Guest
Re: character values?
« Reply #10 on: June 21, 2012, 01:48:11 AM »
ok i think i get pretty much of the codes you have used now except the 
Code: [Select]
movsx   eax,word ptr lParam and the   
Code: [Select]
movsx  eax,word ptr lParam+2i know movsx adds sign bits to the word but i don't see why we would have to use sign in this case.
and could you also explain what exactly is going on in the copystring. because i know it puts the numbers or spaces in the buffer but i don't see how that is accomplished :s. i'm sorry for asking so much but i'm just new to this.
and why do you use:
Code: [Select]
or esi,esi in the copystring function. if you do that you still have the same number or not?

qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: character values?
« Reply #11 on: June 21, 2012, 02:23:37 AM »
Mouse coordinates can also get negative - you can get wrong positions without the sign extension, if the window has the mouse capture.
The OR reg,reg modifies the flags, thus you can check whether the register is zero (also possible: sign and parity of the low byte).

BTW: the TEST instruction should be used instead of OR, because it discard the redundant result ...

EDIT: typo
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

  • Member
  • *****
  • Posts: 8828
  • Still using Abacus 2.0
    • DednDave
Re: character values?
« Reply #12 on: June 21, 2012, 02:50:55 AM »
The OR reg,reg modifies the registers, thus you can check whether the register is zero (also possible: sign and parity of the low byte).

mainly, i use OR on a register like that to set the sign and zero flags according to the value of the register
after that, you can use JZ/JNZ or JS/JNS
OR'ing a register on itself does not alter its' value

the CopyString11 routine is fairly simple

at the time i wrote it, i knew i was using unsigned numbers
unsigned binary dword's can have a decimal value from 0 to 4294967295 (10 digits max)
so - i made the buffer for each axis 11 characters in size
the X string will always be seperated from the Y string by at least 1 space

i know the mouse will never get to such coordinates - lol
but - i wanted it to work, even if incorrect values got plugged into it

so - we could simply put the numeric digits into the buffer and be done, right ?
not quite
as smaller values are displayed over larger values, the trailing digits would still be displayed
so - i back-fill the remainder of the 11 characters with spaces
this ensures that the old value will be overwritten and only the new value will show

another thing i did in this regard was to use a monospaced font
if you use a true-type font, remnants of previously displayed characters (artifacts) would need to be cleared out

back to the CopyString11 routine...
we pass a source string address (from ustr$ macro) to the copy routine
we simply copy characters until a 0 is encountered, which signifies the end of the string
after that, we pad with spaces until we have filled a total of 11 characters

if the source pointer is 0, we simply fill in 11 spaces

qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: character values?
« Reply #13 on: June 21, 2012, 02:54:48 AM »
The OR reg,reg modifies the registers, thus you can check whether the register is zero (also possible: sign and parity of the low byte).

mainly, i use OR on a register like that to set the sign and zero flags according to the value of the register
after that, you can use JZ/JNZ or JS/JNS
that was a typo - I meant "[...] modifies the flags [...]"  :redface:
MREAL macros - when you need floating point arithmetic while assembling!

jannes braet

  • Guest
Re: character values?
« Reply #14 on: June 21, 2012, 09:34:42 PM »
and what about the?
Code: [Select]
movsx   eax,word ptr lParam