Delphi – exploração de habilidades:
{Não. 1}
Frases para criar formulários modais:
classe PRocedure TMyForm.RunForm(AObj1, AObj2: TObject);
var
vForm: TMyForm;
começar
vForm := TMyForm.Create(aplicativo);
com vForm faça
Tentar
InitForm(AObj1, AObj2);
ShowModal;
Finalmente
Livre;
fim;
fim;
//*ilustrar:
As funções declaradas por meio da classe são semelhantes às funções estáticas no VC; use a instrução: TMyForm.RunForm(vObj1, vObj2);
Para outras informações específicas, consulte: descrição da classe na Ajuda do Delphi.
O objetivo de enfatizar esse idioma é:
1. Se este formulário for usado em vários locais, você poderá garantir que esse código seja chamado uniformemente;
2. Se a função for modificada, por exemplo: processamento com base no valor de retorno de ShowModal, modifique apenas esta função.
3. O programa tem um bom encapsulamento e é fácil de manter e trabalhar. *//
{Nº 2} // Uso da tag
Resposta aos eventos do botão da barra de ferramentas do formulário
procedimento TMyForm.RunOperate(ATag: Inteiro);
começar
Caso ATag de
1: MeuBotão.Color := clVermelho;
2: MeuBotão.Color := clVerde;
3: MeuBotão.Color := clPreto;
fim;
fim;
procedimento TMyForm.ToolBtnClick(Remetente: TObject);
começar
RunOperate(TControl(Remetente).Tag);
fim;
Se você estiver em um menu suspenso e precisar executar funções semelhantes,
procedimento TMyForm.MenuItemClick(Remetente: TObject);
começar
RunOperate(TMenuItem(Remetente).Tag);
fim;
//*ilustrar:
1. Estrutura clara
2. As informações relevantes são concentradas, facilitando a verificação, modificação e manutenção.
3. Melhorar a adaptabilidade e escalabilidade do programa, por exemplo, se o requisito não for implementado no botão da barra de ferramentas, mas implementado em botões diferentes, será fácil modificá-lo.
Sugestão: Cada categoria é seguida por apenas uma linha ou algumas linhas de código. Se houver muito código, use uma função de processo.
O que é mais interessante é que costumo escrever o seguinte:
Caso btnMyButton.Visível de
{mostrar} Verdadeiro: ...
{Não mostrar} Falso: ...
fim; *//
{Nº 3} //Ponteiro de evento como parâmetro
//Use o ponteiro de evento para ler listas, etc.
tipo
TDataSetEvent = procedimento (DataSet: TDataSet; AIndex, ACount: Integer) do Objeto;
//Classes derivadas do TADOQuery
procedimento TMyADOQuery.EnumRecord(AWhereStr: String; APro: TDataSetEvent);
começar
Fechar;
SQL.Clear;
SQL.Add('Selecione * Da Tabela1');
se AWhereStr <> '' então
SQL.Add('Onde' + AWhereStr);
Abrir;
Embora não seja Eof Do
começar
se atribuído(APro) então APro(Self, RecNo, RecordCount);
Próximo;
fim;
Fechar;
fim;
//*ilustrar:
Este método vem da função API em Window para enumerar todas as janelas filhas atuais, EnumChildWindow
1. Princípio: Tente separar a leitura de dados da exibição de dados, processamento de dados, etc., como: MVC, etc.
2. A escalabilidade do programa foi aprimorada Se você originalmente desejava exibir ou processar uma determinada coluna de informações em uma lista, mas posteriormente mudou para usar o ComboBox, ao modificar o programa, você não precisa ler a parte de leitura de dados. , você só precisa modificar a exibição de informações, etc. Para outro exemplo, agora você precisa usar uma barra de progresso para exibir o progresso da leitura ao ler registros.
*//
{No. 4} //Matriz constante
{No No.2, o seguinte conteúdo é implementado
procedimento TMyForm.RunOperate(ATag: Inteiro);
começar
Caso ATag de
1: MeuBotão.Color := clVermelho;
2: MeuBotão.Color := clVerde;
3: MeuBotão.Color := clPreto;
fim;
fim;
}
//Então seria ideal implementá-lo usando um array.
procedimento TMyForm.RunOperate(ATag: Inteiro);
const
MeuButtonColorMax := 3;
MyButtonColor: array [1..MyButtonColorMax] de TColor = (clRed, clGreen, clBlack);
começar
Caso ATag de
1..MyButtonColorMax: MyButton.Color := MyButtonColor[ATag];
101:....
fim;
fim;
//*ilustrar:
Para uso no modo array, observe que o limite superior ou inferior do array é implementado usando constantes e, em seguida, tente usar essa constante para leitura do loop do array em usos futuros.
*//
{No. 5}Mecanismo de mensagem reduz funções públicas de classe
//Como minimizar a definição de funções públicas num formulário;
{Por exemplo: Se você deseja implementar um formulário de lista de propriedades do controle de formulário atual, quando precisar atualizar o formulário de propriedades, haverá muitas informações; que precisa ser interagido. Se usarmos funções públicas de classe, precisaremos definir muitas funções públicas. Ao mesmo tempo, se a conversão do tipo de formulário for necessária, as funções públicas poderão ser usadas somente após a conversão para o tipo de formulário de destino. Portanto, haverá situações em que duas unidades precisarão se incluir}
//Solução:
TfrmMeuFormulário = classe(TForm)
FfrmProperty: TForm;
fim;
...
FfrmProperty := TfrmProperty.MyCreate(Aplicativo, Self);
...
//Quando a janela de propriedades precisa ser atualizada
FfrmProperty.Perform(WD_REFRESHPROPERTYLIST, 0, 0);
PropriedadeTfrm = classe(TForm)
privado
FMyForm: TForm;
procedimento WDREFRESHPROPERTYLIST(var Mensagem: TMessage); mensagem WD_REFRESHPROPERTYLIST;
público
construtor MyCreate(Proprietário: TComponent; AForm: TForm);
fim;
construtor TfrmProperty.MyCreate(Proprietário: TComponent; AForm: TForm);
começar
herdado Criar (Proprietário);
FMyForm := AFormulário;
fim;
//* Para a forma de utilização das mensagens, a definição de funções públicas do formulário pode ser reduzida. Ao mesmo tempo, melhora a escalabilidade do programa. Se você usar o formulário dele, ele poderá ser convertido facilmente, pois no máximo é o seu formulário e não processa a mensagem atual*)//
{Nº 6}Use a lista de registro para gerenciar possíveis módulos de expansão
//Projeto: é necessário oferecer suporte a vários métodos de exibição de saída para um conjunto de dados
...Exemplos serão dados mais tarde
//* ilustrar:
1. "Múltiplos métodos de saída" significa que os métodos de saída podem ser frequentemente expandidos em aplicações futuras, portanto, a fácil escalabilidade dos métodos de saída deve ser levada em consideração durante o design do programa.
2. Referindo-se ao mecanismo de registro de controle (RegisterComponents) na VCL, você pode descobrir que um grande número de mecanismos de registro são usados na VCL, o mais clássico é o registro do editor de propriedades de controle;
*//
{No.7}Usar versão predefinida do programa de controle
//Se você estiver executando um programa de plataforma de desenvolvimento secundário, deverá envolver problemas de controle de versão do produto e de controle de versão do projeto
//Geralmente controlado usando métodos predefinidos
//A declaração é relativamente simples:
{$DEFINE JOYYUAN97}
{$IFDEF JOYYUAN97} {ELSE} {ENDIF}
{$UNDEF JOYYUAN97}
*ilustrar:
1. Divida a predefinição em vários arquivos separados.
2. No início de cada unidade, mas depois da Unidade, use {$I ...} para incluir o arquivo na unidade atual.
3. Controle os arquivos de unidade que a unidade atual pode conter com base em condições predefinidas
4. Tente separar um arquivo predefinido para o projeto. Após incluir todos os arquivos predefinidos, inclua este arquivo, alguns arquivos predefinidos podem ser cancelados de acordo com a necessidade do projeto.
*//
{Nº 8}Use ponteiros de função para reduzir inclusões de projetos unitários
//Muitas vezes penso que reduzir a inclusão de unidades é o primeiro passo para tornar as unidades públicas, então como reduzir a inclusão de unidades tanto quanto possível
//Ou seja, mais esforços devem ser feitos para reduzir o acoplamento de unidades de programa.
{Descrição do cenário:
TMyFormManager: classe de gerenciamento de formulários
TMyForm: classe base do formulário de dados
TMyFormaccess: Classe de salvamento e leitura de informações de formulários. Salve as informações do formulário em um banco de dados ou algum outro tipo de estrutura
analisar:
1. A classe base do formulário (TMyForm) e a classe de gerenciamento de formulários (TMyFormManager) precisam ser implementadas em uma unidade uManagers.
2. A unidade fMyImange da classe de implementação específica do formulário (TMyImageForm) precisa incluir a unidade uManagers para herança e gerenciamento de formulários.
3. A unidade uMyAccess da classe de leitura de dados do formulário (TMyFormAccess) precisa incluir a unidade uManagers e a unidade fMyImange
pergunta:
Se eu quiser salvar o formulário, isso deverá ser feito em um evento de botão do formulário. Quando se trata da unidade de formulário, ela precisa conter a unidade de classe de acesso a dados do formulário, e se for colocada na classe base do formulário, a unidade uManager deve conter a unidade uMyAccess.
A inclusão de células é um perigo quando o acesso aos dados, ou seja, os formatos de armazenamento de dados, mudam com base nos requisitos e exigem escalabilidade.
Solução: Use variáveis de ponteiro de função.
1. Defina uma variável de ponteiro de função na unidade uManagers para salvar informações de dados.
2. Atribua um valor a esta variável de ponteiro de função quando o aplicativo for inicializado.
3. Quando for necessário salvar as informações do formulário, determine se o ponteiro não está vazio e execute a função para salvar as informações do formulário.
{Não. 9}Constantes, entenda constantes, use constantes
Existem muitos livros que apresentam a importância da definição de constantes, e muitas vezes penso nisso, mas quando olho para o código-fonte da VCL, percebo que ignorei o uso de constantes por outros.
1. A definição de mensagem que usamos com frequência é: declarar uma constante e usá-la no momento apropriado.
Comumente definido e usado:
const
WD_MyMessage = WM_User + 101;
tipo
TMyForm = classe(TForm)
...
procedimento WDMyMessage(var mensagem: TMessage); mensagem WD_MyMessage {posição da mensagem de resposta}
fim;
No entanto, se você reescrever a instrução {response message position} como:
procedimento WDMyMessage(var mensagem: TMessage mensagem WM_User + 101;
Da mesma forma, a compilação pode ser bem-sucedida e o uso é normal. Portanto, definições constantes são muito comumente usadas no processamento e interfaces do sistema Windows.
2. No Delphi, definimos variáveis de cores, clRed, clGreen, etc., que também são constantes definidas para facilitar o uso futuro. Através desta observação, descobri que a definição de constantes deve ser parcialmente reutilizável no projeto. Portanto, uma unidade constante padrão pode ser definida para que as constantes definidas possam ser reutilizadas em cada projeto.
{No. 10}Um array comumente usado em Delphi
Existe uma implementação relativamente completa em Delphi para a definição e utilização de arrays do tipo TIdentMapEntryd.
TIdentMapEntry = registro
Valor: Inteiro;
Nome: Sequência;
fim;
1. Definição de array: array[0..ArrMax] de TIdentMapEntry
Consulte: Unidade de controles:
Cursores: array[0..21] de TIdentMapEntry = (
...
);
2. Duas funções que se avaliam: IntToIdent (encontrar o nome do valor) e IdentToInt (encontrar o valor do nome);
Para aplicações específicas, consulte: IdentToCursor e CursorToIdent.
3. Aplicação: a. Aplicar diretamente este método de definição de grupo de árvores e função de manipulação de array b. c. Aprenda a definição padrão da função de acesso à informação: function IntToIdent (Int: Longint; var Ident: string; const Map: array de TIdentMapEntry): Boolean A informação específica retornada é retornada por parâmetros. é passado pela função O valor de retorno booleano é julgado.
{No. 11}De casos especiais a descobertas comuns
Descobri através do rastreamento as funções de definição e operação dos Cursores:
1. Conforme apresentado em {No. 10}, generalize a definição e as operações gerais dos Cursores.
2. Fornece funções para conversão entre Int e Ident.
3. Fornece uma função para ler ciclicamente as informações da lista de arrays: GetCursorValues entre eles, o método de "ponteiro de evento como parâmetro" introduzido em {No. 3} é usado para ler as informações da lista.
Suplemento ao {Nº 6}:
exemplo:
procedimento RegisterComponents(const Página: string;
ComponentClasses: array de TComponentClass);
começar
se atribuído (RegisterComponentsProc) então
RegisterComponentsProc(Página, ComponentClasses)
outro
raise EComponentError.CreateRes(@SRegisterError);
fim;
Interpretação:
1. Use o método de registro para registrar os tipos de controles que podem ser usados, etc.
3. Para RegisterComponentsProc, o método de "usar ponteiros de função para reduzir a inclusão de projetos de unidade" em {No. 8} é usado para facilitar a expansão futura do programa, atualizações de versão, etc.
{Não. 11}Defina apenas uma função pública
//Descrição do projeto: Agora precisamos implementar um desenho CAD ou sistema Visio, que requer boa escalabilidade e fácil manutenção;
//E requer baixo acoplamento, para que partes do sistema ou do sistema expandido possam ser empacotadas e usadas diretamente em projetos futuros.
projeto:
1. Projete uma classe abstrata de objeto gráfico Nesta classe, defina uma função abstrata CadPerform Os parâmetros da função referem-se à função TControl.Perform(Msg: Cardinal; WParam, LParam: Longint): Longint;
2. Na classe de gerenciamento gráfico, implemente o gerenciamento de uma lista de objetos gráficos. O que está armazenado na lista é o ponteiro do objeto abstrato.
3. Quando você deseja controlar objetos de classe específicos, basta usar a função CanPerform e, em seguida, passar Msg de acordo com a categoria da operação atual e passar as informações do parâmetro correspondente.
Implementação: TCad é a classe de controle de primeiro nível herdada da classe abstrata
função TCad.CadPerform(Msg: Cardinal; WParam, LParam: Longint): Longint;
começar
Mensagem de caso de
Minha_Mensagem1: Resultado := MinhaMensagem1(WParam, LParam);
Minha_Mensagem2: Resultado := MinhaMensagem2(WParam, LParam);
fim;
fim;
Pois, TPoint herda de TCad, a função CadPerform é implementada da seguinte forma.
função TPoint.CadPerform (Msg: Cardinal; WParam, LParam: Longint): Longint;
começar
Mensagem de caso de
My_Message1: Result := MyMessage1(WParam, LParam); //O processamento deste tipo de operação no TCad está bloqueado;
Minha_Mensagem3: Resultado := MinhaMensagem3(WParam, LParam);
senão Resultado: = CadPerform herdado (Msg, WParam, LParam);
fim;
fim;
*ilustrar:
Como operamos objetos gráficos com muita frequência, definimos uma função de interface pública e aberta para obter alto encapsulamento da classe e fácil manutenção e expansão do programa.
*//
{Não. 12}
A seguir estão meus requisitos de programação: (Algumas informações não têm restrições de idioma)
//Quase todas as soluções a seguir podem ser encontradas nos métodos acima.
1. Reduza a complexidade do programa. a. Reduza o número de funções, use métodos Case e Tag e aprenda como definir Reduzir relacionamentos de aninhamento de unidades, usar métodos de passagem de mensagens e reduzir a inclusão mútua de unidades de formulário;
2. Reduzir
{No. 13} Use a transmissão para implementar notificações de classes de gerenciamento para objetos de lista de gerenciamento
//Para a descrição do projeto {No. 12}, quando as propriedades ou o status do controle do formulário de desenho mudam, muitas vezes é necessário notificar todos os objetos gráficos e fazer as alterações correspondentes.
//Se apenas uma função de transmissão for definida, a notificação pai-filho poderá ser realizada, o que também melhorará a reutilização, escalabilidade, facilidade de manutenção, etc. do programa e tornará a estrutura de classes clara.
//Por exemplo: 1. No Visio e no MapInfo, se a escala (taxa de zoom) do formulário atual for alterada, todos os objetos gráficos exibidos no momento precisarão ser redesenhados com a nova escala. 2. Quando a fonte padrão do formulário atual é alterada, as fontes de texto dos objetos gráficos que usam a fonte padrão para exibir informações de texto também devem ser alteradas de acordo.
//Solução, consulte o mecanismo de processamento no TWinControl que notifica todos os subcontroles quando atributos ou status mudam:
procedimento TWinControl.NotifyControls(Mensagem: Word);
var
Mensagem: TMessagem;
começar
Mensagem.Mensagem := Mensagem;
Mensagem.WParam := 0;
Mensagem.LParam := 0;
Mensagem.Resultado := 0;
Broadcast(Message); // Transmite a mensagem de alteração atual
fim;
em:
procedimento TWinControl.Broadcast(var Mensagem);
var
Eu: Inteiro;
começar
para I := 0 para ControlCount - 1 faça
começar
Controls[I].WindowProc(TMessage(Message));
//Muda para: with TMessage(Message) do Cads[I].CadPerform(msg, WParam, LParam);
se TMessage(Message).Result <> 0 então Sair;
fim;
fim;
Porém, quando lidamos com objetos gráficos, podemos chamar diretamente a função pública CanPerform do Cads.
{Não. 14}Crie seus objetos dinamicamente quando necessário
Por exemplo: http://www.delphibbs.com/keylife/iblog_show.asp?xid=824
//************Opção 2: Crie um formulário de propriedade quando necessário
usa
...
fPropriedade;
tipo
TfrmMeuMapa = classe
...
procedimento OnfrmMyMapDestroy(Sender: TObject);
procedimento OnMapGeoSelected(AGeo: TGeometry);
privado
FfrmProperty: TfrmProperty;
procedimento ShowPropertyForm(aVisible: Boolean);
público
fim;
procedimento TfrmMyMap.ShowPropertyForm(aVisible: Boolean);
começar
se não for atribuído (FfrmProperty), então FfrmProperty := TfrmProperty.Create(Application);
FfrmProperty.Visible := aVisible;
fim;
procedimento TfrmMyMap.OnfrmMyMapDestroy(Sender: TObject);
começar
se atribuído(FfrmProperty) então FfrmProperty.Free;
fim;
procedimento TfrmMyMap.OnMapGeoSelected(AGeo: TGeometry);
começar
se atribuído(FfrmProperty) então FfrmProperty.MyRefresh(AGeo);
fim;
Aqui está explicado:
1. Crie dinamicamente seu objeto FfrmProperty quando necessário
2. Quando o objeto atual for liberado, determine a legalidade do seu objeto e, em seguida, libere o objeto criado dinamicamente.
{Não. 15}Crie uma interface ou crie uma estrutura
//Descrição do projeto: Quando desenvolvo um controle de tabela, se eu definir a célula como Com, se houver muita informação na tabela, a velocidade de carregamento não pode ser garantida e existe até possibilidade de travamento. A razão pela qual uso Com é para que o processamento e as informações de cada célula possam ser expandidos fora do controle no futuro.
Minha solução é: criar uma instância para cada controle derivado de Cell e criar dinamicamente vários objetos de estrutura. Registro para registrar as informações de cada célula. Se você precisar operar a célula, atribua o ponteiro do objeto de estrutura ao componente Cell, os resultados do teste são. muito satisfatório.
Portanto, se você precisar usar um grande número de instâncias de Com, tente gerenciar e manter uma instância, e os dados nela contidos poderão ser criados e gerenciados dinamicamente, o que terá um bom efeito em termos de velocidade.
Além disso, tente declarar um ponteiro de interface pMyInterface = ^IMyInterface Ao passar ou usar parâmetros, use o ponteiro de interface diretamente. Isso pode reduzir o número de chamadas para a função de contagem _AddInft, etc., e também pode aumentar a velocidade se o. a operação é normal.