jiangsheng

http://www.csdn.net/develop/author/netauthor/jiangsheng/
随笔 - 142, 评论 - 629, 引用 - 27

导航

关于

 
这下要维护3个BLOG了,faint 其他的地址:

所有的文章版权归原文作者所有,任何人需要转载文章,必须征得原文作者授权。
我的MVP配置

标签

每月存档

最新留言

广告

打开大量文件

在我们的程序中有时候需要一次选择多个文件,例如InstallShield的安装程序向导中的一个步骤就是为feature选择文件;但是在选择的文件过多(超过30个)的时候,这样的选择没有效果。我不得不在InstallShield的文件打开对话框中切换到小图标模式,并且一次选择两列的文件(很久之前就不得不用Linked Directory来动态链接整个目录中的文件了,不知道新的InstallShield版本改进没有)。

这种情况是因为默认的缓冲区只有两百多个字符。如果缓冲区不够长,那么调用对话框可能会失败,CommDlgExtendedError()会返回FNERR_BUFFERTOOSMALL。为了解决这个问题,你可以处理CDN_SELCHANGE来在选择项数目变化的时候动态重新分配缓冲区(参见http://support.microsoft.com/kb/131462/)或者在创建对话框的时候把缓冲区设大一点:

但是尽管提供了这么长的缓冲区(我是使用ANSI配置编译的,所以缓冲区有26M,足足可以容纳10万个文件名),但是结果还是没有获得全部文件名,这是因为GetOpenFileName限制了复制到缓冲区中的文件名的总长度(http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/userinput/commondialogboxlibrary/commondialogboxreference/commondialogboxfunctions/getopenfilename.asp)

OK,在文档中我看到了解决方案之一是使用UNICODE版本的函数GetOpenFileNameW,但是在Windows 9x上似乎只能用ANSI版本的函数。难道我要编写Windows版本检查代码来调用不同版本的函数?

这是推荐的作法。但是程序员是很懒的,所以有时候我会使用一些非官方方法。在我以前的一篇BLOG(http://blog.joycode.com/jiangsheng/archive/2004/09/17/33756.aspx)中我提到了如何访问文件打开对话框的IShellBrowser接口。通过这个接口我们可以访问文件打开对话框的IShellView接口,进而获得选中的文件(为节省篇幅,ILIsFile、GetPIDLFolder、GetPIDLItem和WM_GETISHELLBROWSER的定义就不重复了):

然后如下使用

调试输出是

Selected 2415 Files(和资源管理器的报告相符)
GetOpenFileName returned 2378 Files(……)

posted on 2004-11-22 04:00:00 by jiangsheng  评论(10) 阅读(9129)

在浏览器控件中显示信息栏

Windows XP SP2 中的Internet Explorer 6 引入了一个新的安全用户界面元素,称为信息栏。在特定操作被阻止的时候,信息栏给用户显示一个用户界面元素。特别的,它会在以下操作被阻止的时候显示。

  • 弹出窗口初始化
  • 文件下载
  • 安装ActiveX 控件
  • ActiveX控件安全提示的原因是用户安全设置或者是控件未标记为脚本安全的。
  • 文件的扩展名和多用途因特网邮件扩展类型(MIME)不符的
  • 网络协议锁死的内容

SP2WebBrowserControl 

信息栏是Windows XP SP2 中的Internet Explorer 6引入的安全特性之一。和其他安全特性控制一样,可以通过一个注册表键来控制:FEATURE_SECURITYBAND。 默认情况下IE(iexplorer.exe) 和Windows 资源管理器(explorer.exe) 在这个安全特性控制下。下面显示注册表键和启用过程:

HKEY_LOCAL_MACHINE (or HKEY_CURRENT_USER)
SOFTWARE
Microsoft
Internet Explorer
Main
FeatureControl
FEATURE_SECURITYBAND
iexplorer.exe= 0x00000001
explorer.exe= 0x00000001
TTraveler.exe= 0x00000001
process name.exe=0x00000001

 

这个FEATURE_SECURITYBAND 安全特性控制影响IE是否显示信息栏,信息栏在一个操作被阻止的时候提示用户。它不控制操作的阻止过程。

一个集成浏览器控件的程序可以通过将其进程添加到这个注册表键来启用信息栏,也可以通过调用CoInternetSetFeatureEnabled函数来在运行时执行。如果一个应用程序并未在这个安全特性控制下,那么浏览器控件的行为和Internet Explorer 6 SP1b中的一样.

没有方法通过脚本来访问这个特性。

在FEATURE_SECURITYBAND及相关安全特性控制下的应用程序可以使用信息栏应用程序编程接口(API)来在一个URL 操作被禁止时自定义显示的用户界面。为信息栏引入了很多新的OLECMDID命令。头三个是属于CGID_DocHostCommandHandler组。宿主应用程序应该在它们的IDocHostUIHandler实现的同一个对象中实现IOleCommandTarget ,以接受来自浏览器控件IOleCommandTarget::Exec调用。

  • OLECMDID_PAGEACTIONBLOCKED
  • OLECMDID_PAGEACTIONUIQUERY
  • OLECMDID_FOCUSVIEWCONTROLS

宿主应用程序可以使用下面两个新的OLECMDID 命令来执行浏览器控件IOleCommandTarget::Exec调用。

  • OLECMDID_FOCUSVIEWCONTROLSQUERY
  • OLECMDID_SHOWPAGEACTIONMENU
这个示例使用IWebBrowser2::ExecWB 来执行OLECMDID_SHOWPAGEACTIONMENU 命令。
   POINT pt = { 0 };
   GetCursorPos(&pt);

   CComVariant varHwnd((LONG)hwnd);
   CComVariant varX(pt.x);
   CComVariant varY(pt.y);

   SAFEARRAY* psa = SafeArrayCreateVector(VT_VARIANT, 0, 3);

   LONG lIndex = 0;
   SafeArrayPutElement(psa, &lIndex, &varHwnd);
   lIndex++;
   SafeArrayPutElement(psa, &lIndex, &varX);
   lIndex++;
   SafeArrayPutElement(psa, &lIndex, &varY);

   CComVariant varArgIn;
   V_VT(&varArgIn) = VT_ARRAY | VT_I4;
   V_ARRAY(&varArgIn) = psa;

   pBrowser->ExecWB(OLECMDID_SHOWPAGEACTIONMENU, (OLECMDEXECOPT)dwPageActionFlags, &varArgIn, NULL);

另外,应用程序可以实现IInternetSecurityManager来重载默认的安全区域设置,参见创建一个自定义URL安全管理器以获得更多信息。

要在Visual C++中使用CoInternetSetFeatureEnabled函数等XPSP2新增的API的话,必须安装了Windows XP SP2 Platform SDK。这个SDK可以在http://www.microsoft.com/msdownload/platformsdk/sdkupdate/下载。

Windows XP SP2 Platform SDK不支持Visual C++6.0附带的编译器。Visual C++6.0用户建议升级到Visual C++.Net,或者安装Microsoft Visual C++ Toolkit 2003

Microsoft Visual C++ Toolkit 2003 可以在http://msdn.microsoft.com/visualc/vctoolkit2003/下载到,但是在Visual C++6.0中使用Microsoft Visual C++ Toolkit 2003的代价之一就是不能使用内建的调试器。VC的选项中可执行文件、头文件和库文件的目录搜索顺序应该依次是:

  1. Microsoft Visual C++ Toolkit 2003
  2. Windows XP SP2 Platform SDK
  3. Windows SDK (Windows Server 2003)
  4. VC98 (Visual C++ 6.0)

posted on 2004-11-12 14:57:00 by jiangsheng  评论(8) 阅读(10163)

Powered by: Joycode.MVC引擎 0.5.2.0