Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Can't select HBRUSH into device context

Can't select HBRUSH into device context

Scheduled Pinned Locked Moved C / C++ / MFC
helpcsharpgraphicsalgorithmsquestion
9 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Alan Balkany
    wrote on last edited by
    #1

    Hello, Stuck on a Microsoft drawing problem: The brush I'm using to draw text is being ignored, and SelectObject () returns NULL when I try to select it into a device context:

    HFONT hFont = CreateFontIndirect(& logFont);
    HFONT oldFont = (HFONT) SelectObject (hDc, hFont);
    HBRUSH oldBrush = (HBRUSH) SelectObject (hDc, hbrush);
    
    TextOut (hDc, 0, 0, fontName, wcslen (fontName));
    

    The brush comes from the nativeBrush member of a .NET System.Drawing.Brush, which works correctly both before and after this. I've tried using DrawText () instead, with the same result. Can anyone point out what I'm doing wrong? Thanks!

    "Microsoft -- Adding unnecessary complexity to your work since 1987!"

    J enhzflepE 2 Replies Last reply
    0
    • A Alan Balkany

      Hello, Stuck on a Microsoft drawing problem: The brush I'm using to draw text is being ignored, and SelectObject () returns NULL when I try to select it into a device context:

      HFONT hFont = CreateFontIndirect(& logFont);
      HFONT oldFont = (HFONT) SelectObject (hDc, hFont);
      HBRUSH oldBrush = (HBRUSH) SelectObject (hDc, hbrush);
      
      TextOut (hDc, 0, 0, fontName, wcslen (fontName));
      

      The brush comes from the nativeBrush member of a .NET System.Drawing.Brush, which works correctly both before and after this. I've tried using DrawText () instead, with the same result. Can anyone point out what I'm doing wrong? Thanks!

      "Microsoft -- Adding unnecessary complexity to your work since 1987!"

      J Offline
      J Offline
      Jochen Arndt
      wrote on last edited by
      #2

      Brushes are used to fill the interior of filled shapes. They are not used to draw text. TextOut() and DrawText() use the text and background colors currently selected by the device context. These can be set using SetTextColor() and SetBkColor(). SelectObject() returns the object that is going to be replaced. This may be NULL if there is actually no such object selected into the device context. It is not an error condition. The return value is usally used to restore the old state after drawing has been done.

      A 1 Reply Last reply
      0
      • J Jochen Arndt

        Brushes are used to fill the interior of filled shapes. They are not used to draw text. TextOut() and DrawText() use the text and background colors currently selected by the device context. These can be set using SetTextColor() and SetBkColor(). SelectObject() returns the object that is going to be replaced. This may be NULL if there is actually no such object selected into the device context. It is not an error condition. The return value is usally used to restore the old state after drawing has been done.

        A Offline
        A Offline
        Alan Balkany
        wrote on last edited by
        #3

        Hmm... I'm using the same brush to draw text in the .NET half of the application. These are complex patterns (linear gradient and hatch brushes), and the text correctly appears with these textures in GDI+/.NET. I'm using GDI (no plus) in this part because GDI+ doesn't support OpenType or PostScript fonts (only TrueType). So how can these patterns be used in text under GDI?

        "Microsoft -- Adding unnecessary complexity to your work since 1987!"

        J 1 Reply Last reply
        0
        • A Alan Balkany

          Hmm... I'm using the same brush to draw text in the .NET half of the application. These are complex patterns (linear gradient and hatch brushes), and the text correctly appears with these textures in GDI+/.NET. I'm using GDI (no plus) in this part because GDI+ doesn't support OpenType or PostScript fonts (only TrueType). So how can these patterns be used in text under GDI?

          "Microsoft -- Adding unnecessary complexity to your work since 1987!"

          J Offline
          J Offline
          Jochen Arndt
          wrote on last edited by
          #4

          I'm sorry, I don't think that there is a solution with GDI.

          A 1 Reply Last reply
          0
          • J Jochen Arndt

            I'm sorry, I don't think that there is a solution with GDI.

            A Offline
            A Offline
            Alan Balkany
            wrote on last edited by
            #5

            Thanks for the input!

            "Microsoft -- Adding unnecessary complexity to your work since 1987!"

            1 Reply Last reply
            0
            • A Alan Balkany

              Hello, Stuck on a Microsoft drawing problem: The brush I'm using to draw text is being ignored, and SelectObject () returns NULL when I try to select it into a device context:

              HFONT hFont = CreateFontIndirect(& logFont);
              HFONT oldFont = (HFONT) SelectObject (hDc, hFont);
              HBRUSH oldBrush = (HBRUSH) SelectObject (hDc, hbrush);
              
              TextOut (hDc, 0, 0, fontName, wcslen (fontName));
              

              The brush comes from the nativeBrush member of a .NET System.Drawing.Brush, which works correctly both before and after this. I've tried using DrawText () instead, with the same result. Can anyone point out what I'm doing wrong? Thanks!

              "Microsoft -- Adding unnecessary complexity to your work since 1987!"

              enhzflepE Offline
              enhzflepE Offline
              enhzflep
              wrote on last edited by
              #6

              Yeah, it shouldn't be a problem to do what you're asking for. You need to make use of _both_ TextOut and Paths. Basically, the process goes like this (sorry code is in a PDF ebook that prevents copy and paste) 1. Create your font 2. Select it into your hdc 3. Call BeginPath(hdc) 4. Call TextOut 5. Call EndPath 6. Use StrokePath for the outline, FillPath for the interior. 7. Select the old font back into the hdc 8. delete your font from #1 Ah! found a CHM version of the same book. Here's the code given there: (I'll leave it as, unedited, for completeness)

              void PaintRoutine (HWND hwnd, HDC hdc, int cxArea, int cyArea)
              {
              static TCHAR szString [] = TEXT ("Filling") ;
              HFONT hFont ;
              SIZE size ;

               hFont = EzCreateFont (hdc, TEXT ("Times New Roman"), 1440, 0, 0, TRUE) ;
              
               SelectObject (hdc, hFont) ;
               SetBkMode (hdc, TRANSPARENT) ;
              
               GetTextExtentPoint32 (hdc, szString, lstrlen (szString), &size) ;
              
               BeginPath (hdc) ;
               TextOut (hdc, (cxArea - size.cx) / 2, (cyArea - size.cy) / 2,
                              szString, lstrlen (szString)) ;
               EndPath (hdc) ;
              
               SelectObject (hdc, CreateHatchBrush (HS\_DIAGCROSS, RGB (255, 0, 0))) ;
               SetBkColor (hdc, RGB (0, 0, 255)) ;
               SetBkMode (hdc, OPAQUE) ;
              
               StrokeAndFillPath (hdc) ;
              
               DeleteObject (SelectObject (hdc, GetStockObject (WHITE\_BRUSH))) ;
               SelectObject (hdc, GetStockObject (SYSTEM\_FONT)) ;
               DeleteObject (hFont) ;
              

              }

              Make it work. Then do it better - Andrei Straut

              A 1 Reply Last reply
              0
              • enhzflepE enhzflep

                Yeah, it shouldn't be a problem to do what you're asking for. You need to make use of _both_ TextOut and Paths. Basically, the process goes like this (sorry code is in a PDF ebook that prevents copy and paste) 1. Create your font 2. Select it into your hdc 3. Call BeginPath(hdc) 4. Call TextOut 5. Call EndPath 6. Use StrokePath for the outline, FillPath for the interior. 7. Select the old font back into the hdc 8. delete your font from #1 Ah! found a CHM version of the same book. Here's the code given there: (I'll leave it as, unedited, for completeness)

                void PaintRoutine (HWND hwnd, HDC hdc, int cxArea, int cyArea)
                {
                static TCHAR szString [] = TEXT ("Filling") ;
                HFONT hFont ;
                SIZE size ;

                 hFont = EzCreateFont (hdc, TEXT ("Times New Roman"), 1440, 0, 0, TRUE) ;
                
                 SelectObject (hdc, hFont) ;
                 SetBkMode (hdc, TRANSPARENT) ;
                
                 GetTextExtentPoint32 (hdc, szString, lstrlen (szString), &size) ;
                
                 BeginPath (hdc) ;
                 TextOut (hdc, (cxArea - size.cx) / 2, (cyArea - size.cy) / 2,
                                szString, lstrlen (szString)) ;
                 EndPath (hdc) ;
                
                 SelectObject (hdc, CreateHatchBrush (HS\_DIAGCROSS, RGB (255, 0, 0))) ;
                 SetBkColor (hdc, RGB (0, 0, 255)) ;
                 SetBkMode (hdc, OPAQUE) ;
                
                 StrokeAndFillPath (hdc) ;
                
                 DeleteObject (SelectObject (hdc, GetStockObject (WHITE\_BRUSH))) ;
                 SelectObject (hdc, GetStockObject (SYSTEM\_FONT)) ;
                 DeleteObject (hFont) ;
                

                }

                Make it work. Then do it better - Andrei Straut

                A Offline
                A Offline
                Alan Balkany
                wrote on last edited by
                #7

                Wow, that's some fancy coding! People elsewhere are saying it's impossible. Thanks enhzflep!

                "Microsoft -- Adding unnecessary complexity to your work since 1987!"

                enhzflepE 1 Reply Last reply
                0
                • A Alan Balkany

                  Wow, that's some fancy coding! People elsewhere are saying it's impossible. Thanks enhzflep!

                  "Microsoft -- Adding unnecessary complexity to your work since 1987!"

                  enhzflepE Offline
                  enhzflepE Offline
                  enhzflep
                  wrote on last edited by
                  #8

                  You're welcome :) Yeah, Charles Pretzold always was a smart cookie. I'm so glad that I remembered having read a section in his books about the topic.

                  Make it work. Then do it better - Andrei Straut

                  A 1 Reply Last reply
                  0
                  • enhzflepE enhzflep

                    You're welcome :) Yeah, Charles Pretzold always was a smart cookie. I'm so glad that I remembered having read a section in his books about the topic.

                    Make it work. Then do it better - Andrei Straut

                    A Offline
                    A Offline
                    Alan Balkany
                    wrote on last edited by
                    #9

                    Hi enhzflep, I incorporated code from your example into my function, and it works with the CreateHatchBrush call to create a new brush. Unfortunately, when I substitute my already-created brush, it doesn't work; I just get solid white filling the text outlines. I've verified the brush handle is the same as the nativeBrush member of my .NET Brush, which draws correctly both before and after. Can you see anything I'm doing wrong?

                    DLLEXPORT void drawWithGdiFont (HBITMAP hBitmap, HBRUSH hbrush, LPCWSTR fontName,
                    LPCWSTR text, int sizeToUse, bool bold, bool italic, int br, int bg, int bb)
                    {
                    HDC hDc = CreateCompatibleDC (NULL);
                    HGDIOBJ oldObj = SelectObject (hDc, hBitmap);
                    SIZE size ;

                    LOGFONT logFont;
                    ::ZeroMemory(& logFont, sizeof(LOGFONT));
                    wcscpy ((&logFont)->lfFaceName, fontName);
                    logFont.lfHeight = sizeToUse;
                    
                    if (bold)
                    	logFont.lfWeight = 800;
                    else
                    	logFont.lfWeight = 500;
                    
                    logFont.lfItalic = italic;
                    
                    HFONT hFont = CreateFontIndirect(& logFont);
                    HFONT oldFont = (HFONT) SelectObject (hDc, hFont);
                    
                    SetBkMode (hDc, TRANSPARENT) ;
                    
                    BeginPath (hDc) ;
                    TextOut (hDc, 0, 0, fontName, wcslen (fontName));
                    EndPath (hDc) ;
                    

                    **// MY BRUSH FROM .NET (DOESN'T WORK):
                    HBRUSH oldBrush = (HBRUSH) SelectObject (hDc, hbrush);

                    // FROM EXAMPLE (WORKS): HBRUSH oldBrush = (HBRUSH) SelectObject (hDc, CreateHatchBrush (HS_DIAGCROSS, RGB (255, 0, 0))) ;**

                    SetBkColor (hDc, RGB (br, bg, bb));
                    SetBkMode (hDc, OPAQUE) ;
                    
                    StrokeAndFillPath (hDc) ;
                    
                    DeleteObject (SelectObject (hDc, oldFont));
                    SelectObject (hDc, oldBrush);
                    DeleteObject (hDc);
                    

                    }

                    Also, it seems like the background color here is the second color of the hatch pattern. But how do I set the color between the letters (which is also called the "background color"?) Thanks! Alan

                    "Microsoft -- Adding unnecessary complexity to your work since 1987!"

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups