0

ネイティブ Windows アプリケーション内で実行される .Net COM DLL を作成しています。

このアプリのステータスバーに追加のペインを挿入しようとしていますが、そのための特定の実装がないため、アプリのステータスバーを自分でサブクラス化しようとしています。

Win32 API SetParent() を使用して、ラベル コントロールの親を .Net フォームから msctls_statusbar32 インスタンスに切り替えています。ラベルを使用したのは、独自のコントロールを作成しなくても見つけられるネイティブの「静的」クラス コントロールに最も近い実装であるためです。

どういうわけか、NativeWindowをステータスバーとラベルのメッセージの両方に正常にフックすることさえできました(ただし、現時点ではすべてを次のWndProcに渡すだけです)、一致するスタイルとstyleExをラベルのウィンドウに割り当てました、msctls_statusbar32 を親とするラベルを子として見ることができます。すべてが正しく機能しているように見えますが、そうではありません。コントロールが親アプリのステータスバーに表示されません。

私が理解していないのは、なぜそれが表示されないのかということです。私が考えることができるほとんどすべてが正しく一致します-確かに、私のラベルのクラスは「WindowsForms10.STATIC.app.0.378734a」であり、「静的」ではありませんが、それ以外は正しいプロセスとスレッド上にあり、一致するウィンドウがありますスタイル(少なくとも16進値... Spy ++はそれらを異なる方法で列挙しているようです)、そしてすべての目的で、残りのコントロールとほぼ調和しています。それを目に見えるようにするために他に何をする必要があるか誰かが知っていますか?

(私はもともとCreateWindowExのルートをたどり、WNDPROCコールバックを設定していましたが、アプリを動作させることができませんでした.1分ほどフリーズしてからフリーズを解除し、ウィンドウがウィンドウツリーから消えたことに気づきました)

ありがとうございました!

4

3 に答える 3

2

既存のステータス バー コントロールを操作してみることができます。できることは、テキストを既存のセクションにリセットするか、新しいセクションを追加することです。また、ステータスバーの既存のセクションに新しい幅を設定する必要があるでしょう。ステータスバー コントロールの操作方法の詳細については、msdn ステータス バーを参照してください。

以下にその方法の例を示します。私は実際にwin32アプリケーションで使用されるc#comオブジェクトで試してみましたが、うまくいくようです。

    [ComVisible(true)]
    [Guid("CC5B405F-F3CD-417E-AA00-4638A12A2E94"),
    ClassInterface(ClassInterfaceType.None)]
    public class TestInterface : ITestInterface // see declaration of the interface below
    {
        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, IntPtr lParam);

        public const int SB_SETTEXT = 1035;
        public const int SB_SETPARTS = 1028;
        public const int SB_GETPARTS = 1030;

        public unsafe void Test()
        {
            IntPtr mainWindowHandle = Process.GetCurrentProcess().MainWindowHandle;
            // find status bar control on the main window of the application
            IntPtr statusBarHandle = FindWindowEx(mainWindowHandle, IntPtr.Zero, "msctls_statusbar32", IntPtr.Zero);
            if (statusBarHandle != IntPtr.Zero)
            {
                // set text for the existing part with index 0
                IntPtr text = Marshal.StringToHGlobalAuto("test text 0");
                SendMessage(statusBarHandle, SB_SETTEXT, 0, text);
                Marshal.FreeHGlobal(text);

                // create new parts width array
                int nParts = SendMessage(statusBarHandle, SB_GETPARTS, 0, IntPtr.Zero).ToInt32();
                nParts++;
                IntPtr memPtr = Marshal.AllocHGlobal(sizeof(int) * nParts);
                int partWidth = 100; // set parts width according to the form size
                for (int i = 0; i < nParts; i++)
                {
                    Marshal.WriteInt32(memPtr, i*sizeof(int), partWidth);
                    partWidth += partWidth;
                }
                SendMessage(statusBarHandle, SB_SETPARTS, nParts, memPtr);
                Marshal.FreeHGlobal(memPtr);

                // set text for the new part
                IntPtr text0 = Marshal.StringToHGlobalAuto("new section text 1");
                SendMessage(statusBarHandle, SB_SETTEXT, nParts-1, text0);
                Marshal.FreeHGlobal(text0);
            }
        }
    }

    [ComVisible(true)]
    [Guid("694C1820-04B6-4988-928F-FD858B95C880")]
    public interface ITestInterface
    {
       [DispId(1)]
       void Test();
    }

これが役に立てば幸いです、よろしく

于 2009-12-08T07:02:43.827 に答える
0

多くの考えられる理由:

  1. .Net Label コントロールは、WinForms の親を持たないことが判明すると爆発します。
  2. Z オーダーが正しくないため、ネイティブ ステータス バーがラベル コントロールの上に描画されます。
  3. Label コントロールは表示されません。
于 2009-12-08T04:34:21.707 に答える