c++ - 如何在 C++ Builder 中创建 ITaskbarList3?

标签 c++ winapi windows-7 taskbar c++builder-2010

我正在尝试使用 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/

相关文章:

android - 如何在 Windows 7 中运行 "android.bat sdk"

c++ - 正确地将 int 结构数组重新解释为 int 数组

c++ - SIFT 描述符维度

c++ - 我们能够在 C++20 中构造带有 View 的容器吗?

c++ - C++ 中的 SQL 数据库

winapi - Windows - 阻止 toast 通知的代码? (Win32/MFC 桌面)

c++ - CreateFile() 返回 INVALID_HANDLE_VALUE (C++)

windows - Windows 服务的 DirectX 访问

windows-7 - Win7 WOW64中应用程序中的奇怪线程

c# - 确定 Windows 7 通过 C# 设置的字体大小?