世味年来薄似纱,谁令骑马客京华?
小楼一夜听春雨,深巷明朝卖杏花。
矮纸斜行闲作草,晴窗细乳戏分茶。
素衣莫起风尘叹,犹及清明可到家。
缘起《圆月弯刀》之“小楼一夜听春雨”,才感此作之魅。
芳草惜惜,幽谷秀。花香怡怡,缤彩蝶。
轻抚玄琴奏妙曲,小楼听雨舞弯刀,皆往矣!
爱也罢,恨也罢,寻寻觅觅。此情可待,却已成追忆!
流星逝去,而今,只剩孤魂飘零明月间。
于是来了兴致,才有此文。
细说打开文件对话框 OPENFILENAME结构的OFN_ALLOWMULTISELECT 位标记(指定文件名列表框允许多选)。
对于这个属性相信许多人很纠结,主要是在单选与多选时是不同的。
看看数据区就知道了:
图1 单选文件
图2 多选文件
发现单选文件时,得到的是形如
"C:/Documents and Settings/Administrator/桌面/myOK/小楼一夜听春雨,深巷明朝卖杏花。.txt "的全路径。
而多选文件时,得到的是形如
"C:/Documents and Settings/Administrator/桌面/myOK” “ 小楼一夜听春雨,深巷明朝卖杏花。.txt "
"世味年来薄似纱,谁令骑马客京华?.asm"
为什么要分析这个东西呢,主要有以下几点:
1.为文件的选择提供一个统一处理接口
2.实现文件扩展名的提取与识别
3.为文件列表(比如播放文件列表)的形成提供一点思路。
程序花了一上午才写好,丢人了嘿嘿。c程序就不晒了,只写了个Win32汇编的,慢慢看。
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;1.为文件的选择提供一个统一处理接口
;2.实现文件扩展名的提取与识别
;3.为文件列表(比如播放文件列表)的形成提供一点思路。
;By GoldenSpider 2010-6-21 QQ:287014897
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none ; case sensitive
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
includelib kernel32.lib
includelib user32.lib
includelib gdi32.lib
includelib comctl32.lib
includelib comdlg32.lib
include windows.inc
include kernel32.inc
include user32.inc
include gdi32.inc
include comctl32.inc
include comdlg32.inc
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DLG_MAIN equ 1000
ID_BROWSE equ 1001
ID_FILE equ 1002
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hWinMain dd ?
hInstance dd ?
lpBuffer dd ?
szBuffer db MAX_PATH*40 dup (?) ;多个文件名使用的缓冲区
szTemp db MAX_PATH dup (?) ;保存文件名路径前缀
szTemp1 db MAX_PATH dup (?)
szTemp2 db MAX_PATH dup (?)
szPath db MAX_PATH dup (?)
;buf db 256 dup(?)
stOpenFileName OPENFILENAME <?>
.data
inform db 0dh,0ah,0
szTitleSave db " 叶听雨 By G-Spider",0
szTitleMesg db " 临安春雨初霁 陆游",0
szExt db '*.txt;*.c',0
szFilter db 'Files(*.txt,*.c)',0,'*.txt;*.c',0,'ALL Files(*.*)',0,'*.*',0,0
;buffmt db "%d",0 ;///用于数值数据测试
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 子程序声明
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
_GetFileName PROTO
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;*******************************************************************
;文件处理,Good job! By GoldenSpider
;功能: 不论单选多选,均将由得到的lpstrFile全路径
; 分割为A="***/" B="***" "***"..."***" 其中A为全路径前缀,B为各文件名(包含扩展名)
;返回值:B的头指针(不包括全路径前缀A,前缀A存入szTemp缓存中)
;举例1:单选得到"D:/masm32/my.asm"分割为:A="D:/masm32/" B="my.asm"
;举例2:多选得到"D:/masm32" "my.asm" "my1.c"处理为:A="D:/masm32/" B="my.asm" "my1.c"
; 以上两例返回值均为"my.asm"的头指针 ,串"D:/masm32/"在szTemp缓存中
;*******************************************************************
_GetFileName proc
mov stOpenFileName.Flags,OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST
mov stOpenFileName.lStructSize,SIZEOF stOpenFileName
mov eax,hWinMain
mov stOpenFileName.hWndOwner,eax
mov stOpenFileName.lpstrFilter,offset szFilter
mov stOpenFileName.lpstrFile,offset szBuffer
mov stOpenFileName.nMaxFile,MAX_PATH
mov stOpenFileName.lpstrInitialDir,0
mov stOpenFileName.lpstrTitle,offset szTitleMesg
mov stOpenFileName.lpstrDefExt,offset szExt
mov stOpenFileName.Flags,OFN_HIDEREADONLY or OFN_FILEMUSTEXIST /
or OFN_PATHMUSTEXIST or OFN_EXPLORER or OFN_ALLOWMULTISELECT
invoke GetOpenFileName,offset stOpenFileName
.if eax == FALSE
ret
.endif
invoke SetDlgItemText,hWinMain,ID_FILE,addr szBuffer
xor ebx,ebx
mov bx,stOpenFileName.nFileOffset
invoke lstrcpyn,offset szTemp,offset szBuffer, ebx ;///得到A串
;以下处理尾符'/'
invoke lstrlen,offset szTemp
lea esi,szTemp
add esi,eax
xor eax,eax
mov al,'/'
.if BYTE PTR [esi-1]!=al
mov WORD ptr [esi],ax
.endif
xor ebx,ebx
mov bx,stOpenFileName.nFileOffset
lea esi,szBuffer
add esi,ebx
mov eax,esi
ret
_GetFileName endp
;********************************************************************
;PathFindExtensionA By G-Spider[月窟]
;PathFindExtension功能:返回形如路径“D:/masm32/examples/lcd.asm"串的后缀串".asm"的头指针
;输入参数:路径指针lpPathBuffer,可以由lpstrFile得到
;返回值:eax
;********************************************************************
PathFindExtension Proc uses ESI lpPathBuffer:DWORD
;----------------------------------------------------------------------
mov eax,lpPathBuffer
XOR ESI,ESI
TEST EAX,EAX
JE SHORT L77F5F625
MOV CL,BYTE PTR DS:[EAX]
TEST CL,CL
JE SHORT L77F5F625
L77F5F603 :
CMP CL,20h ;20H=32D,为ASCII代码SPACE,即查看是不是空格字符
JE SHORT L77F5F62A ;如果是SPACE,则跳转
CMP CL,2Eh ;2EH=46D,为ASCII代码 '.',即查看是否为点号
JE SHORT L77F5F5E5 ;如果是点号,则跳转
CMP CL,5Ch ;5CH=92D,为ASCII代码'/',即查看是否为分隔斜杠
JE SHORT L77F5F62A ;如果是斜杠,则跳转
L77F5F612 :
PUSH EAX
CALL CharNextA
MOV CL,BYTE PTR DS:[EAX]
TEST CL,CL
JNZ SHORT L77F5F603
TEST ESI,ESI
JE SHORT L77F5F625
MOV EAX,ESI
L77F5F625 :
ret
L77F5F62A :
XOR ESI,ESI ;说明'.'点号后面的不是后缀形式,于是将该指针清0,不用再保存这个点的指针值
JMP SHORT L77F5F612
L77F5F5E5 :
MOV ESI,EAX ;若为'.'点符,则用ESI保存其指针值
JMP SHORT L77F5F612 ;接着判断下一位字符
;----------------------------------------------------------------------
PathFindExtension EndP
;********************************************************************
_ProcDlgMain proc uses ebx edi esi, /
hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
Local @StrLongCount;///用于保存带后缀的文件名串长
Local @DelExtCount ;///用于保存剔除了后缀的文件名串长
mov @StrLongCount,0
mov @DelExtCount,0
mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
mov eax,hWnd
mov hWinMain,eax
invoke SendDlgItemMessage,hWinMain,ID_FILE,EM_SETREADONLY,TRUE,NULL
.elseif eax == WM_COMMAND
mov eax,wParam
.if eax == ID_BROWSE
invoke _GetFileName
mov lpBuffer,eax ;得到文件名指针
;///invoke lstrcat,addr szTemp,lpBuffer ;显示全路径
.elseif eax == IDOK
invoke lstrlen,lpBuffer
mov @StrLongCount,eax
mov @DelExtCount,eax
.repeat
invoke PathFindExtension,lpBuffer
invoke lstrlen,eax
dec eax
sub @DelExtCount,eax
;invoke wsprintf,offset buf,offset buffmt,ExtCount ;///用于测试
;invoke MessageBox,NULL,offset buf,addr szTitleSave,0
invoke lstrcpyn,offset szTemp1,lpBuffer,@DelExtCount ;剔除形如.asm的文件名后缀
invoke lstrcat,addr szTemp1,addr inform ;加上回车换行符
invoke lstrcat,addr szTemp2,addr szTemp1 ;形成连续的长串
mov eax,@StrLongCount
inc eax
add lpBuffer,eax ;指向下个子串的头部
invoke lstrlen,lpBuffer
mov @StrLongCount,eax
mov @DelExtCount,eax
.until eax==0
invoke MessageBox,hWinMain,addr szTemp2,addr szTitleMesg,0 ;显示诗句
.endif
.else
;********************************************************************
; 注意:对话框的消息处理后,要返回 TRUE,对没有处理的消息
; 要返回 FALSE
;********************************************************************
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;********************************************************************
start:
invoke InitCommonControls
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0
invoke ExitProcess,NULL
end start
;********************************************************************
初探从C到Win32汇编之系列二
最新推荐文章于 2023-10-10 15:50:17 发布