you what visual para instalar herramientas escritorio develop desarrollo con applications application aplicaciones aplicacion c++ windows winapi mfc form-designer

c++ - what - Crear un diseñador de formularios de aspecto profesional(¡y que se comporte!)



instalar herramientas de visual c++ 2015 para el escritorio de windows (3)

Ambas respuestas son buenas, pero omitieron lo que considero que son las partes realmente interesantes (incluida una pareja que no preguntaste directamente, pero de todas maneras podrías encontrar de interés), así que aquí está mi 2c:

Dibujando los controles

Lo ideal es seguir adelante y crear una instancia regular del control. ¿Quieres algo que se parece a un botón? Crea un botón real Lo más complicado es evitar que se comporte como un botón: quiere que los clics lo activen para moverse, en realidad no lo ''hagan clic''.

Una forma de lidiar con esto, suponiendo que los controles en cuestión estén ''basados ​​en HWND'' (por ejemplo, el conjunto estándar de ventanas de botón, edición, estática, listbox, treeview, etc.), es crear el control y luego subclasificar es - es decir. anula el wndproc con SetWindowLongPtr (GWLP_WNDPROC, ...), para que el código del diseñador pueda interceptar la entrada del mouse y del teclado y usarlo para iniciar un movimiento, por ejemplo, en lugar de hacer que la entrada del mouse pase al código del botón real, que en su lugar, lo interpretaría como un evento de "clic".

Un enfoque alternativo a la subclasificación es colocar una ventana invisible sobre el botón para capturar la entrada. La misma idea de la entrada de interceptación, solo una implementación diferente.

Lo anterior se aplica a los controles administrados (VB.Net, C #) y no administrados (C / C ++); ambos son esencialmente HWND de Windows de inventario; las versiones administradas solo tienen un código de contenedor gestionado que se transfiere al control subyacente no gestionado.

Los viejos controles ActiveX (código pregestionado), como se usaban en pre.Net VB, eran un juego de pelota completamente diferente. Existe una relación bastante compleja entre un contenedor ActiveX y los controles ActiveX dentro de él, con muchas interfaces COM manejando cosas como la negociación de propiedades, eventos, pintura, etc. (Hay un evento de un conjunto de interfaces que permite a un control ActiveX recibir entrada y dibujarse sin tener su propio HWND.) Sin embargo, uno de los beneficios que obtiene de esta complejidad es que los controles ActiveX tienen un ''modo de diseño'' explícito; por lo que un control sabe que debe responder adecuadamente en ese caso y puede cooperar con todo el procedimiento.

La forma en sí ...

Entonces, básicamente, los controles son solo controles regulares. Entonces, ¿espera que el formulario en sí sea una forma regular? - Casi. Por lo que yo sé, es solo otra ventana basada en HWND, que es hija del diseñador (por lo que se recorta, y se puede desplazar dentro de ella); pero creo que el diseñador está haciendo un poco de "trampa" aquí, porque usualmente Windows solo dibuja marcos como - con la barra de título y los botones mínimo / máximo que para las ventanas de nivel superior reales. No sé de improviso la técnica exacta que están usando aquí, pero algunas opciones podrían incluir: pintarlo manualmente para imitar el aspecto de Windows; utilizando las API "tema" de Windows, que le permiten acceder a los elementos gráficos utilizados para los bits y partes de las barras de título y pintarlos donde quiera; o, quizás menos probable, configurar la ventana como una "ventana MDI secundaria": este es un caso excepcional en el que Windows dibujará un marco alrededor de una ventana anidada.

Manijas arrastrables

El enfoque más simple es que el diseñador cree ocho ventanas emergentes pequeñas sin título cuadrado, que se encuentran sobre todos los demás elementos, que inician el código de cambio de tamaño apropiado cuando se les hace clic. A medida que el usuario hace clic de control en control, simplemente mueva las ventanas del controlador de arrastre al control activo actualmente. (Tenga en cuenta que en todo lo anterior, Windows mismo está averiguando a quién se ha hecho clic, nunca tiene que comparar realmente las coordenadas del mouse contra las coordenadas del rectángulo del elemento y resolverlo usted mismo).

Ahorro y recreación

Para los controles de sistema de Windows simples que utiliza C / C ++ no administrado, es relativamente fácil: existe un conocido formato de archivo basado en texto, .rc, que describe los controles y las ubicaciones. Pídale al diseñador que escuche eso (y probablemente también un archivo resource.h) y listo: cualquier proyecto C / C ++ puede recoger esos archivos y compilarlos. El código administrado (C #, VB.Net) tiene algo más de esquema complejo, pero sigue siendo la misma idea básica: escriba una descripción en el estilo que esperan las herramientas administradas, y la compilarán felizmente y la usarán.

(Los controles ActiveX son, como habrás adivinado, una historia más completa. No conozco un formato estándar, por lo que el editor de formularios y el tiempo de ejecución que los consume estarán estrechamente relacionados, por ejemplo, el editor de formularios de pre.Net VB6 produce formularios que solo VB puede usar. - Creo. Ha sido hace un tiempo ...)

En cuanto a la recreación del formulario: si tiene un archivo .rc, se compila en un recurso de diálogo, Windows ha incorporado soporte para recrear esos. Del mismo modo, las bibliotecas de soporte de código administrado saben cómo volver a crear un formulario desde su formato particular. Ambos básicamente analizan la descripción, y para cada elemento, crean elementos de las clases apropiadas y establecen el estilo, el texto y otras propiedades apropiadas, tal como se especifica. No está haciendo nada que no puedas hacer tú mismo, es solo un código de utilidad auxiliar.

Manejo del enfoque

Para una colección de HWND en cualquier contenedor, ya sea en modo de prueba o realmente ejecutándose en la aplicación real, e independientemente de si permite que Windows o Winforms manejen la creación del formulario o si usted creó cada HWND usted mismo, puede agregar soporte tabulador por llamando a IsDialogMessage en su ciclo de mensajes: vea la sección de comentarios de la página de MSDN para más detalles. (Aunque WinForms podría hacer esto, creo que en realidad hace su propio manejo de enfoque, por lo que puede tener un orden de tabulación independiente del orden Z de apilamiento visual).

Otras cosas para explorar ...

Haz amigos con la aplicación Spy ++ (parte del SDK, se instala con Visual Studio). Si va a hacer algo con HWND, administrado o no, es una buena idea saber cómo usar esta herramienta: puede apuntarla a cualquier parte de la interfaz de usuario en Windows y ver cómo está construida a partir de un árbol de diferentes tipos de HWND. Apúntalo al diseñador de VB y mira lo que realmente te está pasando. (Haga clic en el icono de "binoculares" en la barra de herramientas, luego arrastre el cursor a la ventana que le interesa).

También eche un vistazo a los archivos de recursos que el diseñador escupe. Todo lo que puede modificar, mover o editar en el diseñador de formularios corresponde a algún elemento en algún lugar de uno de esos archivos de recursos. Haga una copia de ellos, modifique algunos ajustes y luego compare los dos conjuntos y vea qué ha cambiado. Intente cambiar algunas cosas en los archivos a mano (creo que son casi todo el texto), vuelva a cargar y vea si el diseñador recogió sus cambios.

Otras cosas a tener en cuenta ...

Gran parte de lo anterior es específico de Windows, sobre todo el hecho de que, dado que estamos utilizando los propios bloques de construcción de Windows (HWND), podemos hacer que Windows haga el trabajo por nosotros: nos da las facilidades para reutilizar los controles en sí mismos. en el momento del diseño, así no tenemos que dibujar maquetas; interceptar la entrada en otros controles para que podamos hacer clic en un movimiento o cualquier otra acción que queramos, o averiguar qué control se hace clic sin tener que hacer la ubicación de matemáticas nosotros mismos. Si se tratara de un diseñador de algún otro marco de interfaz de usuario, como Flash, que no utiliza HWND internamente, probablemente utilizaría las propias funciones internas de ese marco para realizar un trabajo similar.

Además, es mucho más fácil si limita el número de controles en la paleta a un pequeño conjunto finito, al menos al principio. Si desea permitir que se arrastre cualquier control, p. Ej. un tercero, o uno que haya usado en otro proyecto; lo primero que se necesita es que el control se ''registre'' para que el diseñador sepa que está disponible en primer lugar. Y también puede necesitar alguna forma de descubrir qué icono usa en la barra de herramientas, cómo se llama, qué propiedades admite, etc.

¡Diviértete explorando!

Cuando comencé a programar (hace más de 10 años), tres cosas me sorprendieron:

  • Compiladores / intérpretes (en aquel entonces los conocía como "programas que hacen que mis programas funcionen", seguido a menudo por el calificador "lo que sea que sean")
  • Editores de código
  • Diseñadores de formularios

En aquel entonces, los acepté todos como hechos de la vida. Pude crear mis propios programas de propósito especial, pero "programas que hicieron que mis programas funcionaran", los editores de códigos y editores de formularios fueron creados por los Dioses y no había forma de que pudiera meterme con ellos.

Luego fui a la universidad y tomé un curso sobre procesamiento formal del lenguaje. Después de aprender gramáticas formales, analizadores sintácticos, árboles sintácticos abstractos, etc .; toda la magia sobre compiladores, intérpretes y editores de código pronto desapareció. Los compiladores e intérpretes podrían escribirse de una manera sensata y simple, y la única cosa no-sana que un editor de código de resaltado de sintaxis podría requerir fueron los hacks de la API de Windows.

Sin embargo, hasta el día de hoy, los editores de formularios siguen siendo un misterio para mí. O me falta el conocimiento técnico requerido para hacer un diseñador de formularios, o tengo tal conocimiento, pero no puedo encontrar la manera de usarlo para implementar un diseñador de formularios.

Usando Visual C ++ y el MFC, me gustaría implementar un diseñador de formularios inspirado en el mejor diseñador de formularios de todos los tiempos:

En particular, me gustaría imitar sus dos características que me gustan más:

  • El formulario que se está diseñando está dentro de un contenedor. Por lo tanto, se puede diseñar una forma arbitrariamente grande sin desperdiciar demasiado espacio en pantalla, simplemente redimensionando el contenedor a un tamaño apropiado.

  • La opción "Alinear a la cuadrícula" hace que el diseño de interfaces de usuario de aspecto profesional sea mucho menos frustrante. De hecho, llegaría a decir que crear interfaces de usuario de aspecto profesional utilizando el diseñador de formularios de Visual Basic es realmente fácil, divertido y agradable. Incluso para programadores de cerebro izquierdo como yo.

Entonces, tengo las siguientes preguntas:

  1. ¿Cómo hago un diseñador de formularios, en el que el formulario que se está diseñando está dentro de un contenedor? ¿La forma que se está diseñando es una ventana real contenida dentro de otra ventana? ¿O es solo una maqueta "manual" pintada por el diseñador de formularios?

  2. La API de Windows y / o el MFC contienen funciones, clases, lo que sea que facilite la creación de elementos "seleccionables" (rodeados de pequeñas casillas blancas o azules cuando se seleccionan, redimensionables cuando son "capturados" por uno de estos " bordes ")?

  3. ¿Cómo implemento la funcionalidad "Alinear a la cuadrícula"?


Implementa un diseñador de formularios casi como una GUI normal. Tienes cosas que puedes arrastrar (tus widgets), tienes cosas en las que puedes hacer clic (tus botones) y tienes cosas que puedes seleccionar (tus widgets colocados) y eso es todo.

P: ¿Cómo se muestra una ventana en una GUI?
R: Tú lo pintas, así de simple.

P: ¿Y cómo mantienes las cosas dentro de esa ventana?
R: Controla los límites del objeto "principal". Casi podría decirse que un diseñador de formularios es como un pequeño juego y tiene un gráfico de escena que contiene todos sus widgets, conectados por relaciones entre padres e hijos.

P: Entonces, ¿cómo seleccionas cosas en una GUI?
R: Verifique la posición actual del mouse al hacer clic con el botón en los límites de todos los widgets (cercanos) (un gráfico de escena solo ayuda aquí, como un árbol cuádruple).

P: ¿Cómo se alinean los widgets en una grilla?
R: Para la alineación de la cuadrícula, tengamos un ejemplo simple: digamos que su resolución real es 100px en el eje x, pero quiere que su cuadrícula tenga solo una resolución de 10px en x. Ahora diga que mueve su widget 28px en resolución real. Para obtener la resolución de la cuadrícula, simplemente divida por 10 , obtenga 2.8 , redondee eso y finalmente mueva el widget 3 mosaicos en x. El redondeo es la clave aquí. solo si el movimiento de la cuadrícula es >= ?.5 , se ajusta al siguiente mosaico. De lo contrario, simplemente te quedas en la anterior.

Espero que esto pueda darte una pista general sobre cómo iniciar un diseñador de formularios. Que te diviertas. :)
(PD: No sé sobre ninguna función / clase específica de WinAPI / MFC para ayudarlo, lo siento).


Solo para agregar un punto o dos a lo que @Xeo ya ha dicho:

Antes que nada, no, no siempre dibujas todo el contenido tú mismo. Durante la fase de diseño normal básicamente dibuja algo que se parece al control, pero (al menos IIRC) también le permite "ejecutar" un formulario en modo de prueba (sin duda, el diseñador de diálogos de VC ++ lo hace, y aunque VB era más primitivo) , Creo que sí tenía esa capacidad particular también). El modo de prueba fue cuando se puede "ejecutar" un formulario antes de que (necesariamente) se le haya agregado un código; aunque hacer clic en un botón (por ejemplo) no hace nada en el programa circundante, el control en sí mismo funciona normalmente. - un botón hace clic normalmente, un control de edición le permitirá editar, etc.

Esto se hace instanciando un control, diciéndole la posición, el tamaño y las propiedades correctas. Los controles ActiveX hacen bastante para soportar esto, y los "controles personalizados de Windows" anteriores también lo hicieron, aunque con mucha menos sofisticación. Desde el punto de vista del control, funciona exactamente como lo haría normalmente, recibiendo información, enviando notificaciones a su padre, etc. Lo único que ha cambiado es que el padre ignora la mayoría de las notificaciones que recibe, pero el control no lo hace Realmente lo sé.

Hay dos formas básicas de hacer esto. Una es crear una colección de controles usted mismo, junto con sus posiciones, tamaños, etc., y usar CreateWindow (o CreateWindowEx , etc.) para crear una ventana de la clase correcta. Si bien es relativamente fácil de manejar, tiene la desventaja de que te deja todo el manejo de pestañas.

La otra posibilidad es crear una estructura DLGTEMPLATE para contener datos sobre el cuadro de diálogo, y algunos DLGITEMTEMPLATES para los controles individuales, y finalmente usar CreateDialogIndirect para crear un cuadro de diálogo con esas especificaciones, manteniendo esos controles. Es tedioso, pero funciona, y cuando terminas maneja tabular entre controles automáticamente (y funciona igual que cualquier otro diálogo, ya que es el mismo código de Windows que lo crea de cualquier manera).

En segundo lugar, ya que ha etiquetado este C ++, es posible que desee echar un vistazo a algún code en CodeProject que realmente implemente un editor de diálogo. Aunque no es tan sofisticado como algunos de los comerciales, este es un editor de formulario / diálogo razonablemente completo, completo con la mayoría de lo que ha preguntado.