C #: الحصول على التسمية حقن في جزء Status APP الأصلي لتظهر

StackOverflow https://stackoverflow.com/questions/1864123

  •  16-09-2019
  •  | 
  •  

سؤال

أنا أكتب DLL .NET COM يعمل داخل تطبيق Windows الأصلي.

أحاول ضخ جزء إضافي في حالة تطبيق التطبيق هذا، وليس له أي تنفيذ محدد للقيام بذلك، لذلك أحاول أن أقوم بتكوين StatusPar التطبيق بنفسي.

أنا أستخدم Win32 API setparent () لتبديل الأصل عنصر تحكم التسمية من نموذج .NET إلى مثيل MSCTLS_STATUSBAR32. لقد استخدمت علامة تسمية لأنها أقرب عملية للتحكم في الفئة "الثابت" الأصلية التي يمكنني العثور عليها دون كتابة جهاز التحكم الخاص بي.

بطريقة ما تمكنت حتى من الحصول على NativeWindow للإبلاغ بنجاح إلى كل من StatusBar ورسائل ملصقاتي (على الرغم من أن ذلك في الوقت الحالي يمر إليهم جميعا فقط إلى WNDProC المقبل)، فقد قمت بتعيين أنماط مطابقة و Systemexs إلى نافذة التسمية الخاصة بي ، أستطيع أن أرى ملصقتي كطفل مع MSCTLS_STATUSBAR32 كوالديه. كل شئ تبدو مثل ذلك يجب أن تعمل بشكل صحيح، لكنه ليس كذلك. تحكم الخاص بي لا يظهر في StatusBar التطبيق الأم.

ما لا أفهمه هو السبب في أنه لا يظهر. ما يقرب من كل ما يمكنني التفكير في التطابقات بشكل صحيح - منحت، فئة الملصقات الخاصة بي هي "WindowsForms10.static.app.0.378734A" وليس "ثابت"، ولكن بخلاف ذلك هو في العملية الصحيحة والخيط، لديه نافذة مطابقة يبدو أن الأساليب (على الأقل قيمة HEX ... Spy ++ تعدادها بشكل مختلف)، وللجميع الأغراض مزيجا كبيرا مع بقية عناصر التحكم. هل يعرف أي شخص ما الذي يجب القيام به للحصول عليه ليكون مرئيا؟

(لقد ذهبت في الأصل طريق CreatewindowEx وإعداد عمليات الاسترجاعات WNDProc لكنني لم أستطع الحصول على التطبيق للعمل ... سيتجمد لمدة دقيقة أو نحو ذلك، ثم إلغاء تجميده، وأرجأ نافذتي اختفت من شجرة النافذة)

شكرا لك!

هل كانت مفيدة؟

المحلول 3

نظرا لأن الجواب كان بسيطا بشكل كبير ... كانت الجوانس X و Y Label من منطقة عرض الوالد StatusBar. نقلهم إلى (0، 0) ويظهر هناك حق! بالطبع، الآن انتقلت المشاكل إلى: C # WinForms Control في .NET COM Server لن Redraw

نصائح أخرى

يمكنك محاولة العمل مع التحكم في شريط الحالة الموجود؛ ما يمكنك القيام به هو إعادة تعيين النص إلى قسم موجود منه أو إضافة واحدة جديدة؛ ربما تحتاج أيضا إلى إعداد عرض جديد للأقسام الموجودة من StatusBar. يمكنك العثور على تفاصيل حول كيفية العمل مع عنصر التحكم StatusBar هنا:أشرطة حالة MSDN

يرجى الاطلاع على مثال على كيفية القيام بذلك أدناه. لقد جربتها بالفعل مع كائن C # COM المستخدمة من قبل تطبيق Win32 ويبدو أنها تعمل بشكل جيد بالنسبة لي.

    [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();
    }

آمل أن يساعد هذا فيما يتعلق

العديد من الأسباب المحتملة:

  1. يتحكم التحكم في الملصقات .NET عند العثور عليه ليس لديه أصل WinForms.
  2. شريط الحالة الأصلية هو الرسم عبر التحكم في التسمية لأن ترتيب Z غير صحيح.
  3. التحكم في التسمية غير مرئي.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top