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        SHBrowseForFolderlpbi

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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  

 

 

 

 

研究中……

 

posted @ 2010-03-12 21:23  kedebug  阅读(309)  评论(0编辑  收藏  举报