Thread: TextOutPut

  1. #1
    Politics&Cpp geek Da-Nuka's Avatar
    Join Date
    Oct 2004
    Posts
    104

    TextOutPut

    Hi. Im simply trying to use TextOut() to Display two strings.
    One constant, and one which may vary.
    I use a TEXTMETRIC field to keep track on where to begin the secound TextOut(). The problem is that the cxChar(which should contain the character width, have a far too low value. And YES, I am using SYSTEM_FIXED_FONT

    Here is a little of my code:
    Code:
    #define INPUTBUFFER_SIZE      100
    #include <windows.h>
    const char* Ip_Enter = "Enter IP:";
    TCHAR buffer[INPUTBUFFER_SIZE];
    //////////////////////////////////////////////////////
     case WM_CREATE :
             hdc=GetDC(hwnd);
             SelectObject(hdc,GetStockObject(SYSTEM_FIXED_FONT));
             GetTextMetrics(hdc,&tm);
             cxChar=tm.tmMaxCharWidth;
             ReleaseDC(hwnd, hdc);
    
             return 0;
    
     case WM_PAINT :
              hdc = BeginPaint (hwnd, &ps) ;
              SelectObject(hdc,GetStockObject(SYSTEM_FIXED_FONT));
    
              if(connectStat==STATE_ENTER_IP) {
              TextOut(hdc,0,0,Ip_Enter,lstrlen(Ip_Enter));
              TextOut(hdc,cxChar*(lstrlen(Ip_Enter)),0,buffer,lstrlen(buffer));
              }
              EndPaint (hwnd, &ps) ;
    return 0;
    Where does my stupidity show off in code-form this time
    Anyone can help me figure out the error(s)?
    Last edited by Da-Nuka; 02-25-2005 at 02:32 AM.

  2. #2
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    look at

    GetTextExtentPoint32()

    to find the exact length of any given string on any given Device Context.

    Call then use the SIZE.cx param and your client rect (or the update rect in the PAINTSTRUCT.rcPaint)

    Another way is to use DrawText() as it allows more formatting control.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  3. #3
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    I suspect that the tm.tmMaxCharWidth value does not take into account the inter-character spacing. You can use GetTextExtentPoint32 instead.
    Code:
              hdc = BeginPaint(hwnd, &ps);
              SelectObject(hdc,GetStockObject(SYSTEM_FIXED_FONT) );
    
              if(connectStat==STATE_ENTER_IP)
              {
                 SIZE sz;
                 TextOut(hdc,0,0,Ip_Enter,lstrlen(Ip_Enter));
                 GetTextExtentPoint32(hdc, Ip_Enter, lstrlen(Ip_Enter), &sz);
    
                 TextOut(hdc, sz.cx, 0, buffer, lstrlen(buffer));
              }
    
              EndPaint (hwnd, &ps);
    Another option is to use SetTextAlign with TA_UPDATECP. This tells TextOut to use and update the current position.

  4. #4
    Politics&Cpp geek Da-Nuka's Avatar
    Join Date
    Oct 2004
    Posts
    104
    Okay, thanks for the replies..
    But this way have worked before..Why has it suddenly changed now? May it be compiler-dependent?
    (Cuz i just changed from VC++ to DevC++)

  5. #5
    Politics&Cpp geek Da-Nuka's Avatar
    Join Date
    Oct 2004
    Posts
    104
    I just found out another thing...
    Why does GetTextExtentPoint32() have to be within the WM_PAINT : BeginPaint() function?

    Why isn't hdc=GetDC(hwnd);
    enough?

    If i try to put something like this in my WM_CREATE box, the whole things goes crazy, much like my previous TEXTMETRICS.

  6. #6
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    The size of the text is dependent on the HDC. A given string may not be the same size on diff Device Contexts, even if the DC's have the same font.

    MSDN
    "If an application needs to update the current position when it calls TextOut, the application can call the SetTextAlign member function with nFlags set to TA_UPDATECP. When this flag is set, Windows ignores the x and y parameters on subsequent calls to TextOut, using the current position instead."

    This means that it will remember where you drew the last text (so you would have to keep resetting it).

    OR

    As a simple fix why not use sprintf() in the paint..

    Code:
    sprintf(szOutput,"%s %s",IP_Enter,buffer);
    TextOut(hdc,0,0,szOutput,lstrlen(szOutput));
    (Had a bit more time to lok at the code...)

    If not using a .NET version of WIN32 complier, then your use of SelectObject() is a GDI leak.

    'Catch' the return value (from SelectObject() ) and before freeing the HDC return this default GDI object (with SelectObject() )

    ie
    HFONT hDefFont = SelectObject(hdc, hSomeFont );
    //use
    SelectObject(hdc, hDefFont );
    //free DC or call EndPaint()

    EDIT: tried to stop typing but .......just ..........can't..........
    Last edited by novacain; 02-26-2005 at 09:32 PM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  7. #7
    Politics&Cpp geek Da-Nuka's Avatar
    Join Date
    Oct 2004
    Posts
    104
    Code:
    static HFONT hFont;
    case WM_PAINT :
              hdc = BeginPaint (hwnd, &ps) ;
              SetBkColor(hdc,RGB(200,200,200));
              hFont=SelectObject(hdc,GetStockObject(SYSTEM_FIXED_FONT));
    I tried... and got this:
    ANSI C++ forbids implicit conversion from `void *' in assignment

  8. #8
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Yeah, you need to cast that in C++

    Code:
    hFont=static_cast<HFONT>(SelectObject(hdc,GetStockObject(SYSTEM_FIXED  _FONT)));
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  9. #9
    Politics&Cpp geek Da-Nuka's Avatar
    Join Date
    Oct 2004
    Posts
    104
    Whats the point of using static_cast<HFONT>
    when simply (HFONT) does exactly the same, but with less space, and its easier to read?

    Thnx, btw, it worked now

  10. #10
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    You can read one persons opinions here:

    http://www.sjbrown.co.uk/static_cast.html

    If you are going to be using C++ I suggest you start using C++ style casts. Basically C-style casts are reinterpret_cast< >( ) and can be very dangerous if you don't know what you are doing or aren't careful. There are many other reasons too that I'll leave up to you to find.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

Popular pages Recent additions subscribe to a feed