// BIXOLON Sample ProgramDlg.cpp : implementation file
//

#include "stdafx.h"
#include "BIXOLON Sample Program.h"
#include "BIXOLON Sample ProgramDlg.h"

//	++
#include "winspool.h"
#include "Command.h"

#define  CASH_DRAW_1			0
#define  CASH_DRAW_2			1

//	Cash Draw Speed
#define	 SPEED_50MS				0
#define	 SPEED_100MS			1
#define	 SPEED_150MS			2
#define	 SPEED_200MS			3
#define	 SPEED_250MS			4
//	

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CBIXOLONSampleProgramDlg dialog

CBIXOLONSampleProgramDlg::CBIXOLONSampleProgramDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CBIXOLONSampleProgramDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CBIXOLONSampleProgramDlg)
	m_nDrawNumber = -1;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CBIXOLONSampleProgramDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CBIXOLONSampleProgramDlg)
	DDX_Control(pDX, IDC_OPEN_SPEED, m_ctrlCashDrawSpeed);
	DDX_Control(pDX, IDC_DEVICE_FONT_LIST, m_ctrlDeviceFontList);
	DDX_Radio(pDX, IDC_DRAW, m_nDrawNumber);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CBIXOLONSampleProgramDlg, CDialog)
	//{{AFX_MSG_MAP(CBIXOLONSampleProgramDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_FONT_PRINT, OnFontPrint)
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_PARTIAL_CUT, OnPartialCut)
	ON_BN_CLICKED(IDC_PARTIAL_CUT_WITHOUT_FEEDING, OnPartialCutWithoutFeeding)
	ON_BN_CLICKED(IDC_PRINT_RECEIPT, OnPrintReceipt)
	ON_BN_CLICKED(IDC_OPEN_CASH_DRAW, OnOpenCashDraw)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBIXOLONSampleProgramDlg message handlers

BOOL CBIXOLONSampleProgramDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	//	Initialize Device Font List
	m_ctrlDeviceFontList.AddString("Korean1x1");	
	m_ctrlDeviceFontList.AddString("Korean1x2");	
	m_ctrlDeviceFontList.AddString("Korean2x1");	
	m_ctrlDeviceFontList.AddString("Korean2x2");	
	m_ctrlDeviceFontList.AddString("Korean2x4");	
	m_ctrlDeviceFontList.AddString("Korean4x2");	
	m_ctrlDeviceFontList.AddString("Korean4x4");	
	m_ctrlDeviceFontList.AddString("Korean4x8");
	m_ctrlDeviceFontList.AddString("Korean8x4");
	m_ctrlDeviceFontList.AddString("Korean8x8");
	m_ctrlDeviceFontList.AddString("FontA1x1");	
	m_ctrlDeviceFontList.AddString("FontA1x1[255]");	
	m_ctrlDeviceFontList.AddString("FontA1x1[Ext.]");	
	m_ctrlDeviceFontList.AddString("FontA1x2");	
	m_ctrlDeviceFontList.AddString("FontA1x2[255]");	
	m_ctrlDeviceFontList.AddString("FontA1x2[Ext.]");	
	m_ctrlDeviceFontList.AddString("FontA2x1");	
	m_ctrlDeviceFontList.AddString("FontA2x1[255]");	
	m_ctrlDeviceFontList.AddString("FontA2x1[Ext.]");		
	m_ctrlDeviceFontList.AddString("FontA2x2");	
	m_ctrlDeviceFontList.AddString("FontA2x2[255]");	
	m_ctrlDeviceFontList.AddString("FontA2x2[Ext.]");	
	m_ctrlDeviceFontList.AddString("FontA2x4");	
	m_ctrlDeviceFontList.AddString("FontA2x4[255]");	
	m_ctrlDeviceFontList.AddString("FontA2x4[Ext.]");	
	m_ctrlDeviceFontList.AddString("FontA4x2");	
	m_ctrlDeviceFontList.AddString("FontA4x2[255]");	
	m_ctrlDeviceFontList.AddString("FontA4x2[Ext.]");	
	m_ctrlDeviceFontList.AddString("FontA4x4");	
	m_ctrlDeviceFontList.AddString("FontA4x4[255]");	
	m_ctrlDeviceFontList.AddString("FontA4x4[Ext.]");		
	m_ctrlDeviceFontList.AddString("FontA4x8");	
	m_ctrlDeviceFontList.AddString("FontA4x8[255]");	
	m_ctrlDeviceFontList.AddString("FontA4x8[Ext.]");	
	m_ctrlDeviceFontList.AddString("FontA8x4");	
	m_ctrlDeviceFontList.AddString("FontA8x4[255]");	
	m_ctrlDeviceFontList.AddString("FontA8x4[Ext.]");		
	m_ctrlDeviceFontList.AddString("FontA8x8");	
	m_ctrlDeviceFontList.AddString("FontA8x8[255]");	
	m_ctrlDeviceFontList.AddString("FontA8x8[Ext.]");	
	m_ctrlDeviceFontList.AddString("FontB1x1");	
	m_ctrlDeviceFontList.AddString("FontB1x1[255]");	
	m_ctrlDeviceFontList.AddString("FontB1x1[Ext.]");	
	m_ctrlDeviceFontList.AddString("FontB1x2");	
	m_ctrlDeviceFontList.AddString("FontB1x2[255]");	
	m_ctrlDeviceFontList.AddString("FontB1x2[Ext.]");	
	m_ctrlDeviceFontList.AddString("FontB2x1");	
	m_ctrlDeviceFontList.AddString("FontB2x1[255]");	
	m_ctrlDeviceFontList.AddString("FontB2x1[Ext.]");		
	m_ctrlDeviceFontList.AddString("FontB2x2");	
	m_ctrlDeviceFontList.AddString("FontB2x2[255]");	
	m_ctrlDeviceFontList.AddString("FontB2x2[Ext.]");
	m_ctrlDeviceFontList.AddString("FontB2x4");	
	m_ctrlDeviceFontList.AddString("FontB2x4[255]");	
	m_ctrlDeviceFontList.AddString("FontB2x4[Ext.]");	
	m_ctrlDeviceFontList.AddString("FontB4x2");	
	m_ctrlDeviceFontList.AddString("FontB4x2[255]");	
	m_ctrlDeviceFontList.AddString("FontB4x2[Ext.]");	
	m_ctrlDeviceFontList.AddString("FontB4x4");	
	m_ctrlDeviceFontList.AddString("FontB4x4[255]");	
	m_ctrlDeviceFontList.AddString("FontB4x4[Ext.]");		
	m_ctrlDeviceFontList.AddString("FontB4x8");	
	m_ctrlDeviceFontList.AddString("FontB4x8[255]");	
	m_ctrlDeviceFontList.AddString("FontB4x8[Ext.]");	
	m_ctrlDeviceFontList.AddString("FontB8x4");	
	m_ctrlDeviceFontList.AddString("FontB8x4[255]");	
	m_ctrlDeviceFontList.AddString("FontB8x4[Ext.]");		
	m_ctrlDeviceFontList.AddString("FontB8x8");	
	m_ctrlDeviceFontList.AddString("FontB8x8[255]");	
	m_ctrlDeviceFontList.AddString("FontB8x8[Ext.]");	
	m_ctrlDeviceFontList.SetCurSel(0);

	//	Intialize Cash Draw Speed
	m_ctrlCashDrawSpeed.AddString("50ms");
	m_ctrlCashDrawSpeed.AddString("100ms");
	m_ctrlCashDrawSpeed.AddString("150ms");
	m_ctrlCashDrawSpeed.AddString("200ms");
	m_ctrlCashDrawSpeed.AddString("250ms");
	m_ctrlCashDrawSpeed.SetCurSel(0);

	//	Initialzie Cash Draw Number
	m_nDrawNumber = 0;

	UpdateData(FALSE);

	//	Intialzie Printer Name
	m_strPrinterName = "BIXOLON SRP-350plus";
	
	// Create Printer DC	
	m_cDC.CreateDC(NULL, m_strPrinterName, NULL, NULL);	

	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CBIXOLONSampleProgramDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CBIXOLONSampleProgramDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CBIXOLONSampleProgramDlg::OnFontPrint() 
{
	// TODO: Add your control notification handler code here
    TEXTMETRIC tm;		
	int		nYpoint, nPosition;						//	Printing Vertical Position
	char	szFontName[32];					//	Device Font Name
	CString	strBuffer;						//	String Buffer
	CFont	cNewFont;
	CFont*	pcOldFont;	
	DOCINFO di;
	int		pointsize;

	//	Initialize Document Infomation Structure
	::ZeroMemory(&di, sizeof(DOCINFO));
	di.cbSize = sizeof(DOCINFO);
	di.lpszDocName = "Print Device Font";
	
    //	Start Document
	m_cDC.StartDoc(&di);	
    m_cDC.StartPage();
	
	memset(szFontName, 0, sizeof(szFontName));

	//	Get selected font devce name
	m_ctrlDeviceFontList.GetLBText(m_ctrlDeviceFontList.GetCurSel(), szFontName);

	//	Load Font
	pointsize = 10;
	if(strstr(szFontName,"x2"))
		{
		if(strstr(szFontName,"FontA"))
			pointsize = 19;
		else
			pointsize = 14;
		}
	else if(strstr(szFontName,"x4"))
		{
		if(strstr(szFontName,"FontA") || strstr(szFontName,"Korean"))
			pointsize = 40;
		else
			pointsize = 28;
		}
	else if(strstr(szFontName,"x8"))
		{
		if(strstr(szFontName,"FontA") || strstr(szFontName,"Korean"))
			pointsize = 80;
		else
			pointsize = 56;
		}

	LoadDeviceFont(&cNewFont, szFontName, &pcOldFont, pointsize);    

    m_cDC.GetTextMetrics(&tm);
	nYpoint = nPosition = 0;
	
	m_cDC.TextOut( 0, nYpoint, "Device Font Test" );	
	
	nYpoint += tm.tmHeight + tm.tmExternalLeading;
	nPosition += tm.tmHeight;
	strBuffer.Format("FontName: %s", szFontName);
	m_cDC.TextOut( 0, nYpoint, strBuffer);
	nYpoint += tm.tmHeight + tm.tmExternalLeading;
	nPosition += tm.tmHeight;
	
	if(strstr(szFontName,"Korean"))
		{
		strBuffer.Format("한글 디바이스 폰트 테스트");
		nYpoint += tm.tmHeight;
		m_cDC.TextOut( 0, nYpoint, strBuffer);	
		}
	else
		{
		strBuffer.Format("Device Font Test");
		nYpoint += tm.tmHeight;
		m_cDC.TextOut( 0, nYpoint, strBuffer);	
		}
	
	m_cDC.EndPage();
	m_cDC.EndDoc();   
	
	//	Unload Font
	UnloadDeviceFont(&cNewFont, &pcOldFont);
}

void CBIXOLONSampleProgramDlg::LoadDeviceFont(CFont* pNewFont, char* szFontName, CFont** pOldFont, int pointsize)
{
	// Create New Font
	int height;
	height = - MulDiv( pointsize, m_cDC.GetDeviceCaps( LOGPIXELSY ),72 );
	pNewFont->CreateFont(height, 0, 0, 0, FW_NORMAL, FALSE, FALSE,FALSE,
		DEFAULT_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, 
		FW_DONTCARE | FW_DONTCARE, szFontName);   
	
	//	Select New Font
	*(pOldFont) = (CFont*)m_cDC.SelectObject(pNewFont);	
}

void CBIXOLONSampleProgramDlg::UnloadDeviceFont(CFont* pNewFont, CFont** pOldFont)
{
	// Select Old Font
    m_cDC.SelectObject(pOldFont);
	pNewFont->DeleteObject();
	*(pOldFont) = NULL;
}

int CBIXOLONSampleProgramDlg::nNewPage( CFont* newFont, int nPosition )
{
	TEXTMETRIC tm;
	int nFontHeight = 0;
	int nPrinterPageHeight = m_cDC.GetDeviceCaps( VERTRES );
	m_cDC.GetTextMetrics(&tm);

	if(( nPosition + nFontHeight ) > nPrinterPageHeight )
		{
		m_cDC.EndPage();
		m_cDC.StartPage();
		m_cDC.SelectObject( newFont );
		nPosition = 0;
		}

	return nPosition;
}

void CBIXOLONSampleProgramDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here
	m_cDC.DeleteDC();
}

void CBIXOLONSampleProgramDlg::OnPartialCut() 
{
	// TODO: Add your control notification handler code here
	TEXTMETRIC tm;		
	int		nYpoint;	
	CString	strBuffer;
	CFont	cNewFont;
	CFont*	pcOldFont;
	
	DOCINFO di;
	::ZeroMemory(&di, sizeof(DOCINFO));
	di.cbSize = sizeof(DOCINFO);
	di.lpszDocName = "Partial Cut";
	
	//	Load Font
	LoadDeviceFont(&cNewFont, "FontControl", &pcOldFont, 0);    
	
    // Title Print out
	m_cDC.GetTextMetrics(&tm);
	nYpoint = 0;
	m_cDC.StartDoc(&di);	
    m_cDC.StartPage();	
	
	strBuffer.Format("P");
	m_cDC.TextOut( 0, nYpoint, strBuffer);	
	
	m_cDC.EndPage();
	m_cDC.EndDoc();   
	
	//	Unload Font
	UnloadDeviceFont(&cNewFont, &pcOldFont);	
}

void CBIXOLONSampleProgramDlg::OnPartialCutWithoutFeeding() 
{
	// TODO: Add your control notification handler code here
	TEXTMETRIC tm;		
	int		nYpoint;						//	Printing Vertical Position	
	CString	strBuffer;						//	String Buffer
	CFont	cNewFont;
	CFont*	pcOldFont;
	DOCINFO di;

	//	Initialize Document Infomation Structure
	::ZeroMemory(&di, sizeof(DOCINFO));
	di.cbSize = sizeof(DOCINFO);
	di.lpszDocName = "Partial Cut";
	
	//	Load Font
	LoadDeviceFont(&cNewFont, "FontControl", &pcOldFont, 0);    
	
    // Title Print out
	m_cDC.GetTextMetrics(&tm);
	nYpoint = 0;
	m_cDC.StartDoc(&di);	
    m_cDC.StartPage();	
	
	strBuffer.Format("g");
	m_cDC.TextOut( 0, nYpoint, strBuffer);	
	
	//	End Page
	m_cDC.EndPage();

	//	End Document
	m_cDC.EndDoc();   
	
	//	Unload Font
	UnloadDeviceFont(&cNewFont, &pcOldFont);	
}

void CBIXOLONSampleProgramDlg::OnPrintReceipt() 
{
	// TODO: Add your control notification handler code here
	TEXTMETRIC tm;		
	int			nYpoint;	
	CString		strBuffer;
	CFont		cNewFont;
	CFont		*pcOldFont;
	
	DOCINFO di;
	::ZeroMemory(&di, sizeof(DOCINFO));
	di.cbSize = sizeof(DOCINFO);
	di.lpszDocName = "Print Receipt";
	
	//	Get Text Metrics
	m_cDC.GetTextMetrics(&tm);
	nYpoint = 0;
    
	//	Start Document
	m_cDC.StartDoc(&di);	
	//	Start Page
	m_cDC.StartPage();	
	
	LoadDeviceFont(&cNewFont, "FontControl", &pcOldFont, 0);	//	Select FontControl
	strBuffer.Format("x");
	nYpoint += tm.tmHeight;
	m_cDC.TextOut( 0, nYpoint, strBuffer);		
	UnloadDeviceFont(&cNewFont, &pcOldFont);				//	Unselect

	LoadDeviceFont(&cNewFont, "Korean2x1", &pcOldFont, 0);		//	Select FontA2x1
	strBuffer.Format("* 희나리 Cafe *");
	nYpoint += tm.tmHeight;
	m_cDC.TextOut( 0, nYpoint, strBuffer);	
	UnloadDeviceFont(&cNewFont, &pcOldFont);				//	Unselect

	LoadDeviceFont(&cNewFont, "Korean1x1", &pcOldFont, 0);		//	Select FontA1x1    
	nYpoint += (tm.tmHeight)*2;
	//strBuffer = "3000 Spring Street, Rancho,";
	strBuffer = "경기도 수원시 영통구";
	m_cDC.TextOut( 0, nYpoint, strBuffer);
	
	nYpoint += (tm.tmHeight);
	strBuffer = "원천동 332-2";	
	m_cDC.TextOut( 0, nYpoint, strBuffer);
	
	nYpoint += (tm.tmHeight);
	strBuffer = "Tel) 858-519-3698 Fax) 3852";	
	m_cDC.TextOut( 0, nYpoint, strBuffer);
	////////////////////////////////////////////////
	UnloadDeviceFont(&cNewFont, &pcOldFont);				//	Unselect
	
	LoadDeviceFont(&cNewFont, "FontControl", &pcOldFont, 0);	//	Select FontControl
	strBuffer.Format("w");
	nYpoint += tm.tmHeight;
	m_cDC.TextOut( 0, nYpoint, strBuffer);		
	UnloadDeviceFont(&cNewFont, &pcOldFont);				//	Unselect

	LoadDeviceFont(&cNewFont, "Korean1x1", &pcOldFont, 0);		//	Select FontA1x1    
	////////////////////////////////////////////////
	//nYpoint += (tm.tmHeight)*2;
	nYpoint += tm.tmHeight;
	strBuffer = "------------------------------------------";	
	m_cDC.TextOut( 0, nYpoint, strBuffer);
	
	nYpoint += (tm.tmHeight);
	strBuffer = "오렌지 쥬스                         3,500\\";
	m_cDC.TextOut( 0, nYpoint, strBuffer);

	nYpoint += tm.tmHeight;
	strBuffer = "6 Bufalo Wing                       3,000\\";	
	m_cDC.TextOut( 0, nYpoint, strBuffer);

	nYpoint += (tm.tmHeight);
	strBuffer = "감자 튀김                           1,200\\";
	m_cDC.TextOut( 0, nYpoint, strBuffer);

	nYpoint += (tm.tmHeight);
	strBuffer = "------------------------------------------";	
	m_cDC.TextOut( 0, nYpoint, strBuffer);

	nYpoint += (tm.tmHeight);		
	m_cDC.SetTextColor(RGB(255,0,0));					//	Select Red Color
	strBuffer = "총 액                               7,700\\";
	m_cDC.TextOut( 0, nYpoint, strBuffer);

	nYpoint += (tm.tmHeight);	
	m_cDC.SetTextColor(RGB(0,0,0));						//	Select Black Color
	strBuffer = "Tax 6%                                470\\";
	m_cDC.TextOut( 0, nYpoint, strBuffer);

	nYpoint += (tm.tmHeight);
	m_cDC.SetTextColor(RGB(255,0,0));					//	Select Red Color
	strBuffer = "Member Discount                       900\\";
	m_cDC.TextOut( 0, nYpoint, strBuffer);

	nYpoint += (tm.tmHeight);
	m_cDC.SetTextColor(RGB(0,0,0));						//	Select Black Color
	strBuffer = "받은 돈                            10,000\\";
	m_cDC.TextOut( 0, nYpoint, strBuffer);

	nYpoint += (tm.tmHeight);
	m_cDC.SetTextColor(RGB(255,0,0));					//	Select Red Color
	strBuffer = "거스름돈                            2,730\\";
	m_cDC.TextOut( 0, nYpoint, strBuffer);

	nYpoint += (tm.tmHeight);
	m_cDC.SetTextColor(RGB(0,0,0));						//	Select Black Color
	strBuffer = "------------------------------------------";	
	m_cDC.TextOut( 0, nYpoint, strBuffer);

	////////////////////////////////////////////////
	UnloadDeviceFont(&cNewFont, &pcOldFont);				//	Unselect
	
	LoadDeviceFont(&cNewFont, "FontControl", &pcOldFont, 0);	//	Select FontControl
	strBuffer.Format("x");
	nYpoint += tm.tmHeight;
	m_cDC.TextOut( 0, nYpoint, strBuffer);		
	UnloadDeviceFont(&cNewFont, &pcOldFont);				//	Unselect

	LoadDeviceFont(&cNewFont, "Code128", &pcOldFont, 0);	//	Select FontControl
	strBuffer.Format("{A12235884584645");
	nYpoint += tm.tmHeight;
	m_cDC.TextOut( 0, nYpoint, strBuffer);		
	UnloadDeviceFont(&cNewFont, &pcOldFont);				//	Unselect

	LoadDeviceFont(&cNewFont, "Korean1x1", &pcOldFont, 0);		//	Select FontA1x1    
	////////////////////////////////////////////////
	//nYpoint += (tm.tmHeight)*2;
	nYpoint += tm.tmHeight;
	strBuffer = "Member Number : 452331949";	
	m_cDC.TextOut( 0, nYpoint, strBuffer);	

	nYpoint += (tm.tmHeight)*2;		
	strBuffer = "좋은 하루 되세요!";	
	m_cDC.TextOut( 0, nYpoint, strBuffer);

	nYpoint += (tm.tmHeight)*2;		
	strBuffer = "Sale Date: 07/01/03";	
	m_cDC.TextOut( 0, nYpoint, strBuffer);

	nYpoint += tm.tmHeight;		
	strBuffer = "Time: 12:30:45";	
	m_cDC.TextOut( 0, nYpoint, strBuffer);

	UnloadDeviceFont(&cNewFont, &pcOldFont);				//	Unselect		
	
	nYpoint += (tm.tmHeight)*2;
	nYpoint += LoadBitmap("Free.bmp", nYpoint);	

	//	End Page
	m_cDC.EndPage();

	//	End Document
	m_cDC.EndDoc();   
}

int CBIXOLONSampleProgramDlg::LoadBitmap(CString bitmapFile, int yPoint)
{
	LPBYTE		lpImage = NULL;				// starting address of DIB bits
	LPBITMAPINFOHEADER lpBMIH = NULL;		// buffer containing the BITMAPINFOHEADER
	HANDLE hFile = NULL;					// handle to the bitmap file
	HANDLE hMap = NULL;					// handle to the map
	LPVOID lpvFile = NULL;				// address of the file in memory

	//	Draw Bitmap
	
	// open the bitmap file
	hFile = ::CreateFile(bitmapFile, GENERIC_WRITE | GENERIC_READ,
		FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	
	if (hFile == INVALID_HANDLE_VALUE){
		AfxMessageBox("Error open bitmap file", MB_OK );
		return 0;
	}
	
	hMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
	lpvFile = ::MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0); // map whole file
	
	LPVOID lpvMem = (LPBYTE)lpvFile + sizeof(BITMAPFILEHEADER);
	lpBMIH = (LPBITMAPINFOHEADER)lpvMem;
	
	// address of the bitmap image
	lpImage = (LPBYTE)lpvFile + ((LPBITMAPFILEHEADER)lpvFile)->bfOffBits ;
	
	CClientDC dc(this);		// screen device context
	// get twips per pixel
	float screenTwipsPerPixelX = (float)1440 / dc.GetDeviceCaps( LOGPIXELSX );
	float screenTwipsPerPixelY = (float)1440 / dc.GetDeviceCaps( LOGPIXELSY );
	float printerTwipsPerPixelX = (float)1440 / m_cDC.GetDeviceCaps( LOGPIXELSX );
	float printerTwipsPerPixelY = (float)1440 / m_cDC.GetDeviceCaps( LOGPIXELSY );
	
	// get dimensions of bitmap in printer units
	long PrinterWidth = (long)(lpBMIH->biWidth * screenTwipsPerPixelX / 
		printerTwipsPerPixelX);
	long PrinterHeight = (long)(lpBMIH->biHeight * screenTwipsPerPixelY / 
		printerTwipsPerPixelY);
	
	// set stretch mode and ouput the bitmap
	m_cDC.SetStretchBltMode(COLORONCOLOR);	
	::StretchDIBits(m_cDC.GetSafeHdc(), 0, yPoint, PrinterWidth,
		PrinterHeight, 0, 0, lpBMIH->biWidth,
		lpBMIH->biHeight, lpImage, (LPBITMAPINFO) lpBMIH,
		DIB_RGB_COLORS, SRCCOPY);
	
	::UnmapViewOfFile(lpvFile);
	::CloseHandle(hMap);
	::CloseHandle(hFile);
	
	return PrinterHeight;
}

void CBIXOLONSampleProgramDlg::OnOpenCashDraw() 
{
	// TODO: Add your control notification handler code here
	CString	strBuffer;
	CFont	cNewFont;
	CFont*	pcOldFont;
	
	DOCINFO di;
	::ZeroMemory(&di, sizeof(DOCINFO));
	di.cbSize = sizeof(DOCINFO);
	di.lpszDocName = "Open Cash Draw";
	
	//	Load Font
	LoadDeviceFont(&cNewFont, "FontControl", &pcOldFont, 0);    
	
	m_cDC.StartDoc(&di);	
	m_cDC.StartPage();	
	
	UpdateData(TRUE);

	if(m_nDrawNumber == CASH_DRAW_1)
	{
		switch(m_ctrlCashDrawSpeed.GetCurSel()) {
		case 0:
			strBuffer.Format("A");
			break;
		case 1:
			strBuffer.Format("B");	
			break;
		case 2:
			strBuffer.Format("C");
			break;
		case 3:
			strBuffer.Format("D");
			break;
		case 4:
			strBuffer.Format("E");
			break;	
		}
	}

	else if(m_nDrawNumber == CASH_DRAW_2)
	{
		switch(m_ctrlCashDrawSpeed.GetCurSel()) {
		case SPEED_50MS:
			strBuffer.Format("a");
			break;
		case SPEED_100MS:
			strBuffer.Format("b");	
			break;
		case SPEED_150MS:
			strBuffer.Format("c");
			break;
		case SPEED_200MS:
			strBuffer.Format("d");
			break;
		case SPEED_250MS:
			strBuffer.Format("e");
			break;	
		}
	}	
	
	m_cDC.TextOut( 0, 0, strBuffer);		
	m_cDC.EndPage();
	m_cDC.EndDoc();   
	
	//	Unload Font
	UnloadDeviceFont(&cNewFont, &pcOldFont);		
		}
