2012-01-16 26 views
5

estoy dispuesto a diseñado una aplicación en Delphi XE2 Borderlessly y Captionlessly usando el siguiente código:Delphi sin bordes y Aplicación Captionless

BorderIcons = [] 
    BorderStyle = bsNone 

Pero el problema es que no hay ningún menú en Haga clic derecho sobre la Aplicación de Barra de tareas como en la imagen de arriba. Luego probé los siguientes códigos en el evento FormShow, pero también hay otro problema. Se crea un borde en el lado izquierdo y el lado izquierdo en el lado inferior. Los códigos son:

procedure TForm1.FormShow(Sender: TObject); 
var 
    r: TRect; 
begin 
    r := ClientRect; 
    OffsetRect(r, 0, GetSystemMetrics(SM_CYCAPTION)); 
    OffsetRect(r, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME)); 
    SetWindowRgn(Handle, 
    CreateRectRgn(
    r.Left, r.Top, 
    ClientWidth + r.Left, ClientHeight + r.Top), True); 

end; 

Por favor, ayúdenme.

+0

Posible duplicado: http://stackoverflow.com/questions/4901965/can-you- make-a-borderless-application-main-window-in-windows-without-ws-popup-s –

+1

La razón de que lo anterior sea un duplicado se debe a que lo que está sucediendo dentro del componente TForm es que cuando configuras 'BorderStyle = bsNone', también obtienes (¡gratis!) el estilo WS_POPUP configurado. El duplicado vinculado en realidad muestra una forma realmente baja de lograr que su ventana sea reconocida como una ventana de nivel superior, a pesar de que no tiene bordes (sin bordes). Cita: "En resumen, las formas sin bordes que usan BorderStyle = bsNone (dwStyle = WS_POPUP) bloquean todas las funcionalidades de Windows que generalmente se aplican a las ventanas principales de las aplicaciones, y todas las soluciones a continuación resuelven una parte de ellas". –

Respuesta

2

Puede hacer lo que David dice y también puede consultar en SetWindowRgn API.

Si usa solo el SetWindowRgn no tiene que quitar el borde del TForm, simplemente haga un rectángulo que comience debajo de él.

+1

OP ya está haciendo esto, y (parece) tal vez no hace lo que quiere el OP. –

+0

@user Dado que pareciste rechazar esta opción en la pregunta, ¿podrías explicarme cómo resuelve el problema? Parece más complejo que simplemente agregar 'WS_SYSMENU' en el estilo de ventana como se lo hemos propuesto Sertac y yo. –

+0

Guau, el OP aceptó esta respuesta, que contradice el texto en su pregunta. Bajar la votación de esta pregunta como inútil. –

7

La solución simple no es eliminar el menú del sistema en primer lugar. Tenga en cuenta que el menú del sistema es el nombre oficial del menú que falta en su aplicación.

Haga su archivo .dfm aspecto:

BorderIcons = [biSystemMenu] 
BorderStyle = bsNone 

deshacerse de ese código, que no se necesita FormShow.

OK, parece que un fragmento de código de mi experimentación me confundía. Esto es lo que funciona.

hacer exactamente lo que hizo originalmente en su forma .dfm:

BorderIcons = [] 
BorderStyle = bsNone 

A continuación, añadir de nuevo el menú de sistema utilizando CreateParams:

TForm1 = class(TForm) 
protected 
    procedure CreateParams(var Params: TCreateParams); override; 
end; 
... 
procedure TForm1.CreateParams(var Params: TCreateParams); 
begin 
    inherited; 
    Params.Style := Params.Style or WS_SYSMENU; 
end; 
+0

No veo ninguna diferencia en XE2 en el comportamiento de la aplicación iniciada si BorderIcons es [] o [biSystemMenu]. ¿Qué se suponía que vería diferente en Win7? El ícono de la barra de tareas todavía existe y todavía tiene exactamente 'Project.exe' y "Cerrar ventana" y "Pin en la barra de tareas", esos tres elementos solamente, incluso con las opciones establecidas arriba. –

+0

@ Warren Esa es la barra de tareas de ganar 7. Coloque el mouse sobre el botón de la barra de tareas. Luego haz clic derecho en la vista previa de la aerodinámica Luego ves el menú del sistema. Las barras de tareas de XP y Vista mostraron el menú del sistema más fácilmente si no recuerdo mal. –

+0

No puedo hacer que esto funcione, no veo el menú del sistema en el pulgar de la tarea y tampoco aparece con Alt + espacio. –

3

Usted puede tener una ventana que no parece tener una barra de título, o un título estándar, simplemente asumiendo el control de la pintura de toda la ventana:

Cree una nueva aplicación vacía. Utilice este código para el formulario:

unit ncUnit1; 

interface 

// XE2 uses clause 
uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,  
    Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs; 
// If you're not using XE2 take out the prefixes (WinApi, Vcl, System, etc) 

type 
    TForm1 = class(TForm) 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    protected 
    procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT; 
    procedure SolidColorNcPaint(solidColor,frameColor:TColor); 
    procedure Resizing(State: TWindowState); override; 


    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

{ TForm1 } 

procedure TForm1.WMNCPaint(var Message: TWMNCPaint); 
begin 
    SolidColorNcPaint(clBtnFace,clBtnFace); 
end; 

procedure TForm1.Resizing(State: TWindowState); 
begin 
    inherited; 
    PostMessage(Self.Handle,WM_NCPAINT,0,0); {force initial paint} 
end; 

procedure TForm1.SolidColorNcPaint(solidColor,frameColor:TColor); 
var 
aBorder:Integer; 
ahdc : HDC; 
begin 
aBorder := GetSystemMetrics(SM_CYSIZEFRAME); 
canvas.Lock; 
ahdc := GetWindowDC(Handle); 
canvas.Handle := ahdc; 
ExcludeClipRect(canvas.Handle, aBorder, 0, Width-aBorder, Height - aBorder) ; 
Canvas.Brush.Style := bsSolid; 
Canvas.Brush.Color := frameColor; 
Canvas.Pen.Color := solidColor; 
Canvas.Rectangle(0,0, Width,Height); 
ReleaseDC(Self.Handle, ahdc); 
canvas.Handle := 0; 
canvas.Unlock; 
end; 


end. 

Lo que ves arriba es sólo el código suficiente para volver a dibujar un color sólido sobre el área no cliente de la ventana, no para eliminarlo por completo. Dependiendo del estilo de la ventana personalizada que desee, debe procesar lo que desee en el formulario. Si no desea un botón Cerrar, quite el botón Cerrar y, si no desea el comportamiento de cambio de tamaño, elimine el comportamiento de cambio de tamaño. Si configura el FormStyle=fsDialog más el código anterior, obtendrá una ventana que tiene un área de título dibujado a medida completa (que puede poner lo que desee). Si realmente no desea que el área del título exista, puede modificar el código anterior para lograr eso también.

+0

He intentado su procedimiento. Formulo el estilo es bs_none el problema es el mismo. En Wright, haciendo clic en la aplicación en la barra de tareas, el Formulario completo se recrea con el título y el borde –

+1

. No le dije que configurara el estilo del formulario en bsNone. Dije que lo cambie a fsDialog. –

5
procedure TForm1.FormCreate(Sender: TObject); 
begin 
    BorderStyle := bsNone; 
    SetWindowLong(Handle, GWL_STYLE, 
     WS_POPUP or WS_CLIPSIBLINGS or WS_CLIPCHILDREN or WS_SYSMENU); 
    SetWindowLong(Handle, GWL_EXSTYLE, WS_EX_CONTROLPARENT or WS_EX_APPWINDOW); 
end; 

No necesita el código en el controlador OnShow con esta solución.

El código anterior se puede llamar en cualquier momento (no sólo en OnCreate), que puede ser utilizado para alterar el comportamiento de una forma de correr, por ejemplo, (basta con incluir WS_VISIBLE a estilos de ventana si el formulario ya es visible).

Si desea que el comportamiento sea efectivo durante el tiempo de vida del formulario, es mejor configurar los indicadores en un CreateParams modificado (donde VCL aplica los estilos de formulario). Esto también tendrá en cuenta la posibilidad de recreación de la forma. No establecer cualquier propiedad formulario de la OI para esta solución, todas las etiquetas están definidas explícitamente en el código:

type 
    TForm1 = class(TForm) 
    .. 
    protected 
    procedure CreateParams(var Params: TCreateParams); override; 

.. 

procedure TForm1.CreateParams(var Params: TCreateParams); 
begin 
    inherited; 
    Params.Style := WS_POPUP or WS_CLIPSIBLINGS or WS_CLIPCHILDREN or WS_SYSMENU; 
    Params.ExStyle := WS_EX_CONTROLPARENT or WS_EX_APPWINDOW; 
end; 
+0

+1 Pero, ¿no se necesita esto en 'CreateParams' en caso de que se vuelva a crear el identificador? ¿Y no es mejor aumentar los estilos simplemente incluyendo 'WS_SYSMENU' con un' o' en lugar de configurar todos los estilos? –

+0

@David - (1) No conozco el nivel de experiencia de OP, pensé que era mejor comenzar de manera simple ... OP puede encontrar una forma o hacer una pregunta si el formulario está siendo recreado :). (2) No, las banderas son lo que debería ser por defecto. –

+0

(1) Eso es solo almacenar una desagradable sorpresa en algún momento en el futuro, sospecho. (2) Estoy seguro de que tienes razón. –

Cuestiones relacionadas