O componente visual é na verdade uma classe. Para escrever uma classe, você pode escrevê-la diretamente no arquivo *.pas. Mas para escrever controles, você deve usar pacotes. Selecione Novo no menu Arquivo para criar um novo pacote. Este é o pacote usado para armazenar e instalar o controle. Em seguida, clique no botão Adicionar na janela Pacote para adicionar um componente (Unidade).
Selecione Novo Componente na parte superior da caixa de diálogo pop-up. Como é impossível programar todas as propriedades, métodos e eventos de um controle sozinho, você precisa selecionar a classe ancestral (ou "classe pai" ou "classe base") e, em seguida, adicionar suas próprias propriedades, métodos e eventos para isso. Selecione a classe ancestral necessária na caixa suspensa após Tipo de ancestral. Como escrever controles visuais requer desenho, TGraphicControl é selecionado como classe ancestral. Em seguida, insira o nome do novo controle (classe) na caixa Nome da Classe, geralmente começando com “T”. A página da paleta é usada para selecionar o nome da página de controle do novo controle na janela do Delphi, como "Padrão". Adicione o caminho e o nome do arquivo do novo arquivo de controle em Unit File Name e clique no botão OK. Novos controles são adicionados. Agora é hora de escrever o código do controle.
A seguir, é necessário escrever uma barra de rolagem que pode personalizar imagens como exemplo para ilustrar o método de escrita de controles visuais.
Siga o método acima, selecione TGraphicControl como classe ancestral e o nome do novo controle é TPigHorizontalScroller. Depois de selecionar o caminho e o nome do arquivo, clique no botão OK para começar a escrever o código.
Cada controle será criado (Create) e excluído (Destroy), portanto esses dois processos devem ser escritos primeiro. Para cada procedimento no controle, ele deve ser definido primeiro e depois escrito. Existem três tipos de processos ou propriedades definidas: 1. Aqueles definidos após PRivate são usados internamente pelo controle e não podem ser vistos pelas pessoas que usam o controle 2. Aqueles definidos após protegidos são geralmente invisíveis e só podem ser usados por outros quando; outros utilizam o controle. O controle só fica visível ao escrever outros controles como classe ancestral 3. Aqueles definidos após public só podem ser chamados por outros no programa 4. Aqueles definidos após publicados podem ser vistos na janela de propriedades (Object); Inspetor). Como o processo de criação e exclusão não só é executado automaticamente quando o controle é criado durante o processo de programação, mas também pode ser chamado quando o controle é criado dinamicamente durante a execução do programa, ele é definido após público (1). (O número de série indica a posição do código da subetapa no programa fonte anexo, o mesmo abaixo) Talvez você ainda não saiba o que deve ser compilado nesses dois processos e como compilá-lo. Falaremos sobre isso abaixo.
Vamos primeiro adicionar algumas propriedades a este controle. Definimos uma propriedade Max para definir ou ler o valor máximo da barra de rolagem. Como os atributos geralmente não são usados diretamente nos programas, uma variável deve ser definida para corresponder ao atributo e seu valor pode ser modificado ou lido. Por ser usado apenas dentro do controle, nós o definimos após private (2). (Geralmente, variáveis associadas a atributos começam com "F", como FMax) Após definir as variáveis, defina os atributos. Esta propriedade precisa estar visível na janela Object Inspector, então defina-a e publique-a (3). A sintaxe definida é:
propriedade <nome da propriedade>:<tipo> leia <variável correspondente ao ler esta propriedade> escreva <variável ou procedimento correspondente ao escrever esta propriedade>
Outras variáveis e atributos também são definidos de forma semelhante (como valor mínimo mínimo, valor atual do valor, etc.). A seguir definimos diversas propriedades e variáveis para configurar a imagem da barra de rolagem (como a variável imagem é especial, falaremos sobre ela separadamente). Definimos LeftButtonUpPicture (imagem do botão esquerdo), LeftButtonDownPicture (imagem pressionada pelo botão esquerdo), etc. como tipos TBitmap (variáveis correspondentes devem ser definidas).
Você deve ter notado que no programa fonte anexado, ao definir esses atributos, a variável correspondente ao atributo lido após leitura é F..., mas a variável correspondente ao atributo especificado após escrita não é uma Variável, mas algo como Set ... Este é um processo customizado. O processo como função é definido como:
procedimento <nome do procedimento>(Valor: <tipo de valor do atributo que está sendo definido>)
Como outras coisas precisam ser feitas ao escrever esse tipo de atributo, você não pode simplesmente usar uma variável para lidar com ele, você deve usar um processo para lidar com isso. Este processo é geralmente definido após protegido. Neste tipo de procedimento, uma instrução como ⑷ é usada para atribuir um valor a uma variável do tipo TBitmap. Isso é adotado porque variáveis deste tipo não podem receber um valor diretamente.
Após definir as propriedades dessas variáveis do tipo TBitmap, você precisa escrever o código no processo de criação e destruição mencionado acima. Como TBitmap também é uma classe, ela deve ser criada durante o processo de criação (5) e liberada (gratuitamente) durante o processo de destruição (6). A instrução herdada mencionada em ⑺ aqui é usada para indicar que o processo é herdado da classe ancestral. (Isso não deve ser descartado).
Como estamos escrevendo um controle visual, devemos fazer desenhos no controle. A classe ancestral do nosso controle, TGraphicControl, encapsula um objeto Canvas (canvas) e podemos usá-lo diretamente para desenhar imagens. Se você ainda não está familiarizado com o uso do canvas, é uma boa ideia encontrar um livro e lê-lo.
A próxima coisa a fazer é desenhar a imagem. Como fazer desenhos no controle? Existe um evento Paint na classe ancestral TGraphicControl, que é acionado automaticamente quando o controle precisa ser redesenhado. O que temos que fazer agora é escrever um programa para este evento. Primeiro defina um objeto Canvas depois de protegido. Como já existe na classe ancestral, não há necessidade de adicionar nenhuma explicação⑻. Usaremos este objeto para desenhar a imagem. Em seguida, você precisa definir um processo do Paint e escrever o código para desenhar o controle. Defina o processo do Paint primeiro depois de público. Como é acionado pela classe ancestral em vez de ser chamado pelo usuário, a substituição deve ser adicionada posteriormente, caso contrário, o controle não se tornará um controle visual porque o processo do Paint nunca será chamado. A seguir escreveremos o código para o processo Paint⑽.
O T_Height e outras variáveis no processo Paint do programa fonte anexado a este artigo são usadas para salvar o tamanho dos botões, controles deslizantes, etc. na barra de rolagem. Esta parte do programa não é muito diferente do programa em aplicativos comuns. A maioria deles é para operar na tela, acredito que todos entenderão rapidamente. Vale a pena observar o seguinte julgamento da variável FAutoSize. FAutoSize é uma variável booleana associada ao atributo AutoSize do controle. Ela é usada para definir se o tamanho do controle muda com o tamanho da imagem. Observe que no código do controle, as propriedades geralmente não são chamadas diretamente, mas as variáveis correspondentes são usadas.
Neste ponto do programa, você finalmente apareceu para seu novo controle, mas ele ainda não pode rolar. Agora vamos escrever eventos de mouse que nos permitirão manipulá-lo. A definição do processo de evento de mouse é muito semelhante ao processo de Paint, exceto que as descrições dos parâmetros devem ser adicionadas no final. Os eventos de mouse são divididos em três tipos: MouseDown, MouseMove e MouseUp devem ser adicionados após a definição. Em seguida, escreva seu código por trás. Nota: O evento de mouse aqui é Mouse..., não o OnMouse usual.... Mas para que serve a definição em ⒀? As definições de eventos aqui são todas para usuários, ou seja, quando o controle for utilizado, ele será exibido na página Evento do Object Inspector.
O código para esses eventos do mouse também é muito simples. Ele determina as coordenadas do mouse, desenha a imagem correspondente na tela, etc., e aciona o evento correspondente ao mesmo tempo. É importante notar que ao chamar um evento personalizado, você deve primeiro usar uma instrução como ⒁ para determinar se o usuário escreveu o código para o evento. Isto é muito importante, caso contrário ocorrerá um erro.
Todos notaram que os eventos que acabamos de chamar são todos customizados e o método definido também é muito simples. É semelhante à definição de propriedades, exceto que o tipo é TNotifyEvent.
TNotifyEvent é o evento padrão, definido como:
TNotifyEvent = procedimento(Remetente: TObject)
Se quiser definir outra forma de evento, você deve fazer o seguinte: escreva primeiro e depois digite
<nome do tipo de evento> = procedimento(<parâmetro>:<tipo>)
Por exemplo:
TCustomEvent = procedimento(a: Inteiro; b:String);
Em seguida, defina-o após público:
<nome do evento>:<nome do tipo de evento>
Por exemplo:
AnEvent: TCustomEvent;
Depois de ler isto, você deverá compreender todo o procedimento. Se ocorrerem erros de compilação ou execução, verifique os seguintes pontos:
1. Existem instruções herdadas nos processos de criação e destruição?
2. As variáveis do tipo TBitmap foram criadas e liberadas?
3. Existe um nome de controle antes do processo, por exemplo: TPigHorizontalScroller.MoseMove
Como determinar se o mouse entra ou sai do controle:
Defina o seguinte processo:
procedimento MouseEnter(var Msg: TMessage mensagem CM_MOUSEENTER);
procedimento MouseLeave(var Msg: TMessage mensagem CM_MOUSELEAVE);