我正在尝试使用Windows 7引入的ITaskbarList3接口(interface),以便可以在任务栏图标中显示冗长任务的任务进度。该文档指出,在尝试初始化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
窗口每次被(重新)分配时调用(在Form的生命周期中可能多次发生),因此您需要改写虚拟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();
}
最后,在创建
TApplication::ShowMainFormOnTaskbar
之前,在项目的true
函数中将WinMain()
属性设置为MainForm
,以便其窗口而不是TApplication
窗口管理任务栏按钮(并启用其他与Vista +相关的功能,例如Flip 3D和任务栏预览)。否则,您将必须使用TApplication::HookMainWindow()
方法来拦截可能发送到TApplication
窗口的任何“TaskbarButtonCreated”消息。