首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 汇编语言 >

小弟我的win32汇编程序的“导出到文件”功能有有关问题,请高手赐教

2013-11-30 
我的win32汇编程序的“导出到文件”功能有问题,请高手赐教初学win32汇编,用的是RadASM, 而且又不会调试,所以

我的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 这几个,子程如果使用了它们,应该对它们进行保护,保证子程返回时它们的内容不变。

热点排行