Pergunta

eu sei que Controles sem janelas não são mágicos. Um controle sem janela pode ter foco de entrada (por exemplo, Internet Explorer). O foco de entrada também nada mais é do que desenhar:

e quando o usuário começa a pressionar as chaves, reagindo adequadamente. Você conhecer as teclas são destinadas a este controle focado, porque esse é o controle tem foco.

No caso da minha janela (Windows®), eu teria que saber que meu controle infantil sem janelas (vamos fingir É um descendente de TgraphicControl) recebe os eventos do teclado. Então, durante o meu formulário OnKeyDown, OnChar, OnKeyUp, eu precisaria fingir que eles estão indo para o meu controle de crianças sem janelas.

O que posso fazer, mas é uma dor.

Mas então o usuário provavelmente vai querer usar Aba navegação, e terei que interceptar o manuseio normal de ordem de controle de guias de Delphi, e me enganchar para dizer que essa coisa é o próximo (e anterior) na ordem da guia.

O que posso fazer, mas é uma dor.

E depois há ActiveControl, o que não entende nada, exceto TWinControl's. Portanto, se Delphi tentar descobrir quem tem foco, ficará louco. Então, eu teria que ter uma implementação alternativa do ActiveControl.

O que posso fazer, mas é uma dor.

Em outras palavras: Isso é muito trabalho? Estou lutando contra o que Delphi é, tudo para que eu possa ter algumas dezenas de controles sem janelas acessíveis através da entrada do teclado? Os designers de Delphi nunca pensaram usando controles interativos sem janelas e, se eu tentar agora trabalhar, eu apenas ficarei preso no Hurtlocker?

Delphi me deu a chance de me ajudar de bom grado, mas eu olhei o caminho da dor.


Alguma explicação adicional de Controles sem janelas é preciso.

Nem todo controle com o qual você interage deve ser um controle do Windows. É bem possível ter o foco e enviar a entrada do teclado para um controle que não é uma janela do Windows.

Por exemplo, quase todos os controle que você vê em uma janela do navegador do Internet Explorer é um controle sem janela. Na captura de tela a seguir, você pode ver um editar Controle, que você pode digitar, e um botão que (nesta captura de tela) tem foco:

alt text

Você pode ver o retângulo de foco pontilhado e o botão está azulado (que no Windows indica que ele tem foco).

Se eu fosse pressionar Barra de espaço enquanto o Google Search Button tem foco, seria pressione o botão. A razão pela qual isso funciona é porque a Microsoft escreveu uma biblioteca de controles inteira de widgets. Esses controles parecem (quase) exatamente como os controles comuns regulares - são clones quase exatos dos controles comuns do Windows, até os temas que estão sendo aplicados.

O Mozilla Firefox e o Google Chrome também usam uma biblioteca de controles de widgets. Eles não usam os controles de janela embutidos da Microsoft, mas usam uma biblioteca de gráficos, interativos e sem janelas widgets.

E se você tiver um ambiente de desenvolvimento adequado, os widgets sem janelas funcionam como controles em janelas "normais". O GTK+ é uma biblioteca de widgets e a Glade é um IDE que permite controles de layout nessa biblioteca de widgets.

Não sei em que ambiente de desenvolvimento Firefox, Chrome ou Blender foram criados, mas seus widgets suportam controles sem janelas.


Então agora em minha pergunta.

A menos que eu esteja enganado, parece -me que, embora Delphi apoie uma base TControl, (que tem largura, altura e pode se pintar), não pode receber foco do teclado. Parece -me que Borland nunca projetou o VCL de Delphi como uma biblioteca genérica de widgets. A única evidência que tenho para apoiar isso é que um formulário ActiveControl é um Twincontrol:

property ActiveControl: TWinControl;

Isso não significa que Delphi possa ser, ou deve estar, limitado a controles de janela. A biblioteca de widgets VCL pode ser estendida para apoiar o foco para controles sem janelas.

Mas talvez Delphi já suporta controles sem janelas, e eu simplesmente não percebo? Já existe um mecanismo estabelecido em Delphi para apoiar o foco TControl'S? Mas sou um cara razoavelmente inteligente e tenho certeza de que o VCL da Delphi não pode fazer o que outras bibliotecas de widgets podem fazer.

O que então leva a outra pergunta: Quanto trabalho seria para as formas subclasse e tal para apoiá -lo? Existe alguém por aí, talvez alguém no Teamb, que é muito mais inteligente do que eu, que já tentou, e chegou à conclusão de que é impossível?

Estou perguntando agora, na frente, se tentar adicionar o suporte de controle sem janelas é quase impossível (ou seja, inútil) - para que eu não gaste semanas por nada. Estou tentando recorrer ao conhecimento de uma comunidade de desenvolvedores da Delphi.

Estou fazendo uma pergunta.

Foi útil?

Solução

É inútil construir controles sem janelas e Coloque -os na estrutura VCL de Delphi.

Você traz à tona o Internet Explorer como exemplo. Mas, nesse caso, é inteiramente responsável por tudo o que reside nele. Ele tem sua própria noção interna do que é o controle ativo, mas pense sobre como é de fora: é apenas um controle gigante. Quando você pergunta ao sistema operacional o que tem foco, o controle único do navegador tem, independentemente dos subcontrolos do navegador parece ter foco.

Quando você pressiona a guia, ela olha para o sistema operacional como se o navegador tivesse simplesmente consumido um caractere de guia, assim como os controles de edição. Os controles de edição movem o cursor em alguns espaços e adicionam caracteres de guia aos seus buffers internos; Os controles do navegador movem o cursor para outra região da tela.

Você está pensando em fazer tudo isso em um Delphi Tform. Os formulários Delphi já têm uma estrutura para gerenciar o controle ativo e o manuseio de teclas, e você terá que lutar contra tudo. Se você deseja controles sem janelas, siga a rota do Internet Explorer e Construa seu próprio controle de contêiner para segurá -los para que você possa permanecer encarregado de tudo o que acontece dentro dele.

Seu contêiner pode ser um controle VCL, mas as coisas que você coloca provavelmente não pode- eles ainda esperam usar as regras de manuseio de foco e teclado VCL. Observe como você não pode colocar os controles comuns do Windows no Internet Explorer. Qualquer coisa que você coloque lá precisa passar por interfaces ActiveX específicas. Talvez você precise de interfaces também, ou talvez possa simplesmente fazer seu próprio conjunto de classes de controle que descem de alguma classe de ancestrais especial que você projeta para trabalhar com seu contêiner. Não comece com TGraphicControl; Está muito entrincheirado no VCL para ser utilizável como base para a sua biblioteca de controle de ramificação.

Será muito trabalho, mas, novamente, também foi o Internet Explorer.

Outras dicas

Sim, é inútil.
E não é culpa de Delphi, você está apenas lutando contra o próprio Windows.
Se você precisar de um controle que se comporte como um controle janela, use um com janela.
E você está certo, tentar recriar toda a pilha da API de controles com janelas do zero é uma dor.

Sim, você praticamente descobriu. Usar controles sem janelas significa que você perde tudo o que as janelas podem fazer para ajudá -lo. Ter mais de um casal em uma única janela real é dor.

A maioria desses programas provavelmente não foi desenvolvida originalmente usando ferramentas do tipo RAD, por isso não teve escolha a não ser reinventar a roda. Uma das maiores vantagens de Delphi é o suporte profundo de VCL e componentes de terceiros para fornecer a aparência que você deseja.

Uma técnica que usei com grande sucesso para reduzir a quantidade de alças de janela usadas em um aplicativo baseado em formulário complexo (preparação de impostos) foi desenhar o texto em uma tela e mover um único desconforto de Tcustomedit para a posição que o usuário estava editando. Era trivial capturar as teclas de guia/para cima/para baixo e mover a edição para a posição apropriada. O desafio que descobrimos foi desenhar um retângulo quente ao redor do campo pairado do mouse. Acabamos com uma grade de tabjeto, onde o elemento da matriz seria nulo (sem campo), uma tlist (grade contém vários campos) ou classe AA que continha nosso descritor de campo. Isso reduziu a quantidade de verificações de alcance que tivemos que executar, pois era mais provável que a caixa contivesse apenas um único campo, ou no máximo 4 campos.

kit de ferramentas FPGUI é um exemplo do que você deseja. O código FPGUI mais recente no repositório de código-fonte é baseado em um design de várias janelas. Isso simples significa que todo widget/componente possui uma alça de janela, mas o Windows ou o Linux não fazem nada com essa janela, outras mensagens básicas de notificação (MouseEnter, Mouseexit, etc.). O FPGUI ainda tem controle total sobre onde cada componente vai, se for focado, como eles parecem etc. Alguns widgets/componentes no FPGUI também são componentes que não são de janela. por exemplo: tfpgscrollbar, tfpgmainmenu, o botão em um combbobox etc.

Se você deseja uma verdadeira versão sem janelas, significa que há apenas uma janela de nível superior que tem uma alça de janela, todos os outros widgets/componentes dentro dessa janela não existe no sistema operacional (eles não têm alças de janela), então O FPGUI também pode ajudar. O design inicial do FPGUI Toolkit foi baseado nesse design. Novamente, procure no repositório de código -fonte para a ramificação v0.4 do código. Esse design, o FPGUI teve que lidar com absolutamente tudo, criando eventos de mouseEnter/mouseleave, traduzindo sistemas de coordenadas para componentes de contêiner, manipular (falsos) estados de foco componentes etc ... Sim, o design inicial é muito trabalho, mas então você Tenha uma estrutura muito portátil, que também pode ser facilmente aplicada a outros sistemas operacionais.

E sim, o FPGUI está totalmente implementado na linguagem Pascal do Objeto usando o compilador Pascal gratuito para me fornecer suporte cruzado. Atualmente, o FPGUI é executado no Windows, Linux (32 e 64 bits), dispositivos Windows Mobile e Incorpded Linux (ARM).

Não tenho idéia do seu problema, aqui, mas acho que essa pequena história pode ser relevante ...

Temos um aplicativo que preenche uma dúzia de formulários. O usuário pode preencher formulários adicionais e também alterar os valores preenchidos pelo aplicativo.

Agora, em nossa primeira implementação, usamos componentes em janelas para cada campo de entrada, para que os campos pudessem receber foco e entrada. Isso acabou sendo um grande problema, porque todas essas janelas exigiram muitos recursos.

Agora temos controles sem janelas para cada campo de entrada. Isso significa que tudo o que acabamos é um desenho combinado da forma e seus campos de entrada. Quando o usuário clica dentro do desenho ou usa algumas teclas para mover/definir o foco, criamos um novo controle em janela para o campo clicado. Quando o usuário se move para o próximo campo de entrada, destruímos a primeira janela e criamos uma nova. Dessa forma, temos apenas um controle janela que novamente nos deu uma boa melhoria de velocidade.

Novamente - não tenho idéia do que você realmente deseja gerenciar. Twincontrol é um Twincontrol por um motivo, mas pode haver uma solução para o que você quer, o que quer que seja ...

Eu penso FGGUI pode ajudá -lo.

Verifique seu Wiki primeiro.

Eu acho que você pode usar essa estrutura para seu aplicativo em Delphi, pois está totalmente escrito em Pascal. Na verdade, é baseado em FreePasCal;)

Hth

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top