为什么我的窗口接不到TaskbarButtonCreated消息?!

为什么我的窗口接不到TaskbarButtonCreated消息?!

分类: C/C++ TaskbarButtonCreated ITaskbarList3   444人阅读  评论(0)  收藏  举报

今天想在程序上加点新花样,因为见过WM Player能够在任务栏缩略图上加控制按钮,也想在程序上实验一把。在网上搜来搜去,MSDN也翻了一个遍,基本上搞明白了WIN7任务栏开发的基本过程。我也再啰嗦一遍吧。
1.首先需要在应用程序初始化之前调用 CoInitialize 对COM进行初始化,因为Win7的新特性实现是通过一个 ITaskbarList3 接口来实现的,当然 ITaskbarList4 也可以( ITaskbarList4  继承自 ITaskbarList3)。它们包含在 shobjidl.h 头文件中。
2.然后就应该是创建 ITaskbarList3 接口了。但是——MSDN上明确说明了“在调用任何 ITaskbarList3 的方法之前,视窗必须要接收到 TaskbarButtonCreated 消息,并且这个消息必须由 RegisterWindowMessage (" TaskbarButtonCreated ")函数进行注册,然后就可以在窗口的消息循环中进行相应的处理了”。如果实现的话,也就是如下样子:
BOOL CWin7TaskbarDlg::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
    if (message == WM_TASKBARBUTTONCREATED)
    {
        OnCreateTaskBar(wParam, lParam);
    }
    return CDialogEx::OnWndMsg(message, wParam, lParam, pResult);
}
或者响应注册消息:
afx_msg LRESULT OnCreateTaskBar(WPARAM wParam, LPARAM lParam);
ON_REGISTERED_MESSAGE(WM_TASKBARBUTTONCREATED, OnCreateTaskBar)
LRESULT CWin7TaskbarDlg::OnCreateTaskBar(WPARAM wParam, LPARAM lParam)
{
    return TRUE;
}
按说这样应该就可以了。哼哼!如果你真的这样认为,那么你就真的真的即将崩溃了!!为什么?后面再说。
3.一般说来,创建  ITaskbarList3 接口的时机就是收到 TaskbarButtonCreated  消息的时候。如下:
CoCreateInstance(CLSID_TaskbarList,  NULL,  CLSCTX_INPROC_SERVER,  IID_PPV_ARGS(&_taskbarList));
然后记住,一定要对  ITaskbarList3  接口环境进行初始化,也就是调用其HrInit()函数:
_taskbarList->HrInit();
4.接下来的处理我就不讲了,网上说的也都大同小异,而且本篇文章主要是解惑用的,更加详细的处理以后可以开单章进行说明。
5.程序最后当然不要忘了释放  ITaskbarList3   接口以及Com环境 CoUninitialize ()。

重要的时刻就要到了,你按下F5键开始运行和调试,却发现哪里有TaskbarButtonCreated 消息进来!于是你在网上各种搜索,最终你的得到是一团愤怒——因为网上也和上面讲的步骤一样!到底哪里出了问题了!

终于,我想起来了一个很重要的地方——Window SDK Sample。打开资源管理器,搜索taskbar,然后找到一个ThumbnailToolbar工程——这个就应该是我们想要的DEMO吧!于是你打开唯一的一个CPP文件,在茫茫码海中找到了关键的地方:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static UINT s_uTBBC = WM_NULL;
    if (s_uTBBC == WM_NULL)
    {
        // Compute the value for the TaskbarButtonCreated message
        s_uTBBC = RegisterWindowMessage(L"TaskbarButtonCreated");
        // In case the application is run elevated, allow the
        // TaskbarButtonCreated and WM_COMMAND messages through.
        ChangeWindowMessageFilter(s_uTBBC, MSGFLT_ADD);
        ChangeWindowMessageFilter(WM_COMMAND, MSGFLT_ADD);
    }
    if (message == s_uTBBC)
    {
        // Once we get the TaskbarButtonCreated message, we can create
        // our window's thumbnail toolbar.
        CreateThumbnailToolbar(hWnd);
    }

    else switch (message)
    {
......
    }
    return 0;
}
我靠!我忍不住爆了粗口!原来这个消息是需要自己加上去滴!以前在跟踪MFC源码的时候确实注意到了 WM_NULL 消息,当时还想这个消息有啥作用,原来——原来——原来是为了这个用的!当然 WM_NULL 也许会有其他作用,以后再来研究。但是在这里,他确实起了至关重要的作用。

但是为什么要这么使用 TaskbarButtonCreated消息呢?我在ChangeWindowMessageFilter函数的注释中找到了一些蛛丝马迹:
UIPI is a security feature that prevents messages from being received from a lower integrity level sender. All such messages with a value above WM_USER are blocked by default. The filter, somewhat contrary to intuition, is a list of messages that are allowed through. Therefore, adding a message to the filter allows that message to be received from a lower integrity sender, while removing a message blocks that message from being received.
(UIPI是一个安全功能,可以防止(应用程序)从一个较低完整性级别的发件人那里收到消息。默认情况下,所有那些 WM_USER 值以上的消息都被封锁。过滤器,有点违反直觉,是一个允许(是否可以)通过的消息列表。因此,往消息过滤器中加入一个消息来允许从一个较低完整性的发件人那里收到该消息,同时(也可以)从移除一个被阻止接收的消息块。)
既然MSDN上都这么写了,那么应该就是这个原因了。
好了。这回终于有一篇能够彻底解决问题的文章了!为什么我要自夸捏?因为我鄙视那些讲问题讲不到重点的人![Windows]为什么我的窗口接不到TaskbarButtonCreated消息?! - lvan - lvan GoGo 的世界

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
效果图:音乐播放控制按钮 教程开始: 实现方法在微软的帮助文档中,我发不了链(百度关键词 任务栏扩展 MSDN) 文档中提供了3三个API:ThumbBarAddButtons(创建按钮)、 ThumbBarSetImageList、 ThumbBarUpdateButtons(更新按钮) 这三个API在动态链库 Explorerframe.dll 中,我尝试过直调用它们,结果却不存在。 不过MSDN中提供了C++的调用方法,在C++中这三个API被封装在 ITaskBarList3 类中,ITaskBarList3类定义在“ Shobjidl.h ”头文件 所以我想想到个方法,利用微软提供的C++代码编写一个DLL库来实现这三个方法,让易语言程序调用。 下来我编写了 TaskBarEx.dll 这个链库(C++源码在最下面),里面提供了 AddThumbarButtons 这个方法,方法易语言定义如下: 复制代码 .版本 2 .DLL命令 AddThumbarButtons, 整数型, "TaskBarEx", "_AddThumbarButtons@12", 公开 .参数 句柄, 整数型 .参数 sum, 整数型 .参数 pTHUMBBUTTON, THUMBBUTTON, 数组 这个链库的代码都是MSDN中现成的,从微软的帮助文档复制过来,稍加修改就行了。 你们以为这样就结束了! 当我在易语言中声明此API调用后,才发现并没有什么卵用,我也不知道为什么。后面才知道微软提供的这三个API是用COM对象的方式调用的。于是 我在论坛中找了一大堆关于如何调用COM对象的教程,完全看不懂! 当然!什么事情都是有解决的办法的,最终我还是找到办法了,以下方法是我乱搞搞出来的。 我在易语言中创建了一个“对象”类型的变量(用来调用COM对象的)取名: ITAskBarList3并创建了 ITAskBarList3类的COM对象 复制代码 ITAskBarList3.创建 (“{56FDF344-FD6D-11d0-958A-006097C9A090}”, ) 代码中那一串文本是COM对象的唯一标识符,我在VS2017中 ITAskBarList3类的声明中找得到。定义在“ Shobjidl.h ”头文件中。 然后声明了一个THUMBBUTTON 结构(见MSDN),定义按钮的信息: 复制代码 .版本 2 ' 按钮1 Button.hIcon = LoadIconA (mHwnd, 112)' 112为“上一首按钮”的图标在TaskBarEx.dll链库的资源编号 Button.dwMask = 位或 (2, 4, 8)' 表示你准备使用THUMBBUTTON结构中的哪些成员 Button.iId = 0' 按钮的编号,用于在窗口消息循环中的WM_COMMAND消息下判断是哪个按钮 Button.dwFlags = 0' 表示按钮状态,可用还是禁用,0表示可用 wtext = Ansi转Unicode (“上一首”)' 按钮提示文本需要Unicode类型 toBytes (Button.szTip, wtext, 取字节集长度 (wtext)) 加入成员 (sButton, Button)' 声明好一个按钮结构就加sButton数组 最后调用TaskBarEx.dll中我提供的AddThumbarButtons函数 复制代码 AddThumbarButtons (窗口句柄, 1, sButton) 以上就是创建一个缩略图按钮的基本代码。下面还有一些问题: 以下是MSDN的原话: 注意 当应用程序显示窗口时,系统会创建其任务栏按钮。当按钮就位时,任务栏会向窗口发送TaskbarButtonCreated消息。它的值通过调用RegisterWindowMessage(L(“TaskbarButtonCreated”))计算。该消息必须在应用程序调用任何ITaskbarList3方法之前收。 意思就是创建按钮的所有代码都在TaskbarButtonCreated消息之后,并且这个消息值需要我们调用API自己注册。我做过测试,发现要想在窗口创建完成后创建按钮,就必须这样做;如果将创建按钮代码放在 __按钮__被按下事件 下就不一定,不知道为什么。 教程结束 当然还有一些细节问题需要处理,在我的源码中都有注释,可以看看。如果代码看不懂可以问我,不过关于COM对象的问题我也不懂。 TaskBarEx.dll的源代码:整个VC++工程目录100多MB,无语了,如果需要我后面再发;下面两个主要函数代码,其实MSDN都有。 我用的是VS2017 EXTERN_C __declspec(dllexport) int _stdcall eG

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值