Download MetaTrader 5

String width and height in pixel

To add comments, please log in or register
Gabor Torma
2680
Gabor Torma  

Hi,

How can I get a string width and height in pixel with a specific font and size without creating and label object?

DLL usage is not problem for me, if it's needed.

Thanx for help!

Heinz Traub
314
Heinz Traub  

Chances are that the MT terminal internally uses GDI+ for font rendering. You can successfully use that to obtain string dimentions, it requires a couple of lines but it's pretty straightforward once you know how it works. GDI+ is a complement to the Win32/Win64 API and it's the native method for font rendering under Windows. Its execution time is the fastest as it communicates directly with device drivers for displaying or obtaining info. With GDI+ you'll be doing the same thing as the terminal but with no need to display the label nor extra overhead.

Here, entry point for GDI+.

GDI+ (Windows)
  • msdn.microsoft.com
Windows GDI+ is a class-based API for C/C++ programmers. It enables applications to use graphics and formatted text on both the video display and the printer. Applications based on the Microsoft Win32 API do not access graphics hardware directly. Instead, GDI+ interacts with device drivers on behalf of applications. GDI+ is also supported by...
Heinz Traub
314
Heinz Traub  

Hi again, i found this old thread regarding your same question: https://www.mql5.com/en/forum/4627

See if that formula works for you, but i believe that is font dependant. If you know that the font can be changed somehow then better stick to GDI+ to be always sure it's going to work.

font size and pixel
font size and pixel
  • www.mql5.com
How do I calculate the width (in pixel) for a string of a given font size?
Gabor Torma
2680
Gabor Torma  

May be the GDI+ will be the solution, the other is not good for Calibri font.


Thanx for help!


Gabor Torma
2680
Gabor Torma  

How can I import GetTextExtentPoint32 and CreateFont functions?

The following code is not working:

#import "gdi32.dll"
int GetTextExtentPoint32(int hdc,string str,int len,int &size);
int CreateFont(int nHeight,int nWidth,int nEscapement,int nOrientation,int fnWeight,int fdwItalic,uint fdwUnderline,uint fdwStrikeOut,
               uint fdwCharSet,uint fdwOutputPrecision,uint fdwClipPrecision,uint fdwQuality,uint fdwPitchAndFamily,string lpszFace);
#import
GetTextExtentPoint32 function (Windows)
  • msdn.microsoft.com
The GetTextExtentPoint32 function computes the width and height of the specified string of text. Syntax Parameters hdc [in] A handle to the device context. lpString [in] A pointer to a buffer that specifies the text string. The string does not need to be null-terminated, because the c parameter specifies the length of the string. c [in]...
phi nuts
2184
phi nuts  
Let me bump this up for you so all other topic will bump down ;|
Heinz Traub
314
Heinz Traub  

Don't know if you get any messages or it doesn't work at all with a silent result.

I would try first using unsigned types for windows handles "hdc -> uint" (win32) or "hdc -> ulong" (win64). A void pointer type (void*) would be perfect but it's not possible in MQL5. You just need to find the smallest type that can span to fit a memory address, there's no defined type in the MQL5 spec for this kind of work (such as "size_t" in C++) so stick to uint then move to ulong if it doesn't work.

As for the SIZE structure used in GetTextExtentPoint32, try using your own instead of an int:

struct tagSIZE
{
    int cx;
    int cy;
} SIZE;

int GetTextExtentPoint32(uint hdc, string str, int len, SIZE &size);


Second, according to the MQL5 reference, strings are in UNICODE format (the same format used by Windows' Unicode functions, UTF-16LE). So, i would suggest to explicitly import the Unicode "W" version of GetTextExtentPoint32:

int GetTextExtentPoint32W(uint hdc, string str, int len, SIZE &size);


And finally in CreateFont, replace the return type with an unsigned one and fdwItalic should be of type DWORD (uint). Remember to also import the unicode version of CreateFont:

uint CreateFontW(int nHeight,int nWidth,int nEscapement,int nOrientation,int fnWeight,uint fdwItalic,uint fdwUnderline,uint fdwStrikeOut,
               uint fdwCharSet,uint fdwOutputPrecision,uint fdwClipPrecision,uint fdwQuality,uint fdwPitchAndFamily,string lpszFace);


That's it. If the functions are used correctly then all should be allright.

[UPDATE]: According to an article on the internet, the Windows SDK defines device context handles (HDC) and other handles (HFONT) as PVOID type (wich is finally int) so it should make no interference the signed and unsigned thing unless Windows need a signed range for certain functions. Try playing with both (int / uint).

To add comments, please log in or register