C#: Obtener la etiqueta inyectada en el panel de estatus de la aplicación nativa para aparecer

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

  •  16-09-2019
  •  | 
  •  

Pregunta

Estoy escribiendo un .NET com dll que se ejecuta dentro de una aplicación nativa de Windows.

Estoy intentando inyectar un panel adicional en la barra de estado de esta aplicación, y no tiene ninguna implementación específica para hacerlo, por lo que estoy tratando de subclasificar la barra de estado de la aplicación.

Estoy usando la API Win32 setParent () para cambiar el padre de un control de etiqueta de un formulario .NET a la instancia MSCTLS_STATUSBAR32. Utilicé una etiqueta porque es la implementación más cercana a un control de clase "estática" nativa que pude encontrar sin escribir mi propio control.

De alguna manera, incluso he logrado hacer que NativeWindow se conecte con éxito tanto a la barra de estado como en los mensajes de mi etiqueta (aunque en este momento los pasa a todos al siguiente WNDProc), y he asignado estilos de coincidencia y StyleExs a la ventana de mi etiqueta. , y puedo ver mi etiqueta cuando era niño con el msctls_statusbar32 como padre. Todo aspecto Como si debería funcionar correctamente, pero no lo es. Mi control no aparece en la barra de estado de la aplicación principal.

Lo que no entiendo es por qué no aparece. Casi todo lo que se me ocurra correctamente: otorgada, la clase para mi etiqueta es "Windowsforms10.static.app.0.378734a" y no "estática", pero aparte de eso está en el proceso y el hilo correctos, tiene una ventana coincidente que coincide con Los estilos (al menos el valor hexadecimal ... Spy ++ parece enumerarlos de manera diferente), y para todos los fines se combina con el resto de los controles. ¿Alguien sabría qué más se debe hacer para que sea visible?

(Originalmente había ido por la ruta de CreateWindowex y estableciendo devoluciones de llamada WNDProc, pero no pude hacer que la aplicación funcionara ... se congelaría durante un minuto más o menos y luego sin borrar, y notaría que mi ventana desaparecía del árbol de la ventana)

¡Gracias!

¿Fue útil?

Solución 3

Resulta que la respuesta fue extremadamente simple ... Las coordinas X e Y de la etiqueta estaban fuera del área de visualización del Estado Parent Bar. ¡Moverlos a (0, 0) y aparece allí mismo! Por supuesto, ahora los problemas han pasado a: C# Winforms Control en el servidor .NET com no volver a dibujar

Otros consejos

Puede intentar trabajar con el control de la barra de estado existente; Lo que puede hacer es restablecer el texto a una sección existente o agregar una nueva; También probablemente necesitaría configurar nuevos anchos en las secciones existentes de la barra de estado. Puede encontrar detalles sobre cómo trabajar con el control de la barra de estado aquí:barras de estado de MSDN

Encuentre un ejemplo de cómo puede hacerlo a continuación. De hecho, lo probé con el objeto C# com utilizado por la aplicación Win32 y parece que funciona bien para mí.

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

Espero que esto ayude, Saludos

Muchas razones posibles:

  1. El control de la etiqueta .NET explota cuando encuentra que no tiene un padre WinForms.
  2. La barra de estado nativa se basa en el control de la etiqueta porque del orden z incorrecto.
  3. El control de la etiqueta no es visible.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top