void LoadData(CString csMessage, double dNarrowBar, double dFinalHeight,
HDC pDC, int nStartingXPixel, int nStartingYPixel,
double dRatio = 1.0);
virtual void DrawBitmap() = 0;
virtual void BitmapToClipboard() = 0;
virtual void DrawPattern(CString csPattern) = 0;
There are a few things to note about the CBarcode class. First note that it has data members that contain all of the useful data needed to draw a barcode message. This data includes the narrow element pixel width, the wide element pixel width, the message, and the symbology. Second the class has data members that contain information about how to output the barcode message. This data includes a device context handle, and a starting X and Y pixel. Third the class has some public member functions to intialize the class by loading data, and obtain information about the barcode message, namely its pixel height and width. Fourth the class has several abstract member functions that make this class an abstract base class. Any classes derived from CBarcode will be expected to implement these functions.
The CCode39 class
The CCode39 class is the class to implement to draw a Code 39 barcode. The class declaration is listed below.
class CCode39 : public CBarcode
void DrawPattern(CString csPattern);
CString RetrievePattern( char c );
The class has two public functions BitmapToClipboard() and DrawBitmap(), plus it inherits the LoadData() function from the CBarcode class. The steps to use the class are simple, declare an instance of the class, call LoadData() to intialize class data, and then call either BitmapToClipboard() if you want to put a bitmap of the barcode on the clipboard, or call DrawBitmap() to draw the barcode message.
Drawing a Barcode to a Device Context
The following code snipet is an example using
double dNarrowBar,dHeight, dRatio;
long nStartingXPixel, nStartingYPixel;
Drawing a Barcode to the Clipboard
The following code snipet is an example using
HDC hDC = NULL;
Note that when using the BitmapToClipboard() function, you can pass a null device context handle and zeroes for the starting X and Y pixel in the LoadData() call. Obviously the starting X and Y pixels are meaningless on the clipboard, but what about the null device context handle? The answer to that question can be found by looking at this code snipet from the BitmapToClipboard() function.
So the BitmapToClipboard() function creates its own memory device context by using the memDC.CreateCompatibleDC(NULL) function call. A quick look at the MSDN documentation shows that if you pass a NULL value to CreateCompatibleDC, the device context created is compatible with the screen.
The parameters for CBarcode::LoadData() deserve some further explanation and this seems like the place to do it. The first parameter, csMessage is simply the message you wish to be drawn as a Code 39 barcode. The next parameter dNarrowBar is the width of the narrow element in inches. The parameter dHeight is the height of the barcode in inches. The parameter pDC is a handle to the device context that the barcode will be drawn in. The next two parameters, nStartingXPixel and nStartingYPixel define the coordinates to start drawing the barcode. The final parameter, dRatio is the ratio of wide/narrow element widths. If you remember the declaration of the CBarcode class above, you'll remember that it stores all width and height information in pixels, and that it stores the narrow element width and the wide element width instead of the narrow element width and the wide/narrow element width ratio. Clearly CBarcode::LoadData() is doing some behind the scenes conversion work.
The first step to that conversion work is to get the X axis and Y axis dpi, which is done by the following code, taken from CBarcode::LoadData().
nXAxisDpi = tempDC.GetDeviceCaps(LOGPIXELSX);
nYAxisDpi = tempDC.GetDeviceCaps(LOGPIXELSY);
Once you have the X and Y axis dpi, you can calculate the pixel height, narrow element pixel width, and wide element pixel width as shown in the following code snipet.
m_nPixelHeight = (int)((nYAxisDpi*dFinalHeight)+0.5);
m_nNarrowBarPixelWidth = (int)((nXAxisDpi*dNarrowBar)+0.5);
m_nWideBarPixelWidth = (int)(dRatio*m_nNarrowBarPixelWidth);
Note the rounding effect when calculating the narrow element pixel width and the wide element pixel width. The narrow element width has a lower limit of one pixel, so the barcode you can produce is limited by the physical limitations of the output device.
Next you can calculate the final barcode pixel width, this operation is symbology specific and the Code 39 code excerpt is listed below.
nTemp = m_csMessage.GetLength() + 2;
m_nFinalBarcodePixelWidth = nTemp * ((3*m_nWideBarPixelWidth) +
The code above calculates the final barcode pixel width by adding two characters for the message length, (for the start and stop code) and multiplying the total number of characters by the pixel length of each character. Note that the total length of each character uses 7 times the narrow element width to accomodate the inter-character gap.
The DrawBitmap() function is where each message character is drawn. A listing of the CCode39::DrawBitmap() function is listed below.
The CCode39::DrawBitmap() function starts out by drawing the start character, the asterisk. Then the code steps through every character in the message and draws each character. Finally the code draws the stop character, again the asterisk. There are two private member functions that are used here. CCode39::DrawPattern() draws the pattern passed to it, the pattern is a CString in the form of “wnnwnnnnw” (the character '1') like the character data mentioned above. CCode39::RetrievePattern() is basically a giant switch statement, retrieving the pattern for any legal Code 39 character passed to it. Note that each character pattern returned from CCode39::RetrievePattern() has an extra “n” tacked on to the end to add the inter-character gap.
The CCode39::DrawPattern() function draws a single Code 39 barcode character in the passed device context. The CCode39::DrawPattern() function is listed below.
void CCode39::DrawPattern( CString csPattern )
nXPixel = m_nStartingXPixel;
nTempWidth = m_nNarrowBarPixelWidth;
nTempWidth = m_nWideBarPixelWidth;
for (nYPixel = m_nStartingYPixel;