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

С приходом мониторов с разрешением 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.
Удачи.