Winapi — Как я могу создать ITaskbarList3 в C ++ Builder?

Я пытаюсь использовать ITaskbarList3 Интерфейс, представленный в Windows 7, теперь я могу показать ход выполнения задачи в течение длительного времени на значке панели задач. В документации говорится, что мне следует дождаться сообщения TaskbarButtonCreated, прежде чем пытаться инициализировать мой компонент ITaskbarList3, но, похоже, я не получаю никаких сообщений TaskbarButtonCreated.

Вот что у меня так далеко:

У меня есть глобальная переменная в моем файле .cpp для хранения пользовательского идентификатора сообщения для TaskbarButtonCreated.

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 никогда не вызывается.

Я пропускаю шаг? Сообщение отфильтровано или отправлено до того, как мой обработчик сообщений будет готов к нему?

2

Решение

Не очень хорошая идея, чтобы TForm присваивал значение своему собственному WindowProc имущество. Для начала, Handle окно, возможно, уже было выделено до того, как ваш конструктор даже был введен, из-за потоковой передачи DFM, поэтому вы пропустите все начальные сообщения окна (которых может быть несколько), прежде чем ваш конструктор начнет работать. Вам нужно переопределить виртуальный 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();
}

Наконец, установите TApplication::ShowMainFormOnTaskbar собственность на true в проекте WinMain() функционировать до вашего MainForm создается так, что его окно, а не TApplication окно, управляет кнопкой панели задач (и для включения других связанных с Vista + функций, таких как Flip 3D и предварительный просмотр панели задач). В противном случае вам придется использовать TApplication::HookMainWindow() метод для перехвата любых сообщений «TaskbarButtonCreated», которые могут быть отправлены TApplication окно.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]