flat assembler
Message board for the users of flat assembler.

Index > Windows > [HELP] Problem with SendMessage to Edit Control

Author
Thread Post new topic Reply to topic
ctl3d32



Joined: 30 Dec 2009
Posts: 206
Location: Brazil
ctl3d32 07 Jan 2012, 11:16
Hi!

I'm trying to sum the numbers from a multiline edit control, but SendMessage returns wrong string.

Example of input values:
12.3
10.01

The second time i click the 'sum' button, SendMessage returns 12.31 for the first string. Any idea?

Thanks,
ctl3d32
Code:
format PE GUI 4.0
entry start

include 'win32ax.inc'

IDC_EDT1 = 1001
IDC_EDT2 = 1002
IDC_BTN1 = 1003
IDC_BTN2 = 1004

section '.text' code readable executable

  start:
        invoke  GetModuleHandle,0
        mov     [wc.hInstance],eax
        invoke  LoadIcon,0,IDI_APPLICATION
        mov     [wc.hIcon],eax
        invoke  LoadCursor,0,IDC_ARROW
        mov     [wc.hCursor],eax
        invoke  RegisterClass,wc
        test    eax,eax
        jz      error

        invoke  CreateWindowEx,WS_EX_DLGMODALFRAME,\
                               _class,\
                               _title,\
                               WS_VISIBLE+WS_CAPTION+WS_MINIMIZEBOX+WS_SYSMENU,\
                               128,\
                               128,\
                               256,\
                               400,\
                               NULL,\
                               NULL,\
                               [wc.hInstance],\
                               NULL
        test    eax,eax
        jz      error

  msg_loop:
        invoke  GetMessage,msg,NULL,0,0
        cmp     eax,1
        jb      end_loop
        jne     msg_loop
        invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
        jmp     msg_loop

  error:
        invoke  MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK

  end_loop:
        invoke  ExitProcess,[msg.wParam]

;default window processing function
proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam
        cmp     [wmsg],WM_DESTROY
        je      .wmdestroy
        cmp     [wmsg],WM_CREATE
        je      .wmcreate
        cmp     [wmsg],WM_COMMAND
        je      .wmcommand

  .defwndproc:
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
        jmp     .finish

  .wmcreate:
        ;create edit control for bills
        invoke  CreateWindowEx,WS_EX_CLIENTEDGE,\
                               EditClass,\
                               NULL,\
                               WS_CHILD+WS_VISIBLE+WS_TABSTOP+ES_RIGHT+ES_MULTILINE+ES_WANTRETURN,\
                               20,\
                               30,\
                               60,\
                               76,\
                               [hwnd],\
                               IDC_EDT1,\
                               [wc.hInstance],\
                               NULL
        test    eax,eax
        jz      error
        mov     [hEdit1],eax
        invoke  SetFocus,eax

        ;create button control to calculate the sum
        invoke  CreateWindowEx,WS_EX_CLIENTEDGE,\
                               ButtonClass,\
                               szBtnSoma,\
                               WS_CHILD+WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON,\
                               20,\
                               114,\
                               60,\
                               40,\
                               [hwnd],\
                               IDC_BTN1,\
                               [wc.hInstance],\
                               NULL
        test    eax,eax
        jz      error
        mov     [hBtn1],eax

        ;create edit control for sum
        invoke  CreateWindowEx,WS_EX_CLIENTEDGE,\
                               EditClass,\
                               NULL,\
                               WS_CHILD+WS_VISIBLE+WS_TABSTOP+ES_RIGHT+ES_MULTILINE+ES_WANTRETURN,\
                               20,\
                               174,\
                               60,\
                               76,\
                               [hwnd],\
                               IDC_EDT2,\
                               [wc.hInstance],\
                               NULL
        test    eax,eax
        jz      error
        mov     [hEdit2],eax

        ;subclass the edit control
        invoke  SetWindowLong,[hEdit1],GWL_WNDPROC,NewEditWndProc
        mov     [OldWndProc],eax

        ;set focus on edit control
        invoke  SetFocus,[hEdit1]

        xor     eax,eax
        jmp     .finish

  .wmcommand:
        cmp     [wparam],BN_CLICKED shl 16 + IDC_BTN1
        je      .btn1
        jmp     .finish
      .btn1:
        ;get number of lines
        ;invoke  SendMessage,[hEdit1],EM_GETLINECOUNT,[wparam],[lparam]
        ;mov     [lcount],eax

        ;initialization
        fldz
        fstp    qword[total]
        mov     [count],0

      @@:
        ;clear the buffer
        invoke  RtlZeroMemory,buff,10d

        ;get text of each line
        mov     [buff],9d
        invoke  SendMessage,[hEdit1],EM_GETLINE,[count],buff
        test    eax,eax
        je      .endsum

        ;convert text to number and add to the total
        cinvoke atof,buff
        fld     qword[total]
        faddp   st1,st0
        fstp    qword[total]
        inc     [count]
        jmp     @b

      .endsum:
        ;convet total to string and send to the edit control
        invoke  RtlZeroMemory,buff,10d
        invoke  sprintf,buff,fmt,double[total]
        invoke  SetWindowText,[hEdit2],buff
        jmp     .finish
        jmp     .finish

  .wmdestroy:
        invoke  PostQuitMessage,0
        xor     eax,eax

  .finish:
        ret
endp

;edit control subclass proc
proc NewEditWndProc hedit,msg,wparam,lparam
        cmp     [msg],WM_CHAR
        je      .wmchar

      .defwndproc:
        invoke  CallWindowProc,[OldWndProc],[hedit],[msg],[wparam],[lparam]

      .exit:
        ret

  .wmchar:
        mov     eax,[wparam]
        cmp     al,0x08 ;backspace
        je      .defwndproc
        cmp     al,0x09 ;tab
        je      .defwndproc
        cmp     al,0x0A ;linefeed
        je      .defwndproc
        cmp     al,0x0D ;carriage return
        je      .defwndproc
        cmp     al,'.'  ;decimal
        je      .defwndproc
        cmp     al,','
        jne     @f
        mov     al,'.'
        mov     [wparam],eax
        jmp     .defwndproc

      @@:
        cmp     al,'0'
        jb      .exit
        cmp     al,'9'
        jg      .exit
        jmp     .defwndproc
endp

section '.data' data readable writeable

  _class       db 'FASMWIN32',0
  _title       db 'Win32 program template',0
  _error       db 'Startup failed.',0
  EditClass    db 'EDIT',0
  ButtonClass  db 'BUTTON',0
  szBtnSoma    db 'Sum',0
  fmt          db '%.2f',0

  hBtn1        dd 0
  hEdit1       dd 0
  hEdit2       dd 0
  OldWndProc   dd 0

  idEdit1      dd 0

  buff         rb 10

  total        dq 0
  count        dd 0

  wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class

  msg MSG

section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL',\
          msvcrt32,'msvcrt.dll'

  import  msvcrt32,\
          atof,'atof',\
          sprintf,'sprintf'

  include 'api\kernel32.inc'
  include 'api\user32.inc'
    


Last edited by ctl3d32 on 07 Jan 2012, 13:15; edited 1 time in total
Post 07 Jan 2012, 11:16
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1619
Location: Toronto, Canada
AsmGuru62 07 Jan 2012, 12:36
Works fine -- no matter how many clicks on "Sum" I do.

If you mean EM_GETLINE -- it does not put zero at the end of returned text, so before each message you need to zero out the whole line buffer.

See Remarks here:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb761584(v=vs.85).aspx


Last edited by AsmGuru62 on 07 Jan 2012, 12:42; edited 3 times in total
Post 07 Jan 2012, 12:36
View user's profile Send private message Send e-mail Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 07 Jan 2012, 12:39
Yes, I confirm. I haven't observed any problems with your application, see the screenshot:

Image
Post 07 Jan 2012, 12:39
View user's profile Send private message Visit poster's website Reply with quote
ctl3d32



Joined: 30 Dec 2009
Posts: 206
Location: Brazil
ctl3d32 07 Jan 2012, 13:13
This is very strange.
I keep getting this error.

Watch this screencast i made: http://www.youtube.com/watch?feature=player_detailpage&list=ULuyRNFEuVBdE&v=uyRNFEuVBdE

Thanks
Post 07 Jan 2012, 13:13
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 07 Jan 2012, 13:38
Are you sure that you have posted here the same version of your program as the tested one? Sometimes such a qui pro quo may happen when you're coding all day long. Wink

Another thing, could it be possible that there's something wrong with your FPU? Rolling Eyes Overheat or something like that (just guessing)...
Post 07 Jan 2012, 13:38
View user's profile Send private message Visit poster's website Reply with quote
ctl3d32



Joined: 30 Dec 2009
Posts: 206
Location: Brazil
ctl3d32 07 Jan 2012, 13:59
MHajduk wrote:
Are you sure that you have posted here the same version of your program as the tested one? Sometimes such a qui pro quo may happen when you're coding all day long. Wink

Another thing, could it be possible that there's something wrong with your FPU? Rolling Eyes Overheat or something like that (just guessing)...


I were using the same version.

Placing a Null terminating char at the end of the returned string fixed the problem:
Code:
;get text of each line
        mov     word[buff],9d
        invoke  SendMessage,[hEdit1],EM_GETLINE,[count],buff
        test    eax,eax
        je      .endsum

        ;null terminate the string
        mov     byte[buff+eax],0 
    


The problem is that SendMessage was returning not only the string, but other bytes too. See this olly dump (buff address):
Code:
1st run:

Read 1st line:

CPU Dump
Address   Hex dump                                         ASCII
0040205A  31 32 2E 33|06 07 AD 77|00 00                    12.3­w

Read 2nd line:

CPU Dump
Address   Hex dump                                         ASCII
0040205A  31 30 2E 30|31 07 AD 77|00 00                    10.01­w

2nd run:


Read 1st line:

CPU Dump
Address   Hex dump                                         ASCII
0040205A  31 32 2E 33|00 00 00 00|00 00                    12.3


Read 2nd line:

CPU Dump
Address   Hex dump                                         ASCII
0040205A  31 30 2E 30|31 00 00 00|00 00                    10.01

3rd Run:

Read 1st line:

CPU Dump
Address   Hex dump                                         ASCII
0040205A  31 32 2E 33|31 00 00 00|00 00                    12.31

Read 2nd line:

CPU Dump
Address   Hex dump                                         ASCII
0040205A  31 30 2E 30|31 00 00 00|00 00                    10.01
    


Thanks


Last edited by ctl3d32 on 07 Jan 2012, 14:22; edited 1 time in total
Post 07 Jan 2012, 13:59
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 07 Jan 2012, 14:04
Yes, but from the other hand this doesn't explain why we haven't observed this strange behavior - we should see the same, at least from time to time. Wink
Post 07 Jan 2012, 14:04
View user's profile Send private message Visit poster's website Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 07 Jan 2012, 15:31
I've checked carefully your program execution under Olly and still haven't seen anything strange. There is no suspicious behavior of 'RtlZeroMemory' and 'SendMessage' functions - buffer isn't "polluted" by any unneeded chars.

My guess is that the same API functions may behave differently when their realization depends on the Windows version - this is the most rational explanation of this fact I can find for now.

I think we all have to pay more attention to the more strict control on what is going on in our programs - API functions seem to be unpredictable. Even checking the return codes isn't enough as we can see in the aforementioned example.
Post 07 Jan 2012, 15:31
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.