Palabras clave : cuadro de diálogo, diálogo, reinicable
1. Problema planteado
El problema proviene de stanley_xu, con la esperanza de obtener solo el botón de cierre (también puede ayudar), no hay icono para el programa en la parte superior izquierda y el cuadro de diálogo puede cambiar el tamaño de la ventana.
Las propiedades de Borderstyle y Bordericons están establecidas para TForm en VCL para simplificar la configuración de los estilos de ventana (de lo contrario, se deben llamar a funciones de API como setwindowlong y getwindowlong). La definición y la descripción de TFormBorderStyle y Tbordericon son las siguientes:
Valor de significado
BSDialog no reenvitable;
bssingle no reenvible;
bsnonenotresizable;
borde restisible estándar BSSIZABLE
bstoolwindow como bssingle pero con una leyenda más pequeña
BSSIZETOOLWIN como BSSIZEBLE con una leyenda más pequeña
tipo tbordericon = (bisystemmenu, biminimize, bimaximize, bihelp);
Tbordericons = conjunto de tbordericon;
Valor de significado
BisystemMenu El formulario tiene un menú de control (también conocido como menú del sistema).
biminimizar el formulario tiene un botón de minimización
bimaximizar el formulario tiene un botón de maximización
Bihelp Si BorderStyle es BSDialog o Biminimize y BiMaximize están excluidos, aparece un signo de interrogación en la barra de título del formulario y, cuando se hace clic, el cursor cambia a CRHELP;
Obviamente, Borderstyle y Bordericons solo pueden satisfacer las necesidades generales, y es imposible implementar cuadros de diálogo que puedan modificar los tamaños.
En términos generales, si quiero obtener una ventana que no se pueda maximizar pero que pueda cambiar el tamaño, configuré BorderStyle en BSSIZEBLE, elimine la biminimización y la bimáxima de los bordericons, y el resultado es así: la ventana se puede modificar, pero hay Un icono en la esquina superior izquierda ,:
Figura 1 cuadro de diálogo con icono
Tenga en cuenta que hay un ícono en la esquina superior izquierda.
Nuestro objetivo son los dos efectos a continuación.
Figura 2 Abrir cuadro de diálogo Archivo
Cadena de diálogo de la carpeta de navegación de la Figura 3
2. La mitad del problema se resuelve
Busqué MSDN y encontré un artículo que le enseña cómo diseñar páginas de propiedades que puedan cambiar el tamaño (en MFC, CPropertySheet aparece como una subpágina CPropertyPage, que herede de Cdialog y generalmente no puede modificar el tamaño) "cómo diseñar una propiedad MFC RESIZABLE Hoja, el método introducido en el artículo es modificar el estilo de la ventana antes de que se cree la página de la propiedad, y luego procesar manualmente el mensaje WM_SIZE.
int Callback cmyPropertySheet :: xmnpropsheetCallback (hwnd hwnd, mensaje uint, lparam lparam)
{
extern int llamar a AFXPropSheetCallback (HWND, Mensaje UINT, LPARAM LPARAM);
// xmn: llame a la devolución de llamada de MFC
int nres = AFXPropSheetCallback (HWND, Mensaje, LPARAM);
Switch (mensaje)
{
Caso PSCB_PRECREATE:
// Estilizar nuestros propios estilos de ventana
((Lpdlgtemplate) lparam)-> style | = (ds_3dlook | ds_setfont
|
romper;
}
devolver nres;
}
He intentado usar el mismo método en una forma de VCL. Establezca BorderStyle en BSDialog al diseñar, y luego sobrecargue el método CreateParams. Pero el resultado es que el cuadro de diálogo se convierte en un borde grueso (porque tiene un estilo ws_thickframe), el mouse puede cambiar automáticamente después de moverse a cada borde, y no hay ícono en la esquina superior izquierda, pero la ventana no puede cambiar su tamaño (El proceso de procesamiento de mensajes WM_Size agregado no se activa). ¿Cuál es el problema?
Figura 4 Cuadro de diálogo que aún no es completamente satisfactorio
3. Resuelve el problema
Verifiqué el código fuente de Forms.pas y encontré el problema. Existe un proceso de incrustación modifisistema en el proceso de procesamiento de mensajes WM_NCCREATE de tcustomform, que se utiliza para modificar el menú del sistema de formulario. Tenga en cuenta que el texto rojo a continuación dice "Haga que el menú del sistema parezca un cuadro de diálogo". Las siguientes oraciones de código eliminaron los elementos del menú del sistema hasta el punto en que solo "moverse" y "cerrar".
procedimiento tcustomform.wmncCreate (mensaje var: twmnccreate);
procedimiento modifisystemmenu;
varilla
Sysmenu: Hmenu;
Comenzar
...
{Modifique el menú del sistema para que se vea más como si fuera s'pose}
Sysmenu: = getSystemMenu (Handle, False);
Si fBorderStyle = BSDialog entonces
Comenzar
{Hacer que el menú del sistema parezca un diálogo que solo tiene
Moverse y cerrar}
Deletemenu (sysmenu, sc_tasklist, mf_bycommand);
Deletemenu (sysmenu, 7, mf_byposition);
Deletemenu (sysmenu, 5, mf_byposition);
Deletemenu (sysmenu, sc_maximize, mf_bycommand);
Deletemenu (sysmenu, sc_minimize, mf_bycommand);
Deletemenu (sysmenu, sc_size, mf_bycommand);
Deletemenu (sysmenu, sc_restore, mf_bycommand);
fin
...
fin;
Comenzar
heredado;
Setmenu (fmenu);
Si no (CSDesigning in ComponentState) entonces modifysystemmenu;
fin;
Por lo tanto, el problema es que debido a que se elimina "sc_size", el estilo de la ventana tiene una deformidad: hay ws_thickframe (el tamaño de la ventana se puede modificar), pero no responde al mensaje wm_size (se elimina SC_SIZE).
La solución es muy simple: implementa su propio proceso de procesamiento de mensajes WM_NCCreate y modifique manualmente el menú del sistema.
procedimiento tzocdlgresizable.wmncCreate (mensaje var: twmnccreate);
// Los siguientes códigos se copian de Form.Pas Line 4047, Delphi 7 Sp1.
procedimiento modifisystemmenu;
varilla
Sysmenu: Hmenu;
Comenzar
Sysmenu: = getSystemMenu (Handle, False);
{Hacer que el menú del sistema parezca un diálogo que solo tiene
Mueva, tamaño y cierra comandos}
Deletemenu (sysmenu, sc_tasklist, mf_bycommand);
Deletemenu (sysmenu, 7, mf_byposition);
// No retire el separador antes del mando cerrado.
// deletemenu (sysmenu, 5, mf_byposition);
Deletemenu (sysmenu, sc_maximize, mf_bycommand);
Deletemenu (sysmenu, sc_minimize, mf_bycommand);
{No elimine el comando de tamaño, de lo contrario perderemos el
Capacidad de cambiar el tamaño del diálogo.
// deletemenu (sysmenu, sc_size, mf_bycommand);
Deletemenu (sysmenu, sc_restore, mf_bycommand);
fin;
Comenzar
{Skip TCustomForm's WM_NCCreate Handler, que elimina
El comando de tamaño del menú del sistema.}
Deshamos Defaulthandler (mensaje);
// Tratar con el menú del sistema a nuestra manera.
Modifisystemmenu;
fin;
4. Clase Tzocdlgresizable
La solución final I encapsula como una clase heredada de tForm. Tzocdlgresizable.
Por cierto: también agregué un atributo SizeGrip a Tzocdlgresizable.
Figura 5 Cuadro de diálogo con SizeGrip sin icono
Descargar (exe y código fuente)
http://www.zocsoft.com/temp/resizable_dialog.rar
5. Materiales de referencia:
MSDN: Cómo diseñar una hoja de propiedad MFC recuperable
Dirección de cotización: "Implementar un cuadro de diálogo que pueda cambiar el tamaño en Delphi"