我正在尝试使用 ITaskbarList3 Windows 7 引入的界面,以便我可以在任务栏图标中显示冗长任务的任务进度。文档指出我应该在尝试初始化 ITaskbarList3 组件之前等待 TaskbarButtonCreated 消息,但我似乎没有收到任何 TaskbarButtonCreated 消息。
这是我到目前为止所拥有的:
我的 .cpp 文件中有一个全局变量来存储 TaskbarButtonCreated 的自定义消息 ID。
static const UINT m_uTaskbarBtnCreatedMsg =
RegisterWindowMessage( _T("TaskbarButtonCreated") );
我创建了一个单独的 WndProc 函数来处理新消息。
void __fastcall TForm1::WndProcExt(TMessage &Message)
{
if(Message.Msg == uTaskbarBtnCreatedMsg && uTaskbarBtnCreatedMsg != 0) {
OnTaskbarBtnCreated();
}
else {
WndProc(Message);
}
}
在我的表单构造函数中,第一行将 WindowProc 属性设置为 WndProcExt 以路由消息。我还尝试放入 ChangeWindowMessageFilter 来查看 TaskbarButtonCreated 消息是否由于某种原因被过滤。
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
WindowProc = WndProcExt;
ChangeWindowMessageFilterEx(Handle, uTaskbarBtnCreatedMsg, MSGFLT_ALLOW, NULL);
...
}
在调试器中,ChangeWindowMessageFilterEx 的返回值始终为 true。我还确认我的 WndProcExt 函数可以接收各种 Windows 消息,但不是我正在寻找的消息。 OnTaskbarBtnCreated 函数永远不会被调用。
我是不是少了一步?在我的消息处理程序准备好之前,消息是否已被过滤掉或发送?
最佳答案
让 TForm 为其自己的 WindowProc
属性赋值并不是一个好主意。对于初学者来说,由于 DFM 流,Handle
窗口可能在输入构造函数之前就已经被分配,因此您会在构造函数之前错过窗口的所有初始消息(可能有多个)开始运行。您需要重写虚拟 WndProc()
方法,并将 TaskbarButtonCreated 消息传递给默认处理程序,不要阻止它:
static const UINT m_uTaskbarBtnCreatedMsg = RegisterWindowMessage( _T("TaskbarButtonCreated") );
void __fastcall TForm1::WndProc(TMessage &Message)
{
TForm::WndProc(Message);
if ((Message.Msg == uTaskbarBtnCreatedMsg) && (uTaskbarBtnCreatedMsg != 0))
OnTaskbarBtnCreated();
}
至于 ChangeWindowMessageFilterEx()
,每次 TForm 的 Handle
窗口被(重新)分配时都需要调用它(在表单的生命周期中可能会发生多次) ,因此您需要重写虚拟 CreateWnd()
方法:
void __fastcall TForm1::CreateWnd()
{
TForm::CreateWnd();
if (CheckWin32Version(6, 1) && (uTaskbarBtnCreatedMsg != 0))
ChangeWindowMessageFilterEx(Handle, uTaskbarBtnCreatedMsg, MSGFLT_ALLOW, NULL);
// any other Handle-specific registrations, etc...
}
void __fastcall TForm1::DestroyWindowHandle()
{
// any Handle-specific de-registrations, etc...
TForm::DestroyWindowHandle();
}
最后,在 MainForm
之前的项目 WinMain()
函数中将 TApplication::ShowMainFormOnTaskbar
属性设置为 true
创建它的窗口(而不是 TApplication
)来管理任务栏按钮(并启用其他 Vista+ 相关功能,例如 Flip 3D 和任务栏预览)。否则,您将必须使用 TApplication::HookMainWindow()
方法来拦截任何可能发送到 TApplication
窗口的“TaskbarButtonCreated”消息。
关于c++ - 如何在 C++ Builder 中创建 ITaskbarList3?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14614823/