
Criando um Painel Administrativo de Negociação em MQL5 (Parte III): Aprimorando a Interface com Estilo Visual (I)
Conteúdo:
- Introdução
- Importância de uma GUI visualmente atraente
- Aplicando recursos de estilo de GUI no MQL5
- Personalizando Cores e Fontes
- Lógica de gerenciamento de tema
- Ajustando o Layout dos Novos Botões
- Aprimoramento avançado da interface
- Conclusão
Introdução
Analisando os objetivos delineados em nosso artigo anterior, podemos afirmar com confiança que fizemos o suficiente? Na minha opinião, o que vejo inspira um impulso para ir além do que já oferecemos. Imagine o quão benéfico seria implementar uma alternância entre temas claro e escuro para o nosso Painel Administrativo. Além disso, poderíamos melhorar a experiência do usuário adicionando botões estilosos, oferecendo uma seleção variada de fontes e permitindo a troca de idioma entre os principais idiomas. Isso tornaria nosso painel mais acessível para todos.
Nosso objetivo é fornecer aos administradores de negociação uma solução de comunicação abrangente integrada à plataforma de negociação. Os conceitos que pretendemos incorporar são inspirados em pesquisas e desenvolvimentos influentes em interfaces gráficas de usuário (GUIs) desde os anos 1970. Contribuidores notáveis incluem Alan Kay, Xerox PARC, Apple (macOS), Microsoft (Windows), CSS (Cascading Style Sheets) e Material Design do Google. Aproveitando essas ideias, podemos criar um Painel Administrativo que atenda às necessidades dos usuários e melhore sua experiência geral.
O Painel Administrativo Básico que desenvolvemos até agora.
Resumo do que realizamos até agora:
- Criando o Painel Administrativo com uma interface de mensagens e integração com o Telegram.
- Adicionando botões essenciais à interface, como minimizar, maximizar, fechar e botões de mensagem rápida.
Ao final deste artigo, teremos um painel administrativo de negociação totalmente personalizado e com estilo visual em MQL5. Você aprenderá a implementar várias técnicas de estilo que melhoram tanto a aparência quanto a funcionalidade da interface, criando um ambiente profissional e amigável para os traders.
Aqui estão os principais objetivos deste artigo:- Aplicar técnicas básicas de estilo usando MQL5
- Personalizar fontes, cores e layouts
- Melhorar a interação do usuário com elementos visuais
- Incorporar a customização entre modos claro e escuro
- Adicionar recursos dinâmicos como animações e transições
Aplicando recursos de estilo de GUI no MQL5
O MQL5 oferece várias funções e recursos para estilizar a GUI da sua aplicação de negociação. Esses recursos incluem opções para personalizar cores, fontes e layouts para atender às necessidades dos seus usuários e ao design estético desejado.
Estilizar a GUI em MQL5 envolve o uso de várias funções e técnicas-chave. Vamos abordar as funções que permitem alterar as propriedades de objetos gráficos, como botões, rótulos e painéis. Com isso, podemos personalizar a cor de fundo, o estilo da borda, o tamanho da fonte e outros aspectos visuais para criar uma aparência coesa.
- Personalizando Cores e Fontes
- Lógica de Gerenciamento de tema
- Ajustando o Layout dos Novos Botões
Personalizando Cores e Fontes:
Array de Fontes e Índice:
Começamos definindo um array availableFonts e um currentFontIndex para gerenciar as seleções de fonte no Painel Administrativo. O array availableFonts inclui nomes de fontes como "Arial", "Courier New", "Verdana" e "Times New Roman", oferecendo aos usuários uma gama de opções para personalizar a aparência do painel. O currentFontIndex mantém o controle da fonte selecionada ao indexar esse array. Essa configuração nos permite alternar facilmente entre as fontes e aplicá-las aos componentes da interface sempre que o usuário mudar a fonte, garantindo que a experiência do usuário permaneça dinâmica e coesa.
// Array of available fonts string availableFonts[] = {"Arial", "Courier New", "Verdana", "Times New Roman"}; // Index of the current font in use int currentFontIndex = 0;
Criando o Botão de Troca de Fonte:
Vamos criar um botão rotulado como "Fonte<>", que será posicionado estrategicamente dentro do Painel Administrativo. Esse botão não é apenas mais um botão; ele é um recurso essencial para a troca de fontes. Garantimos que ele se encaixe bem no layout do painel e lidamos com quaisquer problemas durante sua criação. Ao adicionar esse botão, oferecemos aos usuários uma forma intuitiva de alternar entre diferentes fontes, melhorando a usabilidade e a flexibilidade estética do painel. Se houver qualquer falha na criação do botão, imprimimos uma mensagem de erro para rastrear o problema.
// Create a button for changing the font CButton changeFontButton; changeFontButton.Create(panel, "ChangeFontButton", 0, 10, 10, 100, 30); changeFontButton.Text("Font<>"); // Verify button creation and handle errors if(!changeFontButton.IsCreated()) { Print("Error creating Font<> button."); }
Lidando com o Clique no Botão de Troca de Fonte:
Ao implementarmos a função OnChangeFontButtonClick, nosso objetivo é gerenciar o processo de troca de fonte de forma fluida. Essa função atualiza o currentFontIndex para selecionar a próxima fonte no array availableFonts, voltando ao início, se necessário. Depois de atualizar o índice, aplicamos a nova fonte a todos os componentes relevantes da interface, como a caixa de entrada, botão limpar e botão enviar, garantindo uma aparência consistente em todo o painel. Para finalizar as alterações, usamos o ChartRedraw para atualizar a exibição e imprimimos uma mensagem de confirmação, informando ao usuário que a fonte foi alterada com sucesso.
// Function to handle the font change button click void OnChangeFontButtonClick() { // Update the font index, wrapping around if necessary currentFontIndex = (currentFontIndex + 1) % ArraySize(availableFonts); string newFont = availableFonts[currentFontIndex]; // Apply the new font to UI components inputBox.Font(newFont); clearButton.Font(newFont); sendButton.Font(newFont); // Refresh the display to apply the changes ChartRedraw(); // Print confirmation of the font change Print("Font changed to ", newFont); }
OnChartEvent para Lidar com Cliques nos Botões:
Na função OnChartEvent, lidamos com interações do usuário com diversos objetos do gráfico, incluindo nosso botão de troca de fonte. Essa função escuta eventos de clique em botões e verifica qual botão foi clicado inspecionando a string sparam. Quando o botão "ChangeFontButton" é clicado, chamamos a função OnChangeFontButtonClick para realizar a troca da fonte. Essa abordagem orientada a eventos mantém nossa interface responsiva e interativa, garantindo que as ações do usuário acionem as respostas corretas e mantenham a interface envolvente.
// Function to handle chart events void OnChartEvent(const int id, const int sub_id, const int type, const int x, const int y, const int state) { // Handle button clicks if(type == CHARTEVENT_OBJECT_CLICK) { string buttonName = ObjectGetString(0, "ChangeFontButton", OBJPROP_TEXT); if(buttonName == "Font<>") { OnChangeFontButtonClick(); } } }
Troca de Fonte funcionando
Lógica de Gerenciamento de Tema:
Lógica de Alternância de Tema:
Começamos configurando o sistema de gerenciamento de tema com dois temas distintos: claro e escuro. Para controlar a troca, usamos uma variável booleana, isDarkMode, que mantém o controle de qual tema está ativo no momento. A alternância é simples: quando o usuário clica no botão de tema, o valor de isDarkMode é invertido, alterando toda a aparência do Painel Administrativo. Definindo separadamente as cores para cada tema, simplificamos o processo, tornando mais fácil a manutenção e aplicação de novos estilos sempre que necessário.
bool isDarkMode = false; // Tracks the current theme mode (light or dark) color lightBackgroundColor = clrWhite; // Background color for light mode color darkBackgroundColor = clrBlack; // Background color for dark mode color lightTextColor = clrBlack; // Text color for light mode color darkTextColor = clrWhite; // Text color for dark mode
Criar o Botão de Alternância de Tema:
Vamos agora criar um botão rotulado como "Tema<>." Esse botão é inserido dentro do Painel Administrativo e oferece aos usuários uma maneira simples de alternar entre os modos claro e escuro. Se algo der errado durante sua criação, garantimos o tratamento do erro com uma mensagem impressa. Isso facilita a resolução de problemas e garante que a interface continue intuitiva e responsiva.
//Creating the theme switch button if(!CreateButton("ToggleThemeButton", "Theme<>", 50, 220, 100, 30)) { Print("Error: Failed to create theme toggle button"); // Error handling if button creation fails }
Tratar o Clique no Botão de Alternância de Tema:
Em seguida, lidamos com a mudança de tema propriamente dita implementando a função OnToggleModeButtonClick. Essa função inverte o valor da variável isDarkMode, alternando entre os temas claro e escuro. Assim que identificamos qual tema está ativo, aplicamos as cores de fundo e texto correspondentes a todos os elementos da interface, como painel, botões e textos. A mudança de tema acontece em tempo real graças a uma atualização rápida, tornando a interface fluida e responsiva. Também imprimimos uma mensagem de confirmação para que o usuário saiba que o modo foi alterado.//Theme switching handler void OnToggleModeButtonClick() { isDarkMode = !isDarkMode; // Toggle the theme mode if(isDarkMode) { ApplyTheme(darkBackgroundColor, darkTextColor); // Apply dark mode colors } else { ApplyTheme(lightBackgroundColor, lightTextColor); // Apply light mode colors } Print("Theme has been switched"); // Inform the user that the theme has changed }
OnChartEvent para Lidar com Cliques no Botão de Alternância de Tema:
Na função OnChartEvent, detectamos quando um usuário clica no botão "Alternar Tema" e acionamos a função OnToggleModeButtonClick. Essa abordagem orientada a eventos garante que o painel responda instantaneamente às ações do usuário. Ao escutar eventos de clique em botões, garantimos que o Painel Administrativo continue interativo e envolvente, permitindo que os usuários alternem facilmente entre os temas claro e escuro conforme necessário.
//The OneChartEvent for the theme void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_OBJECT_CLICK) // Check if the event is a button click { if(sparam == "ToggleThemeButton") // Check if the clicked button is the theme toggle button { OnToggleModeButtonClick(); // Call the function to handle the theme change } } }
Aplicando Tema sem Recriar Objetos:
Uma de nossas decisões de design mais importantes é atualizar o tema sem recriar nenhum dos objetos do painel. Em vez de desmontar e reconstruir novos componentes da interface, simplesmente aplicamos o novo esquema de cores aos elementos existentes. Isso mantém o sistema eficiente, reduzindo atrasos e mantendo uma experiência de usuário fluida. Também garante que o painel permaneça responsivo ao aplicarmos as novas cores dinamicamente.
//Applying theme void ApplyTheme(color backgroundColor, color textColor) { // Update background and text colors of existing objects ObjectSetInteger(0, "AdminPanelBackground", OBJPROP_COLOR, backgroundColor); // Change background color ObjectSetInteger(0, "ClearButton", OBJPROP_COLOR, textColor); // Change text color of clear button ObjectSetInteger(0, "SendButton", OBJPROP_COLOR, textColor); // Change text color of send button ObjectSetInteger(0, "InputBox", OBJPROP_COLOR, textColor); // Change text color of input box ChartRedraw(); // Redraw the chart to reflect the changes }
Ajustando o Layout dos Novos Botões.
Botão de Troca de Fonte:
O botão de troca de fonte foi posicionado no painel administrativo com seu canto superior esquerdo em (95, 95) e o canto inferior direito em (230, 115). Isso o coloca à esquerda dos botões Enviar e Limpar. Suas dimensões o tornam largo o suficiente para o rótulo "Fonte<>" e para uma interação amigável ao usuário. O botão permite que os usuários alternem entre diferentes opções de fonte para todos os elementos de texto no painel.if (!changeFontButton.Create(chart_id, "ChangeFontButton", 0, 95, 95, 230, 115))
Botão de Alternância de Tema:
Quanto ao botão de alternância de tema, o posicionamos nas coordenadas (5, 95) para o canto superior esquerdo e (90, 115) para o inferior direito. Isso coloca o botão na extremidade esquerda do painel, ligeiramente acima do botão de troca de fonte, proporcionando uma separação clara. O tamanho compacto e a proximidade de outros botões facilitam para os usuários alternarem entre os modos claro e escuro sem sobrecarregar a interface.if (!toggleThemeButton.Create(chart_id, "ToggleThemeButton", 0, 5, 95, 90, 115))
Aqui está nosso programa completo com todos os novos recursos perfeitamente integrados.
//+------------------------------------------------------------------+ //| Admin Panel.mq5 | //| Copyright 2024, Clemence Benjamin | //| https://www.mql5.com/en/users/billionaire2024/seller | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property description "A responsive Admin Panel. Send messages to your telegram clients without leaving MT5" #property version "1.11" #include <Trade\Trade.mqh> #include <Controls\Dialog.mqh> #include <Controls\Button.mqh> #include <Controls\Edit.mqh> #include <Controls\Label.mqh> // Input parameters input string QuickMessage1 = "Updates"; input string QuickMessage2 = "Close all"; input string QuickMessage3 = "In deep profits"; input string QuickMessage4 = "Hold position"; input string QuickMessage5 = "Swing Entry"; input string QuickMessage6 = "Scalp Entry"; input string QuickMessage7 = "Book profit"; input string QuickMessage8 = "Invalid Signal"; input string InputChatId = "Enter Chat ID from Telegram bot API"; input string InputBotToken = "Enter BOT TOKEN from your Telegram bot"; // Global variables CDialog adminPanel; CButton sendButton, clearButton, changeFontButton, toggleThemeButton; CButton quickMessageButtons[8], minimizeButton, maximizeButton, closeButton; CEdit inputBox; CLabel charCounter; #define BG_RECT_NAME "BackgroundRect" bool minimized = false; bool darkTheme = false; int MAX_MESSAGE_LENGTH = 4096; string availableFonts[] = { "Arial", "Courier New", "Verdana", "Times New Roman" }; int currentFontIndex = 0; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Initialize the Dialog if (!adminPanel.Create(ChartID(), "Admin Panel", 0, 30, 30, 500, 500)) { Print("Failed to create dialog"); return INIT_FAILED; } // Create controls if (!CreateControls()) { Print("Control creation failed"); return INIT_FAILED; } adminPanel.Show(); // Initialize with the default theme CreateOrUpdateBackground(ChartID(), darkTheme ? clrBlack : clrWhite); Print("Initialization complete"); return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Create necessary UI controls | //+------------------------------------------------------------------+ bool CreateControls() { long chart_id = ChartID(); // Create the input box if (!inputBox.Create(chart_id, "InputBox", 0, 5, 25, 460, 95)) { Print("Failed to create input box"); return false; } adminPanel.Add(inputBox); // Character counter if (!charCounter.Create(chart_id, "CharCounter", 0, 380, 5, 460, 25)) { Print("Failed to create character counter"); return false; } charCounter.Text("0/" + IntegerToString(MAX_MESSAGE_LENGTH)); adminPanel.Add(charCounter); // Clear button if (!clearButton.Create(chart_id, "ClearButton", 0, 235, 95, 345, 125)) { Print("Failed to create clear button"); return false; } clearButton.Text("Clear"); adminPanel.Add(clearButton); // Send button if (!sendButton.Create(chart_id, "SendButton", 0, 350, 95, 460, 125)) { Print("Failed to create send button"); return false; } sendButton.Text("Send"); adminPanel.Add(sendButton); // Change font button if (!changeFontButton.Create(chart_id, "ChangeFontButton", 0, 95, 95, 230, 115)) { Print("Failed to create change font button"); return false; } changeFontButton.Text("Font<>"); adminPanel.Add(changeFontButton); // Toggle theme button if (!toggleThemeButton.Create(chart_id, "ToggleThemeButton", 0, 5, 95, 90, 115)) { Print("Failed to create toggle theme button"); return false; } toggleThemeButton.Text("Theme<>"); adminPanel.Add(toggleThemeButton); // Minimize button if (!minimizeButton.Create(chart_id, "MinimizeButton", 0, 375, -22, 405, 0)) { Print("Failed to create minimize button"); return false; } minimizeButton.Text("_"); adminPanel.Add(minimizeButton); // Maximize button if (!maximizeButton.Create(chart_id, "MaximizeButton", 0, 405, -22, 435, 0)) { Print("Failed to create maximize button"); return false; } maximizeButton.Text("[ ]"); adminPanel.Add(maximizeButton); // Close button if (!closeButton.Create(chart_id, "CloseButton", 0, 435, -22, 465, 0)) { Print("Failed to create close button"); return false; } closeButton.Text("X"); adminPanel.Add(closeButton); // Quick messages return CreateQuickMessageButtons(); } //+------------------------------------------------------------------+ //| Create quick message buttons | //+------------------------------------------------------------------+ bool CreateQuickMessageButtons() { string quickMessages[8] = { QuickMessage1, QuickMessage2, QuickMessage3, QuickMessage4, QuickMessage5, QuickMessage6, QuickMessage7, QuickMessage8 }; int startX = 5, startY = 160, width = 222, height = 65, spacing = 5; for (int i = 0; i < 8; i++) { if (!quickMessageButtons[i].Create(ChartID(), "QuickMessageButton" + IntegerToString(i + 1), 0, startX + (i % 2) * (width + spacing), startY + (i / 2) * (height + spacing), startX + (i % 2) * (width + spacing) + width, startY + (i / 2) * (height + spacing) + height)) { Print("Failed to create quick message button ", i + 1); return false; } quickMessageButtons[i].Text(quickMessages[i]); adminPanel.Add(quickMessageButtons[i]); } return true; } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { adminPanel.Destroy(); ObjectDelete(ChartID(), BG_RECT_NAME); Print("Deinitialization complete"); } //+------------------------------------------------------------------+ //| Handle chart events | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { switch (id) { case CHARTEVENT_OBJECT_CLICK: if (sparam == "SendButton") OnSendButtonClick(); else if (sparam == "ClearButton") OnClearButtonClick(); else if (sparam == "ChangeFontButton") OnChangeFontButtonClick(); else if (sparam == "ToggleThemeButton") OnToggleThemeButtonClick(); else if (sparam == "MinimizeButton") OnMinimizeButtonClick(); else if (sparam == "MaximizeButton") OnMaximizeButtonClick(); else if (sparam == "CloseButton") OnCloseButtonClick(); else if (StringFind(sparam, "QuickMessageButton") != -1) { int index = StringToInteger(StringSubstr(sparam, 18)); OnQuickMessageButtonClick(index - 1); } break; case CHARTEVENT_OBJECT_ENDEDIT: if (sparam == "InputBox") OnInputChange(); break; } } //+------------------------------------------------------------------+ //| Handle custom message send button click | //+------------------------------------------------------------------+ void OnSendButtonClick() { string message = inputBox.Text(); if (message != "") { if (SendMessageToTelegram(message)) Print("Custom message sent: ", message); else Print("Failed to send custom message."); } else { Print("No message entered."); } } //+------------------------------------------------------------------+ //| Handle clear button click | //+------------------------------------------------------------------+ void OnClearButtonClick() { inputBox.Text(""); // Clear the text in the input box OnInputChange(); // Update the character counter Print("Input box cleared."); } //+------------------------------------------------------------------+ //| Handle quick message button click | //+------------------------------------------------------------------+ void OnQuickMessageButtonClick(int index) { string quickMessages[8] = { QuickMessage1, QuickMessage2, QuickMessage3, QuickMessage4, QuickMessage5, QuickMessage6, QuickMessage7, QuickMessage8 }; string message = quickMessages[index]; if (SendMessageToTelegram(message)) Print("Quick message sent: ", message); else Print("Failed to send quick message."); } //+------------------------------------------------------------------+ //| Update character counter | //+------------------------------------------------------------------+ void OnInputChange() { int currentLength = StringLen(inputBox.Text()); charCounter.Text(IntegerToString(currentLength) + "/" + IntegerToString(MAX_MESSAGE_LENGTH)); ChartRedraw(); } //+------------------------------------------------------------------+ //| Handle toggle theme button click | //+------------------------------------------------------------------+ void OnToggleThemeButtonClick() { darkTheme = !darkTheme; color bgColor = darkTheme ? clrBlack : clrWhite; color textColor = darkTheme ? clrWhite : clrBlack; // Set text color appropriate to the theme inputBox.Color(textColor); clearButton.Color(textColor); sendButton.Color(textColor); toggleThemeButton.Color(textColor); changeFontButton.Color(textColor); for(int i = 0; i < ArraySize(quickMessageButtons); i++) { quickMessageButtons[i].Color(textColor); } charCounter.Color(textColor); CreateOrUpdateBackground(ChartID(), bgColor); ChartRedraw(); } //+------------------------------------------------------------------+ //| Create and update background rectangle | //+------------------------------------------------------------------+ void CreateOrUpdateBackground(long chart_id, color bgColor) { if (!ObjectFind(chart_id, BG_RECT_NAME)) { if (!ObjectCreate(chart_id, BG_RECT_NAME, OBJ_RECTANGLE, 0, 0, 0)) Print("Failed to create background rectangle"); } ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_COLOR, bgColor); ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_BACK, true); ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_SELECTABLE, false); ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_SELECTED, false); ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_HIDDEN, false); ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_XOFFSET, 25); ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_YOFFSET, 25); } //+------------------------------------------------------------------+ //| Handle change font button click | //+------------------------------------------------------------------+ void OnChangeFontButtonClick() { currentFontIndex = (currentFontIndex + 1) % ArraySize(availableFonts); inputBox.Font(availableFonts[currentFontIndex]); clearButton.Font(availableFonts[currentFontIndex]); sendButton.Font(availableFonts[currentFontIndex]); toggleThemeButton.Font(availableFonts[currentFontIndex]); changeFontButton.Font(availableFonts[currentFontIndex]); for(int i = 0; i < ArraySize(quickMessageButtons); i++) { quickMessageButtons[i].Font(availableFonts[currentFontIndex]); } Print("Font changed to: ", availableFonts[currentFontIndex]); ChartRedraw(); } //+------------------------------------------------------------------+ //| Handle minimize button click | //+------------------------------------------------------------------+ void OnMinimizeButtonClick() { minimized = true; adminPanel.Hide(); minimizeButton.Hide(); maximizeButton.Show(); closeButton.Show(); Print("Panel minimized."); } //+------------------------------------------------------------------+ //| Handle maximize button click | //+------------------------------------------------------------------+ void OnMaximizeButtonClick() { if (minimized) { adminPanel.Show(); minimizeButton.Show(); maximizeButton.Hide(); closeButton.Hide(); Print("Panel maximized."); } } //+------------------------------------------------------------------+ //| Handle close button click | //+------------------------------------------------------------------+ void OnCloseButtonClick() { ExpertRemove(); // Completely remove the EA Print("Admin Panel closed."); } //+------------------------------------------------------------------+ //| Send the message to Telegram | //+------------------------------------------------------------------+ bool SendMessageToTelegram(string message) { string url = "https://api.telegram.org/bot" + InputBotToken + "/sendMessage"; string jsonMessage = "{\"chat_id\":\"" + InputChatId + "\", \"text\":\"" + message + "\"}"; char post_data[]; ArrayResize(post_data, StringToCharArray(jsonMessage, post_data, 0, WHOLE_ARRAY) - 1); int timeout = 5000; char result[]; string responseHeaders; int res = WebRequest("POST", url, "Content-Type: application/json\r\n", timeout, post_data, result, responseHeaders); if (res == 200) // HTTP 200 OK { Print("Message sent successfully: ", message); return true; } else { Print("Failed to send message. HTTP code: ", res, " Error code: ", GetLastError()); Print("Response: ", CharArrayToString(result)); return false; } }
Novos Recursos Testados no XAUUSD
Com essas técnicas básicas de estilo implementadas, agora podemos explorar opções de personalização mais avançadas que podem proporcionar ainda mais interatividade e apelo visual à GUI. Na imagem acima, podemos ver que nosso tema está funcionando apenas no texto do primeiro plano, mas queremos que ele também afete o fundo do painel. No próximo segmento, abordaremos formas de resolver esse problema.
Aprimoramento avançado da interface
Estendendo a Classe Dialog para Gerenciamento de Tema:
Para estender a Dialog para gerenciamento de tema, podemos personalizar a classe de diálogo existente para suportar mudanças dinâmicas de tema, da mesma forma como fazemos no Painel Administrativo. Isso envolve modificar ou criar uma subclasse da CDialog para incluir propriedades de cores de fundo e texto, além de métodos para aplicar diferentes temas (claro ou escuro). Substituindo o construtor ou adicionando métodos como ApplyTheme, garantimos que caixas de diálogo criadas com essa classe respondam às mudanças de tema sem recriar os objetos de diálogo.
Personalizando as cores na classe Dialog
Por que isso é importante?
Estender a classe Dialog para gerenciamento de tema permite uma experiência de usuário mais fluida e coesa em todos os elementos da interface, não apenas no Painel Administrativo. Garante que todas as partes do aplicativo — incluindo caixas de diálogo — sigam o tema escolhido, melhorando tanto a usabilidade quanto a consistência visual. Esse recurso se torna especialmente importante em aplicações de negociação onde os usuários podem passar longos períodos interagindo com a interface, e temas personalizáveis podem reduzir o cansaço visual e melhorar a satisfação geral.
Painel Administrativo: Tema de fundo após modificar a classe Dialog
Outras opções:
Embora estender a classe Dialog seja uma abordagem direta e flexível, outra opção é aplicar o gerenciamento de tema em um nível mais elevado. Por exemplo, poderíamos criar um sistema global de gerenciamento de tema que atualize automaticamente as propriedades de todos os elementos da interface, incluindo diálogos, sem exigir alterações em componentes individuais. Além disso, usar bibliotecas externas ou projetar uma estrutura personalizada de diálogos pode oferecer um controle mais granular dos elementos de interface, caso surjam necessidades específicas de estilo.
Classe CEdit
Segundo pesquisa no Google, o comprimento máximo de uma mensagem no Telegram é de 4096 caracteres e ela deve estar codificada em UTF-8. Ao tentar implementar esse valor neste projeto, fomos limitados a um máximo de 63 caracteres, e o problema provavelmente está na limitação da classe CEdit, que abordaremos no próximo artigo.
Conclusão
Em conclusão, nossa implementação do gerenciamento de fontes e tema no programa do Painel Administrativo demonstrou resultados promissores. Embora tenhamos enfrentado limitações com o fundo estático da classe de diálogo, o texto do primeiro plano se adaptou com sucesso às mudanças de tema, proporcionando uma experiência de usuário aprimorada O gerenciamento dinâmico de fontes também funcionou bem, permitindo que os usuários alternassem entre diferentes fontes com facilidade.Seguindo em frente, nosso próximo objetivo será estender a classe de diálogo para oferecer suporte total a mudanças de tema, incluindo atualizações dinâmicas de fundo. Essa melhoria visa superar as limitações atuais e proporcionar uma interface mais coesa e visualmente atraente. Fique ligado enquanto enfrentamos esses desafios nos próximos artigos!
Experimente essas técnicas de estilo nos seus próprios painéis de negociação e explore outras opções de personalização no MQL5. Adoraria saber sobre suas experiências e ideias — fique à vontade para compartilhá-las nos comentários enquanto exploramos desafios mais avançados de design de GUI. O arquivo-fonte deste projeto está anexado — sinta-se à vontade para analisá-lo.
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/15419
Aviso: Todos os direitos sobre esses materiais pertencem à MetaQuotes Ltd. É proibida a reimpressão total ou parcial.
Esse artigo foi escrito por um usuário do site e reflete seu ponto de vista pessoal. A MetaQuotes Ltd. não se responsabiliza pela precisão das informações apresentadas nem pelas possíveis consequências decorrentes do uso das soluções, estratégias ou recomendações descritas.





- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Linha de código:
pergunta: a movimentação da janela no gráfico não está implementada?