Look at this:
invoke SendMessage,,WM_GETTEXT,edx,text
invoke MessageBox,NULL,text,text,MB_OK
That works fine, and displays everything in edithwnd.
But if I do:
invoke SendMessage,,WM_GETTEXT,edx,text
stdcall strdelete,text,2,4
invoke MessageBox,NULL,text,text,MB_OK
This displays the text all wrong and weird. Why does this happen? tmp1 and text are both strings. It doesn't matter if I use stdcall or ccall (cdecl call).
This is the proc for strdelete:
proc strdelete, buf,pos1,pos2
enter
push ebx eax
invoke lstrlen,
mov ebx,eax
add ,0
invoke lstrcpyn,tmp1,,
mov eax, ; eax = pos1
add eax, ; eax += pos2
sub eax,1
add ,eax
invoke lstrcpyn,tmp2,,tmp1
invoke lstrcat,tmp1,tmp2
pop ebx eax
mov eax,tmp1
return
invoke SendMessage,,WM_GETTEXT,edx,text
invoke MessageBox,NULL,text,text,MB_OK
That works fine, and displays everything in edithwnd.
But if I do:
invoke SendMessage,,WM_GETTEXT,edx,text
stdcall strdelete,text,2,4
invoke MessageBox,NULL,text,text,MB_OK
This displays the text all wrong and weird. Why does this happen? tmp1 and text are both strings. It doesn't matter if I use stdcall or ccall (cdecl call).
This is the proc for strdelete:
proc strdelete, buf,pos1,pos2
enter
push ebx eax
invoke lstrlen,
mov ebx,eax
add ,0
invoke lstrcpyn,tmp1,,
mov eax, ; eax = pos1
add eax, ; eax += pos2
sub eax,1
add ,eax
invoke lstrcpyn,tmp2,,tmp1
invoke lstrcat,tmp1,tmp2
pop ebx eax
mov eax,tmp1
return
invoke lstrcpyn,tmp2,,tmp1
First of all I don't know how the push and pop macros work but it looks like the eax and ebx registers are popped in the same order they were pushed.
I think the line above might be your problem. I believe tmp1 is the address of a string buffer but the third paramter to the lstrcpyn function is the number of character to copy.
Thanks, but now I have another problem.
My strcopy proc works perfectly except if I do something like this , it would mess up the text string variable.
invoke SendMessage,,WM_GETTEXTLENGTH,0,0
add eax,1
invoke SendMessage,,WM_GETTEXT,eax,text
stdcall strcopy,text,1,3
invoke MessageBox,NULL,text,"Text",MB_OK
Why does it mess up the text string variable? Now the message box only shows only one character in the edithwnd textbox. When I don't use my strcopy proc, it shows all of the text in edithwnd.
My strcopy proc is:
tmp1 is a string.
proc strcopy, buff,pos1,pos2 ; strcopy,"Hello",2,3 returns "ell"
enter
push eax
mov eax,
sub eax,1
add ,eax
mov eax,
add eax,1
invoke lstrcpyn,tmp1,,eax
pop eax
mov eax,tmp1
return
My strcopy proc works perfectly except if I do something like this , it would mess up the text string variable.
invoke SendMessage,,WM_GETTEXTLENGTH,0,0
add eax,1
invoke SendMessage,,WM_GETTEXT,eax,text
stdcall strcopy,text,1,3
invoke MessageBox,NULL,text,"Text",MB_OK
Why does it mess up the text string variable? Now the message box only shows only one character in the edithwnd textbox. When I don't use my strcopy proc, it shows all of the text in edithwnd.
My strcopy proc is:
tmp1 is a string.
proc strcopy, buff,pos1,pos2 ; strcopy,"Hello",2,3 returns "ell"
enter
push eax
mov eax,
sub eax,1
add ,eax
mov eax,
add eax,1
invoke lstrcpyn,tmp1,,eax
pop eax
mov eax,tmp1
return
add ,eax
This is the only line that modifies the string. It adds to the value in buff the value in eax.
But thats the only way to move the string address by somenumber of bytes, right? I mean I couldn't do invoke lstrcpy,strbuffer,somstring+eax,somenumberofbytes it only works with constant values.
Instead of using the buff you could use a register maybe something like
proc strcopy, buff,pos1,pos2 ; strcopy,"Hello",2,3 returns "ell"
enter
push eax
push esi
mov eax,
mov esi,
sub eax,1
add esi,eax
mov eax,
add eax,1
invoke lstrcpyn,tmp1,esi,eax
pop esi
pop eax
mov eax,tmp1
return
proc strcopy, buff,pos1,pos2 ; strcopy,"Hello",2,3 returns "ell"
enter
push eax
push esi
mov eax,
mov esi,
sub eax,1
add esi,eax
mov eax,
add eax,1
invoke lstrcpyn,tmp1,esi,eax
pop esi
pop eax
mov eax,tmp1
return
I tried it , but for some reason the same thing happens, I don't know why though .
I know its in the proc because this doesn't work
invoke SendMessage,,WM_GETTEXTLENGTH,0,0
add eax,1
invoke SendMessage,,WM_GETTEXT,eax,text
stdcall strcopy,text,1,3
invoke MessageBox,NULL,text,"Text",MB_OK
and this does work
invoke SendMessage,,WM_GETTEXTLENGTH,0,0
add eax,1
invoke SendMessage,,WM_GETTEXT,eax,text
invoke lstrcat,text,"Hello"
invoke MessageBox,NULL,text,"Text",MB_OK
I know its in the proc because this doesn't work
invoke SendMessage,,WM_GETTEXTLENGTH,0,0
add eax,1
invoke SendMessage,,WM_GETTEXT,eax,text
stdcall strcopy,text,1,3
invoke MessageBox,NULL,text,"Text",MB_OK
and this does work
invoke SendMessage,,WM_GETTEXTLENGTH,0,0
add eax,1
invoke SendMessage,,WM_GETTEXT,eax,text
invoke lstrcat,text,"Hello"
invoke MessageBox,NULL,text,"Text",MB_OK
A few things:
1) Pos2 appears to be a length parameter, not a position parameter.
2) You are not terminating the copied string with a zero byte. Adding one to the length adds one more character, which might not be a zero byte.
1) Pos2 appears to be a length parameter, not a position parameter.
2) You are not terminating the copied string with a zero byte. Adding one to the length adds one more character, which might not be a zero byte.
I don't understand. I thought that the problem was that the string you passed to the function was being modified. But I tried your orginal code and the string was not modified.
Thats what I don't understand, why doesn't it work when I use WM_GETTEXT , and I tried to null terminate it with 0 but it didn't work, plus I was display the text variable, not the variable returned by strcopy, I don't understand why it doesn't work in this situtation.
I am confused about what the strcopy is supposed to do. More specifically about the pos1 and pos1 parameters. Is the function supposed to extract the characters between pos1 and pos2 or does it copy pos2 characters starting at index pos1 in the string.
Strcopy works like this strcopy,string,startpos,count
Count meaning the number of characters to the left to be copied. Like
strcopy,"Hello",4,2 ;returns "lo" (the 4th position, 2 characters)
Count meaning the number of characters to the left to be copied. Like
strcopy,"Hello",4,2 ;returns "lo" (the 4th position, 2 characters)
I can't figure out why the function is not working. Maybe you could send a an example program where the function is not working.
Ok, I modified the minipad example to show you the problem:
; Simple text editor - fasm example program
include '%include%\win32ax.inc'
IDM_SHOW = 101
IDM_EXIT = 102
IDM_ABOUT = 901
.data
_class db 'MINIPAD32',0
_edit db 'EDIT',0
_title db 'MiniPad',0
_about_title db 'About MiniPad',0
_about_text db 'This is Win32 example program created with flat assembler.',0
hinstance dd ?
edithwnd dd ?
editfont dd ?
msg MSG
wc WNDCLASS
client RECT
buffer db "",0
tmp1 db "",0
.code
proc strcopy, buff,pos1,pos2 ; strcopy,"Hello",2,3 returns "ell"
enter
push eax
mov eax,
sub eax,1
add ,eax
mov eax,
add eax,1
invoke lstrcpyn,tmp1,,eax
pop eax
mov eax,tmp1
return
start:
invoke GetModuleHandle,0
mov ,eax
invoke LoadIcon,eax,17
mov ,eax
invoke LoadCursor,0,IDC_ARROW
mov ,eax
mov ,0
mov ,WindowProc
mov ,0
mov ,0
mov eax,
mov ,eax
mov ,COLOR_WINDOW+1
mov ,0
mov ,_class
invoke RegisterClass,wc
invoke LoadMenu,,37
invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW,144,128,256,256,NULL,eax,,NULL
msg_loop:
invoke GetMessage,msg,NULL,0,0
or eax,eax
jz end_loop
invoke TranslateMessage,msg
invoke DispatchMessage,msg
jmp msg_loop
end_loop:
invoke ExitProcess,
proc WindowProc, hwnd,wmsg,wparam,lparam
enter
push ebx esi edi
cmp ,WM_CREATE
je wmcreate
cmp ,WM_SIZE
je wmsize
cmp ,WM_SETFOCUS
je wmsetfocus
cmp ,WM_COMMAND
je wmcommand
cmp ,WM_DESTROY
je wmdestroy
defwndproc:
invoke DefWindowProc,,,,
jmp finish
wmcreate:
invoke GetClientRect,,client
invoke CreateWindowEx,WS_EX_CLIENTEDGE,_edit,0,WS_VISIBLE+WS_CHILD+WS_HSCROLL+WS_VSCROLL+ES_AUTOHSCROLL+ES_AUTOVSCROLL+ES_MULTILINE,,,,,,0,,NULL
or eax,eax
jz failed
mov ,eax
invoke CreateFont,16,0,0,0,0,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_RASTER_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL
or eax,eax
jz failed
mov ,eax
invoke SendMessage,,WM_SETFONT,eax,FALSE
xor eax,eax
jmp finish
failed:
or eax,-1
jmp finish
wmsize:
invoke GetClientRect,,client
invoke MoveWindow,,,,,,TRUE
xor eax,eax
jmp finish
wmsetfocus:
invoke SetFocus,
xor eax,eax
jmp finish
wmcommand:
mov eax,
and eax,0FFFFh
cmp eax,IDM_SHOW
je show
cmp eax,IDM_ABOUT
je about
cmp eax,IDM_EXIT
je wmdestroy
jmp defwndproc
show:
invoke SendMessage,,WM_GETTEXTLENGTH,0,0
add eax,1
mov ebx,eax
invoke SendMessage,,WM_GETTEXT,ebx,buffer
mov byte ,0
invoke MessageBox,NULL,buffer,"Text in Edithwnd",MB_OK ;Works fine...
stdcall strcopy,buffer,1,3 ;First 3 characters
;This doesn't work, it displays buffer all wrong
invoke MessageBox,NULL,buffer,"Wrong text from edithwnd",MB_OK ;show what was in the edit box
jmp finish
about:
invoke MessageBox,,_about_text,_about_title,MB_OK
jmp finish
wmdestroy:
invoke DeleteObject,
invoke PostQuitMessage,0
xor eax,eax
finish:
pop edi esi ebx
return
section '.rsrc' resource data readable
; resource directory
directory RT_MENU,menus,\
RT_ICON,icons,\
RT_GROUP_ICON,group_icons,\
RT_VERSION,versions
; resource subdirectories
resource menus,\
37,LANG_ENGLISH+SUBLANG_DEFAULT,main_menu
resource icons,\
1,LANG_NEUTRAL,icon_data
resource group_icons,\
17,LANG_NEUTRAL,main_icon
resource versions,\
1,LANG_NEUTRAL,version_info
menu main_menu
menuitem '&File',0,MFR_POPUP
menuitem '&Show',IDM_SHOW,0
menuseparator
menuitem 'E&xit',IDM_EXIT,MFR_END
menuitem '&Help',0,MFR_POPUP + MFR_END
menuitem '&About...',IDM_ABOUT,MFR_END
icon main_icon,icon_data,'minipad.ico'
version version_info,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLANG_DEFAULT,0,\
'FileDescription','MiniPad - example program',\
'LegalCopyright','No rights reserved.',\
'FileVersion','1.0',\
'ProductVersion','1.0',\
'OriginalFilename','MINIPAD.EXE'
.end start
; Simple text editor - fasm example program
include '%include%\win32ax.inc'
IDM_SHOW = 101
IDM_EXIT = 102
IDM_ABOUT = 901
.data
_class db 'MINIPAD32',0
_edit db 'EDIT',0
_title db 'MiniPad',0
_about_title db 'About MiniPad',0
_about_text db 'This is Win32 example program created with flat assembler.',0
hinstance dd ?
edithwnd dd ?
editfont dd ?
msg MSG
wc WNDCLASS
client RECT
buffer db "",0
tmp1 db "",0
.code
proc strcopy, buff,pos1,pos2 ; strcopy,"Hello",2,3 returns "ell"
enter
push eax
mov eax,
sub eax,1
add ,eax
mov eax,
add eax,1
invoke lstrcpyn,tmp1,,eax
pop eax
mov eax,tmp1
return
start:
invoke GetModuleHandle,0
mov ,eax
invoke LoadIcon,eax,17
mov ,eax
invoke LoadCursor,0,IDC_ARROW
mov ,eax
mov ,0
mov ,WindowProc
mov ,0
mov ,0
mov eax,
mov ,eax
mov ,COLOR_WINDOW+1
mov ,0
mov ,_class
invoke RegisterClass,wc
invoke LoadMenu,,37
invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW,144,128,256,256,NULL,eax,,NULL
msg_loop:
invoke GetMessage,msg,NULL,0,0
or eax,eax
jz end_loop
invoke TranslateMessage,msg
invoke DispatchMessage,msg
jmp msg_loop
end_loop:
invoke ExitProcess,
proc WindowProc, hwnd,wmsg,wparam,lparam
enter
push ebx esi edi
cmp ,WM_CREATE
je wmcreate
cmp ,WM_SIZE
je wmsize
cmp ,WM_SETFOCUS
je wmsetfocus
cmp ,WM_COMMAND
je wmcommand
cmp ,WM_DESTROY
je wmdestroy
defwndproc:
invoke DefWindowProc,,,,
jmp finish
wmcreate:
invoke GetClientRect,,client
invoke CreateWindowEx,WS_EX_CLIENTEDGE,_edit,0,WS_VISIBLE+WS_CHILD+WS_HSCROLL+WS_VSCROLL+ES_AUTOHSCROLL+ES_AUTOVSCROLL+ES_MULTILINE,,,,,,0,,NULL
or eax,eax
jz failed
mov ,eax
invoke CreateFont,16,0,0,0,0,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_RASTER_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL
or eax,eax
jz failed
mov ,eax
invoke SendMessage,,WM_SETFONT,eax,FALSE
xor eax,eax
jmp finish
failed:
or eax,-1
jmp finish
wmsize:
invoke GetClientRect,,client
invoke MoveWindow,,,,,,TRUE
xor eax,eax
jmp finish
wmsetfocus:
invoke SetFocus,
xor eax,eax
jmp finish
wmcommand:
mov eax,
and eax,0FFFFh
cmp eax,IDM_SHOW
je show
cmp eax,IDM_ABOUT
je about
cmp eax,IDM_EXIT
je wmdestroy
jmp defwndproc
show:
invoke SendMessage,,WM_GETTEXTLENGTH,0,0
add eax,1
mov ebx,eax
invoke SendMessage,,WM_GETTEXT,ebx,buffer
mov byte ,0
invoke MessageBox,NULL,buffer,"Text in Edithwnd",MB_OK ;Works fine...
stdcall strcopy,buffer,1,3 ;First 3 characters
;This doesn't work, it displays buffer all wrong
invoke MessageBox,NULL,buffer,"Wrong text from edithwnd",MB_OK ;show what was in the edit box
jmp finish
about:
invoke MessageBox,,_about_text,_about_title,MB_OK
jmp finish
wmdestroy:
invoke DeleteObject,
invoke PostQuitMessage,0
xor eax,eax
finish:
pop edi esi ebx
return
section '.rsrc' resource data readable
; resource directory
directory RT_MENU,menus,\
RT_ICON,icons,\
RT_GROUP_ICON,group_icons,\
RT_VERSION,versions
; resource subdirectories
resource menus,\
37,LANG_ENGLISH+SUBLANG_DEFAULT,main_menu
resource icons,\
1,LANG_NEUTRAL,icon_data
resource group_icons,\
17,LANG_NEUTRAL,main_icon
resource versions,\
1,LANG_NEUTRAL,version_info
menu main_menu
menuitem '&File',0,MFR_POPUP
menuitem '&Show',IDM_SHOW,0
menuseparator
menuitem 'E&xit',IDM_EXIT,MFR_END
menuitem '&Help',0,MFR_POPUP + MFR_END
menuitem '&About...',IDM_ABOUT,MFR_END
icon main_icon,icon_data,'minipad.ico'
version version_info,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLANG_DEFAULT,0,\
'FileDescription','MiniPad - example program',\
'LegalCopyright','No rights reserved.',\
'FileVersion','1.0',\
'ProductVersion','1.0',\
'OriginalFilename','MINIPAD.EXE'
.end start
I think I have found the problem. I replaced
buffer db "",0
tmp1 db "",0
with
buffer rb 250
tmp1 rb 250
and the program worked fine.
I don't know Fasm that well so I am not sure how buffer db "" works. Maybe some one more knowledgeable can help explain that.
buffer db "",0
tmp1 db "",0
with
buffer rb 250
tmp1 rb 250
and the program worked fine.
I don't know Fasm that well so I am not sure how buffer db "" works. Maybe some one more knowledgeable can help explain that.
buffer db "",0 works exactly like just buffer db 0.
Thanks Privalov. I should have known.Strings are declared the same way with other assemblers. I was just wondering if it resized to fit any length string.
Thanks :alright: :alright:
No problem