2016-05-07 11 views
1

Windows上でQt5アプリケーションのQPainter::drawText()機能にフックします。 私の目標は、テキストが描画されるトップレベルウィンドウのネイティブハンドルを識別することです。まず、関連するウィジェットを取得しています。ウィジェットでトップレベルウィンドウを取得する

QWidget *widget = static_cast<QWidget *>(painter->device()); 

対応する最上位のウィンドウ/ウィジェットを見つけることができるはずです。 しかし、それは私が思ったよりも難しいです。これは私がこれまで試したものです:

while (widget->parentWidget()) 
    widget = widget->parentWidget(); 

HWND hwnd = (HWND) widget->winId(); 

ません成功。トップの親は決して望ましいウィンドウではありません。

QApplication::topLevelWidgets() 

は、1つのウィンドウは、(私が探しているものを含む)いくつかのトップレベル・ウィジェットが含まれていることを見せてくれました。

また、私は、これは実際に動作するいくつかのケースではQApplication::topLevelAt(widget->mapToGlobal(QPoint()))

を試してみましたが、ない確実。 テキストとウィンドウの位置によってはAccessViolationException、 が表示されます。これはオプションではありません。

テストではwidget->testAttribute(Qt::WA_NativeWindow) 私はほとんどのウィジェットが非ネイティブのAlien Widgetsであることが判明しました。

これは私が(私が何と呼ぶ)トップレベルウィンドウを取得する方法です。

WinAPI.EnumChildWindows(
    WinAPI.GetDesktopWindow(), 
    new EnumWindowsProc(this.EnumWindowsCallback), 0); 

それから私は、私が興味のハンドルを見つけるために、ウィンドウのタイトルを確認してください。

私は(トップレベルへの(低レベル)のウィジェットからの関係を見つけることができないんだけど)ウィジェット。ウィンドウタイトルを保持します。

+1

明確にする:最初の「コンテナクライアント」または「トップレベルウィンドウ」のハンドルを探していますか?コードを表示したり、「トップレベルウィジェット」がその1つのウィンドウにどのように関連しているかを記述できますか? – JKSH

+0

Windows APIやサードパーティのユーティリティを使用してQtでペイントすると、ネイティブウィジェットとペイントに埋め込まない限り、確実に動作する可能性は低いことに注意してください。 –

+0

私は何も描きたくありません。私は、アプリケーションのテキスト出力全体をインターセプトし、各文字列をいくつかのキーワードと比較しています。 一致するものが見つかった場合は、アプリケーションの開いているウィンドウの1つにマップします。 – m1st4x

答えて

1

完了です!私は私の問題の解決策を見つけました。

各ウィンドウには独自のスレッドがあります。それによって

int threadId = WinApi.GetWindowThreadProcessId(wndHandle, IntPtr.Zero) 

私はこのスレッドによって作成されたすべてのウィンドウハンドルのリストを取得するにはEnumThreadWindows を使用しています。

最後に、wheather widget->effectiveWinId()がリストにあることを確認します。

各ウィジェットを対応するウィンドウにマップすることができます。

3

トップレベルウィンドウとして機能するQWidgetについては、call QWidget::window()

ネイティブハンドルを持つ最も近い親の場合はcall QWidget::nativeParentWidget()です。それはあなたの目標ではありません1を、持っていない場合、ネイティブウィンドウハンドルを取得するためにwinId()力ウィジェットを呼び出す

。トップレベルのウィンドウには常にネイティブIDがあるので、(HWND)window()->winId()は問題ありません。これはであり、通常であり、calling QWidget::effectiveWinId()と同じです。

+0

非常に良いヒント!したがって、非ネイティブ(エイリアン)ウィジェットを扱う場合は、私のようにQWidget :: winId()をデバッグの目的で使用しないでください:P – m1st4x

+0

はい。 'widget-> nativeParentWidget() - > effectiveWinId()' は私に最も近いネイティブの親ハンドルを与えます。しかし、残念ながらそれは決して望んでいない:( – m1st4x

関連する問題