2016-09-05 8 views
-3

私は簡単なフックのlibを使用しています。所有者ウィンドウはどのように処理されますか?DrawTextフックの子供から親のHwdを取得

[StructLayout(LayoutKind.Sequential)] 
    public struct Rect 
    { 
     public int Left; 
     public int Top; 
     public int Right; 
     public int Bottom; 

     public override string ToString() 
     { 
      return $"[Left: {Left}, Top: {Top}, Right: {Right}, Bottom: {Bottom}]"; 
     } 
    } 

    [DllImport("user32.dll", CharSet = CharSet.Unicode)] 
    public static extern int DrawText(IntPtr hDc, string lpString, int nCount, ref Rect lpRect, uint uFormat); 

    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)] 
    public delegate int DDrawText(IntPtr hDc, string lpString, int nCount, ref Rect lpRect, uint uFormat); 



    private int DrawText_Hooked(IntPtr hDc, string lpString, int nCount, ref Rect lpRect, uint uFormat) 
    { 
     var This = (Main) HookRuntimeInfo.Callback; 
     lock (This._queue) 
     { 
      var parent = GetAncestor(hDc, GetAncestorFlags.GetParent); // always return 0! why????????????????         
      This._queue.Push($"parent [{parent}]"); 
     } 
     return DrawText(hDc, lpString, nCount, ref lpRect, uFormat); 
    } 

GetWindowDC、GetDC、GetParent関数およびその他の がどのように親ウィンドウを取得するには、あまりにも、何の作業ではありませんか?

+1

GetAncestorは、ウィンドウハンドルが必要です。描画コンテキストを渡しています。描画コンテキストからウィンドウハンドルを取得するには、[GetWindowFromDC](https://msdn.microsoft.com/en-us/library/dd145201(VS.85).aspx)を呼び出します。 –

+0

あなたは何をしようとしていますか? – andlabs

+0

WindowFromDCは機能しません! –

答えて

0
var parent = GetAncestor(hDc, GetAncestorFlags.GetParent); // always return 0! why???????????????? 

このコードは完全間違っています。コンパイルできる唯一の理由は、HWNDHDCの両方が、管理対象環境でポインタ(IntPtr)と入力されているためです。 CやC++で書いていたのであれば、コンパイルエラーが発生し、問題が見やすくなります。

フックしたDrawText関数は、その最初のパラメータとして、テキストが描画されるデバイスコンテキスト(HDC)へのハンドルを持ちます。

呼び出すGetAncestor関数は、最初のパラメータとしてウィンドウ(HWND)のハンドルを持ちます。 HDCHWNDは互換性のないタイプです。彼らは交換することはできません。

デバイスコンテキスト(HDC)には「祖先」がなく、たとえそれがあったとしても、GetAncestor関数はウィンドウ用にのみ設計されています。デバイスコンテキストをどうすればいいのか分かりませんので、失敗します。無効なウィンドウハンドルを渡しました。

実際の質問、DCに対応する「親ウィンドウ」の取得方法については、この質問は意味をなさない。デバイスコンテクストには「親」ウィンドウがなく、のデバイスコンテキストのみがウィンドウに関連付けられています。デバイスコンテキストがウィンドウに関連付けられている場合は、WindowFromDC functionを呼び出し、HDCを渡して、関連付けられたHWNDを取得できます。再び、私はあなたの実際の問題を解決することはできないと強調しなければなりません。 デバイスコンテキストがウィンドウに関連付けられているとは限りません。デバイスコンテキストが画面に関連付けられているか、メモリDCであるか、デバイスDC(物理モニタ、プリンタ、またはその他の出力デバイスに関連付けられている)である可能性があります。これらのすべてのケースでは、WindowFromDCNULL(ヌルポインタまたは値IntPtr.Zero)を返します。

これを論理的に考えると、何を求めているのかが分かります。アプリケーションがメモリDCを作成し、その中にテキストを描画するためにDrawTextを呼び出すという単純なケースを考えてみましょう。どのような「ウィンドウ」を検索したいですか?たぶんプロセスのための "メイン"ウィンドウ?まず、任意のプロセスのためにそれを判断する方法はありません。第二に、プロセスもすべてのウィンドウを持っていない可能性があります!私はテキストを作成してメモリDCに描画するウィンドウレスプロセスを作成できます。私がそうするなら、それはあなたのフックをクラッシュさせないほうが良いでしょう!

このコードの目的が何であるかを説明するコメントには、いくつかの嘆願書には抵抗しました。最初にDrawTextにフックしている理由はまだ分かりません。フックプロシージャは何も役に立ちません。また、アプリケーションがDrawTextExExtTextOut、またはTextOutを呼び出してテキストを描画するケースがありません。これは、GDIを使用してテキストを描画することも想定しています。 GDI +、DirectDraw、またはその他の描画APIを使用する場合、フックは決して呼び出されません。 DrawTextに電話をかける唯一の理由は、その動作を変更したい場合です。フックプロシージャの動作を実際に変更しているわけではなく、ウィンドウに基づいてその動作を変更することも可能でも賢明でもありません。これは、デバイスコンテキストのみを扱う描画関数です。

+0

答えに感謝! –

+0

私には質問があります。 私たちは多くのWindowsアプリケーションを持っています。各ウィンドウには独自の設定があります。ウィンドウに応じて、コントロール内のテキストを変更する必要があります。これらのコントロールへのアクセス方法spy ++はC#を使用して(ウィンドウを持たない)表示されません –

+0

アプリケーションのソースコードを掘り下げたり、[System.Windows.Automation](https://msdn.microsoft.com/en) -us/library/ms747327(v = vs.110).aspx)は、コントロールを表示したり、テキストを変更できるようにします。または、文字列が文字列テーブルリソースから来た場合は、リソースエディタを使用します。がんばろう。 – andlabs

関連する問題