Win32汇编---浏览目录对话框
这是我做的最晕的一个例子,演示的是“浏览目录对话框”。之所以晕是因为要用到了COM库函数,而以我的程度,对于COM技术肯定一窍不通的!还好老罗的代码中提供了两个COM的接口,可以直接拿来调用。可是我对于其中是如何运作的琢磨不透……
虽然浏览对话框也是通用控件,但是windows并不是在Comdlg32.dll提供的,而是在Shell32.dll中!截图如下:
主程序框架并不复杂,主要功能代码在_BrowseFolder.asm,主程序BrowseFolder.asm中代码如下:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< .386 .model flat, stdcall option casemap: none ;--------------------------------------------------------------------------------- include windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib include shell32.inc includelib shell32.lib include ole32.inc includelib ole32.lib ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< .data? szPath db MAX_PATH dup(?) .const szSelect db "您选择的目录",0 szNoSelect db "您取消了选择!",0 ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< .code include _BrowseFolder.asm start: invoke GetCurrentDirectory,sizeof szPath,addr szPath invoke _BrowseFolder,NULL,addr szPath .if eax invoke MessageBox,NULL,offset szPath,offset szSelect,MB_ICONINFORMATION or MB_OK .else invoke MessageBox,NULL,offset szNoSelect,NULL,MB_OK or MB_ICONINFORMATION .endif invoke ExitProcess,NULL ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< end start
下面关键到了,用到了两个COM接口,不怎么懂,如何去释放COM库的也是一知半解。显示对话框是由SHBrowseForFolder函数完成的:
invoke SHBrowseForFolder,lpbi
mov lpItemIDList,eax ;返回一个ITEMIDLIST结构指针
参数lpbi指向一个包含对话框初始化数据的BROWSEINFO结构
当SHBrowseForFolder返回的时候,如果用户单击的是“取消”按钮,那么函数的返回值是0,否则的话,函数返回一个指向ITEMIDLIST结构的指针,对于这个结构可以不必去深究,因为使用SHGetPathFromIDList函数可以很方便地将它转换成目录字符串。
_BrowseFolder.asm代码如下:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; IUnknown interface ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> externdef IID_IUnknown:IID LPUNKNOWN typedef DWORD LPPUNKNOWN typedef ptr LPUNKNOWN IUnknown_QueryInterfaceProto typedef proto :DWORD, :DWORD, :DWORD IUnknown_AddRefProto typedef proto :DWORD IUnknown_ReleaseProto typedef proto :DWORD IUnknown_QueryInterface typedef ptr IUnknown_QueryInterfaceProto IUnknown_AddRef typedef ptr IUnknown_AddRefProto IUnknown_Release typedef ptr IUnknown_ReleaseProto IUnknown struct DWORD QueryInterface IUnknown_QueryInterface ? AddRef IUnknown_AddRef ? Release IUnknown_Release ? IUnknown ends ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;IMalloc Interface ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> externdef IID_IMalloc:IID LPMALLOC typedef DWORD LPPMALLOC typedef ptr LPMALLOC IMalloc_AllocProto typedef proto :DWORD, :DWORD IMalloc_ReallocProto typedef proto :DWORD, :DWORD, :DWORD IMalloc_FreeProto typedef proto :DWORD, :DWORD IMalloc_GetSizeProto typedef proto :DWORD, :DWORD IMalloc_DidAllocProto typedef proto :DWORD, :DWORD IMalloc_HeapMinimizeProto typedef proto :DWORD IMalloc_Alloc typedef ptr IMalloc_AllocProto IMalloc_Realloc typedef ptr IMalloc_ReallocProto IMalloc_Free typedef ptr IMalloc_FreeProto IMalloc_GetSize typedef ptr IMalloc_GetSizeProto IMalloc_DidAlloc typedef ptr IMalloc_DidAllocProto IMalloc_HeapMinimize typedef ptr IMalloc_HeapMinimizeProto IMalloc struct DWORD QueryInterface IUnknown_QueryInterface ? AddRef IUnknown_AddRef ? Release IUnknown_Release ? Alloc IMalloc_Alloc ? Realloc IMalloc_Realloc ? Free IMalloc_Free ? GetSize IMalloc_GetSize ? DidAlloc IMalloc_DidAlloc ? HeapMinimize IMalloc_HeapMinimize ? IMalloc ends ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .data? _lpBrowseFolderTmp dd ? .const _szDirInfo db "请选择目录:",0 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .code _BrowseFolderCallBack proc hWnd, uMsg, lParam, lpData local @szBuffer[260]:BYTE .if uMsg == BFFM_INITIALIZED invoke SendMessage,hWnd,BFFM_SETSELECTION,TRUE,_lpBrowseFolderTmp .elseif uMsg == BFFM_SELCHANGED invoke SHGetPathFromIDList,lParam,addr @szBuffer invoke SendMessage,hWnd,BFFM_SETSTATUSTEXT,0,addr @szBuffer .endif xor eax,eax ret _BrowseFolderCallBack endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> _BrowseFolder proc _hWnd, _lpszPathBuf local @stBrowseInfo:BROWSEINFO local @stMalloc local @dwReturn local @pIdParent pushad ;====================初始化 COM 库 invoke CoInitialize,NULL invoke SHGetMalloc,addr @stMalloc .if eax == E_FAIL mov @dwReturn,FALSE jmp @F .endif invoke RtlZeroMemory,addr @stBrowseInfo,sizeof @stBrowseInfo push _hWnd pop @stBrowseInfo.hwndOwner push _lpszPathBuf pop _lpBrowseFolderTmp mov @stBrowseInfo.lpfn,offset _BrowseFolderCallBack mov @stBrowseInfo.lpszTitle,offset _szDirInfo mov @stBrowseInfo.ulFlags,BIF_RETURNONLYFSDIRS or BIF_STATUSTEXT invoke SHBrowseForFolder,addr @stBrowseInfo mov @pIdParent,eax .if eax != NULL invoke SHGetPathFromIDList,eax,_lpszPathBuf mov eax,TRUE .else mov eax,FALSE .endif mov @dwReturn,eax ;==================释放 COM 库 mov eax,@stMalloc mov eax,[eax] invoke (IMalloc ptr [eax]).Free,@stMalloc,@pIdParent mov eax,@stMalloc mov eax,[eax] invoke (IMalloc ptr [eax]).Release,@stMalloc @@: invoke CoUninitialize popad mov eax,@dwReturn ret _BrowseFolder endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
研究中……
kedebug
Department of Computer Science and Engineering,
Shanghai Jiao Tong University
E-mail: kedebug0@gmail.com
GitHub: http://github.com/kedebug
-------------------------------------------------------