Die einzige Möglichkeit den Fehler zu verhindern ist die TAB-Taste innerhalb der Windows-Nachrichtenschleife des Programms abzufangen. Unsere Lösung für die Qt-Klassenbibliothek:
//Erstellen des Controlsviewer()->setControl("AcroPDF.PDF");
WId wid = viewer()->winId();
if (m_AdobeWindows.isEmpty())
{ //Installieren des Event-Filters im eventDispatcher
prevFilter = QAbstractEventDispatcher::instance()->setEventFilter( ::eventFilter );
}
//Eintragen des Windows-Handle in die Liste der zu überwachenden Fenster
m_AdobeWindows.append(wid);Beim Beenden des Controls wird der Viewer aus der Liste ausgetragen:
if (!viewer()->isNull())
{
m_AdobeWindows.removeAll( viewer()->winId() );
//Wenn keine Controls mehr überwacht werden wird der EventFilter wieder zurückgesetzt.
if (m_AdobeWindows.isEmpty())
{
QAbstractEventDispatcher::instance()->setEventFilter( prevFilter );
}
}Der Event-Dispatcher sieht folgendermassen aus:
//Liste der zu überwachenden Fenster
QList m_AdobeWindows;
//Nimmt einen ggf. bereits gesetzten EventFilter auf
static QAbstractEventDispatcher::EventFilter prevFilter = 0;
static bool eventFilter(void *message)
{ LPMSG msg = (LPMSG)message;
//Diese Message ist der Auslöser für die Schutzverletzung
if (msg->message == 0x1450)
{
//Hier prüfen wir ob der Adressat der Nachricht ein Kindfenster des Controls ist
HWND wnd = msg->hwnd;
while (wnd != NULL)
{
if (m_AdobeWindows.contains(wnd))
{
//Falls der Empfänger also ein Kindfenster unseres Controls ist, dann schlucken wir die Nachricht -> Keine Schutzverletzung im Reader mehr.
return true;
}
wnd = GetParent( wnd );
}
}
if (prevFilter) return prevFilter(message);
return false;
}Besser wäre natürlich das Fenster-Handle des Readers direkt bei der Initialisierung des Controls zu holen, den Aufwand über die entsprechenden OLE-Interfaces zu gehen wollten wir uns hier sparen.
Hier ist der Adobe-Thread in dem ich die Anregung für die obige Lösung gefunden habe
Keine Kommentare:
Kommentar veröffentlichen