Archive

Posts Tagged ‘GDI’

A humble attempt to explain GDI stock objects…

January 7, 2009 Leave a comment

So what are stock objects? “Stock” as the name says means goods in hand, which a shop keeper always has as a backup. In the same way GDI also keep a set of backup of objects which it creates during initialization and these are known as stock objects. Let’s think of a case like this… you are creating a fancy brush but somehow the creation fails, so what will be your backup policy, mine would be to use a stock brush, for e.g. BLACK_BRUSH since these objects are always available. Think of a case where you have to quickly create a black brush, I would go for stock object BLACK_BRUSH.

Following are the stock objects that I know, taken straight out of MSDN

Value Meaning
BLACK_BRUSH Black brush.
DKGRAY_BRUSH Dark gray brush.
DC_BRUSH Windows 2000/XP: Solid color brush. The default color is white. The color can be changed by using the SetDCBrushColor function. For more information, see the Remarks section.
GRAY_BRUSH Gray brush.
HOLLOW_BRUSH Hollow brush (equivalent to NULL_BRUSH).
LTGRAY_BRUSH Light gray brush.
NULL_BRUSH Null brush (equivalent to HOLLOW_BRUSH).
WHITE_BRUSH White brush.
BLACK_PEN Black pen.
DC_PEN Windows 2000/XP: Solid pen color. The default color is white. The color can be changed by using the SetDCPenColor function. For more information, see the Remarks section.
NULL_PEN Empty pen.
WHITE_PEN White pen.
ANSI_FIXED_FONT Windows fixed-pitch (monospace) system font.
ANSI_VAR_FONT Windows variable-pitch (proportional space) system font.
DEVICE_DEFAULT_FONT Windows NT/2000/XP: Device-dependent font.
DEFAULT_GUI_FONT Default font for user interface objects such as menus and dialog boxes. This is MS Sans Serif. Compare this with SYSTEM_FONT.
OEM_FIXED_FONT Original equipment manufacturer (OEM) dependent fixed-pitch (monospace) font.
SYSTEM_FONT System font. By default, the system uses the system font to draw menus, dialog box controls, and text.Windows 95/98 and Windows NT: The system font is MS Sans Serif.Windows 2000/XP: The system font is Tahoma
SYSTEM_FIXED_FONT Fixed-pitch (monospace) system font. This stock object is provided only for compatibility with 16-bit Windows versions earlier than 3.0.
DEFAULT_PALETTE Default palette. This palette consists of the static colors in the system palette.

If you look at above table, we can see that almost all GDI object classes (exceptions are regions and bitmaps) has a backup stock object, mainly to act as a fallback method just in case of a failure IMO.

To use retrieve a stock object we call function GetStockObject. The good thing about working with a stock object is that we don’t have to delete it, since we didn’t create it. Now think how easy it’s to create a black pen, or black brush. No overheads to delete/free them. It’s definitely faster too.

There is a brush called NULL_BRUSH, a pen called NULL_PEN which are quite useful to draw a hollow rectangle without any fill, instead of selecting a brush equivalent to background window color to simulate drawing a rectangle without any fill.

CDC class of MFC has a very easy to use function for stock object. It’s CDC::SelectStockObject. I’m going nuts for this function. 😉 Take a look at these calls….

// Select a black brush
CDC ClientDC;
ClientDC.Attach( ::GetDC( m_hWnd ));

const int RestorePoint = ClientDC.SaveDC();

// Select a black brush
ClientDC.SelectStockObject( BLACK_BRUSH );
// Select a black pen
ClientDC.SelectStockObject( BLACK_PEN );
// Select existing font
ClientDC.SelectStockObject( <strong>DEVICE_DEFAULT_FONT</strong> );

ClientDC.RestoreDC( RestorePoint );

See how easy it’s to use these stock objects. No overhead of creating or freeing them, but as I already said these are just for backup action purpose. For fancy stuff you of course have to go for other functions.

So bottom line is stock objects are just to avoid cases were you end up with no brush to paint or no pen to write. 🙂

Making many drawing calls using just one API call!

April 11, 2008 Leave a comment

Use Polyxxxx set of functions. Some of the functions that I know are listed below

  1. PolyPolyline
  2. PolyTextOut
  3. PolylineTo
  4. PolyDraw
  5. PolyBezier
  6. PolyBezierTo

From MSDN:

These functions exploit the fact that many drawing calls use identical attributes, and so multiple items can be drawn in a single call once the brushes, pens, colors, and fonts have been selected. For example, the console window uses PolyTextOut. This change significantly reduces scrolling time in a console window.

Retrieving current text color of a DC!

Use GetTextColor! Function signature is as follows…

// MFC
COLORREF GetTextColor() const;
// SDK
COLORREF GetTextColor( HDC hdc  ); // handle to DC

Retrieving face name of font selected into a DC!

Use GetTextFace function! Function signature is as follows…

 // MFC
int GetTextFace( CString& rString ) const;

// SDK
int GetTextFace( HDC hdc, // handle to DC
                 int nCount, //length of typeface name buffer
                 LPTSTR lpFaceName // typeface name buffer
               );

Retrieving graphics objects selected into a DC!

Felt the need to retrieve current brush or pen or palette selected into a DC? Sometime back a friend of mine asked me this question, as an answer I gave him a better solution, but the question was a valid one!

So are there any windows api’s that helps us in the regard? Well the answer is yes, use GetCurrentObject and GetObject in tandem to retrieve details of graphics object selected into a dc.

GetCurrentObject signature

HGDIOBJ GetCurrentObject( HDC hdc, // handle to DC
                          UINT uObjectType // object type
                        );

Lookup MSDN for possible values of uObjectType.

GetObject signature

int GetObject( HGDIOBJ hgdiobj,  // handle to graphics object
               int cbBuffer,     // size of buffer for object information
               LPVOID lpvObject  // buffer for object information
             );

Lookup MSDN for possible values of lpvObject in GetObject. Here is an example of how to use these functions!

// Use GetCurrentObject to get current brush selected in to a DC
HBRUSH hCurrentDCBrush = GetCurrentObject( hDC, OBJ_BRUSH );

// Get brush details
LOGBRUSH lCurrentBrushDetails = { 0 };
GetObject( hCurrentDCBrush, sizeof( lCurrentBrushDetails ), &lCurrentBrushDetails );

Type of GDI object!

March 27, 2008 Leave a comment

To retrieve type of a HGDIOBJ object call GetObjectType.

E.g.

GetObjectType( hGdiObj );

Possible return values taken from MSDN…

OBJ_BITMAP
OBJ_BRUSH
OBJ_COLORSPACE
OBJ_DC
OBJ_ENHMETADC
OBJ_ENHMETAFILE
OBJ_EXTPEN
OBJ_FONT
OBJ_MEMDC
OBJ_METAFILE
OBJ_METADC
OBJ_PAL
OBJ_PEN
OBJ_REGION

Drawing outlined text!

March 21, 2008 Leave a comment

How to draw text like this!
outlinedrawing.png

Looks interesting right! Well this is done using plain window’s GDI functions, here is a function which does this!

// Thanks to Charles Petzold!
void CCanvas::DrawOutlineText( CDC& dc, const CString& Text )
{
  const int RestorePoint = dc.SaveDC();

  // Create new font
  CFont NewFont;
  NewFont.CreatePointFont( 700, TEXT( "Verdana" ), &dc );

  // Use this font
  dc.SelectObject( &NewFont );

  // Brush for pen
  LOGBRUSH lBrushForPen = { 0 };
  lBrushForPen.lbColor = RGB( 200, 150, 100 );
  lBrushForPen.lbHatch = HS_CROSS;
  lBrushForPen.lbStyle = BS_SOLID;

  // New pen for drawing outline text
  CPen OutlinePen;
  OutlinePen.CreatePen( PS_GEOMETRIC | PS_SOLID, 2, &lBrushForPen, 0, 0 );

  // Use this pen
  dc.SelectObject( &OutlinePen );

  dc.SetBkMode( TRANSPARENT );

  dc.BeginPath();
  // This text is not drawn on screen, but instead each action is being
  // recorded and stored internally as a path, since we called BeginPath
  dc.TextOut( 20, 20, Text );
  // Stop path
  dc.EndPath();

  // Now draw outline text
  dc.StrokePath();

  dc.RestoreDC( RestorePoint );
}

How to get color of a pixel from any Bitmap?

October 13, 2007 2 comments

It’s easy to get color of a pixel from a bitmap. Here is a function which does this…

#include
#include

// Returns Pixel color from bitmap
COLORREF GetPixelValueFromBitmap( const int x, const int y, CBitmap& bmp )
{
// DC for desktop
CDC dcDesktop;
dcDesktop.Attach( ::GetDC( GetDesktopWindow() ));

// Create a DC compatible with desktop or any other existing window
CDC dc;
dc.CreateCompatibleDC( &dcDesktop );

// Save the DC settings here, so that we can restore it later
const int nRestorePoint = dc.SaveDC();

// Select the bitmap into the DC
dc.SelectObject( &bmp );

// Now get the pixels value from the DC
const COLORREF clr = dc.GetPixel( x, y );

// Restore DC settings
dc.RestoreDC( nRestorePoint );

// Return pixel value/color
return clr;
}// End GetPixelValueFromBitmap

// main function
int main()
{
// initialize MFC and print an error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
std::cerr << _T("Fatal Error: MFC initialization failed") << std::endl; return 1; } // Prepare a bitmap CBitmap bmp; // Provide your own bitmap id bmp.LoadBitmap( IDB_BITMAP1 ); // Get color of given pixel from given bitmap COLORREF clr = GetPixelValueFromBitmap( 0, 2, bmp ); // Split up the colors and see const int Red = GetRValue( clr ); const int Green = GetGValue( clr ); const int Blue = GetBValue( clr ); return 0; }// End main[/sourcecode]