validar texto tag form campos c# winforms hwnd

c# - texto - ¿Puedo obtener el comportamiento de establecer el propietario de mi formulario WinForms usando un hwnd/NativeWindow?



validar campos de texto c# (2)

Mi aplicación es un ejecutable vb6, pero algunas formas más nuevas en el sistema están escritas en C #. Me gustaría poder establecer la propiedad Propietario del formulario C # utilizando un identificador en la ventana principal de la aplicación, para que los cuadros de diálogo permanezcan en la parte superior cuando se avanza y retrocede entre mi aplicación y otras aplicaciones.

Puedo obtener el hwnd de la ventana principal de la aplicación. No estoy seguro de lo que puedo hacer desde allí?

ACTUALIZACIÓN 20 de octubre de 2008 a las 17:06:

Scott,

Gracias por la respuesta. Había pasado por alto que el parámetro del método Show / ShowDialog no era de tipo Formulario; solo buscaba en la propiedad Owner.

Modifiqué ligeramente el código que estoy usando de lo anterior: tenemos un componente que carga nuestros formularios de forma genérica y llama a ShowDialog. Mi código se ve así:

Form launchTarget = FormFactory.GetForm(xxx); // psuedo-code for generic form loader launchTarget.StartPosition = FormStartPosition.CenterParent; IWin32Window parentWindow = GetWindowFromHwnd(hwnd); launchTarget.ShowDialog(parentWindow);

GetWindowFromHwnd es una versión envuelta en método de su código:

private IWin32Window GetWindowFromHost(int hwnd) { IWin32Window window = null; IntPtr handle = new IntPtr(hwnd); try { NativeWindow nativeWindow = new NativeWindow(); nativeWindow.AssignHandle(handle); window = nativeWindow; } finally { handle = IntPtr.Zero; } return window; }

Lamentablemente, esto no está haciendo lo que esperaba. El formulario se muestra modalmente, pero no se muestra en la posición correcta ni está aún en la parte superior cuando elimino la pestaña y regreso a la ventana principal. Nuestros modales no muestran una tarea en la barra de tareas, por lo que la ventana aparentemente "desaparece" (aunque todavía está presente en la lista de ventanas de alt-tab). Eso para mí indica que podría no tener el derecho de hwnd. Si tiene alguna otra sugerencia, responda. Gracias de nuevo.

ACTUALIZACIÓN el 10 de noviembre de 2008 a las 16:25

Una observación de seguimiento: si la factorizas en una llamada a un método en un try / finally, como en la segunda publicación de Scott, la llamada en el bloque finally debería ser:

parentWindow.ReleaseHandle();


Entonces está llamando a una clase C # Windows Form desde VB6, lo que significa que probablemente esté usando Show() o ShowDialog() , ¿correcto? Ambos métodos también toman un parámetro IWin32Window, que simplemente define un objeto que devuelve una propiedad IntPtr llamada Handle.

Entonces ... necesita agregar un constructor sobrecargado (o el método ShowDialog) para sus clases de Windows Forms que toman un long como parámetro para que pueda pasar el VW6 hwnd al formulario. Una vez dentro del código C #, necesita crear un IntPtr a partir del hwnd y asignarlo a un objeto NativeWindow y luego pasarlo como el propietario.

Algo así debería funcionar, aunque no haya sido probado:

public DialogResult ShowDialog(long hwnd) { IntPtr handle = new IntPtr(hwnd); try { NativeWindow nativeWindow = new NativeWindow(); nativeWindow.AssignHandle(handle); return this.ShowDialog(nativeWindow); } finally { handle = IntPtr.Zero; } }


Esto es demasiado largo para publicarlo como comentario ...

Creo que el problema al que te estás enfrentando es la forma en que envuelves el código que presenté en la sobrecarga de ShowDialog. Si sigues lo que hace tu código GetWindowFromHost , sigue los siguientes pasos:

  1. Crea un nuevo IntPtr a partir del hwnd dado.
  2. Crea un nuevo objeto NativeWindow y le asigna su manejador para que sea el IntPtr.
  3. Establece el IntPtr (en el bloque finally) para ser IntPtr.Zero.

Creo que es este bloque finalmente el que está causando problemas. En mi código, el bloque finally se ejecutará después de la llamada a this.ShowDialog(nativeWindow) finalizado. En ese momento, el identificador (IntPtr) ya no se usaba. En su código, está devolviendo un IWin32Window que aún debe contener una referencia a ese IntPtr, que en el momento en que llama a launchTarget.ShowDialog(parentWindow) es IntPtr.Zero.

Intenta cambiar tu código para que se vea así:

private NativeWindow GetWindowFromHost(int hwnd) { IntPtr handle = new IntPtr(hwnd); NativeWindow nativeWindow = new NativeWindow(); nativeWindow.AssignHandle(handle); return window; }

Y luego cambie su código de llamada para que se vea así:

Form launchTarget = FormFactory.GetForm(xxx); // psuedo-code for generic form loaderlaunchTarget.StartPosition = FormStartPosition.CenterParent; NativeWindow parentWindow = GetWindowFromHwnd(hwnd); try { launchTarget.ShowDialog(parentWindow); } finally { parentWindow.DestroyHandle(); }

Estos cambios deberían funcionar, pero nuevamente esto no se ha probado.