抓狂的Namespace Shell Extension (5)

这次说的是如何在自己的NSE中将工具条按钮添加到Explorer中。SEF所包含的RarFS源码中有本文所讲的所有信息的参考实现,以及目前网上所能找到的所有公开和未公开的SFVM_*消息的含义的参数结构。 :)
 
第一个问题是:什么时候加入按钮。
 
微软有一个例子:CabView,在老的SDK里面有源码,新的SDK不再提供这个例子。它是自己用ListView实现了一个IShellView,在IShellView::CreateViewWindow函数中用SendControlMsg加入的。对于使用SHCreateShellFolderView(Ex)的程序来说,这个时机是我们得不到的。经试验,如果插入按钮时机不对,有两种可能的后果:
 
(1) 加入后不显示
(2) 整个工具条被清空
 
究竟什么时机加入合适呢?答案在IShellFolderViewCB::MessageSFVCB中。
 
这个接口是NSE和Explorer通讯的唯一合法接口。事件以类似消息的形式传递给NSE,消息名称以SFVM_开头。
 
微软只公布了很少几条消息,所幸我们需要的几条还都公开了。(有一条消息例外,后面会讲到。)
 
我们只需要依次处理这几条消息:
 
(1) SFVM_GETBUTTONINFO
传回按钮的总个数,包括separator。
 
(2) SFVM_GETBUTTONS
这时,Explorer已经为NSE分配好了各个TBBUTTON所需要的内存,只要顺序填入就可以。
 
(3) SFVM_INVOKECOMMAND
用户按下按钮,会通过这个消息通知NSE。
 
最重要的消息是SFVM_GETBUTTONS。这个消息是:
 
USHORT idCmdFirst = LOWORD(wParam);
USHORT cbtnMax = HIWORD(wParam);
TBBUTTON* ptbbutton = reinterpret_cast<TBBUTTON*>(lParam);
 
idCmdFirst是Explorer为你的NSE分配的command id范围下界,你的command id必须在0-255之间。每个TBBUTTON的idCommand必须是idCmdFirst+YourCommandID。比如命令IDC_ADDFILE = 1,idCmdFirst = 0x7200,那么idCommand就写成idCmdFirst + IDC_ADDFILE。将来在SFVM_INVOKECOMMAND处理函数中,Explorer传回的是1,而不是0x7201。
 
按钮的iBitmap和iString两个值的写法和普通的toolbar没什么区别。需要注意的是必须使用TB_ADDBITMAP和TB_ADDSTRING来添加按钮位图和文字。
 
最后要说的是,如果需要在某一个文件选中/取消选择的时机来修改按钮状态,比如checked/enabled等等,就需要处理SFVM_SELECTIONCHANGED消息。这个消息微软没有公开,它的值为8,wParam含义未知,lParam是一个指向SFVCB_SELECTINFO的指针,该结构定义为:
 
typedef struct tag_SFVCB_SELECTINFO
{
 UINT uOldState; // 0
 UINT uNewState; //LVIS_SELECTED, LVIS_FOCUSED,...
 LPITEMIDLIST pidl;
} SFVCB_SELECTINFO;
 
实际上,这个结构的数据对我们来说意义不大,我们通过IShellView::GetItemObject就可以得到同样的数据,而且内容更丰富。
 
你会遇到两个问题:
 
(1) 所有加进去的按钮最初都处于允许状态,即使没有指定TBSTATE_ENABLED也一样。
 
(2) 无法通过正常的SendControlMsg或者先取得工具条HWND然后SendMessage来改变其允许/禁止状态。你可以改变其checked/unchecked、normal/highlight状态,唯一不能改变的就是允许状态。
 
这两个问题本质相同。解决方法有两个:
 
(1) 使用自己的ShellView,然后通过SetToolbarItems来添加按钮;这样,你可以随意改变按钮的各种状态。
 
(2) 之所以无法修改允许状态,是因为Explorer判断了这些按钮的owner,如果是你添加进去的,就不让改。想办法骗过它!这里已经把原因解释得很清楚了,如果你还不知道怎么实现,就购买SEF的咨询服务吧。 :)))))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值