WIN32汇编语言教程:第08章 通用对话框 · 8.3 浏览目录对话框(2)
Alloc IMalloc_Alloc ? Realloc IMalloc_Realloc ? Free IMalloc_Free ? GetSize IMalloc_GetSize ? DidAlloc IMalloc_DidAlloc ? HeapMinimize IMalloc_HeapMinimize ? IMalloc ends ;##################################################################### .data ? _BrowseFolderTmp dd ? ;##################################################################### .const _szDirInfo db '请选择目录:',0 .code ;##################################################################### ; 弹出选择目录的对话框 ;##################################################################### _BrowseFolderCallBack proc hWnd,uMsg,lParam,lpData local @szBuffer[260]:byte mov eax,uMsg .if eax == BFFM_INITIALIZED invoke SendMessage,hWnd,BFFM_SETSELECTION,\ TRUE,_BrowseFolderTmp .elseif eax == 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,_lpszBuffer local @stBrowseInfo:BROWSEINFO local @stMalloc local @pidlParent,@dwReturn 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 ;******************************************************************** ; SHBrowseForFolder 选择一个目录,把不含路径的目录名放入 ; stBrowseInfo.pszDisplayName 中,SHGetPathFromIDList 把 ; stBrowseInfo.pszDisplayName 转换成含全部路径的目录名 ;******************************************************************** push _hWnd pop @stBrowseInfo.hwndOwner push _lpszBuffer pop _BrowseFolderTmp mov @stBrowseInfo.lpfn,offset _BrowseFolderCallBack mov @stBrowseInfo.lpszTitle,offset _szDirInfo mov @stBrowseInfo.ulFlags,\ BIF_RETURNONLYFSDIRS or BIF_STATUSTEXT invoke SHBrowseForFolder,addr @stBrowseInfo mov @pidlParent,eax .if eax != NULL invoke SHGetPathFromIDList,eax,_lpszBuffer mov eax,TRUE .else mov eax,FALSE .endif mov @dwReturn,eax ;******************************************************************** ; 释放COM库 ;******************************************************************** mov eax,@stMalloc mov eax,[eax] invoke (IMalloc PTR [eax]).Free,@stMalloc,@pidlParent mov eax,@stMalloc mov eax,[eax] invoke (IMalloc PTR [eax]).Release,@stMalloc @@: invoke CoUninitialize popad mov eax,@dwReturn ret _BrowseFolder endp ;#####################################################################
8.3.2 使用浏览目录对话框
浏览目录对话框的实现分为两个部分:初始化部分和对话框功能部分。
1. 初始化COM库
浏览目录对话框要用到COM接口,所以必须首先调用CoInitialize函数来初始化COM库并调用SHGetMalloc函数来获取一个IMalloc类型的接口,这个接口实际上是一个内存块,中间包含各种COM功能模块的入口地址。在对话框返回的时候,再调用接口中的Free模块释放接口,并调用CoUninitialize函数释放COM库。
COM编程是一个很大的课题,有关COM组件中的IUnknown接口和IMalloc接口等工作机理的内容本身就是一个比较深奥的问题,这不是本书所要涉及的内容,读者可以不必深入研究_BrowseFolder.asm文件中关于这两种接口的定义,只要将定义部分和代码中初始化和释放COM库的代码直接拿过来用就是了,这也是本书将这个模块单独放入一个文件的原因。如果读者对COM编程的内容感兴趣,可以访问http://here.is/cominasm(可能需要使用代理服务器访问),这是一个讨论如何用Win32汇编编写COM程序的站点。
COM库的相关函数包含在ole32.dll中,所以源程序中必须包含下列语句:
include ole32.inc includelib ole32.lib
2. 显示对话框
显示对话框的功能函数包含在Shell32.dll中,所以在源程序的头部也应该有下列包含语句:
include shell32.inc includelib shell32.lib
显示对话框的功能由SHBrowseForFolder函数实现,函数的用法是:
invoke SHBrowseForFolder,lpbi mov lpItemIDList,eax ;返回一个ITEMIDLIST结构指针
参数lpbi指向一个包含对话框初始化数据的BROWSEINFO结构:
BROWSEINFO STRUCT HwndOwner dd ? ;对话框的父窗口 PidlRoot dd ? ;用来表示起始目录的ITEMIDLIST目录 PszDisplayName dd ? ;用来接收用户选择目录的缓冲区 LpszTitle dd ? ;对话框中的用户定义文字 ulFlags dd ? ;标志 lpfn dd ? ;回调函数地址 lParam dd ? ;传给回调函数的参数 iImage dd ? ;用来接收选中目录的图像 BROWSEINFO ENDS
上页:第08章 通用对话框 · 8.3 浏览目录对话框(1) 下页:第08章 通用对话框 · 8.3 浏览目录对话框(3)
第08章 通用对话框
版权所有 © 云南伯恩科技 证书:粤ICP备09170368号