Автоматическое масштабирование текста и объектов в зависимости от настроек размера шрифта Windows

28 сентября 2020, 14:27
Konstantin Efremov
1
262

С приходом мониторов с разрешением 4к (да и не редко 1080p), встает вопрос масштабирования графических объектов, отображаемых советниками и индикаторами на чартах.

Обратил внимание, что многие разработчики продуктов, опубликованных здесь на Маркете, не озаботились этой проблемой. Однако, многие конечные пользователи продуктов используют встроенную в Windows возможность увеличить масштаб шрифтов и графики, что отражается и на терминале Metatrader 5.

Вот пример такой настройки в ОС Windows 7:

 

Стоит пользователю выставить масштаб, отличный от 100%, как многие советники и индикаторы начнут "давится" тестовыми метками, полями ввода и прочими графическими объектами.

Вот пример известного индикатора, где не учтен этот момент:

 

Тем не менее, задача решается очень просто, достаточно добавить пару функций и устанавливать размер шрифта или расстояние между объектами в зависимости от выбранного пользователем DPI.

Первая функция уменьшает размер шрифта, чтобы он не вылезал за рамки/объекты:

//+----------------------------------------------------------------------------------+
//| Функция рассчитывает размер шрифта в зависимости от настроек windows пользователя|
//+----------------------------------------------------------------------------------+
int ScaleFunction(int _FontSize)
   {
      int NewFontSize=0;
      int scale_factor=(TerminalInfoInteger(TERMINAL_SCREEN_DPI) * 100) / 96;
      if(scale_factor == 0) 
         {
            NewFontSize = _FontSize;
         }
      else
         {
            NewFontSize = (int)MathCeil(_FontSize*100.0/scale_factor);
         } 
      return(NewFontSize);
   }

Применяем очень просто. Где у вас задается размер шрифта, допустим, для текстовой метки, заменяем:

ObjectSetInteger(0,objname,OBJPROP_FONTSIZE,objFONTSIZE);

на

ObjectSetInteger(0,objname,OBJPROP_FONTSIZE,ScaleFunction(objFONTSIZE));

Вторая функция наоборот увеличивает некое число. Допустим у вас расстояние между ценовой меткой и текстовой сопровождающей меткой открытой рыночной позиции определяется количеством свечей с коэффициентом, рассчитанным от количества свечей на экране. Коэффициент тоже нужно масштабировать, так как ценовая метка увеличится в размерах и уменьшить её не выйдет.

//+------------------------------------------------------------------------------------------------------+
//| Функция рассчитывает коэффициент увеличения расстояния в зависимости от настроек windows пользователя|
//+------------------------------------------------------------------------------------------------------+
int ScaleFunctionToBig(int _Distance)
   {
      int NewDistance=0;
      int scale_factor=(TerminalInfoInteger(TERMINAL_SCREEN_DPI) * 100) / 96;
      if(scale_factor == 0) 
         {
            NewDistance = _Distance;
         }
      else
         {
            NewDistance = (int)MathCeil(_Distance*scale_factor/100.0);
         } 
      return(NewDistance);
   }


Применяем аналогично первой функции.

Надеюсь это простое и очевидное решение будет полезно разработчикам, проверьте свои эксперты и индикаторы на предмет совместимости с функцией масштабирования Windows.

Удачи.