Я пытаюсь использовать 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 никогда не вызывается.
Я пропускаю шаг? Сообщение отфильтровано или отправлено до того, как мой обработчик сообщений будет готов к нему?
Не очень хорошая идея, чтобы 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
окно.
Других решений пока нет …