zoukankan      html  css  js  c++  java
  • 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
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  

    研究中……

    -------------------------------------------------------

    kedebug

    Department of Computer Science and Engineering,

    Shanghai Jiao Tong University

    E-mail: kedebug0@gmail.com

    GitHub: http://github.com/kedebug

    -------------------------------------------------------

  • 相关阅读:
    第一章 重构
    Android View的事件分发
    java.lang.NoSuchMethodError: android.view.View.setBackground
    handler消息机制
    魅族手机Listview下拉出现hold字样的奇葩问题解决方案
    数据结构--树,二叉树
    数据结构之栈和队列
    设计模式--六大原则
    ListView上下线添加
    Python 入门(七)函数
  • 原文地址:https://www.cnblogs.com/kedebug/p/2791757.html
Copyright © 2011-2022 走看看