读书人

小弟我的win32汇编程序的“导出到文件

发布时间: 2013-11-30 22:36:00 作者: rapoo

我的win32汇编程序的“导出到文件”功能有问题,请高手赐教
初学win32汇编,用的是RadASM, 而且又不会调试,所以请各位高手这个程序的问题原因。
问题:
1. 执行“获取窗口”按钮后,为什么列表框里的每一项尾部都显示有"||".
2. “导出到文件”按钮的功能是把列表框里的内容导出到一个文件里,可是当执行“导出到窗口”按钮后,
导出文件里为什么总是只有一行内容??
3. 哪位高手有关于程序调试的教程,比较适合我这个初学者的,如果有请与俺共享。这样俺就可以在以后的
日子里,如果程序有问题就可以自己调试找出原因。就不用总是找别人帮忙。

程序代码如下:
;********************************
; ASM文件
;*********************************
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;Include
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;Equ
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 100
DLG_MAIN equ 1
IDC_WINLIST equ 1000
IDC_GET equ 1001
IDC_CLEAN equ 1002
IDC_OUTFILE equ 1003
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?
hDeskWnd dd ?
hFirstWnd dd ?
hBrotWnd dd ?
hFile dd ?
dwDistanceLow dd ?
dwDistanceHigh dd ?
dwCounter dd ?
szClassName db 128 dup (?)
szBuffer db 2048 dup (?)
szBuf db 256 dup (?)
szTitle db 128 dup(?)
.const
szText db '确定要清除 ?',0
szCaption db '提示',0
szOutFileName db 'Out.txt',0
szForm db '%s',0dh,0ah,0
szFormat db '%d>.窗口标题:%s; 窗口类名:%s',0dh,0ah,0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
LOCAL @dwCountList
LOCAL @dwBytesWrite

mov eax,wMsg
.if eax == WM_CLOSE
invoke CloseHandle,hFile

invoke EndDialog,hWnd,NULL
;**************************************************
.elseif eax == WM_INITDIALOG
push hWnd
pop hWinMain
;**************************************************
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDC_GET
invoke GetDesktopWindow ;得到桌面窗口的句柄
mov hDeskWnd,eax
invoke GetWindow,eax,GW_CHILD ;寻找桌面窗口的第一个子窗口
mov hFirstWnd,eax
mov hBrotWnd,eax
mov dwDistanceLow,0
mov dwDistanceHigh,0
mov dwCounter,0

.while hBrotWnd
invoke GetParent,hBrotWnd
.if !eax
mov ecx,dwCounter
inc ecx
mov dwCounter,ecx
invoke GetWindowText,hBrotWnd,addr szTitle,sizeof szTitle
invoke GetClassName,hBrotWnd,addr szClassName,sizeof szClassName

invoke RtlZeroMemory,addr szBuffer,sizeof szBuffer
invoke wsprintf,addr szBuffer,addr szFormat,dwCounter,addr szTitle,\
addr szClassName
invoke SendDlgItemMessage,hWnd,IDC_WINLIST,LB_ADDSTRING,\
0,addr szBuffer
invoke GetWindow,hBrotWnd,GW_HWNDNEXT
mov hBrotWnd,eax
.else
invoke GetWindow,hBrotWnd,GW_HWNDNEXT
mov hBrotWnd,eax
.endif
.endw
;*******************************************************************************************
.elseif ax == IDC_OUTFILE
invoke CreateFile,addr szOutFileName,GENERIC_WRITE,\
FILE_SHARE_READ,NULL,OPEN_ALWAYS,\
FILE_ATTRIBUTE_NORMAL,NULL
.if eax != INVALID_HANDLE_VALUE


mov hFile,eax
mov ecx,0
.while ecx < dwCounter
invoke RtlZeroMemory,addr szBuffer,sizeof szBuffer
invoke RtlZeroMemory,addr szBuf,sizeof szBuf

invoke SendDlgItemMessage,hWnd,IDC_WINLIST,\
LB_GETTEXT,ecx,addr szBuf

invoke RtlZeroMemory,addr szBuffer,sizeof szBuffer
invoke wsprintf,addr szBuffer,addr szForm,addr szBuf

push ecx
invoke lstrlen,addr szBuffer
mov ecx,eax
invoke WriteFile,hFile,addr szBuffer,\
ecx,addr @dwBytesWrite,NULL
pop ecx
inc ecx
.endw
invoke CloseHandle,hFile
.endif
;********************************************************************************************
.elseif ax == IDC_CLEAN
invoke SendDlgItemMessage,hWnd,IDC_WINLIST,LB_GETCOUNT,0,0
mov @dwCountList,eax
mov ecx,@dwCountList
.while ecx > 0
dec ecx
invoke SendDlgItemMessage,hWnd,IDC_WINLIST,LB_DELETESTRING,ecx,0
dec @dwCountList
mov ecx,@dwCountList
.endw
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,addr _ProcDlgMain,NULL
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
;********************************
;资源文件
;********************************
#define ICO_MAIN 100
#define DLG_MAIN 1
#define IDC_WINLIST 1000
#define IDC_GET 1001
#define IDC_CLEAN 1002
#define IDC_OUTFILE 1003
#include <resource.h>
ICO_MAIN ICON DISCARDABLE "Main.ico"
DLG_MAIN DIALOGEX 10,10,396,129
CAPTION "桌面打开窗口列表"
STYLE WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX
BEGIN
CONTROL "",IDC_WINLIST,"ListBox",WS_CHILDWINDOW|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP|LBS_NOINTEGRALHEIGHT|LBS_HASSTRINGS|LBS_NOTIFY,3,3,387,84,WS_EX_CLIENTEDGE
CONTROL "获 取 窗 口",IDC_GET,"Button",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP,6,93,69,27
CONTROL "清 除 列 表",IDC_CLEAN,"Button",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP,321,93,69,30
CONTROL "导 出 到 文 件",IDC_OUTFILE,"Button",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP,156,93,99,24
END


[解决办法]
你用的是 ListBox 来显示信息的,所以不要有 0dh, 0ah 来做换行;ecx 会被系统函数调用破坏了(eax 和 edx 也是),所以不适合用作大范围内的带复杂操作情况下的计数器,可以用 esi 什么的。
[解决办法]
这个,就是个寄存器使用上的约定。Masm32 的 help 目录下有个 asmintro.chm 文件,里面的 Register Preservation Convention 说的就是这个。大致就是 8 个通用寄存器,sp/esp 用做堆栈指针;bp/ebp 用作子程的参数和局部变量的访问;eax/edx 用作子程的返回参数,ecx 用作对象自身(OOP 时),所以它们会被子程所改变,程序里如果要连续地使用它们,必须自己对它们进行保护;ebx/esi/edi 这几个,子程如果使用了它们,应该对它们进行保护,保证子程返回时它们的内容不变。

读书人网 >汇编语言

热点推荐