Взаимное выравнивание графики и текста

 

Здравствуйте!

Я пытаюсь сделать панель, то есть аккуратно подложить прямоугольник под текст, но в зависимости от компьютера всё разъезжается.

Например вот такой код:

      TextSetFont(Font, FontSize);
      string txt = StringConcatenate(WindowExpertName(), " Indicator: M30");
      bool success = TextGetSize(txt, textWidth, textHeight);
      if(!success) {
         Print(ErrorDescription(GetLastError()), " l = ", __LINE__);
      }
      else {
         width = textWidth+3*BlocksGap;
         heightTitle = textHeight+2*BlocksGap;
      }
      Rectangle(InfoX-BlocksGap, InfoY-BlocksGap, width, heightTitle, BgTitleClr) ;

Даёт прямоугольник в два раза уже, чем текст.

Я пытался спрашивать сообщением в другой теме, но нормального обсуждения не получилось, и решение проблемы не сформировалось.

Похоже, рационально сделать отдельную тему по этому вопросу.

 
Evgeny Potapov:

Здравствуйте!

Я пытаюсь сделать панель, то есть аккуратно подложить прямоугольник под текст, но в зависимости от компьютера всё разъезжается.

Например вот такой код:

Даёт прямоугольник в два раза уже, чем текст.

Я пытался спрашивать сообщением в другой теме, но нормального обсуждения не получилось, и решение проблемы не сформировалось.

Похоже, рационально сделать отдельную тему по этому вопросу.

А какое обсуждение вы ждёте если но моё предложение

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Вопросы от начинающих MQL4 MT4 MetaTrader 4

Alexey Viktorov, 2019.08.22 09:24

Попробуйте определить ширину текста TextGetSize, а потом рисовать прямоугольник соответствующей ширины.

Ведь ширина зависит не только от имени шрифта, но и от размера.

вы вообще не отреагировали. Если вы ждёте готовое решение, то не надо называть это обсуждением.
 
Alexey Viktorov:

А какое обсуждение вы ждёте если но моё предложение


вы вообще не отреагировали. Если вы ждёте готовое решение, то не надо называть это обсуждением.

Извините! Я прочитал ваш ответ, но потом не смог найти его на форуме.

Но из приложенного мной кода вы можете видеть, что мой подход базируется именно на функции: "TextGetSize()".

Я-то думал, что есть простое известное решение для этой задачи, но после вашего ответа стало очевидным, что общеизвестного ответа нет.

Поэтому интересно хотя бы обсудить возможные варианты, узнать, кому что посчастливилось достичь.

(Конечно, в начале я ждал готовое решение, слова не правильные написал)

Спасибо за совет и замечание!

 
Evgeny Potapov:

Извините! Я прочитал ваш ответ, но потом не смог найти его на форуме.

Но из приложенного мной кода вы можете видеть, что мой подход базируется именно на функции: "TextGetSize()".

Я-то думал, что есть простое известное решение для этой задачи, но после вашего ответа стало очевидным, что общеизвестного ответа нет.

Поэтому интересно хотя бы обсудить возможные варианты, узнать, кому что посчастливилось достичь.

(Конечно, в начале я ждал готовое решение, слова не правильные написал)

Спасибо за совет и замечание!

Там где я отвечал кода не наблюдалось. А ответ, как говорит В. Высоцкий "А ответ ужасно прост..."

И какое может быть обсуждение неизвестной функции Rectangle с непонятными параметрами. Вообще-то OBJ_RECTANGLE строится по координатам времени и цены, а ширина текста измеряется в пикселях.

 
Alexey Viktorov:

Там где я отвечал кода не наблюдалось. А ответ, как говорит В. Высоцкий "А ответ ужасно прост..."

И какое может быть обсуждение неизвестной функции Rectangle с непонятными параметрами. Вообще-то OBJ_RECTANGLE строится по координатам времени и цены, а ширина текста измеряется в пикселях.

//+------------------------------------------------------------------+
int Rectangle(int x, int y, int width, int height, color back_clr) {
   int newY = y;
   string obj = StringConcatenate(WindowExpertName(), "_", x, "_", newY);
   ObjectDelete(obj);
   bool success = RectLabelCreate(obj, x, y, width, height, back_clr);
   return newY;
}

//+------------------------------------------------------------------+
bool RectLabelCreate(
                     const string           name="RectLabel",         // label name
                     const int              x=0,                      // X coordinate
                     const int              y=0,                      // Y coordinate
                     const int              width=50,                 // width
                     const int              height=18,                // height
                     const color            back_clr=C'236,233,216',  // background color
                     const ENUM_BORDER_TYPE border=BORDER_SUNKEN,     // border type
                     const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER, // chart corner for anchoring
                     const color            clr=clrRed,               // flat border color (Flat)
                     const ENUM_LINE_STYLE  style=STYLE_SOLID,        // flat border style
                     const int              line_width=1,             // flat border width
                     const bool             back=false,               // in the background
                     const bool             selection=false,          // highlight to move
                     const bool             hidden=true,              // hidden in the object list
                     const long             z_order=0)                // priority for mouse click
   {
   long             chart_ID=0;               // chart's ID
   int              sub_window=0;             // subwindow index
//--- reset the error value
   ResetLastError();
//--- create a rectangle label
   if(!ObjectCreate(chart_ID,name,OBJ_RECTANGLE_LABEL,sub_window,0,0))  {
      Print(__FUNCTION__, ": failed to create a rectangle label! Error code = ",GetLastError());
      return(false);
   }
//--- set label coordinates
   ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
//--- set label size
   ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
   ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
//--- set background color
   ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr);
//--- set border type
   ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_TYPE,border);
//--- set the chart's corner, relative to which point coordinates are defined
   ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
//--- set flat border color (in Flat mode)
   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- set flat border line style
   ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- set flat border width
   ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,line_width);
//--- display in the foreground (false) or background (true)
   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the label by mouse
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
   return(true);
}
//+------------------------------------------------------------------+
 
Evgeny Potapov:
И что? Вы хотите чтобы кто-то вам командовал: делай раз, делай два и так далее? Это не похоже на обсуждение.
 
Alexey Viktorov:
И что? Вы хотите чтобы кто-то вам командовал: делай раз, делай два и так далее? Это не похоже на обсуждение.

Я хочу, чтобы кто-то поделился опытом.

Может быть получалось подлинковать фонты, или собрать надпись из картинок.

Неужели никто не делал панелей? Какие-то способы, более или менее успешные, вероятно существуют.

Может быть функцию TextGetSize() можно использовать другим способом.

В сообществе могут существовать опытные программисты... с практическим опытом, им может быть есть что посоветовать.

 
Evgeny Potapov:

Я хочу, чтобы кто-то поделился опытом.

Может быть получалось подлинковать фонты, или собрать надпись из картинок.

Неужели никто не делал панелей? Какие-то способы, более или менее успешные, вероятно существуют.

Может быть функцию TextGetSize() можно использовать другим способом.

В сообществе могут существовать опытные программисты... с практическим опытом, им может быть есть что посоветовать.

Так вот я и пытаюсь поделиться опытом, но вам всё-же нужен готовый код, а не опыт.

Вот я тоже просил поделиться опытом и мне ответили

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Есть ли возможность в объекте OBJ_TEXT выводить текст в несколько строк?

Реter Konow, 2019.08.19 19:41

Хорошо, попытаюсь более подробно.

1. Объявляете юнион.

2. Внутри юниона объявляете несколько массивов разных типов.

Например:

//--------------------------------------------------------------------
union SEND{uchar char_Send[32000]; uint uint_Send[8000];};
union READ{uchar char_Read[32000]; uint uint_Read[8000];};
//--------------------------------------------------------------------


3. Для записи строки нам нужен массив char_Send.

4. Для чтения строки нам нужен массив char_Read. 

5. Допустим, у нас есть строка "aalksdjghalkfhaerlkvhelvkjhalekhavk" и мы хотим записать ее в ресурс. Мы делаем так:

int q = StringToCharArray("aalksdjghalkfhaerlkvhelvkjhalekhavk",send.Char_Send);

После этого, наша строка находится в массиве Char_Send.

6. Чтобы строка оказалась в ресурсе, мы должны сохранить массив uint_Send в функции ResourceCreate();

ResourceCreate("::Имя_ресурса",send.uint_Send,8000,1,0,0,0,COLOR_FORMAT_XRGB_NOALPHA);

7. Важно понимать, что записав строку в Char_Send, мы перевели ее в тип чар, а в типе  uint строка окажется автоматически. В этом суть юнионов. Если Вы запишите в Char_Send строку, в Uint_Send она уже будет. Вы только сохраните ее с помощью ResourceCreate();

8. Чтобы извлечь строку из ресурса, воспользуйтесь функцией ResourceReadImage(); Укажите имя ресурса и передайте в нее массив uint_Read.

ResourceReadImage("::Имя_ресурса",read.uint_Read,width,height);

9. После этого, строка предствленная в массиве uint_Read уже будет находится в массиве char_Read (без перезаписи), а из char_Read вы ее извлечете с помощью функции CharArrayToString().


Фу, кажется все...))


И этого было не только достаточно, а даже чуток лишнего.
 
Alexey Viktorov:


И этого было не только достаточно, а даже чуток лишнего.

Спасибо!

Интересный вариант.

Но до меня что-то даже и половина не доходит.

Получается объект, но он не виден.

#include <stdlib.mqh>
//--------------------------------------------------------------------
union SEND{uchar char_Send[32000]; uint uint_Send[8000];};
union READ{uchar char_Read[32000]; uint uint_Read[8000];};
//--------------------------------------------------------------------
SEND send;
READ read;
void OnStart()  {
   bool success;
   int q = StringToCharArray("aalksdjghalkfhaerlkvhelvkjhalekhavk", send.char_Send);
   success = ResourceCreate("::TestResorce.bmp",send.uint_Send,800,10,10,10,0,COLOR_FORMAT_XRGB_NOALPHA);
   if(!success) {
      Print(ErrorDescription(GetLastError()), " l=", __LINE__);
      return;
   }
   ObjectDelete(0, "MyObj");
   ObjectCreate(0, "MyObj", OBJ_BITMAP_LABEL,0, 100, 100);
   ObjectSetString(0, "MyObj", OBJPROP_BMPFILE, "::TestResorce.bmp");
}
 
Evgeny Potapov:

Здравствуйте!

Я пытаюсь сделать панель, то есть аккуратно подложить прямоугольник под текст, но в зависимости от компьютера всё разъезжается.

Например вот такой код:

Даёт прямоугольник в два раза уже, чем текст.

Я пытался спрашивать сообщением в другой теме, но нормального обсуждения не получилось, и решение проблемы не сформировалось.

Похоже, рационально сделать отдельную тему по этому вопросу.

Функции SetFont и TextGetSize относятся к рисованию на канвасе. К графическим объектам они отношения не имеют. Читайте документацию.

В вашем случае нужен только тупой подбор размеров
 
Andrey Barinov:
Функции SetFont и TextGetSize относятся к рисованию на канвасе. К графическим объектам они отношения не имеют. Читайте документацию.

В вашем случае нужен только тупой подбор размеров

Спасибо! Я не заметил функцию TextOut(), с ней можно что-то попробовать сделать!

А что я делаю неправильно с ResourceCreate()?