Palavras -chave : diálogo, diálogo, redimensionável
1. Problema levantado
O problema vem de Stanley_XU, na esperança de obter apenas o botão Fechar (também pode ajudar), não há ícone para o programa no canto superior esquerdo e a caixa de diálogo é capaz de alterar o tamanho da janela.
As propriedades BordersTyle e Bordericons estão definidas para o TForm no VCL para simplificar a configuração dos estilos de janela (caso contrário, as funções da API como setWindowlong e GetWindowlong devem ser chamadas). A definição e a descrição de TformBordersTyle e Tbordericon são as seguintes:
Significado de valor
BSDIALOG NÃO RESIDADE;
bssingle não é redimensível;
BSNONONOTRESIZABLE;
borda redimensível padrão BSSizable
bstoolwindow como bssingle, mas com uma legenda menor
BSSizetoolwin como Bssizeable com uma legenda menor
Tipo tbordericon = (bisystemmenu, biminimize, bimaximize, bihelp);
Tbordericons = conjunto de tbordericon;
Significado de valor
Bisystemmenu O formulário possui um menu de controle (também conhecido como menu de sistema).
biminimize o formulário tem um botão de minimizar
bimaximize o formulário tem um botão de maximizar
BIHELP Se o BordersTyle for Bsdialog ou Biminimize e Bimaximize for excluído, um ponto de interrogação aparece na barra de título do formulário e, quando clicada, o cursor muda para o CRHELP;
Obviamente, BordersTyle e Bordericons só podem atender às necessidades gerais, e é impossível implementar caixas de diálogo que podem modificar tamanhos.
De um modo geral, se eu quiser obter uma janela que não pode ser maximizada, mas pode alterar o tamanho, defino BordersTyle como BSSizable, Remova o biminimize e o bimaximize de Bordericons, e o resultado é assim: a janela pode ser modificada, mas há Um ícone no canto superior esquerdo ::
Figura 1 Caixa de diálogo com ícone
Observe que há um ícone no canto superior esquerdo.
Nosso objetivo é os dois efeitos abaixo.
Figura 2 Caixa de diálogo de arquivo aberto
Figura 3 Caixa de diálogo Pasta Browse
2. Metade do problema é resolvido
Eu procurei por MSDN e encontrei um artigo que ensina como projetar páginas de propriedades que podem mudar o tamanho (no MFC, o CPropertySheet aparece como uma subpagem CPropertyPage, que herda do CDialog e geralmente não pode modificar o tamanho) Folha, o método introduzido no artigo é modificar o estilo da janela antes da criação da página da propriedade e, em seguida, processar manualmente a mensagem WM_SIZE.
Int Callback CMyPropertySheet :: XMNPropsheetCallback (HWND HWND, MENSAGEM UINT, LPARAM LPARAM)
{
Extern int Retorno de chamada AfxPropsheetCallback (HWND, Mensagem UINT, LPARAM LPARAM);
// xmn: ligue para o retorno de chamada do MFC
int nres = AfxPropsheetCallback (hwnd, mensagem, lparam);
Switch (mensagem)
{
case pscb_precreate:
// Defina nossos próprios estilos de janela
((Lpdlgtemplate) lparam)-> style | = (ds_3dlook | ds_setfont
|
quebrar;
}
retornar NRES;
}
Eu tentei usar o mesmo método em uma forma de VCL. Defina o BordersTyle como Bsdialog ao projetar e depois sobrecarregue o método CreateParams. Mas o resultado é que a caixa de diálogo se torna uma borda espessa (porque possui estilo WS_THICKFRAME), o mouse pode mudar automaticamente após a mudança para cada borda e não há ícone no canto superior esquerdo, mas a janela não pode alterar seu tamanho (O processo de processamento de mensagens WM_SIZE adicionado não é acionado). Qual é o problema?
Figura 4 Caixa de diálogo que ainda não está completamente satisfatória
3. Resolva o problema
Eu verifiquei o código -fonte do formulário.PAs e encontrei o problema. Existe um processo de incorporação de ModifySystemMenu no processo de processamento de mensagens WM_NCCRETE do TCustomForm, que é usado para modificar o menu do sistema do Sistema. Observe que o texto vermelho abaixo diz "Faça o menu do sistema parecer uma caixa de diálogo". As próximas frases de código excluíram os itens do menu do sistema até o ponto em que apenas "mover" e "fechar".
procedimento tcustomform.wmnccreate (var mensagem var: twmncCreate);
procedimento modifysystemmenu;
var
Sysmenu: Hmenu;
Começar
...
{Modifique o menu do sistema para parecer mais como se é para}
Sysmenu: = getSystemmenu (alça, false);
Se fbordersTyle = bsdialog então
Começar
{Faça o menu do sistema parecer uma caixa de diálogo que tem apenas
Mover e fechar}
Deletemenu (sysmenu, sc_tasklist, mf_byCommand);
Deletemenu (Sysmenu, 7, Mf_byposition);
Deletemenu (Sysmenu, 5, Mf_byposition);
Deletemenu (Sysmenu, SC_MAXIMIZE, MF_BYCOMAND);
Deletemenu (sysmenu, sc_minimize, mf_byCommand);
Deletemenu (sysmenu, sc_size, mf_byCommand);
Deletemenu (sysmenu, sc_restore, mf_byCommand);
fim mais
...
fim;
Começar
herdado;
Setmenu (fmenu);
se não (csdesigning no componentState), então modifysystemmenu;
fim;
Portanto, o problema é que, como "sc_size" é excluído, o estilo da janela tem uma deformidade: existe ws_thickframe (o tamanho da janela pode ser modificado), mas não responde à mensagem wm_size (sc_size é excluído).
A solução é muito simples: implemente seu próprio processo de processamento de mensagens WM_NCCRETE e modifique manualmente o menu do sistema.
procedimento tzocdlgresizable.wmnccreate (var mensagem: twmncCreate);
// Os seguintes códigos são copiados do formulário.PAS Linha 4047, Delphi 7 Sp1.
procedimento modifysystemmenu;
var
Sysmenu: Hmenu;
Começar
Sysmenu: = getSystemmenu (alça, false);
{Faça o menu do sistema parecer uma caixa de diálogo que tem apenas
Mova, tamanho e comandos de fechamento}
Deletemenu (sysmenu, sc_tasklist, mf_byCommand);
Deletemenu (Sysmenu, 7, Mf_byposition);
// Não remova o Separater antes do comando de fechar.
// Deletemenu (Sysmenu, 5, Mf_byposition);
Deletemenu (Sysmenu, SC_MAXIMIZE, MF_BYCOMAND);
Deletemenu (sysmenu, sc_minimize, mf_byCommand);
{Não remova o comando de tamanho, caso contrário, perderemos o
Capacidade de redimensionar a caixa de diálogo.
// Deletemenu (sysmenu, sc_size, mf_byCommand);
Deletemenu (sysmenu, sc_restore, mf_byCommand);
fim;
Começar
{Skip
O comando de tamanho do menu do sistema.}
herdou DefaultHandler (Mensagem);
// lidando com o menu do sistema à nossa maneira.
Modifysystemmenu;
fim;
4. Classe TzocdlGresizable
A solução final que eu encapsulou como uma classe herdada do TForm. Tzocdlgresizable.
BTW: Eu também adicionei um atributo SizeGrip ao tzocdlgesizable.
Figura 5 Caixa de diálogo com sizeGrip sem ícone
Download (exe e código fonte)
http://www.zocsoft.com/temp/resizable_dialog.rar
5. Materiais de referência:
MSDN: Como projetar uma folha de propriedades MFC redimensível
Endereço da citação: "Implementando uma caixa de diálogo que pode alterar o tamanho em Delphi"