一个文件分割器源码(MASM32)
2010年09月27日
文章作者:一块三毛钱
;************************************************* ************
;* Author: 一块三毛钱
;* E_mail: crazy_soft@163.net
;* Homepage: http://zhongts.51.net
;************************************************* ************
;* Compile: Hutch's Masm32
;* Create Time: 2002.6.5
;* Modify: 2002.6.5
;* Description: 文件分割器 V1.10
;************************************************* ************
.386
.model flat,stdcall
option casemap:none
;************************************************* ***************************************
include ztsSplit.inc
include c:\masm32\include\windows.inc
include c:\masm32\include\user32.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\comdlg32.inc
include c:\masm32\include\comctl32.inc
include c:\masm32\include\shell32.inc
include c:\masm32\include\masm32.inc
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\comdlg32.lib
includelib c:\masm32\lib\comctl32.lib
includelib c:\masm32\lib\shell32.lib
includelib c:\masm32\lib\masm32.lib
;************************************************* ***************************************
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD
SetToolTip proto :DWORD
GetFolder proto :DWORD,:DWORD
SizeEditProc proto :DWORD,:DWORD,:DWORD,:DWORD
FileEditProc proto :DWORD,:DWORD,:DWORD,:DWORD
FolderEditProc proto :DWORD,:DWORD,:DWORD,:DWORD
Split proto :DWORD,:DWORD,:DWORD
Merge proto :DWORD,:DWORD
;************************************************* ***************************************
.data
AppName db "ztsSplit",0
DlgName db "DLG_MAIN",0
TooltipClassName db "Tooltips_class32",0
strSysMenu db "窗口处在最上",0
strBtnStart01 db "分割(&C)",0
strBtnStart02 db "合并(&M)",0
strMergeExt db ".mrg",0
strTitleSplit db "选择要分割的文件",0
strTitleMerge db "选择要合并的文件",0
strFilterSplit db "所有文件(*.*)",0,"*.*",0,0
strFilterMerge db "合并信息文件(*.mrg)",0,"*.mrg",0,0
strBrowseTitle db "选择文件存放目录:",0
strFolderInfo db "分割软件 ztsSplit 所在的目录",0
strIniFileName db "desktop.ini",0
strIniFileSection db ".ShellClassInfo",0
strIniFileKeyValue db "InfoTip=分割软件 ztsSplit 所在的目录",0
db "IconIndex=1",0
db "IconFile=\",0,0
strError01 db "打开文件出错",0
strError02 db "文件创建错误",0
strError03 db "文件太小,不需要分割",0
strError04 db "请先指定分割的大小",0
strError05 db "请先选择需要分割/合并的文件",0
strError06 db "请选择分割/合并后文件存放的目录",0
strError07 db "没有合并信息,不能正确合并文件",0
strCopyright db "ztsmrg1.1该文件由分割软件 ztsSplit 生成",0
strBatCopy db "copy /b ",0
format1 db "%03d",0
.data?
hInstance HINSTANCE ?
hToolTip dd ? ;工具提示控件的句柄
hSysMenu dd ? ;系统菜单句柄
hProgress dd ? ;进度条句柄
hEditFile dd ? ;文件名编辑框句柄
hEditFolder dd ? ;目录编辑框句柄
hEditSize dd ? ;分割大小编辑框句柄
hBtnStart dd ? ;分割/合并按钮的句柄
hBtnExit dd ? ;退出按钮的句柄
hBtnFile dd ?
hBtnFolder dd ?
bSplitOrMerge BOOL ? ;分割还是合并
bKbOrMb BOOL ? ;分割大小的单位是 KB 还是 MB
bSizeEditFocus BOOL ? ;"分割大小"编辑框是否拥有焦点
bFileEditFocus BOOL ? ;"文件名"编辑框是否拥有焦点
bFolderEditFocus BOOL ? ;"目录"编辑框是否拥有焦点
strPath db MAX_PATH dup (?) ;接收拖动来的文件名
strFolder db MAX_PATH dup (?) ;文件所在的目录
strFileName db MAX_PATH dup (?) ;可执行文件路径
strModuleDir db MAX_PATH dup (?) ;可执行文件所在的目录
strIniFilePath db MAX_PATH dup (?)
ofn OPENFILENAME
bi BROWSEINFO
OldSizeEditProc dd ?
OldFileEditProc dd ?
OldFolderEditProc dd ?
;************************************************* ***************************************
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,addr DlgName,NULL,addr DlgProc,0
invoke ExitProcess,eax
invoke InitCommonControls
;对话框窗口过程************************************************** ************************
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
local rect:RECT
local pt:POINT
.IF uMsg==WM_CLOSE
invoke GetModuleFileName, hInstance, addr strFileName, MAX_PATH ;取得文件名
invoke GetFolder, addr strModuleDir, addr strFileName ;计算所属目录
invoke SetFileAttributes,addr strModuleDir, FILE_ATTRIBUTE_SYSTEM ;设置目录属性为系统属性
;计算 desktop.ini 文件的文件名(包括目录)
invoke lstrcat, addr strIniFilePath, addr strModuleDir
invoke lstrcat, addr strIniFilePath, addr strIniFileName
;计算 desktop.ini 文件中需要写入的内容
mov esi, offset strFileName
mov edi, offset strIniFileKeyValue
labelLoop:
cmp BYTE ptr [edi], '\'
je labelQuit
inc edi
jmp labelLoop
labelQuit:
invoke StrLen, addr strFileName
mov ecx, eax
rep movsd
;写入 desktop.ini 文件
invoke WritePrivateProfileSection, addr strIniFileSection, addr strIniFileKeyValue, addr strIniFilePath
invoke SetFileAttributes, addr strIniFilePath, FILE_ATTRIBUTE_HIDDEN ;设置文件属性为隐藏
invoke EndDialog, hWnd, NULL
.ELSEIF uMsg==WM_INITDIALOG
;设置图标
invoke LoadIcon, hInstance, IDI_MAIN
invoke SendMessage, hWnd, WM_SETICON, ICON_SMALL, eax
;添加系统菜单项:"窗口处在最上"
invoke GetSystemMenu, hWnd, FALSE ;取得系统菜单的句柄
mov hSysMenu, eax ;句柄 => hSysMenu
invoke AppendMenu, hSysMenu, MF_SEPARATOR, NULL,NULL ;插入分隔线
invoke AppendMenu, hSysMenu, MF_STRING or MF_UNCHECKED, IDM_SYSMENU, addr strSysMenu ;插入"窗口处在最上"菜单
;取得几个控件的句柄
invoke GetDlgItem, hWnd, IDC_PROGRESS
mov hProgress, eax
invoke GetDlgItem, hWnd, IDC_EDIT_FILE
mov hEditFile, eax
invoke GetDlgItem, hWnd, IDC_EDIT_FOLDER
mov hEditFolder, eax
invoke GetDlgItem, hWnd, IDC_EDIT_SIZE
mov hEditSize, eax
invoke GetDlgItem, hWnd, IDC_BTN_START
mov hBtnStart, eax
invoke GetDlgItem, hWnd, IDC_BTN_EXIT
mov hBtnExit, eax
invoke GetDlgItem, hWnd, IDC_BTN_FILE
mov hBtnFile, eax
invoke GetDlgItem, hWnd, IDC_BTN_FOLDER
mov hBtnFolder, eax
;初始化为"分割文件""KB"方式
invoke GetDlgItem, hWnd, IDC_RADIO_SPLIT
invoke SendMessage, eax, BM_SETCHECK,BST_CHECKED,0
mov bSplitOrMerge, TRUE
invoke GetDlgItem, hWnd, IDC_RADIO_KB
invoke SendMessage, eax, BM_SETCHECK,BST_CHECKED,0
mov bKbOrMb, TRUE
;创建工具提示控件
invoke CreateWindowEx, NULL, addr TooltipClassName, NULL, TTS_ALWAYSTIP, \
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, \
NULL, NULL, hInstance, NULL
mov hToolTip, eax
invoke SetWindowPos, hToolTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE
;设置所有的提示信息
invoke SetToolTip, hWnd
;子类化编辑框控件
invoke SetWindowLong, hEditSize, GWL_WNDPROC, addr SizeEditProc
mov OldSizeEditProc, eax
mov bSizeEditFocus, FALSE
invoke SetWindowLong, hEditFile, GWL_WNDPROC, addr FileEditProc
mov OldFileEditProc, eax
mov bFileEditFocus, FALSE
invoke SetWindowLong, hEditFolder, GWL_WNDPROC, addr FolderEditProc
mov OldFolderEditProc, eax
mov bFolderEditFocus, FALSE
invoke SetFocus, hEditFile ;设置焦点,加了这条语句后下面要用 mov eax, FLASE / ret ,否则无效
mov eax, FALSE
ret
.ELSEIF uMsg==WM_COMMAND
mov eax, wParam
and eax, 0ffffh
.IF eax==IDC_RADIO_SPLIT ;切换到分割状态
.IF !bSplitOrMerge
invoke GetDlgItem, hWnd, IDC_EDIT_SIZE
invoke EnableWindow, eax, TRUE
invoke GetDlgItem, hWnd, IDC_RADIO_KB
invoke EnableWindow, eax, TRUE
invoke GetDlgItem, hWnd, IDC_RADIO_MB
invoke EnableWindow, eax, TRUE
invoke GetDlgItem, hWnd, IDC_BTN_START
invoke SetWindowText, eax, addr strBtnStart01
mov bSplitOrMerge, TRUE
.ENDIF
.ELSEIF eax==IDC_RADIO_MERGE ;切换到合并状态
.IF bSplitOrMerge
invoke GetDlgItem, hWnd, IDC_EDIT_SIZE
invoke EnableWindow, eax, FALSE
invoke GetDlgItem, hWnd, IDC_RADIO_KB
invoke EnableWindow, eax, FALSE
invoke GetDlgItem, hWnd, IDC_RADIO_MB
invoke EnableWindow, eax, FALSE
invoke GetDlgItem, hWnd, IDC_BTN_START
invoke SetWindowText, eax, addr strBtnStart02
mov bSplitOrMerge, FALSE
.ENDIF
.ELSEIF eax==IDC_RADIO_KB ;分割大小的单位是 KB
.IF !bKbOrMb
mov bKbOrMb, TRUE
invoke SetFocus, hEditSize ;"分割大小"编辑框得到焦点
.ENDIF
.ELSEIF eax==IDC_RADIO_MB ;分割大小的单位是 MB
.IF bKbOrMb
mov bKbOrMb, FALSE
invoke SetFocus, hEditSize ;"分割大小"编辑框得到焦点
.ENDIF
.ELSEIF eax==IDC_BTN_FILE ;选择要分割/合并的文件
mov ofn.lStructSize, sizeof ofn
push hWnd
pop ofn.hwndOwner
push hInstance
pop ofn.hInstance
mov ofn.lpstrFile, offset strPath ;接收文件名
mov ofn.nMaxFile, MAX_PATH
mov ofn.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_HIDEREADONLY or OFN_EXPLORER or OFN_LONGNAMES
.IF bSplitOrMerge ;分割状态
mov ofn.lpstrFilter, offset strFilterSplit ;文件过滤器
mov ofn.lpstrTitle, offset strTitleSplit ;标题文本
.ELSE ;合并状态
mov ofn.lpstrFilter, offset strFilterMerge ;文件过滤器
mov ofn.lpstrTitle, offset strTitleMerge ;标题文本
.ENDIF
invoke GetOpenFileName, addr ofn
.IF eax
invoke SetDlgItemText, hWnd, IDC_EDIT_FILE, addr strPath
invoke GetFolder, addr strFolder, addr strPath
invoke SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strFolder
.IF bSplitOrMerge
invoke SetFocus, hEditSize ;"分割大小"编辑框得到焦点
.ELSE
invoke SetFocus, hBtnStart ;"分割/合并"按钮得到焦点
.ENDIF
.ENDIF
.ELSEIF eax==IDC_BTN_FOLDER ;选择分割/合并后文件的存放目录
invoke RtlZeroMemory, addr bi, sizeof BROWSEINFO ;内存清零
push hWnd
pop bi.hwndOwner
mov eax, offset strFolder ;接收目录字符串
mov bi.pszDisplayName, eax
mov eax, offset strBrowseTitle ;目录选择框上面的文本
mov bi.lpszTitle, eax
mov bi.ulFlags, BIF_RETURNONLYFSDIRS ;选择目录
invoke SHBrowseForFolder, addr bi
.IF eax
invoke SHGetPathFromIDList, eax, addr strFolder ;转换 PIDL 为目录名
invoke StrLen, addr strFolder ;取得字符串长度
mov esi, offset strFolder ;esi 指向开始的位置
add esi, eax ;esi 指向结束的位置
cmp BYTE ptr [esi-1], '\' ;判断是不是以'\'结尾
je labelExit
mov BYTE ptr [esi], '\' ;如果不是则添加一个'\'
mov BYTE ptr [esi+1], 0
labelExit:
invoke SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strFolder
invoke SetForegroundWindow, hWnd ;激活窗口
.IF bSplitOrMerge
invoke SetFocus, hEditSize ;"分割大小"编辑框得到焦点
.ELSE
invoke SetFocus, hBtnStart ;"分割/合并"按钮得到焦点
.ENDIF
.ENDIF
.ELSEIF eax==IDC_BTN_START
.IF bSplitOrMerge
invoke GetDlgItemInt, hWnd, IDC_EDIT_SIZE, NULL, FALSE
.IF bKbOrMb
shl eax, 10
.ELSE
shl eax, 20
.ENDIF
invoke Split, addr strPath, addr strFolder, eax
invoke SendMessage, hProgress, PBM_SETPOS, 0, 0
.ELSE
invoke Merge, addr strPath, addr strFolder
invoke SendMessage, hProgress, PBM_SETPOS, 0, 0
.ENDIF
.ELSEIF eax==IDC_BTN_EXIT
invoke SendMessage, hWnd, WM_CLOSE, 0, 0
.ENDIF
.ELSEIF uMsg==WM_SYSCOMMAND
mov eax,wParam
movzx eax,ax
.IF eax==IDM_SYSMENU
invoke GetMenuState, hSysMenu, IDM_SYSMENU, MF_BYCOMMAND
.IF (eax & MF_CHECKED) ;判断菜单是否是选中的
invoke CheckMenuItem, hSysMenu, IDM_SYSMENU, MF_UNCHECKED
invoke SetWindowPos, hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE
.ELSE
invoke CheckMenuItem, hSysMenu, IDM_SYSMENU, MF_CHECKED
invoke SetWindowPos, hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE
.ENDIF
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
.ENDIF
.ELSEIF uMsg==WM_DROPFILES
invoke DragQueryFile, wParam, 0, addr strPath, MAX_PATH ;得到文件路径
invoke GetFileAttributes, addr strPath ;取得文件属性,判断是否文件夹
and eax, FILE_ATTRIBUTE_DIRECTORY
.IF eax ;如果是文件夹
invoke SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strPath
invoke SetForegroundWindow, hWnd ;激活窗口
.IF bSplitOrMerge
invoke SetFocus, hEditSize ;"分割大小"编辑框得到焦点
.ELSE
invoke SetFocus, hBtnStart ;"分割/合并"按钮得到焦点
.ENDIF
.ELSE
.IF bSplitOrMerge ;当前为分割状态
invoke SetDlgItemText, hWnd, IDC_EDIT_FILE, addr strPath
invoke GetFolder, addr strFolder, addr strPath
invoke SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strFolder
invoke SetForegroundWindow, hWnd ;激活窗口
invoke SetFocus, hEditSize ;"分割大小"编辑框得到焦点
.ELSE ;当前为合并状态
mov esi, offset strPath
invoke StrLen, addr strPath
add esi, eax
sub esi, 4
invoke lstrcmp, esi, addr strMergeExt ;判断最后 4 个字符是否为 ".mrg"
.IF eax==0
invoke SetDlgItemText, hWnd, IDC_EDIT_FILE, addr strPath
invoke GetFolder, addr strFolder, addr strPath
invoke SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strFolder
invoke SetForegroundWindow, hWnd ;激活窗口
invoke SetFocus, hBtnStart ;"分割/合并"按钮得到焦点
.ENDIF
.ENDIF
.ENDIF
invoke DragFinish,wParam ;释放内存
.ELSE
mov eax,FALSE
ret
.ENDIF
mov eax,TRUE
ret
DlgProc endp
;==========================================
; 设置所有提示信息
;==========================================
SetToolTip proc hWnd:DWORD
local ti:TOOLINFO
mov ti.cbSize, sizeof TOOLINFO
mov ti.uFlags, TTF_SUBCLASS or TTF_IDISHWND
push hWnd
pop ti.hWnd
;先设置主界面提示信息
push hWnd
pop ti.uId
mov ti.lpszText, offset strMainTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;------------------------------------------------
; 设置其他控件的提示信息
;------------------------------------------------
;"分割文件"单选框提示信息
invoke GetDlgItem, hWnd, IDC_RADIO_SPLIT
mov ti.uId, eax
mov ti.lpszText, offset strSplitTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"合并文件"单选框提示信息
invoke GetDlgItem, hWnd, IDC_RADIO_MERGE
mov ti.uId, eax
mov ti.lpszText, offset strMergeTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"文件名"编辑框提示信息
invoke GetDlgItem, hWnd, IDC_EDIT_FILE
mov ti.uId, eax
mov ti.lpszText, offset strFileTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"目录"编辑框提示信息
invoke GetDlgItem, hWnd, IDC_EDIT_FOLDER
mov ti.uId, eax
mov ti.lpszText, offset strFolderTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"选择文件"按钮提示信息
invoke GetDlgItem, hWnd, IDC_BTN_FILE
mov ti.uId, eax
mov ti.lpszText, offset strBtnFileTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"选择文件夹"按钮提示信息
invoke GetDlgItem, hWnd, IDC_BTN_FOLDER
mov ti.uId, eax
mov ti.lpszText, offset strBtnFolderTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"分割大小"编辑框提示信息
invoke GetDlgItem, hWnd, IDC_EDIT_SIZE
mov ti.uId, eax
mov ti.lpszText, offset strSizeTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"KB"单选框提示信息
invoke GetDlgItem, hWnd, IDC_RADIO_KB
mov ti.uId, eax
mov ti.lpszText, offset strKbTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"MB"单选框提示信息
invoke GetDlgItem, hWnd, IDC_RADIO_MB
mov ti.uId, eax
mov ti.lpszText, offset strMbTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;进度条提示信息
invoke GetDlgItem, hWnd, IDC_PROGRESS
mov ti.uId, eax
mov ti.lpszText, offset strProgressTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"分割/合并"按钮提示信息
invoke GetDlgItem, hWnd, IDC_BTN_START
mov ti.uId, eax
mov ti.lpszText, offset strStartTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"退出"按钮提示信息
invoke GetDlgItem, hWnd, IDC_BTN_EXIT
mov ti.uId, eax
mov ti.lpszText, offset strExitTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
ret
SetToolTip endp
;==========================================
; 根据文件名得到文件夹
;==========================================
GetFolder proc lpFolder:HWND, lpFile:DWORD
;把 lpFile 地址处的字符串传送到 lpFolder 地址处
mov esi, lpFile
mov edi, lpFolder
invoke StrLen, lpFile
mov ecx, eax
rep movsd
mov esi, lpFolder ; esi 指向 lpFolder,也就是字符串开始的位置
add esi, eax ; esi 加上 eax(字符串长度)后指向字符串结束的位置
dec esi ; esi 指向字符串末尾的一个字符
;从字符串末尾向前测试每一个字符,如果为 '\' 则说明再往前就是文件夹
labelTest:
cmp BYTE ptr [esi], '\'
je labelExit
dec esi
jmp labelTest
labelExit:
inc esi
mov BYTE ptr [esi], 0
ret
GetFolder endp
;==========================================
; "分割大小"编辑框窗口过程
; 当窗口获得焦点时选中所有文本
;==========================================
SizeEditProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_SETFOCUS
mov bSizeEditFocus, TRUE ;拥有焦点
invoke SendMessage, hWnd, EM_SETSEL, 0, -1 ;选中全部文本
invoke CallWindowProc, OldSizeEditProc, hWnd, uMsg, wParam, lParam
ret
.ELSEIF uMsg==WM_LBUTTONDOWN
.IF !bSizeEditFocus ;如果没有焦点
invoke SetFocus, hWnd ;则设置焦点
.ELSE ;如果已经有焦点,则按缺省处理
invoke CallWindowProc, OldSizeEditProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
.ELSEIF uMsg==WM_KILLFOCUS
mov bSizeEditFocus, FALSE ;失去焦点
invoke CallWindowProc, OldSizeEditProc, hWnd, uMsg, wParam, lParam
ret
.ELSE
invoke CallWindowProc, OldSizeEditProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
xor eax, eax
ret
SizeEditProc endp
;================================================= =
; "文件名"编辑框窗口过程
; 当窗口获得焦点时光标滚到最后,方便修改
; 当窗口失去焦点时光标滚到最前,方便观看
;================================================= =
FileEditProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_SETFOCUS
mov bFileEditFocus, TRUE ;拥有焦点
invoke SendMessage, hWnd, WM_GETTEXTLENGTH, 0, 0 ;取得文本长度
invoke SendMessage, hWnd, EM_SETSEL, eax, eax ;光标滚到最后
invoke CallWindowProc, OldFileEditProc, hWnd, uMsg, wParam, lParam
ret
.ELSEIF uMsg==WM_LBUTTONDOWN
.IF !bFileEditFocus ;如果没有焦点
invoke SetFocus, hWnd ;则设置焦点
.ELSE ;如果已经有焦点,则按缺省处理
invoke CallWindowProc, OldFileEditProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
.ELSEIF uMsg==WM_KILLFOCUS
mov bFileEditFocus, FALSE ;失去焦点
invoke SendMessage, hWnd, EM_SETSEL, 0, 0 ;光标滚到最前
invoke CallWindowProc, OldFileEditProc, hWnd, uMsg, wParam, lParam
ret
.ELSE
invoke CallWindowProc, OldFileEditProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
xor eax, eax
ret
FileEditProc endp
;================================================= =
; "目录"编辑框窗口过程
; 当窗口获得焦点时光标滚到最后,方便修改
; 当窗口失去焦点时光标滚到最前,方便观看
;================================================= =
FolderEditProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_SETFOCUS
mov bFolderEditFocus, TRUE ;拥有焦点
invoke SendMessage, hWnd, WM_GETTEXTLENGTH, 0, 0 ;取得文本长度
invoke SendMessage, hWnd, EM_SETSEL, eax, eax ;光标滚到最后
invoke CallWindowProc, OldFolderEditProc, hWnd, uMsg, wParam, lParam
ret
.ELSEIF uMsg==WM_LBUTTONDOWN
.IF !bFolderEditFocus ;如果没有焦点
invoke SetFocus, hWnd ;则设置焦点
.ELSE ;如果已经有焦点,则按缺省处理
invoke CallWindowProc, OldFolderEditProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
.ELSEIF uMsg==WM_KILLFOCUS
mov bFolderEditFocus, FALSE ;失去焦点
invoke SendMessage, hWnd, EM_SETSEL, 0, 0 ;光标滚到最前
invoke CallWindowProc, OldFolderEditProc, hWnd, uMsg, wParam, lParam
ret
.ELSE
invoke CallWindowProc, OldFolderEditProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
xor eax, eax
ret
FolderEditProc endp
;=========================================
; 分割过程
; 参数:待分割文件,存放目录,分割大小
;=========================================
Split proc lpfile:DWORD, lpfolder:DWORD, blocksize:DWORD
local hSourceFile, hDestFile:DWORD
local hMrgFile:DWORD
local buffer[1024]:BYTE ;缓冲区
local sourcefilename[128]:BYTE ;被分割的文件名(包括扩展名)
local filetitle[128]:BYTE ;文件名(不包括扩展名)
local fileExt[10]:BYTE ;扩展名
local filename[128]:BYTE ;文件名(包括路径和扩展名)
local ActualReaded:DWORD ;实际读出来的字节
local BufCount:DWORD ;记录每个分割文件已经写入的字节
local number:DWORD ;分割文件的个数
;没指定需要分割的文件
mov esi, lpfile
mov al, byte ptr [esi]
.IF al == 0
invoke MessageBox, NULL, addr strError05, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
;没指定分割后文件存放的目录
mov esi, lpfolder
mov al, byte ptr [esi]
.IF al == 0
invoke MessageBox, NULL, addr strError06, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
;没指定分割大小
.IF blocksize==0
invoke MessageBox, NULL, addr strError04, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
;打开文件失败
invoke CreateFile, lpfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL
.IF eax==INVALID_HANDLE_VALUE
invoke MessageBox, NULL, addr strError01, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
mov hSourceFile, eax
;文件太小(比指定的分割大小)
invoke GetFileSize, hSourceFile, NULL
.IF eax<blocksize
invoke CloseHandle, hSourceFile
invoke MessageBox, NULL, addr strError03, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
;计算文件名(包括扩展名)
mov esi, lpfile
lea edi, filetitle
invoke StrLen, lpfile
add esi, eax
xor ecx, ecx
labelTest:
cmp BYTE ptr [esi], '\'
je labelExit
dec esi
inc ecx
jmp labelTest
labelExit:
inc esi
dec ecx
rep movsd
invoke lstrcpy, addr sourcefilename, addr filetitle ;保存文件名到 sourcefilename 中
;计算文件名(不包括扩展名)
lea esi, filetitle
mov ebx, esi
invoke StrLen, addr filetitle
add ebx, eax
labelLoop:
cmp BYTE ptr [esi], '.'
je labelQuit
inc esi
cmp esi, ebx
je labelQuit
jmp labelLoop
labelQuit:
mov BYTE ptr [esi], '.'
mov BYTE ptr [esi+1], 0
;mrg 文件的扩展名
lea esi, fileExt
mov BYTE ptr [esi], 'm'
mov BYTE ptr [esi+1], 'r'
mov BYTE ptr [esi+2], 'g'
mov BYTE ptr [esi+3], 0
;计算 mrg 文件的文件名(包括路径)
invoke lstrcpy, addr filename, lpfolder
invoke lstrcat, addr filename, addr filetitle
invoke lstrcat, addr filename, addr fileExt
invoke CreateFile, addr filename, GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL
.IF eax==INVALID_HANDLE_VALUE
invoke MessageBox, NULL, addr strError02, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
mov hMrgFile, eax
;写入版本信息
invoke StrLen, addr strCopyright
mov ebx, eax
invoke WriteFile, hMrgFile, addr strCopyright, ebx, addr ActualReaded, NULL
;初始化一些数据
mov number, -1
mov eax, blocksize
mov BufCount, eax
invoke ReadFile, hSourceFile, addr buffer, 1024, addr ActualReaded, NULL
mov eax, ActualReaded
.WHILE eax!=0 ;文件没到末尾就继续读
;当一个分割文件写完后创建一个新的分割文件来写
mov eax, BufCount
.IF eax==blocksize
invoke CloseHandle, hDestFile
;计算分割文件的扩展名
inc number
invoke wsprintf, addr fileExt, addr format1, number
invoke lstrcpy, addr filename, lpfolder
invoke lstrcat, addr filename, addr filetitle
invoke lstrcat, addr filename, addr fileExt
invoke CreateFile, addr filename, GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL
.IF eax==INVALID_HANDLE_VALUE
invoke MessageBox, NULL, addr strError02, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
mov hDestFile, eax
mov BufCount, 0 ;每次新创建的分割文件,写入的大小为零
.ENDIF
;写入数据
mov ebx, ActualReaded
invoke WriteFile, hDestFile, addr buffer, ebx, addr ActualReaded, NULL
add BufCount, 1024 ;写入的大小递增
;根据已经读出的大小和需要分割文件的大小来设置进度条
invoke GetFileSize, hSourceFile, NULL
mov ebx, eax
mov eax, number
inc eax
mul blocksize
mov ecx, 100
mul ecx
div ebx
invoke SendMessage, hProgress, PBM_SETPOS, eax, 0
;读出数据
invoke ReadFile, hSourceFile, addr buffer, 1024, addr ActualReaded, NULL
mov eax, ActualReaded
.ENDW
;把分割文件的个数和原文件名(包括扩展名)写入 mrg 文件中
inc number
invoke wsprintf, addr fileExt, addr format1, number
invoke WriteFile, hMrgFile, addr fileExt, 3, addr ActualReaded, NULL
invoke StrLen, addr sourcefilename
mov ebx, eax
invoke WriteFile, hMrgFile, addr sourcefilename, ebx, addr ActualReaded, NULL
invoke CloseHandle, hMrgFile
invoke CloseHandle, hDestFile
invoke CloseHandle, hSourceFile
ret
Split endp
;=================================
; 合并过程
; 参数:待合并文件,存放目录
;=================================
Merge proc lpfile:DWORD, lpfolder:DWORD
local hSourceFile, hDestFile:DWORD
local buffer[1024]:BYTE ;缓冲区
local srcFolder[MAX_PATH]:BYTE ;分割文件所在目录
local filetitle[128]:BYTE ;文件名(不包括扩展名)
local fileExt[10]:BYTE ;扩展名
local filename[128]:BYTE ;文件名(包括路径和扩展名)
local nfile,ntotal:DWORD ;分割文件的个数
local number:DWORD ;用来计算扩展名
local ActualReaded:DWORD ;实际读出的字节
;没指定需要分割的文件
mov esi, lpfile
mov al, byte ptr [esi]
.IF al == 0
invoke MessageBox, NULL, addr strError05, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
;没指定分割后文件存放的目录
mov esi, lpfolder
mov al, byte ptr [esi]
.IF al == 0
invoke MessageBox, NULL, addr strError06, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
;打开 mrg 文件
invoke CreateFile, lpfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL
.IF eax==INVALID_HANDLE_VALUE
invoke MessageBox, NULL, addr strError01, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
mov hSourceFile, eax
;读出版本信息,比较是否为合法的文件
invoke StrLen, addr strCopyright
mov ebx, eax
invoke ReadFile, hSourceFile, addr buffer, ebx, addr ActualReaded, NULL
invoke lstrcmp, addr buffer, addr strCopyright
.IF eax!=0
invoke CloseHandle, hSourceFile
invoke MessageBox, NULL, addr strError07, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
;读出分割文件的个数,保存在 nfile 中
invoke ReadFile, hSourceFile, addr buffer, 3, addr ActualReaded, NULL
lea esi, buffer
xor eax, eax
mov al, byte ptr [esi]
sub al, 48
mov ebx, 100
mul ebx
mov nfile, eax
xor eax, eax
mov al, byte ptr [esi+1]
sub al, 48
mov ebx, 10
mul ebx
add nfile, eax
xor eax, eax
mov al, byte ptr [esi+2]
sub al, 48
add nfile, eax
mov ntotal, eax
;读出合并后的文件名(包括扩展名)
invoke RtlZeroMemory, addr buffer, 1024
invoke GetFileSize, hSourceFile, NULL
mov ebx, eax
invoke StrLen, addr strCopyright
sub ebx, eax
invoke ReadFile, hSourceFile, addr buffer, ebx, addr ActualReaded, NULL
invoke lstrcpy, addr filename, lpfolder
invoke lstrcat, addr filename, addr buffer
;创建文件准备写
invoke CreateFile, addr filename, GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL
.IF eax==INVALID_HANDLE_VALUE
invoke MessageBox, NULL, addr strError02, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
mov hDestFile, eax
;取得分割文件所在的目录
invoke GetFolder, addr srcFolder, lpfile
;计算文件名(不包括扩展名)
invoke lstrcpy, addr filetitle, addr buffer
lea esi, filetitle
mov ebx, esi
invoke StrLen, addr filetitle
add ebx, eax
labelLoop:
cmp BYTE ptr [esi], '.'
je labelQuit
inc esi
cmp esi, ebx
je labelQuit
jmp labelLoop
labelQuit:
mov BYTE ptr [esi], '.'
mov BYTE ptr [esi+1], 0
mov number, -1
.WHILE nfile ;用分割文件的个数来控制循环
invoke CloseHandle, hSourceFile
;计算扩展名,然后得出文件名(包括路径和扩展名)
inc number
invoke wsprintf, addr fileExt, addr format1, number
invoke lstrcpy, addr filename, addr srcFolder
invoke lstrcat, addr filename, addr filetitle
invoke lstrcat, addr filename, addr fileExt
;打开文件准备读
invoke CreateFile, addr filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL
.IF eax==INVALID_HANDLE_VALUE
invoke MessageBox, NULL, addr strError01, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
mov hSourceFile, eax
invoke ReadFile, hSourceFile, addr buffer, 1024, addr ActualReaded, NULL
mov eax, ActualReaded
.WHILE eax ;循环读,一直到文件末尾
mov ebx, eax
invoke WriteFile, hDestFile, addr buffer, ebx, addr ActualReaded, NULL
invoke ReadFile, hSourceFile, addr buffer, 1024, addr ActualReaded, NULL
mov eax, ActualReaded
.ENDW
dec nfile
mov eax, nfile
mov ebx, 100
mul ebx
div ntotal
invoke SendMessage, hProgress, PBM_SETPOS, eax, 0
.ENDW
invoke CloseHandle, hDestFile
invoke CloseHandle, hSourceFile
ret
Merge endp
end start
2010年09月27日
文章作者:一块三毛钱
;************************************************* ************
;* Author: 一块三毛钱
;* E_mail: crazy_soft@163.net
;* Homepage: http://zhongts.51.net
;************************************************* ************
;* Compile: Hutch's Masm32
;* Create Time: 2002.6.5
;* Modify: 2002.6.5
;* Description: 文件分割器 V1.10
;************************************************* ************
.386
.model flat,stdcall
option casemap:none
;************************************************* ***************************************
include ztsSplit.inc
include c:\masm32\include\windows.inc
include c:\masm32\include\user32.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\comdlg32.inc
include c:\masm32\include\comctl32.inc
include c:\masm32\include\shell32.inc
include c:\masm32\include\masm32.inc
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\comdlg32.lib
includelib c:\masm32\lib\comctl32.lib
includelib c:\masm32\lib\shell32.lib
includelib c:\masm32\lib\masm32.lib
;************************************************* ***************************************
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD
SetToolTip proto :DWORD
GetFolder proto :DWORD,:DWORD
SizeEditProc proto :DWORD,:DWORD,:DWORD,:DWORD
FileEditProc proto :DWORD,:DWORD,:DWORD,:DWORD
FolderEditProc proto :DWORD,:DWORD,:DWORD,:DWORD
Split proto :DWORD,:DWORD,:DWORD
Merge proto :DWORD,:DWORD
;************************************************* ***************************************
.data
AppName db "ztsSplit",0
DlgName db "DLG_MAIN",0
TooltipClassName db "Tooltips_class32",0
strSysMenu db "窗口处在最上",0
strBtnStart01 db "分割(&C)",0
strBtnStart02 db "合并(&M)",0
strMergeExt db ".mrg",0
strTitleSplit db "选择要分割的文件",0
strTitleMerge db "选择要合并的文件",0
strFilterSplit db "所有文件(*.*)",0,"*.*",0,0
strFilterMerge db "合并信息文件(*.mrg)",0,"*.mrg",0,0
strBrowseTitle db "选择文件存放目录:",0
strFolderInfo db "分割软件 ztsSplit 所在的目录",0
strIniFileName db "desktop.ini",0
strIniFileSection db ".ShellClassInfo",0
strIniFileKeyValue db "InfoTip=分割软件 ztsSplit 所在的目录",0
db "IconIndex=1",0
db "IconFile=\",0,0
strError01 db "打开文件出错",0
strError02 db "文件创建错误",0
strError03 db "文件太小,不需要分割",0
strError04 db "请先指定分割的大小",0
strError05 db "请先选择需要分割/合并的文件",0
strError06 db "请选择分割/合并后文件存放的目录",0
strError07 db "没有合并信息,不能正确合并文件",0
strCopyright db "ztsmrg1.1该文件由分割软件 ztsSplit 生成",0
strBatCopy db "copy /b ",0
format1 db "%03d",0
.data?
hInstance HINSTANCE ?
hToolTip dd ? ;工具提示控件的句柄
hSysMenu dd ? ;系统菜单句柄
hProgress dd ? ;进度条句柄
hEditFile dd ? ;文件名编辑框句柄
hEditFolder dd ? ;目录编辑框句柄
hEditSize dd ? ;分割大小编辑框句柄
hBtnStart dd ? ;分割/合并按钮的句柄
hBtnExit dd ? ;退出按钮的句柄
hBtnFile dd ?
hBtnFolder dd ?
bSplitOrMerge BOOL ? ;分割还是合并
bKbOrMb BOOL ? ;分割大小的单位是 KB 还是 MB
bSizeEditFocus BOOL ? ;"分割大小"编辑框是否拥有焦点
bFileEditFocus BOOL ? ;"文件名"编辑框是否拥有焦点
bFolderEditFocus BOOL ? ;"目录"编辑框是否拥有焦点
strPath db MAX_PATH dup (?) ;接收拖动来的文件名
strFolder db MAX_PATH dup (?) ;文件所在的目录
strFileName db MAX_PATH dup (?) ;可执行文件路径
strModuleDir db MAX_PATH dup (?) ;可执行文件所在的目录
strIniFilePath db MAX_PATH dup (?)
ofn OPENFILENAME
bi BROWSEINFO
OldSizeEditProc dd ?
OldFileEditProc dd ?
OldFolderEditProc dd ?
;************************************************* ***************************************
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,addr DlgName,NULL,addr DlgProc,0
invoke ExitProcess,eax
invoke InitCommonControls
;对话框窗口过程************************************************** ************************
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
local rect:RECT
local pt:POINT
.IF uMsg==WM_CLOSE
invoke GetModuleFileName, hInstance, addr strFileName, MAX_PATH ;取得文件名
invoke GetFolder, addr strModuleDir, addr strFileName ;计算所属目录
invoke SetFileAttributes,addr strModuleDir, FILE_ATTRIBUTE_SYSTEM ;设置目录属性为系统属性
;计算 desktop.ini 文件的文件名(包括目录)
invoke lstrcat, addr strIniFilePath, addr strModuleDir
invoke lstrcat, addr strIniFilePath, addr strIniFileName
;计算 desktop.ini 文件中需要写入的内容
mov esi, offset strFileName
mov edi, offset strIniFileKeyValue
labelLoop:
cmp BYTE ptr [edi], '\'
je labelQuit
inc edi
jmp labelLoop
labelQuit:
invoke StrLen, addr strFileName
mov ecx, eax
rep movsd
;写入 desktop.ini 文件
invoke WritePrivateProfileSection, addr strIniFileSection, addr strIniFileKeyValue, addr strIniFilePath
invoke SetFileAttributes, addr strIniFilePath, FILE_ATTRIBUTE_HIDDEN ;设置文件属性为隐藏
invoke EndDialog, hWnd, NULL
.ELSEIF uMsg==WM_INITDIALOG
;设置图标
invoke LoadIcon, hInstance, IDI_MAIN
invoke SendMessage, hWnd, WM_SETICON, ICON_SMALL, eax
;添加系统菜单项:"窗口处在最上"
invoke GetSystemMenu, hWnd, FALSE ;取得系统菜单的句柄
mov hSysMenu, eax ;句柄 => hSysMenu
invoke AppendMenu, hSysMenu, MF_SEPARATOR, NULL,NULL ;插入分隔线
invoke AppendMenu, hSysMenu, MF_STRING or MF_UNCHECKED, IDM_SYSMENU, addr strSysMenu ;插入"窗口处在最上"菜单
;取得几个控件的句柄
invoke GetDlgItem, hWnd, IDC_PROGRESS
mov hProgress, eax
invoke GetDlgItem, hWnd, IDC_EDIT_FILE
mov hEditFile, eax
invoke GetDlgItem, hWnd, IDC_EDIT_FOLDER
mov hEditFolder, eax
invoke GetDlgItem, hWnd, IDC_EDIT_SIZE
mov hEditSize, eax
invoke GetDlgItem, hWnd, IDC_BTN_START
mov hBtnStart, eax
invoke GetDlgItem, hWnd, IDC_BTN_EXIT
mov hBtnExit, eax
invoke GetDlgItem, hWnd, IDC_BTN_FILE
mov hBtnFile, eax
invoke GetDlgItem, hWnd, IDC_BTN_FOLDER
mov hBtnFolder, eax
;初始化为"分割文件""KB"方式
invoke GetDlgItem, hWnd, IDC_RADIO_SPLIT
invoke SendMessage, eax, BM_SETCHECK,BST_CHECKED,0
mov bSplitOrMerge, TRUE
invoke GetDlgItem, hWnd, IDC_RADIO_KB
invoke SendMessage, eax, BM_SETCHECK,BST_CHECKED,0
mov bKbOrMb, TRUE
;创建工具提示控件
invoke CreateWindowEx, NULL, addr TooltipClassName, NULL, TTS_ALWAYSTIP, \
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, \
NULL, NULL, hInstance, NULL
mov hToolTip, eax
invoke SetWindowPos, hToolTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE
;设置所有的提示信息
invoke SetToolTip, hWnd
;子类化编辑框控件
invoke SetWindowLong, hEditSize, GWL_WNDPROC, addr SizeEditProc
mov OldSizeEditProc, eax
mov bSizeEditFocus, FALSE
invoke SetWindowLong, hEditFile, GWL_WNDPROC, addr FileEditProc
mov OldFileEditProc, eax
mov bFileEditFocus, FALSE
invoke SetWindowLong, hEditFolder, GWL_WNDPROC, addr FolderEditProc
mov OldFolderEditProc, eax
mov bFolderEditFocus, FALSE
invoke SetFocus, hEditFile ;设置焦点,加了这条语句后下面要用 mov eax, FLASE / ret ,否则无效
mov eax, FALSE
ret
.ELSEIF uMsg==WM_COMMAND
mov eax, wParam
and eax, 0ffffh
.IF eax==IDC_RADIO_SPLIT ;切换到分割状态
.IF !bSplitOrMerge
invoke GetDlgItem, hWnd, IDC_EDIT_SIZE
invoke EnableWindow, eax, TRUE
invoke GetDlgItem, hWnd, IDC_RADIO_KB
invoke EnableWindow, eax, TRUE
invoke GetDlgItem, hWnd, IDC_RADIO_MB
invoke EnableWindow, eax, TRUE
invoke GetDlgItem, hWnd, IDC_BTN_START
invoke SetWindowText, eax, addr strBtnStart01
mov bSplitOrMerge, TRUE
.ENDIF
.ELSEIF eax==IDC_RADIO_MERGE ;切换到合并状态
.IF bSplitOrMerge
invoke GetDlgItem, hWnd, IDC_EDIT_SIZE
invoke EnableWindow, eax, FALSE
invoke GetDlgItem, hWnd, IDC_RADIO_KB
invoke EnableWindow, eax, FALSE
invoke GetDlgItem, hWnd, IDC_RADIO_MB
invoke EnableWindow, eax, FALSE
invoke GetDlgItem, hWnd, IDC_BTN_START
invoke SetWindowText, eax, addr strBtnStart02
mov bSplitOrMerge, FALSE
.ENDIF
.ELSEIF eax==IDC_RADIO_KB ;分割大小的单位是 KB
.IF !bKbOrMb
mov bKbOrMb, TRUE
invoke SetFocus, hEditSize ;"分割大小"编辑框得到焦点
.ENDIF
.ELSEIF eax==IDC_RADIO_MB ;分割大小的单位是 MB
.IF bKbOrMb
mov bKbOrMb, FALSE
invoke SetFocus, hEditSize ;"分割大小"编辑框得到焦点
.ENDIF
.ELSEIF eax==IDC_BTN_FILE ;选择要分割/合并的文件
mov ofn.lStructSize, sizeof ofn
push hWnd
pop ofn.hwndOwner
push hInstance
pop ofn.hInstance
mov ofn.lpstrFile, offset strPath ;接收文件名
mov ofn.nMaxFile, MAX_PATH
mov ofn.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_HIDEREADONLY or OFN_EXPLORER or OFN_LONGNAMES
.IF bSplitOrMerge ;分割状态
mov ofn.lpstrFilter, offset strFilterSplit ;文件过滤器
mov ofn.lpstrTitle, offset strTitleSplit ;标题文本
.ELSE ;合并状态
mov ofn.lpstrFilter, offset strFilterMerge ;文件过滤器
mov ofn.lpstrTitle, offset strTitleMerge ;标题文本
.ENDIF
invoke GetOpenFileName, addr ofn
.IF eax
invoke SetDlgItemText, hWnd, IDC_EDIT_FILE, addr strPath
invoke GetFolder, addr strFolder, addr strPath
invoke SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strFolder
.IF bSplitOrMerge
invoke SetFocus, hEditSize ;"分割大小"编辑框得到焦点
.ELSE
invoke SetFocus, hBtnStart ;"分割/合并"按钮得到焦点
.ENDIF
.ENDIF
.ELSEIF eax==IDC_BTN_FOLDER ;选择分割/合并后文件的存放目录
invoke RtlZeroMemory, addr bi, sizeof BROWSEINFO ;内存清零
push hWnd
pop bi.hwndOwner
mov eax, offset strFolder ;接收目录字符串
mov bi.pszDisplayName, eax
mov eax, offset strBrowseTitle ;目录选择框上面的文本
mov bi.lpszTitle, eax
mov bi.ulFlags, BIF_RETURNONLYFSDIRS ;选择目录
invoke SHBrowseForFolder, addr bi
.IF eax
invoke SHGetPathFromIDList, eax, addr strFolder ;转换 PIDL 为目录名
invoke StrLen, addr strFolder ;取得字符串长度
mov esi, offset strFolder ;esi 指向开始的位置
add esi, eax ;esi 指向结束的位置
cmp BYTE ptr [esi-1], '\' ;判断是不是以'\'结尾
je labelExit
mov BYTE ptr [esi], '\' ;如果不是则添加一个'\'
mov BYTE ptr [esi+1], 0
labelExit:
invoke SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strFolder
invoke SetForegroundWindow, hWnd ;激活窗口
.IF bSplitOrMerge
invoke SetFocus, hEditSize ;"分割大小"编辑框得到焦点
.ELSE
invoke SetFocus, hBtnStart ;"分割/合并"按钮得到焦点
.ENDIF
.ENDIF
.ELSEIF eax==IDC_BTN_START
.IF bSplitOrMerge
invoke GetDlgItemInt, hWnd, IDC_EDIT_SIZE, NULL, FALSE
.IF bKbOrMb
shl eax, 10
.ELSE
shl eax, 20
.ENDIF
invoke Split, addr strPath, addr strFolder, eax
invoke SendMessage, hProgress, PBM_SETPOS, 0, 0
.ELSE
invoke Merge, addr strPath, addr strFolder
invoke SendMessage, hProgress, PBM_SETPOS, 0, 0
.ENDIF
.ELSEIF eax==IDC_BTN_EXIT
invoke SendMessage, hWnd, WM_CLOSE, 0, 0
.ENDIF
.ELSEIF uMsg==WM_SYSCOMMAND
mov eax,wParam
movzx eax,ax
.IF eax==IDM_SYSMENU
invoke GetMenuState, hSysMenu, IDM_SYSMENU, MF_BYCOMMAND
.IF (eax & MF_CHECKED) ;判断菜单是否是选中的
invoke CheckMenuItem, hSysMenu, IDM_SYSMENU, MF_UNCHECKED
invoke SetWindowPos, hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE
.ELSE
invoke CheckMenuItem, hSysMenu, IDM_SYSMENU, MF_CHECKED
invoke SetWindowPos, hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE
.ENDIF
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
.ENDIF
.ELSEIF uMsg==WM_DROPFILES
invoke DragQueryFile, wParam, 0, addr strPath, MAX_PATH ;得到文件路径
invoke GetFileAttributes, addr strPath ;取得文件属性,判断是否文件夹
and eax, FILE_ATTRIBUTE_DIRECTORY
.IF eax ;如果是文件夹
invoke SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strPath
invoke SetForegroundWindow, hWnd ;激活窗口
.IF bSplitOrMerge
invoke SetFocus, hEditSize ;"分割大小"编辑框得到焦点
.ELSE
invoke SetFocus, hBtnStart ;"分割/合并"按钮得到焦点
.ENDIF
.ELSE
.IF bSplitOrMerge ;当前为分割状态
invoke SetDlgItemText, hWnd, IDC_EDIT_FILE, addr strPath
invoke GetFolder, addr strFolder, addr strPath
invoke SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strFolder
invoke SetForegroundWindow, hWnd ;激活窗口
invoke SetFocus, hEditSize ;"分割大小"编辑框得到焦点
.ELSE ;当前为合并状态
mov esi, offset strPath
invoke StrLen, addr strPath
add esi, eax
sub esi, 4
invoke lstrcmp, esi, addr strMergeExt ;判断最后 4 个字符是否为 ".mrg"
.IF eax==0
invoke SetDlgItemText, hWnd, IDC_EDIT_FILE, addr strPath
invoke GetFolder, addr strFolder, addr strPath
invoke SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strFolder
invoke SetForegroundWindow, hWnd ;激活窗口
invoke SetFocus, hBtnStart ;"分割/合并"按钮得到焦点
.ENDIF
.ENDIF
.ENDIF
invoke DragFinish,wParam ;释放内存
.ELSE
mov eax,FALSE
ret
.ENDIF
mov eax,TRUE
ret
DlgProc endp
;==========================================
; 设置所有提示信息
;==========================================
SetToolTip proc hWnd:DWORD
local ti:TOOLINFO
mov ti.cbSize, sizeof TOOLINFO
mov ti.uFlags, TTF_SUBCLASS or TTF_IDISHWND
push hWnd
pop ti.hWnd
;先设置主界面提示信息
push hWnd
pop ti.uId
mov ti.lpszText, offset strMainTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;------------------------------------------------
; 设置其他控件的提示信息
;------------------------------------------------
;"分割文件"单选框提示信息
invoke GetDlgItem, hWnd, IDC_RADIO_SPLIT
mov ti.uId, eax
mov ti.lpszText, offset strSplitTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"合并文件"单选框提示信息
invoke GetDlgItem, hWnd, IDC_RADIO_MERGE
mov ti.uId, eax
mov ti.lpszText, offset strMergeTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"文件名"编辑框提示信息
invoke GetDlgItem, hWnd, IDC_EDIT_FILE
mov ti.uId, eax
mov ti.lpszText, offset strFileTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"目录"编辑框提示信息
invoke GetDlgItem, hWnd, IDC_EDIT_FOLDER
mov ti.uId, eax
mov ti.lpszText, offset strFolderTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"选择文件"按钮提示信息
invoke GetDlgItem, hWnd, IDC_BTN_FILE
mov ti.uId, eax
mov ti.lpszText, offset strBtnFileTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"选择文件夹"按钮提示信息
invoke GetDlgItem, hWnd, IDC_BTN_FOLDER
mov ti.uId, eax
mov ti.lpszText, offset strBtnFolderTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"分割大小"编辑框提示信息
invoke GetDlgItem, hWnd, IDC_EDIT_SIZE
mov ti.uId, eax
mov ti.lpszText, offset strSizeTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"KB"单选框提示信息
invoke GetDlgItem, hWnd, IDC_RADIO_KB
mov ti.uId, eax
mov ti.lpszText, offset strKbTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"MB"单选框提示信息
invoke GetDlgItem, hWnd, IDC_RADIO_MB
mov ti.uId, eax
mov ti.lpszText, offset strMbTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;进度条提示信息
invoke GetDlgItem, hWnd, IDC_PROGRESS
mov ti.uId, eax
mov ti.lpszText, offset strProgressTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"分割/合并"按钮提示信息
invoke GetDlgItem, hWnd, IDC_BTN_START
mov ti.uId, eax
mov ti.lpszText, offset strStartTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
;"退出"按钮提示信息
invoke GetDlgItem, hWnd, IDC_BTN_EXIT
mov ti.uId, eax
mov ti.lpszText, offset strExitTip
invoke SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti
ret
SetToolTip endp
;==========================================
; 根据文件名得到文件夹
;==========================================
GetFolder proc lpFolder:HWND, lpFile:DWORD
;把 lpFile 地址处的字符串传送到 lpFolder 地址处
mov esi, lpFile
mov edi, lpFolder
invoke StrLen, lpFile
mov ecx, eax
rep movsd
mov esi, lpFolder ; esi 指向 lpFolder,也就是字符串开始的位置
add esi, eax ; esi 加上 eax(字符串长度)后指向字符串结束的位置
dec esi ; esi 指向字符串末尾的一个字符
;从字符串末尾向前测试每一个字符,如果为 '\' 则说明再往前就是文件夹
labelTest:
cmp BYTE ptr [esi], '\'
je labelExit
dec esi
jmp labelTest
labelExit:
inc esi
mov BYTE ptr [esi], 0
ret
GetFolder endp
;==========================================
; "分割大小"编辑框窗口过程
; 当窗口获得焦点时选中所有文本
;==========================================
SizeEditProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_SETFOCUS
mov bSizeEditFocus, TRUE ;拥有焦点
invoke SendMessage, hWnd, EM_SETSEL, 0, -1 ;选中全部文本
invoke CallWindowProc, OldSizeEditProc, hWnd, uMsg, wParam, lParam
ret
.ELSEIF uMsg==WM_LBUTTONDOWN
.IF !bSizeEditFocus ;如果没有焦点
invoke SetFocus, hWnd ;则设置焦点
.ELSE ;如果已经有焦点,则按缺省处理
invoke CallWindowProc, OldSizeEditProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
.ELSEIF uMsg==WM_KILLFOCUS
mov bSizeEditFocus, FALSE ;失去焦点
invoke CallWindowProc, OldSizeEditProc, hWnd, uMsg, wParam, lParam
ret
.ELSE
invoke CallWindowProc, OldSizeEditProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
xor eax, eax
ret
SizeEditProc endp
;================================================= =
; "文件名"编辑框窗口过程
; 当窗口获得焦点时光标滚到最后,方便修改
; 当窗口失去焦点时光标滚到最前,方便观看
;================================================= =
FileEditProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_SETFOCUS
mov bFileEditFocus, TRUE ;拥有焦点
invoke SendMessage, hWnd, WM_GETTEXTLENGTH, 0, 0 ;取得文本长度
invoke SendMessage, hWnd, EM_SETSEL, eax, eax ;光标滚到最后
invoke CallWindowProc, OldFileEditProc, hWnd, uMsg, wParam, lParam
ret
.ELSEIF uMsg==WM_LBUTTONDOWN
.IF !bFileEditFocus ;如果没有焦点
invoke SetFocus, hWnd ;则设置焦点
.ELSE ;如果已经有焦点,则按缺省处理
invoke CallWindowProc, OldFileEditProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
.ELSEIF uMsg==WM_KILLFOCUS
mov bFileEditFocus, FALSE ;失去焦点
invoke SendMessage, hWnd, EM_SETSEL, 0, 0 ;光标滚到最前
invoke CallWindowProc, OldFileEditProc, hWnd, uMsg, wParam, lParam
ret
.ELSE
invoke CallWindowProc, OldFileEditProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
xor eax, eax
ret
FileEditProc endp
;================================================= =
; "目录"编辑框窗口过程
; 当窗口获得焦点时光标滚到最后,方便修改
; 当窗口失去焦点时光标滚到最前,方便观看
;================================================= =
FolderEditProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_SETFOCUS
mov bFolderEditFocus, TRUE ;拥有焦点
invoke SendMessage, hWnd, WM_GETTEXTLENGTH, 0, 0 ;取得文本长度
invoke SendMessage, hWnd, EM_SETSEL, eax, eax ;光标滚到最后
invoke CallWindowProc, OldFolderEditProc, hWnd, uMsg, wParam, lParam
ret
.ELSEIF uMsg==WM_LBUTTONDOWN
.IF !bFolderEditFocus ;如果没有焦点
invoke SetFocus, hWnd ;则设置焦点
.ELSE ;如果已经有焦点,则按缺省处理
invoke CallWindowProc, OldFolderEditProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
.ELSEIF uMsg==WM_KILLFOCUS
mov bFolderEditFocus, FALSE ;失去焦点
invoke SendMessage, hWnd, EM_SETSEL, 0, 0 ;光标滚到最前
invoke CallWindowProc, OldFolderEditProc, hWnd, uMsg, wParam, lParam
ret
.ELSE
invoke CallWindowProc, OldFolderEditProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
xor eax, eax
ret
FolderEditProc endp
;=========================================
; 分割过程
; 参数:待分割文件,存放目录,分割大小
;=========================================
Split proc lpfile:DWORD, lpfolder:DWORD, blocksize:DWORD
local hSourceFile, hDestFile:DWORD
local hMrgFile:DWORD
local buffer[1024]:BYTE ;缓冲区
local sourcefilename[128]:BYTE ;被分割的文件名(包括扩展名)
local filetitle[128]:BYTE ;文件名(不包括扩展名)
local fileExt[10]:BYTE ;扩展名
local filename[128]:BYTE ;文件名(包括路径和扩展名)
local ActualReaded:DWORD ;实际读出来的字节
local BufCount:DWORD ;记录每个分割文件已经写入的字节
local number:DWORD ;分割文件的个数
;没指定需要分割的文件
mov esi, lpfile
mov al, byte ptr [esi]
.IF al == 0
invoke MessageBox, NULL, addr strError05, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
;没指定分割后文件存放的目录
mov esi, lpfolder
mov al, byte ptr [esi]
.IF al == 0
invoke MessageBox, NULL, addr strError06, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
;没指定分割大小
.IF blocksize==0
invoke MessageBox, NULL, addr strError04, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
;打开文件失败
invoke CreateFile, lpfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL
.IF eax==INVALID_HANDLE_VALUE
invoke MessageBox, NULL, addr strError01, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
mov hSourceFile, eax
;文件太小(比指定的分割大小)
invoke GetFileSize, hSourceFile, NULL
.IF eax<blocksize
invoke CloseHandle, hSourceFile
invoke MessageBox, NULL, addr strError03, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
;计算文件名(包括扩展名)
mov esi, lpfile
lea edi, filetitle
invoke StrLen, lpfile
add esi, eax
xor ecx, ecx
labelTest:
cmp BYTE ptr [esi], '\'
je labelExit
dec esi
inc ecx
jmp labelTest
labelExit:
inc esi
dec ecx
rep movsd
invoke lstrcpy, addr sourcefilename, addr filetitle ;保存文件名到 sourcefilename 中
;计算文件名(不包括扩展名)
lea esi, filetitle
mov ebx, esi
invoke StrLen, addr filetitle
add ebx, eax
labelLoop:
cmp BYTE ptr [esi], '.'
je labelQuit
inc esi
cmp esi, ebx
je labelQuit
jmp labelLoop
labelQuit:
mov BYTE ptr [esi], '.'
mov BYTE ptr [esi+1], 0
;mrg 文件的扩展名
lea esi, fileExt
mov BYTE ptr [esi], 'm'
mov BYTE ptr [esi+1], 'r'
mov BYTE ptr [esi+2], 'g'
mov BYTE ptr [esi+3], 0
;计算 mrg 文件的文件名(包括路径)
invoke lstrcpy, addr filename, lpfolder
invoke lstrcat, addr filename, addr filetitle
invoke lstrcat, addr filename, addr fileExt
invoke CreateFile, addr filename, GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL
.IF eax==INVALID_HANDLE_VALUE
invoke MessageBox, NULL, addr strError02, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
mov hMrgFile, eax
;写入版本信息
invoke StrLen, addr strCopyright
mov ebx, eax
invoke WriteFile, hMrgFile, addr strCopyright, ebx, addr ActualReaded, NULL
;初始化一些数据
mov number, -1
mov eax, blocksize
mov BufCount, eax
invoke ReadFile, hSourceFile, addr buffer, 1024, addr ActualReaded, NULL
mov eax, ActualReaded
.WHILE eax!=0 ;文件没到末尾就继续读
;当一个分割文件写完后创建一个新的分割文件来写
mov eax, BufCount
.IF eax==blocksize
invoke CloseHandle, hDestFile
;计算分割文件的扩展名
inc number
invoke wsprintf, addr fileExt, addr format1, number
invoke lstrcpy, addr filename, lpfolder
invoke lstrcat, addr filename, addr filetitle
invoke lstrcat, addr filename, addr fileExt
invoke CreateFile, addr filename, GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL
.IF eax==INVALID_HANDLE_VALUE
invoke MessageBox, NULL, addr strError02, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
mov hDestFile, eax
mov BufCount, 0 ;每次新创建的分割文件,写入的大小为零
.ENDIF
;写入数据
mov ebx, ActualReaded
invoke WriteFile, hDestFile, addr buffer, ebx, addr ActualReaded, NULL
add BufCount, 1024 ;写入的大小递增
;根据已经读出的大小和需要分割文件的大小来设置进度条
invoke GetFileSize, hSourceFile, NULL
mov ebx, eax
mov eax, number
inc eax
mul blocksize
mov ecx, 100
mul ecx
div ebx
invoke SendMessage, hProgress, PBM_SETPOS, eax, 0
;读出数据
invoke ReadFile, hSourceFile, addr buffer, 1024, addr ActualReaded, NULL
mov eax, ActualReaded
.ENDW
;把分割文件的个数和原文件名(包括扩展名)写入 mrg 文件中
inc number
invoke wsprintf, addr fileExt, addr format1, number
invoke WriteFile, hMrgFile, addr fileExt, 3, addr ActualReaded, NULL
invoke StrLen, addr sourcefilename
mov ebx, eax
invoke WriteFile, hMrgFile, addr sourcefilename, ebx, addr ActualReaded, NULL
invoke CloseHandle, hMrgFile
invoke CloseHandle, hDestFile
invoke CloseHandle, hSourceFile
ret
Split endp
;=================================
; 合并过程
; 参数:待合并文件,存放目录
;=================================
Merge proc lpfile:DWORD, lpfolder:DWORD
local hSourceFile, hDestFile:DWORD
local buffer[1024]:BYTE ;缓冲区
local srcFolder[MAX_PATH]:BYTE ;分割文件所在目录
local filetitle[128]:BYTE ;文件名(不包括扩展名)
local fileExt[10]:BYTE ;扩展名
local filename[128]:BYTE ;文件名(包括路径和扩展名)
local nfile,ntotal:DWORD ;分割文件的个数
local number:DWORD ;用来计算扩展名
local ActualReaded:DWORD ;实际读出的字节
;没指定需要分割的文件
mov esi, lpfile
mov al, byte ptr [esi]
.IF al == 0
invoke MessageBox, NULL, addr strError05, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
;没指定分割后文件存放的目录
mov esi, lpfolder
mov al, byte ptr [esi]
.IF al == 0
invoke MessageBox, NULL, addr strError06, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
;打开 mrg 文件
invoke CreateFile, lpfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL
.IF eax==INVALID_HANDLE_VALUE
invoke MessageBox, NULL, addr strError01, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
mov hSourceFile, eax
;读出版本信息,比较是否为合法的文件
invoke StrLen, addr strCopyright
mov ebx, eax
invoke ReadFile, hSourceFile, addr buffer, ebx, addr ActualReaded, NULL
invoke lstrcmp, addr buffer, addr strCopyright
.IF eax!=0
invoke CloseHandle, hSourceFile
invoke MessageBox, NULL, addr strError07, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
;读出分割文件的个数,保存在 nfile 中
invoke ReadFile, hSourceFile, addr buffer, 3, addr ActualReaded, NULL
lea esi, buffer
xor eax, eax
mov al, byte ptr [esi]
sub al, 48
mov ebx, 100
mul ebx
mov nfile, eax
xor eax, eax
mov al, byte ptr [esi+1]
sub al, 48
mov ebx, 10
mul ebx
add nfile, eax
xor eax, eax
mov al, byte ptr [esi+2]
sub al, 48
add nfile, eax
mov ntotal, eax
;读出合并后的文件名(包括扩展名)
invoke RtlZeroMemory, addr buffer, 1024
invoke GetFileSize, hSourceFile, NULL
mov ebx, eax
invoke StrLen, addr strCopyright
sub ebx, eax
invoke ReadFile, hSourceFile, addr buffer, ebx, addr ActualReaded, NULL
invoke lstrcpy, addr filename, lpfolder
invoke lstrcat, addr filename, addr buffer
;创建文件准备写
invoke CreateFile, addr filename, GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL
.IF eax==INVALID_HANDLE_VALUE
invoke MessageBox, NULL, addr strError02, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
mov hDestFile, eax
;取得分割文件所在的目录
invoke GetFolder, addr srcFolder, lpfile
;计算文件名(不包括扩展名)
invoke lstrcpy, addr filetitle, addr buffer
lea esi, filetitle
mov ebx, esi
invoke StrLen, addr filetitle
add ebx, eax
labelLoop:
cmp BYTE ptr [esi], '.'
je labelQuit
inc esi
cmp esi, ebx
je labelQuit
jmp labelLoop
labelQuit:
mov BYTE ptr [esi], '.'
mov BYTE ptr [esi+1], 0
mov number, -1
.WHILE nfile ;用分割文件的个数来控制循环
invoke CloseHandle, hSourceFile
;计算扩展名,然后得出文件名(包括路径和扩展名)
inc number
invoke wsprintf, addr fileExt, addr format1, number
invoke lstrcpy, addr filename, addr srcFolder
invoke lstrcat, addr filename, addr filetitle
invoke lstrcat, addr filename, addr fileExt
;打开文件准备读
invoke CreateFile, addr filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL
.IF eax==INVALID_HANDLE_VALUE
invoke MessageBox, NULL, addr strError01, addr AppName, MB_OK or MB_ICONERROR
ret
.ENDIF
mov hSourceFile, eax
invoke ReadFile, hSourceFile, addr buffer, 1024, addr ActualReaded, NULL
mov eax, ActualReaded
.WHILE eax ;循环读,一直到文件末尾
mov ebx, eax
invoke WriteFile, hDestFile, addr buffer, ebx, addr ActualReaded, NULL
invoke ReadFile, hSourceFile, addr buffer, 1024, addr ActualReaded, NULL
mov eax, ActualReaded
.ENDW
dec nfile
mov eax, nfile
mov ebx, 100
mul ebx
div ntotal
invoke SendMessage, hProgress, PBM_SETPOS, eax, 0
.ENDW
invoke CloseHandle, hDestFile
invoke CloseHandle, hSourceFile
ret
Merge endp
end start