{"id":444,"date":"2016-08-30T00:19:50","date_gmt":"2016-08-30T03:19:50","guid":{"rendered":"http:\/\/www.pascalscada.com\/?page_id=444"},"modified":"2026-09-17T09:36:48","modified_gmt":"2026-09-17T12:36:48","slug":"hmi-control-library-hcl","status":"publish","type":"page","link":"https:\/\/www.pascalscada.com\/pb\/hmi-control-library-hcl\/","title":{"rendered":"Biblioteca de controles HMI (HCl)"},"content":{"rendered":"<h5>Introdu\u00e7\u00e3o<\/h5>\n<p>A <strong>HMI Control Library (HCl)<\/strong> \u00e9 o conjunto de controles visuais do PascalSCADA \u2014 a paleta <strong>PascalSCADA HMI Controls<\/strong>. Cada um deles \u00e9 um controle comum da LCL (<code>TEdit<\/code>, <code>TLabel<\/code>, <code>TCheckBox<\/code>, <code>TTrackBar<\/code>\u2026) que aprendeu a conversar com um <a href=\"\/pb\/tags\/\">tag<\/a>: voc\u00ea solta o controle no form, aponta a propriedade <strong><code>PLCTag<\/code><\/strong> para um tag e pronto \u2014 o controle passa a mostrar o valor do tag e, nos controles de entrada, a escrever nele. N\u00e3o h\u00e1 c\u00f3digo a escrever para o caso comum.<\/p>\n<p>O que todos os controles da HCl t\u00eam em comum:<\/p>\n<ul>\n<li><strong><code>PLCTag<\/code><\/strong> \u2014 o tag ao qual o controle est\u00e1 ligado. Um tag pode alimentar v\u00e1rios controles ao mesmo tempo. Se o tag for destru\u00eddo, o controle se desliga sozinho.<\/li>\n<li><strong><code>SecurityCode<\/code><\/strong> \u2014 um c\u00f3digo de seguran\u00e7a (texto livre, ex.: <code>\"setpoints\"<\/code>) que integra o controle ao <a href=\"\/pb\/security-system\/\">sistema de seguran\u00e7a<\/a>: o controle s\u00f3 fica habilitado se o usu\u00e1rio logado tiver permiss\u00e3o para esse c\u00f3digo. Vazio = sem restri\u00e7\u00e3o. O c\u00f3digo \u00e9 registrado automaticamente no gerenciador de seguran\u00e7a na primeira vez que aparece.<\/li>\n<li><strong><code>Enabled<\/code><\/strong> \u2014 al\u00e9m do valor que voc\u00ea define, o controle \u00e9 desabilitado automaticamente quando o usu\u00e1rio n\u00e3o tem o <code>SecurityCode<\/code>.<\/li>\n<li><strong>Selo de falha de comunica\u00e7\u00e3o<\/strong> \u2014 quando o tag ligado ao controle para de comunicar (timeout, porta fechada, driver sem resposta), um pequeno tri\u00e2ngulo amarelo de aviso aparece sobre o controle, e some quando a comunica\u00e7\u00e3o volta. N\u00e3o precisa configurar nada; o exemplo <a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_comm_fault_control_icon_test\"><code>examples\/laz_comm_fault_control_icon_test<\/code><\/a> mostra o efeito em cada controle.<\/li>\n<li><strong><code>BeforeSendAValueToTag<\/code><\/strong> \/ <strong><code>AfterSendValueToTag<\/code><\/strong> \u2014 eventos dos controles de entrada, disparados antes e depois de o valor ir para o tag. No <em>Before<\/em> voc\u00ea pode alterar ou vetar o valor.<\/li>\n<\/ul>\n<p>Os controles rodam na <em>thread<\/em> principal e s\u00e3o atualizados pelos eventos do tag \u2014 a atualiza\u00e7\u00e3o \u00e9 imediata quando o valor muda no equipamento, sem timers.<\/p>\n<h5>Formata\u00e7\u00e3o de valores<\/h5>\n<p>Os controles que exibem texto (<code>THMIEdit<\/code>, <code>THMILabel<\/code>) formatam o valor do tag com tr\u00eas propriedades:<\/p>\n<ul>\n<li><strong><code>NumberFormat<\/code><\/strong> \u2014 m\u00e1scara no formato da fun\u00e7\u00e3o <code>FormatFloat<\/code> do Free Pascal (<code>#0.00<\/code>, <code>000<\/code>, <code>#,##0.0<\/code>, <code>0.000E+00<\/code>\u2026). Vale s\u00f3 para tags num\u00e9ricos.<\/li>\n<li><strong><code>Prefix<\/code><\/strong> \/ <strong><code>Sufix<\/code><\/strong> \u2014 texto antes e depois do valor (<code>\"T = \"<\/code>, <code>\" \u00b0C\"<\/code>). Aparecem apenas em exibi\u00e7\u00e3o; no <code>THMIEdit<\/code>, somem enquanto o controle tem o foco para o operador editar s\u00f3 o n\u00famero.<\/li>\n<\/ul>\n<p>Com um <code>TPLCString<\/code> o controle mostra e edita o texto do tag diretamente.<\/p>\n<h5>Zonas<\/h5>\n<p>V\u00e1rios controles (<code>THMIText<\/code>, <code>THMIAnimation<\/code>, os conectores de propriedade e os controles de fluxo) n\u00e3o mostram o valor do tag, mas <strong>escolhem uma apar\u00eancia em fun\u00e7\u00e3o dele<\/strong>. A escolha \u00e9 feita por uma cole\u00e7\u00e3o de <strong>zonas<\/strong> (<code>Zones<\/code>, <code>Conditions<\/code>, <code>ColorAndFlowStates<\/code>): cada zona tem uma condi\u00e7\u00e3o e um resultado (um texto, uma imagem, uma cor, um booleano). O controle percorre a cole\u00e7\u00e3o e usa a <strong>primeira zona cuja condi\u00e7\u00e3o for verdadeira<\/strong>; se nenhuma for, usa a zona marcada como <strong><code>DefaultZone<\/code><\/strong>.<\/p>\n<p>A condi\u00e7\u00e3o de cada zona \u00e9 definida por <code>ZoneType<\/code>, <code>Value1<\/code>, <code>Value2<\/code>, <code>IncludeValue1<\/code> e <code>IncludeValue2<\/code>:<\/p>\n<table>\n<thead>\n<tr>\n<th>ZoneType<\/th>\n<th>A zona \u00e9 selecionada quando\u2026<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>ztEqual<\/code><\/td>\n<td>valor do tag = <code>Value1<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>ztNotEqual<\/code><\/td>\n<td>valor do tag \u2260 <code>Value1<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>ztRange<\/code><\/td>\n<td><code>Value1<\/code> &lt; valor &lt; <code>Value2<\/code> (<code>IncludeValue1<\/code>\/<code>IncludeValue2<\/code> tornam os limites inclusivos)<\/td>\n<\/tr>\n<tr>\n<td><code>ztOutOfRange<\/code><\/td>\n<td>valor &lt; <code>Value1<\/code> <strong>ou<\/strong> valor &gt; <code>Value2<\/code> (idem para os limites)<\/td>\n<\/tr>\n<tr>\n<td><code>ztGreaterThan<\/code><\/td>\n<td>valor &gt; <code>Value1<\/code> (\u2265 com <code>IncludeValue1<\/code>)<\/td>\n<\/tr>\n<tr>\n<td><code>ztLessThan<\/code><\/td>\n<td>valor &lt; <code>Value1<\/code> (\u2264 com <code>IncludeValue1<\/code>)<\/td>\n<\/tr>\n<tr>\n<td><code>ztBit<\/code><\/td>\n<td>o bit n\u00famero <code>Value1<\/code> do valor inteiro do tag \u00e9 igual a <code>IncludeValue1<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Zonas de anima\u00e7\u00e3o (texto, imagem e cor) t\u00eam ainda <strong><code>BlinkTime<\/code><\/strong> e <strong><code>BlinkWith<\/code><\/strong>: passado <code>BlinkTime<\/code> milissegundos, o controle troca para a zona de \u00edndice <code>BlinkWith<\/code> \u2014 que pode apontar de volta, formando um pisca-pisca, ou para uma terceira zona, formando uma sequ\u00eancia de anima\u00e7\u00e3o. <code>BlinkTime = 0<\/code> desliga.<\/p>\n<p><code>THMIText<\/code> e <code>THMIAnimation<\/code> t\u00eam em tempo de projeto a propriedade <strong><code>TestValue<\/code><\/strong>: um valor de teste que o controle usa no lugar do tag para voc\u00ea conferir as zonas no editor sem comunica\u00e7\u00e3o.<\/p>\n<h5>Controles de entrada<\/h5>\n<h6 id=\"THMIEdit\">THMIEdit<\/h6>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIEdit.png\"> Campo de edi\u00e7\u00e3o para tags num\u00e9ricos ou string. Mostra o valor formatado e, quando o operador digita um novo valor e confirma, escreve no tag.<\/p>\n<table>\n<thead>\n<tr>\n<th>Propriedade<\/th>\n<th>Padr\u00e3o<\/th>\n<th>Descri\u00e7\u00e3o<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>SendValueWhen<\/code><\/td>\n<td><code>[scLostFocus, scPressEnter]<\/code><\/td>\n<td>Quando o valor digitado vai para o tag: ao perder o foco, ao pressionar Enter, ao pressionar Esc, ou a cada tecla (<code>scAnyChange<\/code>).<\/td>\n<\/tr>\n<tr>\n<td><code>FreezeValueOnFocus<\/code><\/td>\n<td><code>True<\/code><\/td>\n<td>Enquanto o campo tem o foco, o valor do tag n\u00e3o sobrescreve o que o operador est\u00e1 digitando.<\/td>\n<\/tr>\n<tr>\n<td><code>EnableMinValue<\/code> \/ <code>MinValue<\/code>, <code>EnableMaxValue<\/code> \/ <code>MaxValue<\/code><\/td>\n<td><\/td>\n<td>Faixa aceita para entrada. Valor fora da faixa n\u00e3o \u00e9 enviado ao tag.<\/td>\n<\/tr>\n<tr>\n<td><code>NumberFormat<\/code>, <code>Prefix<\/code>, <code>Sufix<\/code><\/td>\n<td><\/td>\n<td>Formata\u00e7\u00e3o (veja acima).<\/td>\n<\/tr>\n<tr>\n<td><code>ShowFocused<\/code><\/td>\n<td><code>False<\/code><\/td>\n<td>Inverte cores de fundo e fonte quando o campo tem o foco, para destacar em telas de toque.<\/td>\n<\/tr>\n<tr>\n<td><code>ScreenKeyboardBehavior<\/code><\/td>\n<td><code>oskbDisabled<\/code><\/td>\n<td>Teclado virtual: <code>oskbEnabled<\/code> abre o teclado do pr\u00f3prio controle ao ganhar o foco (num\u00e9rico ou alfanum\u00e9rico conforme o tag e o <code>NumberFormat<\/code>); <code>oskbManager<\/code> delega ao <code>THMIKeyboardManager<\/code> do form. <code>ScreenNumericKBShowMinus<\/code>\/<code>ScreenNumericKBShowDecimal<\/code> controlam as teclas do teclado num\u00e9rico. Veja <a href=\"\/pb\/keyboard-manager\/\">Teclado virtual<\/a>.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h6 id=\"THMICheckBox\">THMICheckBox e THMIRadioButton<\/h6>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMICheckBox.png\"> Caixa de sele\u00e7\u00e3o ligada a um tag num\u00e9rico. Marcada quando o tag vale <code>ValueTrue<\/code>, desmarcada quando vale <code>ValueFalse<\/code>; <code>OtherValuesIS<\/code> diz o que fazer com qualquer outro valor (<code>isChecked<\/code>, <code>isUnchecked<\/code>, <code>isGrayed<\/code>, <code>isNone<\/code>). Quando o operador clica, escreve <code>ValueTrue<\/code> ou <code>ValueFalse<\/code> no tag \u2014 se <code>WriteTrueValue<\/code>\/<code>WriteFalseValue<\/code> estiverem em <code>True<\/code>, o que permite, por exemplo, um bot\u00e3o que s\u00f3 liga e nunca desliga.<\/p>\n<p>O texto, a cor e a fonte podem mudar com o estado: <code>CaptionTrue<\/code>\/<code>CaptionFalse<\/code>\/<code>CaptionGrayed<\/code>, <code>ColorTrue<\/code>\/<code>ColorFalse<\/code>\/<code>ColorGrayed<\/code>, <code>FontTrue<\/code>\/<code>FontFalse<\/code>\/<code>FontGrayed<\/code>. Escrever em <code>Caption<\/code>, <code>Color<\/code> ou <code>Font<\/code> preenche as tr\u00eas variantes de uma vez.<\/p>\n<p>Com um <a href=\"\/pb\/tags\/#TTagBit\"><code>TTagBit<\/code><\/a> como <code>PLCTag<\/code> (<code>ValueTrue = 1<\/code>, <code>ValueFalse = 0<\/code>) o <code>THMICheckBox<\/code> vira o controle padr\u00e3o para um bit de comando ou status.<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIRadioButton.png\"> <code>THMIRadioButton<\/code> \u00e9 o mesmo controle com apar\u00eancia de bot\u00e3o de r\u00e1dio. Prefira <code>THMIRadioGroup<\/code> para escolher entre v\u00e1rias op\u00e7\u00f5es.<\/p>\n<h6 id=\"THMIRadioGroup\">THMIRadioGroup<\/h6>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIRadioGroup.png\"> Grupo de op\u00e7\u00f5es ligado a um tag num\u00e9rico: a op\u00e7\u00e3o de \u00edndice <em>n<\/em> em <code>Items<\/code> fica selecionada quando o tag vale <em>n<\/em>, e clicar em uma op\u00e7\u00e3o escreve seu \u00edndice no tag. <code>DefaultIndex<\/code> \u00e9 a op\u00e7\u00e3o usada quando o valor do tag n\u00e3o corresponde a nenhum item.<\/p>\n<h6 id=\"THMIComboBox\">THMIComboBox<\/h6>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIComboBox.png\"> Lista suspensa ligada a um tag num\u00e9rico, com o mesmo mapeamento do <code>THMIRadioGroup<\/code>: \u00edndice do item = valor do tag. Para associar valores arbitr\u00e1rios (ex.: 10, 20, 50) aos itens, preencha <code>Items<\/code> por c\u00f3digo com objetos <code>TComboboxItemInfo<\/code>:<\/p>\n<pre class=\"brush: delphi; tab-size: 2; title: ; notranslate\" title=\"\">uses hmicombobox;\n\nHMIComboBox1.Items.AddObject(&#039;Lento&#039;,  TComboboxItemInfo.Create(nil, 10));\nHMIComboBox1.Items.AddObject(&#039;Normal&#039;, TComboboxItemInfo.Create(nil, 20));\nHMIComboBox1.Items.AddObject(&#039;R\u00e1pido&#039;, TComboboxItemInfo.Create(nil, 50));<\/pre>\n<h6 id=\"THMITrackBar\">THMITrackBar, THMIScrollBar e THMIUpDown<\/h6>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMITrackBar.png\"> <code>THMITrackBar<\/code> e <img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIScrollBar.png\"> <code>THMIScrollBar<\/code> movem-se com o valor do tag e escrevem nele quando o operador arrasta. No <code>THMIScrollBar<\/code>, <code>UpdateOnMove<\/code> decide se a escrita acontece durante o arrasto (<code>True<\/code>) ou s\u00f3 ao soltar (<code>False<\/code>). <code>Min<\/code>\/<code>Max<\/code> s\u00e3o os da LCL, em inteiros \u2014 para tags com escala, use um <code>ScaleProcessor<\/code> no tag.<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIUpDown.png\"> <code>THMIUpDown<\/code> s\u00e3o as setas de incremento\/decremento: cada clique soma ou subtrai <code>Increment<\/code> (um <code>Double<\/code>, ent\u00e3o serve para passos de 0,1) ao valor do tag, respeitando <code>Min<\/code>\/<code>Max<\/code> quando <code>EnableMin<\/code>\/<code>EnableMax<\/code> est\u00e3o ligados. Costuma ser colocado ao lado de um <code>THMIEdit<\/code> ligado ao mesmo tag.<\/p>\n<h6 id=\"THMITransparentButton\">THMITransparentButton<\/h6>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMITransparentButton.png\"> Um ret\u00e2ngulo invis\u00edvel com <code>OnClick<\/code>\/<code>OnMouseUp<\/code> e <code>SecurityCode<\/code>. Coloque-o sobre uma imagem de fundo ou sobre um desenho para criar uma \u00e1rea clic\u00e1vel com controle de acesso \u2014 o clique n\u00e3o acontece se o usu\u00e1rio n\u00e3o tiver o c\u00f3digo.<\/p>\n<h5>Controles de exibi\u00e7\u00e3o<\/h5>\n<h6 id=\"THMILabel\">THMILabel<\/h6>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMILabel.png\"> Mostra o valor de qualquer tag (num\u00e9rico ou string) com <code>NumberFormat<\/code>, <code>Prefix<\/code> e <code>Sufix<\/code>. \u00c9 o controle de exibi\u00e7\u00e3o mais usado. Para um tag que guarda data\/hora como n\u00famero, <code>FormatDateTimeOptions<\/code> ajusta a convers\u00e3o.<\/p>\n<h6 id=\"THMIText\">THMIText<\/h6>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIText.png\"> Um <code>THMILabel<\/code> que, em vez do valor, mostra o <strong>texto da zona selecionada<\/strong>: cada <code>TTextZone<\/code> em <code>Zones<\/code> tem <code>Text<\/code>, <code>Color<\/code>, <code>Transparent<\/code>, <code>Font<\/code> e alinhamento pr\u00f3prios. \u00c9 a forma padr\u00e3o de traduzir um c\u00f3digo de estado em palavras \u2014 <code>0 \u2192 \"Parado\"<\/code> em cinza, <code>1 \u2192 \"Rodando\"<\/code> em verde, <code>2 \u2192 \"Falha\"<\/code> em vermelho piscando (<code>BlinkTime<\/code> + <code>BlinkWith<\/code> apontando para uma zona com outra cor).<\/p>\n<h6 id=\"THMIProgressBar\">THMIProgressBar<\/h6>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIProgressBar.png\"> Barra de n\u00edvel desenhada pelo pr\u00f3prio PascalSCADA (n\u00e3o depende do tema do sistema): <code>Min<\/code>\/<code>Max<\/code> em <code>Double<\/code>, <code>Orientation<\/code> horizontal ou vertical, <code>Color<\/code> para o preenchimento, <code>BackgroundColor<\/code> e <code>BorderColor<\/code>. Serve para n\u00edvel de tanque, posi\u00e7\u00e3o, carga de motor.<\/p>\n<h6 id=\"THMIAnimation\">THMIAnimation<\/h6>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIAnimation.png\"> Mostra a <strong>imagem da zona selecionada<\/strong>. Cada <code>TGraphicZone<\/code> em <code>Zones<\/code> aponta para um arquivo (<code>FileName<\/code>) ou para uma imagem de um <code>TImageList<\/code> (<code>ImageList<\/code> + <code>ImageIndex<\/code>; <code>ImageListAsDefault<\/code> escolhe qual dos dois tem prioridade quando ambos est\u00e3o preenchidos), com <code>Transparent<\/code>\/<code>TransparentColor<\/code>. Com <code>BlinkTime<\/code>\/<code>BlinkWith<\/code> entre duas ou mais zonas voc\u00ea obt\u00e9m uma anima\u00e7\u00e3o \u2014 um motor girando, uma l\u00e2mpada piscando. O evento <code>ZoneChanged<\/code> avisa quando a zona muda. O post <a href=\"\/2019\/05\/10\/how-build-a-tank-level-animation-on-pascalscada\/\">How to build a tank level animation<\/a> mostra o uso com um <code>TImageList<\/code>.<\/p>\n<h5>Conectores de propriedades<\/h5>\n<p>Os conectores n\u00e3o t\u00eam apar\u00eancia pr\u00f3pria: eles <strong>alteram propriedades de outros controles<\/strong> (qualquer controle da LCL, n\u00e3o s\u00f3 da HCl) em fun\u00e7\u00e3o do valor de um tag. Isso permite, por exemplo, mudar a cor de um <code>TShape<\/code> comum ou esconder um <code>TPanel<\/code> sem escrever c\u00f3digo.<\/p>\n<h6 id=\"THMIBooleanPropertyConnector\">THMIBooleanPropertyConnector e THMIColorPropertyConnector<\/h6>\n<ul>\n<li><strong><code>PLCTag<\/code><\/strong> \u2014 o tag que dirige as condi\u00e7\u00f5es.<\/li>\n<li><strong><code>Conditions<\/code><\/strong> \u2014 cole\u00e7\u00e3o de zonas (as mesmas condi\u00e7\u00f5es da tabela acima). Cada zona tem um resultado: <code>ZoneResult<\/code> booleano (com <code>InvertResult<\/code>) no conector booleano, <code>ZoneResult<\/code> cor no conector de cor. Uma delas pode ser <code>DefaultZone<\/code>.<\/li>\n<li><strong><code>AffectedObjects<\/code><\/strong> \u2014 cole\u00e7\u00e3o de pares <code>TargetObject<\/code> + <code>TargetObjectProperty<\/code> (ex.: <code>Shape1<\/code> + <code>Brush.Color<\/code>, <code>Panel1<\/code> + <code>Visible<\/code>, <code>Label1<\/code> + <code>Font.Color<\/code>). A cada mudan\u00e7a do tag, o conector avalia as condi\u00e7\u00f5es e escreve o resultado em <strong>todas<\/strong> as propriedades listadas.<\/li>\n<\/ul>\n<p>O editor de propriedades lista as propriedades do tipo certo (booleano ou <code>TColor<\/code>) do objeto escolhido, inclusive as aninhadas (<code>Font.Color<\/code>, <code>Brush.Color<\/code>).<\/p>\n<h6 id=\"THMIControlDislocatorAnimation\">THMIControlDislocatorAnimation e THMIControlDislocatorAnimation2<\/h6>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIControlDislocatorAnimation.png\"> Movem um controle (<code>Control<\/code>) pela tela em fun\u00e7\u00e3o de um tag: quando o tag vale <code>ValueP0<\/code> o controle fica em (<code>P0_X<\/code>, <code>P0_Y<\/code>); quando vale <code>ValueP1<\/code>, em (<code>P1_X<\/code>, <code>P1_Y<\/code>); entre os dois, interpola linearmente. <code>EnableXMin\/XMax\/YMin\/YMax<\/code> com <code>MinXValue<\/code>\u2026 limitam o deslocamento. As propriedades <code>Gets_P0_Position<\/code>, <code>Gets_P1_Position<\/code> e <code>GoTo_P0_Position<\/code> s\u00e3o &#8220;bot\u00f5es&#8221; no Object Inspector: d\u00ea um duplo clique para capturar a posi\u00e7\u00e3o atual do controle como P0\/P1 ou para lev\u00e1-lo de volta a P0.<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIControlDislocatorAnimation2.png\"> A vers\u00e3o <strong>2<\/strong> usa dois tags independentes \u2014 <code>PLCTagX<\/code> com <code>ValueP0x<\/code>\/<code>ValueP1x<\/code> e <code>PLCTagY<\/code> com <code>ValueP0y<\/code>\/<code>ValueP1y<\/code> \u2014 para movimento em duas dimens\u00f5es (a posi\u00e7\u00e3o de um carro em uma ponte rolante, por exemplo).<\/p>\n<h5>Desenhos b\u00e1sicos<\/h5>\n<p>Formas de equipamentos desenhadas pelo PascalSCADA (via BGRABitmap, sem imagens externas), com <code>BodyColor<\/code>, <code>BorderColor<\/code>, <code>BorderWidth<\/code> e <code>SecurityCode<\/code>. Elas <strong>n\u00e3o t\u00eam <code>PLCTag<\/code><\/strong>: s\u00e3o est\u00e1ticas, e voc\u00ea as anima com os conectores de propriedade (cor) ou usa as vers\u00f5es <em>Flow<\/em> descritas em <a href=\"\/pb\/flow-controls\/\">Controles de fluxo<\/a>.<\/p>\n<table>\n<thead>\n<tr>\n<th>Controle<\/th>\n<th>Desenho<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIBasicValve.png\"> <code>THMIBasicValve<\/code><\/td>\n<td>V\u00e1lvula; <code>ValveType<\/code> escolhe o atuador (<code>vtSimple<\/code>, <code>vtPneumaticOnOff<\/code>, <code>vtPneumaticProportional<\/code>, <code>vtMotorisedProportional<\/code>, <code>vtPneumaticDrawer<\/code>), <code>ValveBodyPercent<\/code> a propor\u00e7\u00e3o corpo\/atuador, <code>Mirrored<\/code> espelha.<\/td>\n<\/tr>\n<tr>\n<td><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIBasicEletricMotor.png\"> <code>THMIBasicEletricMotor<\/code><\/td>\n<td>Motor el\u00e9trico; com <code>DrawPump = True<\/code> desenha uma bomba acoplada.<\/td>\n<\/tr>\n<tr>\n<td><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIFitaBasica.png\"> <code>THMIFitaBasica<\/code><\/td>\n<td>Transportador de correia (horizontal; <code>BodyHeight<\/code>).<\/td>\n<\/tr>\n<tr>\n<td><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIRedlerBasico.png\"> <code>THMIRedlerBasico<\/code><\/td>\n<td>Transportador de corrente (redler).<\/td>\n<\/tr>\n<tr>\n<td><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIRoscaBasica.png\"> <code>THMIRoscaBasica<\/code><\/td>\n<td>Transportador helicoidal (rosca).<\/td>\n<\/tr>\n<tr>\n<td><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIElevadorBasico.png\"> <code>THMIElevadorBasico<\/code><\/td>\n<td>Elevador de canecas (<code>HeadAtLeft<\/code>, <code>HeadColor<\/code>, <code>FooterColor<\/code>, <code>BodyWidth<\/code>).<\/td>\n<\/tr>\n<tr>\n<td><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/THMIPolyline.png\"> <code>THMIPolyline<\/code><\/td>\n<td>Linha poligonal \u2014 tubula\u00e7\u00e3o, cabo, fio. Pontos em <code>PointCoordinates<\/code>, <code>LineColor<\/code>, <code>LineWidth<\/code>, <code>PenStyle<\/code>.<\/td>\n<\/tr>\n<tr>\n<td><code>THMIBandeja<\/code><\/td>\n<td>Painel (&#8220;bandeja&#8221;) cujas cores de borda e fundo v\u00eam de tags (<code>BorderColorPLCTag<\/code>, <code>BackgroundColorPLCTag<\/code>, valores <code>TColor<\/code>) e cujo texto vem de um <code>TPLCStructString<\/code> (<code>BandejaTextPLCTag<\/code>). Feito para pain\u00e9is sin\u00f3ticos de silos e moegas dirigidos pelo CLP.<\/td>\n<\/tr>\n<tr>\n<td><code>THMIBasicVectorControl<\/code><\/td>\n<td>Desenho <strong>SVG<\/strong> (<code>SVGContents<\/code>, colado do arquivo) com <code>Stretch<\/code>\/<code>Proportional<\/code>. \u00c9 a base dos controles vetoriais de fluxo, que trocam a cor de elementos do SVG por zona.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h5>Gr\u00e1ficos: TTagLinkedSeriesSource<\/h5>\n<p><code>TTagLinkedSeriesSource<\/code> \u00e9 uma fonte de dados do <strong>TAChart<\/strong> alimentada por um tag: ligue-o \u00e0 propriedade <code>Source<\/code> de uma <code>TLineSeries<\/code> e ele acrescenta um ponto (instante, valor) a cada atualiza\u00e7\u00e3o.<\/p>\n<ul>\n<li><strong><code>PLCTag<\/code><\/strong> \u2014 o tag num\u00e9rico.<\/li>\n<li><strong><code>SourceUpdateType<\/code><\/strong> \u2014 <code>tlTagUpdate<\/code> (um ponto a cada leitura, mesmo sem mudan\u00e7a), <code>tlTagChange<\/code> (s\u00f3 quando o valor muda) ou <code>tlCyclic<\/code> (a cada <code>CyclicUptimeTime<\/code> ms, com o \u00faltimo valor).<\/li>\n<li><strong><code>EnableXAxisMaxInterval<\/code><\/strong> \/ <strong><code>XAxisMaximumInterval<\/code><\/strong> \u2014 descarta pontos mais velhos que o intervalo (em milissegundos), mantendo o gr\u00e1fico deslizante.<\/li>\n<li><strong><code>UseNowInsteadTagTimestamp<\/code><\/strong> \u2014 usa o rel\u00f3gio do PC em vez do timestamp do tag.<\/li>\n<li><strong><code>YMinOffset<\/code><\/strong> \/ <strong><code>YMaxOffset<\/code><\/strong> \u2014 margens acrescentadas aos extremos do eixo Y.<\/li>\n<\/ul>\n<h5>Exemplo passo a passo<\/h5>\n<p>Uma tela m\u00ednima para um motor: estado, velocidade e comando.<\/p>\n<ol>\n<li>Tags: <code>Motor_Status<\/code> (<code>TPLCTagNumber<\/code>, palavra de estado), <code>Motor_Ligado<\/code> (<code>TTagBit<\/code> sobre <code>Motor_Status<\/code>, bit 0), <code>Motor_Velocidade<\/code> (<code>TPLCTagNumber<\/code>, <code>pttFloat<\/code>) e <code>Motor_Setpoint<\/code>.<\/li>\n<li>Um <code>THMIText<\/code> com <code>PLCTag = Motor_Status<\/code> e tr\u00eas zonas: <code>ztEqual 0 \u2192 \"Parado\"<\/code>, <code>ztEqual 1 \u2192 \"Rodando\"<\/code> (verde), <code>ztBit 7 \u2192 \"Falha\"<\/code> (vermelho, <code>BlinkTime = 500<\/code>, <code>BlinkWith<\/code> apontando para uma quarta zona id\u00eantica em branco).<\/li>\n<li>Um <code>THMILabel<\/code> com <code>PLCTag = Motor_Velocidade<\/code>, <code>NumberFormat = \"#0.0\"<\/code>, <code>Sufix = \" rpm\"<\/code>.<\/li>\n<li>Um <code>THMIEdit<\/code> com <code>PLCTag = Motor_Setpoint<\/code>, <code>MinValue = 0<\/code>, <code>MaxValue = 1800<\/code>, <code>EnableMinValue<\/code>\/<code>EnableMaxValue = True<\/code>, <code>SecurityCode = \"operacao\"<\/code>.<\/li>\n<li>Um <code>THMICheckBox<\/code> com <code>PLCTag = Motor_Ligado<\/code>, <code>CaptionTrue = \"Desligar\"<\/code>, <code>CaptionFalse = \"Ligar\"<\/code>, <code>SecurityCode = \"operacao\"<\/code>.<\/li>\n<li>Um <code>THMIColorPropertyConnector<\/code> com <code>PLCTag = Motor_Ligado<\/code>, uma condi\u00e7\u00e3o <code>ztEqual 1 \u2192 clLime<\/code> e a <code>DefaultZone \u2192 clSilver<\/code>, afetando <code>Shape1.Brush.Color<\/code>.<\/li>\n<\/ol>\n<p>Sem uma linha de c\u00f3digo, a tela mostra o estado, a velocidade, aceita o setpoint dentro da faixa, liga e desliga o motor e colore a forma \u2014 e tudo isso fica desabilitado para um usu\u00e1rio sem o c\u00f3digo <code>operacao<\/code>.<\/p>\n<h5>Exemplos relacionados<\/h5>\n<ul>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_weg_twp03_full_project\"><code>examples\/laz_weg_twp03_full_project<\/code><\/a> \u2014 projeto completo de supervis\u00e3o de um CLP WEG TPW03 por Modbus RTU: <code>THMIEdit<\/code>, <code>THMICheckBox<\/code>, <code>THMILabel<\/code> e blocos em telas reais.<\/li>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/both_modbus_rtu_corn_weigh\"><code>examples\/both_modbus_rtu_corn_weigh<\/code><\/a> \u2014 sin\u00f3tico de pesagem com <code>THMIAnimation<\/code>, <code>THMIText<\/code>, <code>TTagBit<\/code> e blocos (Lazarus e Delphi).<\/li>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_modbus_tcp_example\"><code>examples\/laz_modbus_tcp_example<\/code><\/a> \u2014 <code>THMIEdit<\/code>, <code>THMICheckBox<\/code>, <code>THMIText<\/code> e <code>THMILabel<\/code> sobre um bloco Modbus TCP.<\/li>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_comm_fault_control_icon_test\"><code>examples\/laz_comm_fault_control_icon_test<\/code><\/a> \u2014 o selo de falha de comunica\u00e7\u00e3o em cada tipo de controle.<\/li>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_isotcp_hourmeter\"><code>examples\/laz_isotcp_hourmeter<\/code><\/a> \u2014 <code>THMIAnimation<\/code> com <code>TImageList<\/code> e zonas piscando.<\/li>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/hmi_bandeja\"><code>examples\/hmi_bandeja<\/code><\/a> \u2014 <code>THMIBandeja<\/code> com cores e texto vindos do CLP.<\/li>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/hmi_flowvectorcontrol\"><code>examples\/hmi_flowvectorcontrol<\/code><\/a> e <a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_svg_example\"><code>examples\/laz_svg_example<\/code><\/a> \u2014 <code>THMIFlowVectorControl<\/code> recolorindo elementos de um SVG por zona (veja <a href=\"\/pb\/flow-controls\/\">Controles de fluxo<\/a>).<\/li>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_numericexpr\"><code>examples\/laz_numericexpr<\/code><\/a> \u2014 <code>THMITrackBar<\/code> e <code>THMILabel<\/code> em volta de um <code>TNumericExprTag<\/code>.<\/li>\n<\/ul>\n<p>Outras p\u00e1ginas da HCl: <a href=\"\/pb\/flow-controls\/\">Controles de fluxo<\/a>, <a href=\"\/pb\/event-and-alarm-loggers\/\">Registradores de eventos e alarmes<\/a>, <a href=\"\/pb\/keyboard-manager\/\">Teclado virtual<\/a> e <a href=\"\/pb\/security-system\/\">Sistema de seguran\u00e7a<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Introdu\u00e7\u00e3o A HMI Control Library (HCl) \u00e9 o conjunto de controles visuais do PascalSCADA \u2014 a paleta PascalSCADA HMI Controls. Cada um deles \u00e9 um controle comum da LCL (TEdit, &#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-fullwidth.php","meta":{"footnotes":""},"class_list":["post-444","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/pages\/444","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/comments?post=444"}],"version-history":[{"count":17,"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/pages\/444\/revisions"}],"predecessor-version":[{"id":1237,"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/pages\/444\/revisions\/1237"}],"wp:attachment":[{"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/media?parent=444"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}