DeskBand 开发摸索过程

以下按照已知流程来梳理,随时更新

首先,我感觉从已知资料来看DeskBand的开发是需要通过COM组件来实现的,也就是说最终会注册一个进程内COM组件,被任务栏调起

接下来就是要做的这个COM组件具体的实现

1.完成这个特定的COM组件需要实现一些接口,否则任务栏无法调起你

接口是多个,我都列出来:

一、IOleWIndow <-IDockingWIndow <- IDeskBand

箭头指向的是爹,从爹到儿子都要做实现,I前缀就是接口,类似IUNKNOWN,不懂的自己去科普windows的接口

二、 IDeskBand<- IDeskBand2(可选)

这个好像是为了做各种显示特效的

说一下这一家四个接口需要实现的方法:

1、IDeskBand

GetBandInfo 得到窗体的大小,标题,背景色等信息

2、 IOleWindow

GetWindow  拿到Band对象的窗体句柄(Handle)

ContextSensitiveHelp

3、 IDockingWindow

ShowDW 显示隐藏窗体

CloseDW 关闭窗体

ResizeBorderDW 可能是做特效用的,一般不用

4、 IDeskBand2 做毛玻璃特效的接口

CanRenderComposited

SetCompositionState

GetCompositionState

5、IInputObject 输入类的接口(可选)

6、 IContextMenu (上下文菜单)

下文是步骤:

1、首先我们要明确现在做的是一个Band(一种专属于任务栏外挂的COM对象),那就要说明两件事a.我要注册一个Band的COM b.他还得注册自己的类别是放在任务栏上的,因此这个COM对象需要注册2个地方,

a.Band类COM的线程模型必须为“Apartment” ,所以他必须是个dll,你要说不做Band的话,那你进来看这篇文章干啥

b.

====================我是华丽的分割线=============================

以下是我抄的,还是没搞明白

 执行顺序

Windows(桌面band用于资源管理器,浏览栏用于IE)通过查找实现了CATID_DeskBand,,CATID_InfoBand,或 CATID_CommBand的COM对象来发现band对象,并将band的名字添加到工具栏菜单。

1、当用户从菜单选中band时,Windows调用CoCreateInstance或它的同等函数。COM则调用DLL中的 DllGetClassObject输出函数,COM用正确的 ID搜索到一个类工厂并将它返回。然后COM调用IClassFactory::CreateInstance进行一系列的COM常规处理。

关键就是类工厂能正确找到我们自己写的COM,那说明我们要重写IClassFactory::CreateInstance,让它能正确创建出我们写的COM的对象。

2、Windows调用IObjectWithSite::SetSite给出一个(IUnknown*)类型的指针指向对象容器,在这个函数里面我们就要创建BAND对象的窗口了。注意,此时创建的窗口一定要是不可见的,即保证不要使用WS_VISIBLE来创建窗口。

3、接下来,Windows调用IOleWindow::GetWindow来获得窗口的HWND。(这就是为什么你必须在SetSite中创建窗口的原因)。

4、接着,Windows调用IDeskBand::GetBandInfo请求关于band的信息,如大小,可变高度或者定高,以及背景颜色和标题。

5、接着,Windows调用IDockingWindow::ShowDW来显示窗体。

6、当用户关闭Band时,Windows调用IDockingWindow::CloseDW。

通常,IObjectWithSite::SetSite实现应该完成下列步骤:

1. 释放当前所把持的任何现场指针。

2. 如果传递到SetSite的指针被置为NULL,此则区对象被删除。SetSite可以返回S_OK。

3. 如果传递到SetSite的指针被置为非NULL,则建立新的现场。SetSite应该做以下的事情:

   a)调用现场QueryInterface方法请求IOleWindow接口。

   b)调用IOleWindow::GetWindow获取父窗口句柄,并存储它,以便以后使用。如果不再使用的话,就释放IOleWindow接口。

   c)创建此band对象的窗口为一个子窗口,其父窗口就是上一步获得的那个窗口。注意在此不能将它创建成可见窗口。

   d)如果此band对象实现IInputObject,调用现场QueryInterface方法请求IInputObjectSite接口,存储这个接口的指针以备后用。

   e)如果所有步骤都成功,则返回S_OK,否则返回OLE定义的错误代码以指示错误类型。

发表评论

电子邮件地址不会被公开。 必填项已用*标注