Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Nazgulled

Como remover o border/caption de um Form sem usar o FormBorderStyle

Recommended Posts

Nazgulled

Bem, estou aqui às voltas e não consigo fazer isto de forma que fique a funcionar como deve ser, passo a explicar...

Actualmente, estou a remover o border usando FormBorderStyle = None para remover o dito cujo e desenhar livremente a minha skin com o border/caption que eu quiser. Mas o problema é que eu queria usar o valor do FormBorderStyle para permitir ao utilizador escolher se quer o Form resizable ou não sem necessitar de criar uma propriedade extra para o fazer e sem que o border/caption do Windows seja desenhado.

Primeira tentativa foi apanhar a mensagem WM_NCCALCSIZE que calcula o tamanho da janela e da área de cliente. Ainda tentei brincar com o parâmetro RECT desta mensagem mas cheguei à conclusão que se apenas apanhar a mensagens WM_NCCALCSIZE e não chamar o método base. O border/caption do Form não irão aparecer. Até aqui tudo bem, mas...

O problema é que eu estou a usar a API AnimateWindow para mostrar/esconder o meu Form e de todas as vezes que essa API é chamada, o border do Windows é desenhado por cima da minha skin e quando a animação termina, o border desaparece e a minha skin fica bem desenhada.

Eu queria ainda, que isto também funcionasse em DesignTime, mas se eu não chamar o método base do WM_NCCALCSIZE em DesignTime, o resultado não é lá muito agradável e fica um mix da minha skin com o Form do Windows...

Haverá melhores soluções?

EDIT:

Lembrei-me agora... O ideal seria eu saber qual é o código que é executado pelo .NET quando definimos o FormBorderStyle = None. Assim eu removia o border normalmente usando esse código em vez de estar a mudar a propriedade do FormBorderStyle. Já usei o .NET Reflector mas aquele código é demasiado confuso para mim...

Share this post


Link to post
Share on other sites
Nazgulled

Consegui arranjar duas soluções:

protected override CreateParams CreateParams {
    get {
        CreateParams param = base.CreateParams;
        param.Style &= ~0x00C40000;
        return param;
    }
}

Este código faz exactamente aquilo que eu quero (remove o o border em modificar o FormBorderStyle). Mas tem um pequeno problema, se o FormBorderStyle for Fixed3D ou FixedSingle, em design-time ele vai desenhar um pequeno e muito fino border à volta do form mas isto já não acontece em run-time. No entanto, é um problema que me irrita :)

private FormBorderStyle formBorderStyle;

public new FormBorderStyle FormBorderStyle {
    get {
        return formBorderStyle;
    }
    set {
        formBorderStyle = value;

        if(EnableSkin) base.FormBorderStyle = FormBorderStyle.None;
        else base.FormBorderStyle = formBorderStyle;
    }
}

Esta solução já resolve o problema de cima e funciona na perfeição. No fundo estou a mudar a propriedade apenas no Form base, alterando assim o aspecto do border. Mantendo o valor "real" na propriedade do Form. Por um lado isto é uma forma de contornar o problema, mas a solução do CreateParams pare-me mais lógica. Se não fosse aquele pequeno problema, preferiria-a.

Estou indeciso... :/

Share this post


Link to post
Share on other sites
Nazgulled

Parece que vou ter que usar a minha solução, funciona melhor que a do CreateParams. Esta última, no meu caso especial, provoca algumas incompatibilidades com a implementação que estou a fazer para que a minha aplicação tenha "skins".

Mas para quem estiver interessado, consegui resolver o problema mencionado acima sobre o Fixed3D/FixedSingle, fica aqui o código que resolve o problema:

private const int WS_CAPTION = 0x00C00000;
private const int WS_THICKFRAME = 0x00040000;
private const int WS_EX_DLGMODALFRAME = 0x00000001;
private const int WS_EX_CLIENTEDGE = 0x00000200;

protected override CreateParams CreateParams {
    get {
        CreateParams param = base.CreateParams;

        param.Style &= ~WS_CAPTION & ~WS_THICKFRAME;
        param.ExStyle &= ~WS_EX_DLGMODALFRAME & ~WS_EX_CLIENTEDGE;

        return param;
    }
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.