////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2008-2016 HiTi Digital, Inc.  All Rights Reserved.
//
// Revision: 1.7.11.1100
// Date    : 2016.02.03
//
////////////////////////////////////////////////////////////////////////////////
// Demo1Dlg.cpp : implementation file
//

#include "stdafx.h"
#include "Demo1.h"
#include "Demo1Dlg.h"

#include "DlgPasswd.h"
#include "DlgSecurityMode.h"

//for printer
#include <winspool.h>
#include <setupapi.h>
#include "PavoApi.h"

//for smart card
#include <Winscard.h>
#include <Winsmcrd.h>
#include "AlcorEMV.h"

//for RFID
#include "6801000.h"

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

typedef int (__stdcall *_YLE402S_GetCardNo)(char *InStr, char *RcStr);
#define YLE402S_OK              0       /* 操作成功       */
#define YLE402S_ERROR           -1      /* 操作错误       */
#define YLE402S_ERRPARAMETER    -2      /* 错误的调用参数 */
#define YLE402S_EMPTYDATA       -3      /* 空的输入缓冲区 */

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
LONG __stdcall ReadDataFromSLE4428_CS2xx(TCHAR* lpReaderName, BYTE* lpData, int nStartAddr, DWORD dwDataLen)
{
	SCARDCONTEXT		ScardContext = 0;
	SCARD_READERSTATE	ScardReaderState = {0};
	SCARDHANDLE			ScardHandle = 0;
	SCARD_IO_REQUEST	ScardIoRequest = {0};
	DWORD				dwScardProtocol = 0;
	LONG				lResult = 0;

	//TCHAR				lpszReaderName[1024] = {0};
	//DWORD				dwReaderNameLength = 0;
	//DWORD				dwReadersNum = 0;

	bool				bRet = true;
	long				i = 0, k = 0;
	TCHAR				szError[256] = {0};
	DWORD				dwRead = 0;

	//2012.07.04
	BYTE				*lpTmp = 0;
	LONG				nReadRemain = 0,
						nAddr = 0,
						nReadOneTime = 0,
						nReadTotal = 0;

	//1. establishes the SmartCard's context
	lResult = SCardEstablishContext(SCARD_SCOPE_USER,
									NULL,
									NULL,
									&ScardContext);

	if ( lResult != SCARD_S_SUCCESS )
	{
		_stprintf(szError, _T("SCardEstablishContext() fail.\n\nError = 0x%08X"), lResult);
		//MessageBox(0, szError, _T("Error!"), MB_OK);
		return lResult;
	}

	//2. check if there is card in reader
	ScardReaderState.szReader = lpReaderName;
	lResult = SCardGetStatusChange(ScardContext,
								INFINITE,
								&ScardReaderState,
								1);

	if ( lResult != SCARD_S_SUCCESS )
	{
		SCardReleaseContext(ScardContext);
		_stprintf(szError, _T("SCardGetStatusChange() fail.\n\nError = 0x%08X"), lResult);
		//MessageBox(0, szError, _T("Error!"), MB_OK);
		return lResult;
	}

	if ( !(ScardReaderState.dwEventState & SCARD_STATE_PRESENT) )
	{
		SCardReleaseContext(ScardContext);
		return SCARD_E_NO_SMARTCARD;//=0x8010000C
	}

	//3. conect to card
	lResult = SCardConnect(ScardContext,
						ScardReaderState.szReader,
						SCARD_SHARE_DIRECT,
						0,
						&ScardHandle,
						&dwScardProtocol);

	//TRACE(_T("In CICCard::ConnectCard(), after SCardConnect(2), result = 0x%08X, protocal = 0x%08X,\n"), result, m_dwScardProtocol[m_dwCurrentReader]);

	if ( SCARD_S_SUCCESS == lResult )
	{
	//switch card mode to SLE4428
	lResult = Alcor_SwitchCardMode(ScardHandle, 0, SYNCHRONOUS_CARD_SLE4428_MODE);

	lResult = SCardDisconnect(ScardHandle, SCARD_LEAVE_CARD);
	//TRACE(_T("In CICCard::ConnectCard(), after SCardDisconnect(2), result = %d,\n"), result);

	lResult = SCardConnect(ScardContext,
						ScardReaderState.szReader,
						SCARD_SHARE_SHARED,
						SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
						&ScardHandle,
						&dwScardProtocol);

	//TRACE(_T("In CICCard::ConnectCard(), after SCardConnect(3), result = 0x%08X, protocal = 0x%08X,\n"), result, m_dwScardProtocol[m_dwCurrentReader]);
	}

	if ( lResult != SCARD_S_SUCCESS )
	{
		SCardReleaseContext(ScardContext);
		_stprintf(szError, _T("SCardConnect() fail.\n\nError = 0x%08X"), lResult);
		//MessageBox(0, szError, _T("Error!"), MB_OK);
		return lResult;
	}

	//5. read data from card
/*	lResult = SLE4428Cmd_Read8Bits(ScardHandle,
									0,
									nStartAddr,
									dwDataLen,
									(BYTE*)lpData,
									&dwRead);

	if ( lResult != SCARD_S_SUCCESS )
	{
		_stprintf(szError, _T("SLE4428Cmd_Read8Bits() fail.\n\nError = 0x%08X"), lResult);
		//MessageBox(0, szError, _T("Error!"), MB_OK);
	}
*/
	//2012.07.04
	nReadRemain = dwDataLen;
	nAddr = nStartAddr;
	lpTmp = lpData;

	while ( nReadRemain > 0 )
	{
		if ( nReadRemain > 255 )
			nReadOneTime = 255;
		else
			nReadOneTime = nReadRemain;

		lResult = SLE4428Cmd_Read8Bits(ScardHandle,
									0,
									nAddr,
									nReadOneTime,
									(BYTE*)lpTmp,
									&dwRead);

		if ( lResult == 0 )
		{
			nAddr += dwRead;
			nReadRemain -= dwRead;
			lpTmp += dwRead;
			nReadTotal += dwRead;
		}
		else if ( lResult != SCARD_S_SUCCESS )
		{
			_stprintf(szError, _T("SLE4428Cmd_Read8Bits() fail.\n\nError = 0x%08X"), lResult);
			//MessageBox(0, szError, _T("Error!"), MB_OK);
			break;
		}
	}

	SCardDisconnect(ScardHandle, SCARD_EJECT_CARD);
	SCardReleaseContext(ScardContext);

	return lResult;
}


//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
LONG __stdcall WriteDataToSLE4428_CS2xx(TCHAR* lpReaderName, BYTE* lpData, int nStartAddr, DWORD dwDataLen)
{
	SCARDCONTEXT		ScardContext = 0;
	SCARD_READERSTATE	ScardReaderState = {0};
	SCARDHANDLE			ScardHandle = 0;
	SCARD_IO_REQUEST	ScardIoRequest = {0};
	DWORD				dwScardProtocol = 0;
	LONG				lResult = 0;

	bool				bRet = true;
	BYTE				lpRead[1024] = {0};
	DWORD				dwRead = 0;
	long				i = 0, k = 0;
	TCHAR				szError[256] = {0};

	BYTE				byErrorCount = 0;
	BYTE				byProtectBits = 0;

	BYTE				flagNeedWrite[1024] = {0};//2012.07.03

	//2012.07.04
	BYTE				*lpTmp = 0;
	LONG				nReadRemain = 0,
						nAddr = 0,
						nReadOneTime = 0,
						nReadTotal = 0;

	//1. establishes the SmartCard's context
	lResult = SCardEstablishContext(SCARD_SCOPE_USER,
									NULL,
									NULL,
									&ScardContext);

	if ( lResult != SCARD_S_SUCCESS )
	{
		_stprintf(szError, _T("SCardEstablishContext() fail.\n\nError = 0x%08X"), lResult);
		//MessageBox(0, szError, _T("Error!"), MB_OK);
		return lResult;
	}

	//2. check if there is card in reader
	ScardReaderState.szReader = lpReaderName;
	lResult = SCardGetStatusChange(ScardContext,
								INFINITE,
								&ScardReaderState,
								1);

	if ( lResult != SCARD_S_SUCCESS )
	{
		SCardReleaseContext(ScardContext);
		_stprintf(szError, _T("SCardGetStatusChange() fail.\n\nError = 0x%08X"), lResult);
		//MessageBox(0, szError, _T("Error!"), MB_OK);
		return lResult;
	}

	if ( !(ScardReaderState.dwEventState & SCARD_STATE_PRESENT) )
	{
		SCardReleaseContext(ScardContext);
		return SCARD_E_NO_SMARTCARD;//=0x8010000C
	}

	//3. conect to card
	lResult = SCardConnect(ScardContext,
						ScardReaderState.szReader,
						SCARD_SHARE_DIRECT,
						0,
						&ScardHandle,
						&dwScardProtocol);

	//4. switch card mode to SLE4428
	if ( SCARD_S_SUCCESS == lResult )
	{
		lResult = Alcor_SwitchCardMode(ScardHandle, 0, SYNCHRONOUS_CARD_SLE4428_MODE);

		lResult = SCardDisconnect(ScardHandle, SCARD_LEAVE_CARD);

		lResult = SCardConnect(ScardContext,
							ScardReaderState.szReader,
							SCARD_SHARE_SHARED,
							SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
							&ScardHandle,
							&dwScardProtocol);
	}


	if ( lResult != SCARD_S_SUCCESS )
	{
		SCardReleaseContext(ScardContext);
		_stprintf(szError, _T("SCardConnect() fail.\n\nError = 0x%08X"), lResult);
		//MessageBox(0, szError, _T("Error!"), MB_OK);
		return lResult;
	}

	//5. read old data from card
/*
	lResult = SLE4428Cmd_Read8Bits(ScardHandle,
									0,
									nStartAddr,
									dwDataLen,
									(BYTE*)lpRead,
									&dwRead);

	if ( lResult != SCARD_S_SUCCESS )
	{
		SCardDisconnect(ScardHandle, SCARD_EJECT_CARD);
		SCardReleaseContext(ScardContext);
		_stprintf(szError, _T("SLE4428Cmd_Read8Bits() fail.\n\nError = 0x%08X"), lResult);
		//MessageBox(0, szError, _T("Error!"), MB_OK);
		return lResult;
	}
*/
	//2012.07.04
	nReadRemain = dwDataLen;
	nAddr = nStartAddr;
	lpTmp = lpRead;

	while ( nReadRemain > 0 )
	{
		if ( nReadRemain > 255 )
			nReadOneTime = 255;
		else
			nReadOneTime = nReadRemain;

		lResult = SLE4428Cmd_Read8Bits(ScardHandle,
									0,
									nAddr,
									nReadOneTime,
									(BYTE*)lpTmp,
									&dwRead);

		if ( lResult == 0 )
		{
			nAddr += dwRead;
			nReadRemain -= dwRead;
			lpTmp += dwRead;
			nReadTotal += dwRead;
		}
		else if ( lResult != SCARD_S_SUCCESS )
		{
			SCardDisconnect(ScardHandle, SCARD_EJECT_CARD);
			SCardReleaseContext(ScardContext);
			_stprintf(szError, _T("SLE4428Cmd_Read8Bits() fail.\n\nError = 0x%08X"), lResult);
			//MessageBox(0, szError, _T("Error!"), MB_OK);
			return lResult;
		}
	}

	//2012.07.03
	//Check if old data on card is same as data to write.
	//If data to write is same as old data, don't write it again.
	//Otherwise SLE4428Cmd_WriteEraseWithoutPB() will return error 0x80100004.
	for(i=0;i<dwDataLen;i++)
	{
		if ( lpRead[i] != lpData[i] )
		{
			flagNeedWrite[i] = 1;
		}
	}

	//6. read error count from card
	lResult = SLE4428Cmd_Read9Bits(ScardHandle,
									0,
									1021,
									1,
									(BYTE*)&byErrorCount,
									(BYTE*)&byProtectBits,
									&dwRead);

	byErrorCount <<= 1;
	lResult = SLE4428Cmd_WriteErrorCounter(ScardHandle,
									0,
									byErrorCount);

	//7. verify
	lResult = SLE4428Cmd_Verify1stPSC(ScardHandle, 0, 0xFF);
	lResult = SLE4428Cmd_Verify2ndPSC(ScardHandle, 0, 0xFF);

	//erase error counter
	byErrorCount = 0xFF;
	lResult = SLE4428Cmd_WriteEraseWithoutPB(ScardHandle,
											0,
											1021,
											(BYTE)byErrorCount);

	if ( lResult != SCARD_S_SUCCESS )
	{
		SCardDisconnect(ScardHandle, SCARD_EJECT_CARD);
		SCardReleaseContext(ScardContext);
		_stprintf(szError, _T("SLE4428Cmd_Verify2ndPSC() fail.\n\nError = 0x%08X"), lResult);
		//MessageBox(0, szError, _T("Error!"), MB_OK);
		return lResult;
	}

	//8. write data to card
	for(i=nStartAddr,k=0;i<nStartAddr+dwDataLen;i++,k++)
	{
		if ( flagNeedWrite[k] == 1 )//2012.07.03
		{
		lResult = SLE4428Cmd_WriteEraseWithoutPB(ScardHandle,
												0,
												i,
												(BYTE)lpData[k]);

		if ( lResult != SCARD_S_SUCCESS )
		{
			SCardDisconnect(ScardHandle, SCARD_EJECT_CARD);
			SCardReleaseContext(ScardContext);
			_stprintf(szError, _T("SLE4428Cmd_WriteEraseWithPB() fail.\n\nError = 0x%08X"), lResult);
			//MessageBox(0, szError, _T("Error!"), MB_OK);
			return lResult;
		}
		}
	}

	//9. read data from card again to verify result
	memset(lpRead, 0, 1024);
	/*
	lResult = SLE4428Cmd_Read8Bits(ScardHandle,
									0,
									nStartAddr,
									dwDataLen,
									(BYTE*)lpRead,
									&dwRead);
	*/

	//2012.07.04
	nReadRemain = dwDataLen;
	nAddr = nStartAddr;
	lpTmp = lpRead;
	nReadTotal = 0;

	while ( nReadRemain > 0 )
	{
		if ( nReadRemain > 255 )
			nReadOneTime = 255;
		else
			nReadOneTime = nReadRemain;

		lResult = SLE4428Cmd_Read8Bits(ScardHandle,
									0,
									nAddr,
									nReadOneTime,
									(BYTE*)lpTmp,
									&dwRead);

		if ( lResult == 0 )
		{
			nAddr += dwRead;
			nReadRemain -= dwRead;
			lpTmp += dwRead;
			nReadTotal += dwRead;
		}
		else if ( lResult != SCARD_S_SUCCESS )
		{
			break;
		}
	}


	if ( lResult != SCARD_S_SUCCESS )
	{
		_stprintf(szError, _T("SLE4428Cmd_Read8Bits() fail.\n\nError = 0x%08X"), lResult);
		//MessageBox(0, szError, _T("Error!"), MB_OK);
	}
	else
	{
		bRet = true;
		for(i=0;i<dwDataLen;i++)
		{
			if ( lpData[i] != lpRead[i] )
			{
				bRet = false;
				break;
			}
		}

		//TRACE(_T("In WriteDataToSLE4428_CS2xx(4), compare result = %d,\n"), bRet);

		if ( !bRet )
			lResult = 30;//=ERROR_READ_FAULT
	}

	SCardDisconnect(ScardHandle, SCARD_EJECT_CARD);
	SCardReleaseContext(ScardContext);

	return lResult;
}



//
static DWORD SUPPORT_MODELS[] =
{
	0x0D160309,		//HiTi CS-200e
	0x0D16030A,		//HiTi CS-220e
	0x0D16030B,		//HiTi CS-230e
	0x0D16030C,		//HiTi CS-250e //2016.08.08 added by Bill
	0x0D16030D,		//HiTi CS-290e //2017.04.06 added by Bill
	0x0D16A302,		//Fagoo P280E
	0
};



BOOL EnumUSBDevice(HWND hComboBox, IN HDEVINFO HardwareDeviceInfo, IN PSP_INTERFACE_DEVICE_DATA InterfaceInfoData, IN PSP_DEVINFO_DATA DeviceInfoData, DWORD dwVidPid)
{
	ULONG				ulRequiredLength = 0;
	ULONG				ulPredictedLength = 0;
	BOOL				bOK = FALSE;
	BOOL				bRet = FALSE;

	TCHAR				szVidPid[32] = {0};

	DWORD				dwLastError = 0;

	PSP_INTERFACE_DEVICE_DETAIL_DATA	interfaceDetailData = 0;

	TCHAR				szDeviceID[MAX_PATH] = {0};
	DWORD				dwDeviceIDSize = 0;
	TCHAR				szDeviceDESC[MAX_PATH] = {0};
	DWORD				dwDeviceDESCSize = 0;
	TCHAR				szDEVID[MAX_PATH] = {0};


	_stprintf(szVidPid, _T("vid_%04x&pid_%04x"), HIWORD(dwVidPid), LOWORD(dwVidPid));

	bRet = SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo, InterfaceInfoData, NULL, 0, &ulRequiredLength, NULL);
	if ( ulRequiredLength == 0 )
		return FALSE;

	ulPredictedLength		= ulRequiredLength;

	interfaceDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc(ulPredictedLength);
	if ( interfaceDetailData == NULL )
	{
		::SetLastError(ERROR_NOT_ENOUGH_MEMORY);
		return FALSE;
	}

	interfaceDetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
	bRet = SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo, InterfaceInfoData, interfaceDetailData, ulPredictedLength, &ulRequiredLength, NULL);
	if ( bRet )
	{
		//get hardware ID
		bRet = SetupDiGetDeviceRegistryProperty(HardwareDeviceInfo, DeviceInfoData, SPDRP_HARDWAREID, NULL, (unsigned char*)szDeviceID, MAX_PATH*sizeof(TCHAR), &dwDeviceIDSize);
		if ( bRet )
		{
			bRet = SetupDiGetDeviceRegistryProperty(HardwareDeviceInfo, DeviceInfoData, SPDRP_DEVICEDESC, NULL, (unsigned char*)szDeviceDESC, MAX_PATH*sizeof(TCHAR), &dwDeviceDESCSize);
			if ( bRet )
			{
				lstrcpy(szDEVID, szDeviceID);
				_tcslwr(szDEVID);

				if ( _tcsstr(szDEVID,szVidPid) != NULL )
				{
					::SendMessage(hComboBox, CB_ADDSTRING, NULL, (LPARAM)interfaceDetailData->DevicePath);
				}
				bOK = TRUE;
			}
			else
			{
				dwLastError = ::GetLastError();
			}
		}
		else
		{
			dwLastError = ::GetLastError();
		}
	}
	else
	{
		dwLastError = ::GetLastError();
	}

	free(interfaceDetailData);
	::SetLastError(dwLastError);

	return bOK;
}


BOOL EnumUSBPrinters(HWND hComboBox)
{
	BOOL						bResult = FALSE;
	HDEVINFO					hardwareDeviceInfo = 0;
	SP_INTERFACE_DEVICE_DATA	interfaceInfoData = {0};
	SP_DEVINFO_DATA				deviceInfo = {0};
	DWORD						dwIndex = 0;
	DWORD						dwDev = 0;
	HANDLE						hDev = INVALID_HANDLE_VALUE;
	GUID						UsbprintGuid;//{28D78FAD-5A12-11D1-AE5B-0000F803A8C2}

	int							i = 0;
	DWORD						dwLastError = 0;

	if ( hComboBox == NULL )
	{
		return(FALSE);
	}

	UsbprintGuid.Data1	 = 0x28D78FAD;
	UsbprintGuid.Data2	 = 0x5A12;
	UsbprintGuid.Data3	 = 0x11D1;
	UsbprintGuid.Data4[0]= 0xAE;
	UsbprintGuid.Data4[1]= 0x5B;
	UsbprintGuid.Data4[2]= 0x00;
	UsbprintGuid.Data4[3]= 0x00;
	UsbprintGuid.Data4[4]= 0xF8;
	UsbprintGuid.Data4[5]= 0x03;
	UsbprintGuid.Data4[6]= 0xA8;
	UsbprintGuid.Data4[7]= 0xC2;

	interfaceInfoData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
	deviceInfo.cbSize		 = sizeof(SP_DEVINFO_DATA);

	hardwareDeviceInfo = SetupDiGetClassDevs((LPGUID)&UsbprintGuid, NULL, NULL, (DIGCF_PRESENT|DIGCF_INTERFACEDEVICE));

	bResult = (INVALID_HANDLE_VALUE != hardwareDeviceInfo);

	dwDev = 0;
	while ( bResult && SetupDiEnumDeviceInfo(hardwareDeviceInfo, dwDev, &deviceInfo) )
	{
		dwIndex = 0;
		while ( bResult && SetupDiEnumDeviceInterfaces(hardwareDeviceInfo, &deviceInfo, (LPGUID)&UsbprintGuid, dwIndex, &interfaceInfoData) )
		{
			bResult = FALSE;
			for(i=0;;i++)
			{
				if ( SUPPORT_MODELS[i] == 0 )
					break;

				bResult = EnumUSBDevice(hComboBox, hardwareDeviceInfo, &interfaceInfoData, &deviceInfo, SUPPORT_MODELS[i]);
			}

			if ( !bResult )
			{
				dwLastError = ::GetLastError();

				SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);

				::SetLastError(dwLastError);
				return(FALSE);
			}
			++dwIndex;
		}

		++dwDev;
	}

	SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);

	return(TRUE);
}

#define MAX_READER_NUMBER   	10

BOOL EnumScardReaders(HWND hComboBox)
{
	BOOL				bRet = FALSE;
	LONG				result = 0;

	SCARDCONTEXT		hScardContext = 0;

	LPTSTR				lpszReaderName = 0;
	DWORD				dwReaderNameLength = 0;
	DWORD				dwReadersNum = 0;

	LPTSTR				readerName = 0;

	result = SCardEstablishContext(SCARD_SCOPE_USER,
									NULL,
									NULL,
									&hScardContext);

	if ( result != SCARD_S_SUCCESS )
	{
		//MessageBox(0, _T("Establish Context Fail!"), _T("EnumScardReaders"), MB_OK|MB_ICONERROR);
		return FALSE;
	}

	// Find out dwReaderNameLength
	result = SCardListReaders(hScardContext, NULL, NULL, &dwReaderNameLength);

	TRACE(_T("In CICCard::Initialize(), after SCardListReaders(1) result = %d,\n"), result);

	if ( result != SCARD_S_SUCCESS )
	{
		//MessageBox(0, _T("Can not find any card reader!"), _T("EnumScardReaders"), MB_OK|MB_ICONERROR);
		return FALSE;
	}

	// Allcoate Memory for lpszReaderName
	lpszReaderName = (LPTSTR) new TCHAR[dwReaderNameLength+12];
	memset(lpszReaderName, 0, sizeof(TCHAR)*dwReaderNameLength+12);

	// List Reader Name
	result = SCardListReaders(hScardContext,
								NULL,
								lpszReaderName,
								&dwReaderNameLength);

	if ( result == SCARD_S_SUCCESS )
	{
		dwReadersNum = 0;
		readerName = lpszReaderName;

		while ( (*readerName != '\0') && (dwReadersNum < MAX_READER_NUMBER) )
		{
			::SendMessage(hComboBox, CB_ADDSTRING, NULL, (LPARAM)readerName);

			dwReadersNum++;
			readerName += lstrlen(readerName) + 1;
		}

		bRet = TRUE;
	}
	else
	{
		//MessageBox(0, _T("Can not find any card reader!"), _T("EnumScardReaders"), MB_OK|MB_ICONERROR);
		bRet = FALSE;
	}

	SCardReleaseContext(hScardContext);

	delete [] lpszReaderName;

	return bRet;
}

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)

	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDemo1Dlg dialog

CDemo1Dlg::CDemo1Dlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDemo1Dlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDemo1Dlg)
	m_bT1 = FALSE;
	m_bT2 = FALSE;
	m_bT3 = FALSE;
	m_bFlag1 = FALSE;
	m_bFlag2 = FALSE;
	m_bFlag3 = FALSE;
	m_nRibbonType = 0;
	m_nCardType = 0;
	m_Bmp24Name = _T("../../1014x642_bgr.bmp");
	m_T1 = _T("");
	m_T2 = _T("");
	m_T3 = _T("");
	m_nCoercivity = 1;
	m_bFlag4 = FALSE;
	m_bShowStep = FALSE;
	m_nLoop = 1;
	m_Bmp24Name2 =  _T("../../1014x642_bgr2.bmp");
	m_BmpOName = _T("../../1014x642_o.bmp");
	m_BmpKName = _T("../../1014x642_k.bmp");
	m_BmpKName2 = _T("../../1014x642_k2.bmp");
	m_BmpOName2 = _T("../../1014x642_o2.bmp");
	m_SymbolicLink = _T("");
	m_PrinterName = _T("");
	m_ScardReaderName = _T("");
	m_nConnectType = 1;
	m_nMoveCardPosition = -1;
	m_bY1 = TRUE;
	m_bY2 = FALSE;
	m_bK1 = TRUE;
	m_bK2 = FALSE;
	m_bO1 = TRUE;
	m_bO2 = FALSE;
	m_nRfidPort = -1;
	m_nOrientation = 1;
	m_nFrontSide = 3;
	m_nBackSide = 0;
	m_byStandbyPos = 0;
	m_byStandbyTime = 0;
	m_bFlag6 = FALSE;
	m_nInfoType = -1;
	m_bTransparentCard = FALSE;
	m_nCommand = -1;
	m_bF1 = FALSE;
	m_bF2 = FALSE;
	m_BmpFName = _T("../../1014x642_f.bmp");
	m_BmpFName2 = _T("../../1014x642_f2.bmp");
	m_bFlag5 = FALSE;
	m_nLeft = 100;
	m_nTop = 200;
	m_nRight = 600;
	m_nBottom = 500;
	m_bFlagNotOvercoat = FALSE;
	m_bCS290AsCS230 = FALSE;
	m_uiRetryDcm = 0;
	m_uiTimeOutDcm = 5;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	m_PrinterName = _T("");
	m_bCipherMode = FALSE;
}

void CDemo1Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDemo1Dlg)
	DDX_Control(pDX, IDC_STATIC_RF_SERIAL, m_StaticCardSerial);
	DDX_Control(pDX, IDC_COMBO_SCARD_READER, m_ComboScardReader);
	DDX_Control(pDX, IDC_COMBO_SYMLINK, m_ComboSymlink);
	DDX_Control(pDX, IDC_IPADDRESS1, m_IPaddr);
	DDX_Control(pDX, IDC_COMBO_PRINTER, m_ComboPrinter);
	DDX_Check(pDX, IDC_CHECK_T1, m_bT1);
	DDX_Check(pDX, IDC_CHECK_T2, m_bT2);
	DDX_Check(pDX, IDC_CHECK_T3, m_bT3);
	DDX_Check(pDX, IDC_CHECK_FLAG1, m_bFlag1);
	DDX_Check(pDX, IDC_CHECK_FLAG2, m_bFlag2);
	DDX_Check(pDX, IDC_CHECK_FLAG3, m_bFlag3);
	DDX_CBIndex(pDX, IDC_COMBO_RIBBON, m_nRibbonType);
	DDX_CBIndex(pDX, IDC_COMBO_CARD, m_nCardType);
	DDX_Text(pDX, IDC_EDIT_BMP_RGB_FRONT, m_Bmp24Name);
	DDX_Text(pDX, IDC_EDIT1, m_T1);
	DDX_Text(pDX, IDC_EDIT2, m_T2);
	DDX_Text(pDX, IDC_EDIT3, m_T3);
	DDX_Radio(pDX, IDC_RADIO3, m_nCoercivity);
	DDX_Check(pDX, IDC_CHECK_FLAG4, m_bFlag4);
	DDX_Check(pDX, IDC_CHECK_STEP, m_bShowStep);
	DDX_Text(pDX, IDC_EDIT_LOOP, m_nLoop);
	DDX_Text(pDX, IDC_EDIT_BMP_RGB_BACK, m_Bmp24Name2);
	DDX_Text(pDX, IDC_EDIT_BMP_O_FRONT, m_BmpOName);
	DDX_Text(pDX, IDC_EDIT_BMP_K_FRONT, m_BmpKName);
	DDX_Text(pDX, IDC_EDIT_BMP_K_BACK, m_BmpKName2);
	DDX_Text(pDX, IDC_EDIT_BMP_O_BACK, m_BmpOName2);
	DDX_CBString(pDX, IDC_COMBO_SYMLINK, m_SymbolicLink);
	DDX_CBString(pDX, IDC_COMBO_PRINTER, m_PrinterName);
	DDX_CBString(pDX, IDC_COMBO_SCARD_READER, m_ScardReaderName);
	DDX_Radio(pDX, IDC_RADIO5, m_nConnectType);
	DDX_CBIndex(pDX, IDC_COMBO_MOVE_CARD_POSITION, m_nMoveCardPosition);
	DDX_Check(pDX, IDC_CHECK_Y1, m_bY1);
	DDX_Check(pDX, IDC_CHECK_Y2, m_bY2);
	DDX_Check(pDX, IDC_CHECK_K1, m_bK1);
	DDX_Check(pDX, IDC_CHECK_K2, m_bK2);
	DDX_Check(pDX, IDC_CHECK_O1, m_bO1);
	DDX_Check(pDX, IDC_CHECK_O2, m_bO2);
	DDX_CBIndex(pDX, IDC_COMBO_RFID_PORT, m_nRfidPort);
	DDX_CBIndex(pDX, IDC_COMBO_ORIENTATION, m_nOrientation);
	DDX_CBIndex(pDX, IDC_COMBO_FRONT_SIDE, m_nFrontSide);
	DDX_CBIndex(pDX, IDC_COMBO_BACK_SIDE, m_nBackSide);
	DDX_Text(pDX, IDC_EDIT4, m_byStandbyPos);
	DDV_MinMaxByte(pDX, m_byStandbyPos, 0, 255);
	DDX_Text(pDX, IDC_EDIT5, m_byStandbyTime);
	DDV_MinMaxByte(pDX, m_byStandbyTime, 0, 255);
	DDX_Check(pDX, IDC_CHECK_FLAG6, m_bFlag6);
	DDX_CBIndex(pDX, IDC_COMBO_INFO_TYPE, m_nInfoType);
	DDX_Check(pDX, IDC_CHECK_TRANSPARENT_CARD, m_bTransparentCard);
	DDX_CBIndex(pDX, IDC_COMBO_COMMAND, m_nCommand);
	DDX_Check(pDX, IDC_CHECK_F1, m_bF1);
	DDX_Check(pDX, IDC_CHECK_F2, m_bF2);
	DDX_Text(pDX, IDC_EDIT_BMP_F_FRONT, m_BmpFName);
	DDX_Text(pDX, IDC_EDIT_BMP_F_BACK, m_BmpFName2);
	DDX_Check(pDX, IDC_CHECK_FLAG5, m_bFlag5);
	DDX_Text(pDX, IDC_EDIT_LEFT, m_nLeft);
	DDX_Text(pDX, IDC_EDIT_TOP, m_nTop);
	DDX_Text(pDX, IDC_EDIT_RIGHT, m_nRight);
	DDX_Text(pDX, IDC_EDIT_BOTTOM, m_nBottom);
	DDX_Check(pDX, IDC_CHECK_Overcoat, m_bFlagNotOvercoat);
	DDX_Check(pDX, IDC_CHECK_290AS230, m_bCS290AsCS230);
	DDX_Text(pDX, IDC_EDIT_RETRY_DCM, m_uiRetryDcm);
	DDV_MinMaxUInt(pDX, m_uiRetryDcm, 0, 255);
	DDX_Text(pDX, IDC_EDIT_TIMEOUT_DCM, m_uiTimeOutDcm);
	DDV_MinMaxUInt(pDX, m_uiTimeOutDcm, 1, 255);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CDemo1Dlg, CDialog)
	//{{AFX_MSG_MAP(CDemo1Dlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_CHECK_STATUS, OnBtnCheckStatus)
	ON_CBN_SELCHANGE(IDC_COMBO_PRINTER, OnSelchangeComboPrinter)
	ON_BN_CLICKED(IDC_BTN_GET_DEVICE_INFO, OnBtnGetDeviceInfo)
	ON_BN_CLICKED(IDC_BTN_SET_PASSWD, OnBtnSetPasswd)
	ON_BN_CLICKED(IDC_BTN_SET_SECURITY_MODE, OnBtnSetSecurityMode)
	ON_BN_CLICKED(IDC_BTN_MOVE_CARD, OnBtnMoveCard)
	ON_BN_CLICKED(IDC_BTN_READ_SLE4428, OnBtnReadSle4428)
	ON_BN_CLICKED(IDC_BTN_WRITE_SLE4428, OnBtnWriteSle4428)
	ON_BN_CLICKED(IDC_BTN_WRITE_MAG_TRACK_DATA, OnBtnWriteMagTrackData)
	ON_BN_CLICKED(IDC_BTN_READ_MAG_TRACK_DATA, OnBtnReadMagTrackData)
	ON_BN_CLICKED(IDC_BTN_DIRECT_PRINT, OnBtnDirectPrint)
	ON_BN_CLICKED(IDC_BTN_RFID_GET_CARD_SERIAL, OnBtnRfidGetCardSerial)
	ON_BN_CLICKED(IDC_BTN_PRINT_BY_DRIVER, OnBtnPrintByDriver)
	ON_BN_CLICKED(IDC_BTN_SET_STANDBY_PARAMETER, OnBtnSetStandbyParameter)
	ON_BN_CLICKED(IDC_BTN_DO_COMMAND, OnBtnDoCommand)
	ON_BN_CLICKED(IDC_BTN_SAVE_PRINTER_SETTING_TO_FILE, OnBtnSavePrinterSettingToFile)
	ON_BN_CLICKED(IDC_BTN_APPLY_PRINTER_SETTING_FROM_FILE, OnBtnApplyPrinterSettingFromFile)
	ON_BN_CLICKED(IDC_BTN_ERASE_CARD, OnBtnEraseCard)
	ON_BN_CLICKED(IDC_BTN_QUERY_IO, OnBtnQueryIOValue)
	ON_WM_SIZE()
	ON_WM_VSCROLL()
	ON_BN_CLICKED(IDC_CHECK_290AS230, OnCheck290As230)
	ON_BN_CLICKED(IDC_BUTTON_CS290eMODE1, OnBUTTONCS290eMODE1)
	ON_BN_CLICKED(IDC_BUTTON_CS290eMODE0, OnBUTTONCS290eMODE0)
	ON_BN_CLICKED(IDC_BTTN_DCM, OnBttnDcm)
	//}}AFX_MSG_MAP
	ON_COMMAND_RANGE(IDC_BTN_BMP_RGB_FRONT, IDC_BTN_BMP_F_BACK, OnSelectBmpFile)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDemo1Dlg message handlers

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

	GetWindowRect(m_rect);
	m_nScrollPos = 0;
	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 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
	EnumSupportedPrinters();
	if ( m_ComboPrinter.GetCount() > 0 )
		m_ComboPrinter.SetCurSel(0);

	EnumUSBPrinters(::GetDlgItem(GetSafeHwnd(), IDC_COMBO_SYMLINK));
	if ( m_ComboSymlink.GetCount() > 0 )
		m_ComboSymlink.SetCurSel(0);

	m_IPaddr.SetAddress(192, 168, 2, 127);

	EnumScardReaders(::GetDlgItem(GetSafeHwnd(), IDC_COMBO_SCARD_READER));
	if ( m_ComboScardReader.GetCount() > 0 )
		m_ComboScardReader.SetCurSel(0);

	UpdateData(FALSE);

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

void CDemo1Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// 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 CDemo1Dlg::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 CDemo1Dlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CDemo1Dlg::OnSelchangeComboPrinter()
{
	// TODO: Add your control notification handler code here
	int				i = 0;

	i = m_ComboPrinter.GetCurSel();
	m_ComboPrinter.GetLBText(i, m_PrinterName);
}

DWORD CDemo1Dlg::EnumSupportedPrinters()
{
	BOOL			bResult = FALSE;
	DWORD			i = 0,
					dwBuf = 0,
					dwNeeded = 0,
					dwPrinterNum = 0;
	BYTE			*lpBuf = NULL;

	DWORD			dwFlags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS;

	PRINTER_INFO_2	*lpPrinterInfo2 = NULL;


	bResult = EnumPrinters(dwFlags, NULL, 2, NULL, 0, &dwNeeded, &dwPrinterNum);

	if ( dwNeeded == 0 )
		return ERROR_PRINTER_NOT_FOUND;

	dwBuf = dwNeeded;
	lpBuf = new BYTE[dwBuf];

	if ( !lpBuf )
		return ERROR_OUTOFMEMORY;

	bResult = EnumPrinters(dwFlags, NULL, 2, lpBuf, dwBuf, &dwNeeded, &dwPrinterNum);

	lpPrinterInfo2 = (PRINTER_INFO_2*)lpBuf;
	for(i=0;i<dwPrinterNum;i++,lpPrinterInfo2++)
	{
		if ( _tcsstr(lpPrinterInfo2->pDriverName, _T("HiTi CS-2")) )
			m_ComboPrinter.AddString(lpPrinterInfo2->pPrinterName);
		else
		{
			if(_tcsstr(lpPrinterInfo2->pDriverName, _T("Seaory T12")))
				m_ComboPrinter.AddString(lpPrinterInfo2->pPrinterName);
			else
			{
				if(_tcsstr(lpPrinterInfo2->pDriverName, _T("Fagoo P28")))
					m_ComboPrinter.AddString(lpPrinterInfo2->pPrinterName);
			}
		}
	}

	delete [] lpBuf;

	return 0;
}

void CDemo1Dlg::GetSelectedPrinter(LPTSTR szPrinter)
{
	TCHAR				szIP[32] = {0};
	unsigned char		byIP0 = 0, byIP1 = 0, byIP2 = 0, byIP3 = 0;

	UpdateData(TRUE);

	if ( m_nConnectType == 0 )//printer queue name
	{
		lstrcpy(szPrinter, m_PrinterName);
	}
	else if ( m_nConnectType == 1 )//symbolic link
	{
		lstrcpy(szPrinter, m_SymbolicLink);
	}
	else if ( m_nConnectType == 2 )//IP address
	{
		m_IPaddr.GetAddress(byIP0, byIP1, byIP2, byIP3);
		_stprintf(szIP, _T("%d.%d.%d.%d"), byIP0, byIP1, byIP2, byIP3);
		lstrcpy(szPrinter, szIP);
	}
}



//=============================================================================
//
//=============================================================================
void CDemo1Dlg::OnBtnCheckStatus()
{
	// TODO: Add your control notification handler code here
	HINSTANCE		hInst = 0;
	DWORD			dwRet = 0;
	DWORD			dwStatus = 0;
	CString			Temp;

	TCHAR				szPrinter[256] = {0};

	GetSelectedPrinter(szPrinter);

	dwRet = PAVO_CheckPrinterStatus(szPrinter, &dwStatus);

	if ( dwRet == PAVO_DS_OFFLINE )//printer is not connected
	{
		Temp.Format(_T("Printer is not connected."));
	}
	else if ( dwRet != 0 )//some error happened
	{
		Temp.Format(_T("Error happened: %d,"), dwRet);
	}
	else
	{
		if ( dwStatus == PAVO_DS_BUSY )//busy
		{
			Temp.Format(_T("Printer is busy."));
		}
		else if ( dwStatus == PAVO_DS_PRINTING )//printing
		{
			Temp.Format(_T("Printer is printing."));
		}
		else
			Temp.Format(_T("Printer = \"%s\",\n\ndwStatus = 0x%08X,"), szPrinter, dwStatus);
	}

	MessageBox(Temp, _T("OnBtnCheckStatus"), MB_OK);
}

//=============================================================================
//
//=============================================================================
LRESULT CDemo1Dlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	// TODO: Add your specialized code here and/or call the base class
	CString		test;

	switch(message)
	{
		case WM_PAVO_PRINTER:
		{
			switch(wParam)
			{
				case MSG_JOB_BEGIN:
						test.Format(_T("Job is begining by driver!!\n\n lParam = %d,"), (DWORD)lParam);
						MessageBox(test, _T("MSG_JOB_BEGIN"), MB_OK);
						break;

				case MSG_JOB_END:
						test.Format(_T("Job is processed by driver!!\n\n lParam = %d,"), (DWORD)lParam);
						MessageBox(test, _T("MSG_JOB_END"), MB_OK);
						break;

				case MSG_JOB_CANCELED:
						test.Format(_T("Job is canceled by driver!!\n\n lParam = %d,"), (DWORD)lParam);
						MessageBox(test, _T("MSG_JOB_CANCELED"), MB_OK);
						break;

				case MSG_DEVICE_STATUS:
						if ( lParam != PAVO_DS_PRINTING && lParam != PAVO_DS_PROCESSING_DATA && lParam != PAVO_DS_SENDING_DATA )
						{
							test.Format(_T("error = 0x%08X"), (DWORD)lParam);
							MessageBox(test, _T("Error happened!!"), MB_OK);
						}
						break;

				case MSG_JOB_PRINTED:
						test.Format(_T("Job is printed completely by printer!!\n\n lParam = %d,"), (DWORD)lParam);
						MessageBox(test, _T("MSG_JOB_PRINTED"), MB_OK);
						break;

				default:
						break;
			}

			return 0;
		}
		break;

		default:
				break;
	}

	return CDialog::WindowProc(message, wParam, lParam);
}

void CDemo1Dlg::OnBtnGetDeviceInfo()
{
	// TODO: Add your control notification handler code here
	DWORD				dwRet = 0;
	TCHAR				szPrinterSerial[64] = {0};
	TCHAR				szPrinterModel[64] = {0};
	TCHAR				szFWversion[64] = {0};
	DWORD				RibbonInfo[4] = {0};
	DWORD				dwPrintCount = 0;
	DWORD				dwCardPos = 0;
	DWORD				dwUncleanCount = 0;
	DWORD				dwAttachedModule = 0;

	DWORD				dwSize = 64;
	CString				Temp;

	TCHAR				szPrinterName[256] = {0};
	TCHAR				szFilePath[256] = {0};

	GetSelectedPrinter(szPrinterName);

	if ( m_nInfoType == 0 )
	{
		dwSize = 64;
		dwRet = PAVO_GetDeviceInfo(szPrinterName, PAVO_DEVINFO_MFG_SERIAL, (BYTE*)szPrinterSerial, &dwSize);
		Temp.Format(_T("Printer Serial = \"%s\",\n\ndwRet = %d,"), szPrinterSerial, dwRet);
	}
	else if ( m_nInfoType == 1 )
	{
		dwSize = 64;
		dwRet = PAVO_GetDeviceInfo(szPrinterName, PAVO_DEVINFO_MODEL_NAME, (BYTE*)szPrinterModel, &dwSize);
		Temp.Format(_T("Printer Model = \"%s\",\n\ndwRet = %d,"), szPrinterModel, dwRet);
	}
	else if ( m_nInfoType == 2 )
	{
		dwSize = 64;
		dwRet = PAVO_GetDeviceInfo(szPrinterName, PAVO_DEVINFO_FIRMWARE_VERSION, (BYTE*)szFWversion, &dwSize);
		Temp.Format(_T("Firmware version = \"%s\",\n\ndwRet = %d,"), szFWversion, dwRet);
	}
	else if ( m_nInfoType == 3 )
	{
		dwSize = sizeof(DWORD)* 4;
		dwRet = PAVO_GetDeviceInfo(szPrinterName, PAVO_DEVINFO_RIBBON_INFO, (BYTE*)RibbonInfo, &dwSize);
		Temp.Format(_T("Ribbon type = %d,\n\nRemain count = %d,\n\ndwRet = %d,\n\n"), RibbonInfo[0], RibbonInfo[1], dwRet);

		switch(RibbonInfo[0])
		{
			case PAVO_RIBBON_TYPE_YMCKO:		Temp += _T("YMCKO");								break;
			case PAVO_RIBBON_TYPE_K:			Temp += _T("Resin K");								break;
			case PAVO_RIBBON_TYPE_KO:			Temp += _T("KO");									break;
			case PAVO_RIBBON_TYPE_YMCKOK:		Temp += _T("YMCKOK");								break;
			case PAVO_RIBBON_TYPE_HALF_YMCKO:	Temp += _T("1/2 YMCKO");							break;
			case PAVO_RIBBON_TYPE_YMCKFO:		Temp += _T("YMCKFO");								break;
			//default:
			case 255:							Temp += _T("Ribbon is missing or not supported");	break;
		}
	}
	else if ( m_nInfoType == 4 )
	{
		dwSize = sizeof(DWORD);
		dwRet = PAVO_GetDeviceInfo(szPrinterName, PAVO_DEVINFO_PRINT_COUNT, (BYTE*)&dwPrintCount, &dwSize);
		Temp.Format(_T("Printed card = %d,\n\ndwRet = %d,"), dwPrintCount, dwRet);
	}
	else if ( m_nInfoType == 5 )
	{
		dwSize = sizeof(DWORD);
		dwRet = PAVO_GetDeviceInfo(szPrinterName, PAVO_DEVINFO_CARD_POSITION, (BYTE*)&dwCardPos, &dwSize);

		Temp.Format(_T("Card position = %d,\n\ndwRet = %d,\n\n"), dwCardPos, dwRet);

		switch(dwCardPos)
		{
			case 0:		Temp += _T("Out of printer");					break;
			case 1:		Temp += _T("Start printing position");			break;
			case 2:		Temp += _T("Mag out position");					break;
			case 3:		Temp += _T("Mag in position");					break;
			case 4:		Temp += _T("Contact encoder position");			break;
			case 5:		Temp += _T("Contactless encoder position");		break;
			case 6:		Temp += _T("Flipper position");					break;
			case 7:		Temp += _T("Card jam");							break;
		}

	}
	else if ( m_nInfoType == 6 )
	{
		dwSize = sizeof(DWORD);
		dwRet = PAVO_GetDeviceInfo(szPrinterName, PAVO_DEVINFO_UNCLEAN_COUNT, (BYTE*)&dwUncleanCount, &dwSize);

		Temp.Format(_T("Unclean count = %d,\n\ndwRet = %d,\n\n"), dwUncleanCount, dwRet);
	}
	else if ( m_nInfoType == 7 )
	{
		lstrcpy(szFilePath, _T("D:/"));//forder name
		dwSize = lstrlen(szFilePath) * sizeof(TCHAR);
		dwRet = PAVO_GetDeviceInfo(szPrinterName, PAVO_DEVINFO_SAVE_MAINTENANCE_INFO, (BYTE*)szFilePath, &dwSize);

		Temp.Format(_T("Save maintenance info file to \n\n\"%s\"\n\ndwRet = %d,\n\n"), szFilePath, dwRet);
	}
	else if ( m_nInfoType == 8 )
	{
		dwSize = sizeof(DWORD);
		dwRet = PAVO_GetDeviceInfo(szPrinterName, PAVO_DEVINFO_ATTACHED_MODULE, (BYTE*)&dwAttachedModule, &dwSize);

		Temp.Format(_T("Attached module flag = 0x%08X,\n\nFlipper is attached: %s\n\ndwRet = %d,\n\n"), dwAttachedModule, (dwAttachedModule&0x00000001)?_T("Yes"):_T("No"), dwRet);
	}
	else
	{
		Temp.Format(_T("Not a valid option."));
	}

	MessageBox(Temp, _T("OnBtnGetDeviceInfo"), MB_OK);
}

void CDemo1Dlg::OnBtnSetPasswd()
{
	// TODO: Add your control notification handler code here
	CDlgPasswd			*cpDlg = 0;
	TCHAR				szPasswdOld[64] = {0},
						szPasswdNew[64] = {0};

	DWORD				dwRet = 0;
	CString				Temp;

	TCHAR				szPrinter[256] = {0};

	GetSelectedPrinter(szPrinter);

	cpDlg = new CDlgPasswd(szPasswdOld, szPasswdNew);
	if ( cpDlg->DoModal() == IDOK )
	{
		dwRet = PAVO_SetPassword(szPrinter, szPasswdOld, szPasswdNew);

		Temp.Format(_T("PAVO_SetPassword return %d,"), dwRet);
		MessageBox(Temp, _T("OnBtnSetPasswd"), MB_OK);
	}
}

void CDemo1Dlg::OnBtnSetSecurityMode()
{
	// TODO: Add your control notification handler code here
	CDlgSecurityMode	*cpDlg = 0;
	TCHAR				szPasswdOld[64] = {0};
	int					nSecurityMode = 0;

	DWORD				dwRet = 0;
	CString				Temp;

	TCHAR				szPrinter[256] = {0};

	GetSelectedPrinter(szPrinter);

	cpDlg = new CDlgSecurityMode(szPasswdOld, &nSecurityMode);
	if ( cpDlg->DoModal() == IDOK )
	{
		dwRet = PAVO_SetSecurityMode(szPrinter, szPasswdOld, nSecurityMode);

		Temp.Format(_T("PAVO_SetSecurityMode return %d,"), dwRet);
		MessageBox(Temp, _T("OnBtnSetSecurityMode"), MB_OK);
	}
}

void CDemo1Dlg::OnSelectBmpFile(UINT nBtnId)
{
	// TODO: Add your control notification handler code here
	CString				OpenFileName = _T("");
	CFileDialog			SrcFileDlg(TRUE, _T("*.*"), _T(""));

	int					nEditId = 0;

	nEditId = IDC_EDIT_BMP_RGB_FRONT + nBtnId - IDC_BTN_BMP_RGB_FRONT;

	SrcFileDlg.m_ofn.lpstrFilter  = _T("BMP(*.bmp)\0*.bmp\0\0");
	SrcFileDlg.m_ofn.nFilterIndex = 1;
	SrcFileDlg.m_ofn.lpstrInitialDir = _T("C:\\");

	if ( SrcFileDlg.DoModal() == IDOK )
	{
		OpenFileName = (LPCTSTR)SrcFileDlg.GetPathName();
		GetDlgItem(nEditId)->SetWindowText(OpenFileName);
	}
}

void CDemo1Dlg::OnBtnMoveCard()
{
	// TODO: Add your control notification handler code here
	DWORD				dwRet = 0;
	CString				Temp;

	DWORD				dwPosition = 0;
	CString				PosString;

	TCHAR				szPrinter[256] = {0};

	GetSelectedPrinter(szPrinter);

	switch(m_nMoveCardPosition)
	{
		case 0:		dwPosition = MOVE_CARD_TO_IC_ENCODER;			PosString = _T("Contact Encoder"); 			break;
		case 1:		dwPosition = MOVE_CARD_TO_RFID_ENCODER;			PosString = _T("Contactless Encoder");		break;
		case 2:		dwPosition = MOVE_CARD_TO_HOPPER;				PosString = _T("Output Hopper");			break;
		case 3:		dwPosition = MOVE_CARD_TO_REJECT_BOX;			PosString = _T("Reject Box");				break;
		case 4:		dwPosition = MOVE_CARD_TO_FLIPPER;				PosString = _T("Flipper");					break;
		case 5:		dwPosition = MOVE_CARD_TO_PRINT_FROM_FLIPPER;	PosString = _T("Print Position");			break;
		case 6:		dwPosition = MOVE_CARD_TO_STANDBY_POSITION;		PosString = _T("Standby Position");			break;
		case 7:		dwPosition = MOVE_CARD_TO_EJECT_CARD_FROM_FLIPPER; PosString = _T("Eject Card from Flipper");	break;
	}

	//if ( dwPosition == 0 )
	//	return;

	dwRet = PAVO_MoveCard(szPrinter, dwPosition);
	//dwRet = PAVO_MoveCard3(szPrinter, dwPosition);//not wait buzy

	Temp.Format(_T("Move card to %s finished.\n\ndwRet = 0x%08X,"), PosString, dwRet);
	MessageBox(Temp, _T("OnBtnMoveCard"), MB_OK);
}

void CDemo1Dlg::OnBtnReadSle4428()
{
	// TODO: Add your control notification handler code here
	DWORD				dwRet = 0;
	CString				Temp;

	int					i = 0;

	TCHAR				szScardReaderName[128] = {0};

	BYTE				lpBuf[1024] = {0};
	DWORD				dwBuf = 300;//16;
	int					nStartAddr = 0;//32;

	UpdateData(TRUE);

	lstrcpy(szScardReaderName, m_ScardReaderName);

	for(i=0;i<3;i++)//2011.05.04, try 3 times
	{
		Sleep(1300);
		dwRet = ReadDataFromSLE4428_CS2xx(szScardReaderName, lpBuf, nStartAddr, dwBuf);
		if ( dwRet == 0 )
			break;
	}

	Temp.Format(_T("After ReadDataFromSLE4428().\n\nReadDataFromSLE4428() return 0x%08X.\n\nRead Data = \"%s\""), dwRet, (TCHAR*)lpBuf);
	MessageBox(Temp, _T("OnBtnReadSle4428"), MB_OK);
}

void CDemo1Dlg::OnBtnWriteSle4428()
{
	// TODO: Add your control notification handler code here
	DWORD				dwRet = 0;
	CString				Temp;

	int					i = 0;

	TCHAR				szScardReaderName[128] = {0};

	BYTE				lpBuf[1024] = {0};
	DWORD				dwBuf = 300;//16;
	int					nStartAddr = 0;//32;

	UpdateData(TRUE);

	lstrcpy(szScardReaderName, m_ScardReaderName);

	for(i=0;i<dwBuf;i++)
		lpBuf[i] = 'B' + i;

	for(i=0;i<3;i++)//2011.05.04, try 3 times
	{
		Sleep(1300);
		dwRet = WriteDataToSLE4428_CS2xx(szScardReaderName, lpBuf, nStartAddr, dwBuf);
		if ( dwRet == 0 )
			break;
	}

	Temp.Format(_T("After WriteDataToSLE4428().\n\nWriteDataToSLE4428() return 0x%08X.\n\nWrite Data = \"%s\""), dwRet, (TCHAR*)lpBuf);
	MessageBox(Temp, _T("OnBtnWriteSle4428"), MB_OK);
}

void CDemo1Dlg::OnBtnReadMagTrackData()
{
	// TODO: Add your control notification handler code here
	DWORD				dwRet = 0;
	CString				Temp;
	BOOL				bSucc = TRUE;
	ULONG				nBytes = 0;

	BOOL				bRaw = FALSE;

	TCHAR				szPrinter[256] = {0};

	MAG_TRACK_DATA2		TrackDataR = {0};

	GetSelectedPrinter(szPrinter);

	GetDlgItem(IDC_EDIT1)->SetWindowText(_T(""));
	GetDlgItem(IDC_EDIT2)->SetWindowText(_T(""));
	GetDlgItem(IDC_EDIT3)->SetWindowText(_T(""));
	UpdateData(FALSE);

	memset(&TrackDataR, 0, sizeof(MAG_TRACK_DATA2));

	if ( m_bT1 )
	{
		if(bRaw)
			TrackDataR.byTrackFlag |= 0x11;
		else
			TrackDataR.byTrackFlag |= 0x01;
	}
	if ( m_bT2 )
	{
		if(bRaw)
			TrackDataR.byTrackFlag |= 0x12;
		else
			TrackDataR.byTrackFlag |= 0x02;
	}
	if ( m_bT3 )
	{
		if(bRaw)
			TrackDataR.byTrackFlag |= 0x14;
		else
			TrackDataR.byTrackFlag |= 0x04;

	}
	dwRet = PAVO_ReadMagTrackData(szPrinter, 0, (BYTE*)&TrackDataR);

	if ( m_bT1 )
	{
		if(bRaw)
		{
			unsigned char mychar = 0x00;
			int iLen = TrackDataR.byRawLenT1;
			TCHAR				szCode[256*8] = {0};

			for(int j = 0; j < iLen; j++)
			{
				mychar = TrackDataR.szTrack1[j];

				for (int i = 0; i < 8 ; i++) {

					itoa (((mychar >> (7 - i)) & 1), &(szCode[i + j * 8]),10);
				}
			}
			m_T1 = szCode;
		}
		else
			m_T1 = TrackDataR.szTrack1;
	}

	if ( m_bT2 )
	{
		if(bRaw)
		{
			unsigned char mychar = 0x00;
			int iLen = TrackDataR.byRawLenT2;
			TCHAR				szCode[256*8] = {0};

			/*TCHAR				szTmp[16] = {0};

			CString str;
			str.Format(_T("0x"));
			CString strTmp;*/

			for(int j = 0; j < iLen; j++)
			{
				mychar = TrackDataR.szTrack2[j];

				for (int i = 0; i < 8 ; i++) {

					itoa (((mychar >> (7 - i)) & 1), &(szCode[i + j * 8]),10);
				}

				//strTmp.Format(_T("%02x"), mychar);
				//str = str + strTmp;
			}
			//m_T2 = str;
			m_T2 = szCode;
		}
		else
			m_T2 = TrackDataR.szTrack2;
	}
	
	if ( m_bT3 )
	{
		if(bRaw)
		{
			unsigned char mychar = 0x00;
			int iLen = TrackDataR.byRawLenT3;
			TCHAR				szCode[256*8] = {0};

			for(int j = 0; j < iLen; j++)
			{
				mychar = TrackDataR.szTrack3[j];

				for (int i = 0; i < 8 ; i++) {

					itoa (((mychar >> (7 - i)) & 1), &(szCode[i + j * 8]),10);
				}
			}
			m_T3 = szCode;
		}
		else
			m_T3 = TrackDataR.szTrack3;
	}
	UpdateData(FALSE);

	//some error happened
	if ( dwRet != 0 )
	{
		Temp.Format(_T("Error happened.(%d)\n\n"), dwRet);

		switch(dwRet)
		{
			case ERROR_MAGCARD_CONNECT_FAIL:		Temp += _T("Cannot connect COM port of magnetic module.");			break;
			case ERROR_MAGCARD_READ_FAIL: 			Temp += _T("Read track data fail.");								break;
			case ERROR_MAGCARD_WRITE_FAIL: 			Temp += _T("Write track data fail.");								break;
			case ERROR_MAGCARD_NO_TRACK_SELECTED: 	Temp += _T("No track is specified to be read/write.");				break;
			case ERROR_MAGCARD_EMPTY_TRACK_DATA: 	Temp += _T("One of the track data is empty.");						break;
			case ERROR_MAGCARD_NO_MODULE: 			Temp += _T("The magnetic stripe encoder module is not attached.");	break;
			case ERROR_MAGCARD_WRONG_DATA_TRACK1: 	Temp += _T("The track 1 has invalid characters.");					break;
			case ERROR_MAGCARD_WRONG_DATA_TRACK2: 	Temp += _T("The track 2 has invalid characters.");					break;
			case ERROR_MAGCARD_WRONG_DATA_TRACK3: 	Temp += _T("The track 3 has invalid characters.");					break;
		}
	}
	else
	{
		Temp.Format(_T("Read mag track data success."));
/*
		if ( m_bT1 )		m_T1 = TrackDataR.szTrack1;
		if ( m_bT2 )		m_T2 = TrackDataR.szTrack2;
		if ( m_bT3 )		m_T3 = TrackDataR.szTrack3;
		UpdateData(FALSE);
*/
	}

	MessageBox(Temp, _T("OnBtnReadMagTrackData"), MB_OK);
}

void CDemo1Dlg::OnBtnWriteMagTrackData()
{
	// TODO: Add your control notification handler code here
	DWORD				dwRet = 0;
	CString				Temp;
	BOOL				bSucc = TRUE;
	ULONG				nBytes = 0;

	TCHAR				szPrinter[256] = {0};

	MAG_TRACK_DATA2		TrackDataW = {0};

	GetSelectedPrinter(szPrinter);

	//1. set track data to encode
	memset(&TrackDataW, 0, sizeof(MAG_TRACK_DATA2));

	TrackDataW.byCoercivity = m_nCoercivity;//0=Lo-Co, 1=Hi-Co

	if ( m_bT1 )	TrackDataW.byTrackFlag |= 0x01;
	if ( m_bT2 )	TrackDataW.byTrackFlag |= 0x02;
	if ( m_bT3 )	TrackDataW.byTrackFlag |= 0x04;

	if ( m_bCipherMode )	TrackDataW.byTrackFlag |= 0x20;

	//The track data are not checked by this sample. Please check them by your own code.
#ifdef UNICODE

	nBytes = WideCharToMultiByte(CP_ACP, 0, (LPCTSTR)m_T1, -1, NULL, 0, NULL, NULL);
	nBytes = WideCharToMultiByte(CP_ACP, 0, (LPCTSTR)m_T1, -1, TrackDataW.szTrack1, nBytes, NULL, NULL);

	nBytes = WideCharToMultiByte(CP_ACP, 0, (LPCTSTR)m_T2, -1, NULL, 0, NULL, NULL);
	nBytes = WideCharToMultiByte(CP_ACP, 0, (LPCTSTR)m_T2, -1, TrackDataW.szTrack2, nBytes, NULL, NULL);

	nBytes = WideCharToMultiByte(CP_ACP, 0, (LPCTSTR)m_T3, -1, NULL, 0, NULL, NULL);
	nBytes = WideCharToMultiByte(CP_ACP, 0, (LPCTSTR)m_T3, -1, TrackDataW.szTrack3, nBytes, NULL, NULL);

#else
	strcpy(TrackDataW.szTrack1, m_T1);
	strcpy(TrackDataW.szTrack2, m_T2);
	strcpy(TrackDataW.szTrack3, m_T3);
#endif

	//2. write track data to card
	dwRet = PAVO_WriteMagTrackData(szPrinter, 0, (BYTE*)&TrackDataW);

	//some error happened
	if ( dwRet != 0 )
	{
		Temp.Format(_T("Error happened.(%d)\n\n"), dwRet);

		switch(dwRet)
		{
			case ERROR_MAGCARD_CONNECT_FAIL:		Temp += _T("Cannot connect COM port of magnetic module.");			break;
			case ERROR_MAGCARD_READ_FAIL: 			Temp += _T("Read track data fail.");								break;
			case ERROR_MAGCARD_WRITE_FAIL: 			Temp += _T("Write track data fail.");								break;
			case ERROR_MAGCARD_NO_TRACK_SELECTED: 	Temp += _T("No track is specified to be read/write.");				break;
			case ERROR_MAGCARD_EMPTY_TRACK_DATA: 	Temp += _T("One of the track data is empty.");						break;
			case ERROR_MAGCARD_NO_MODULE: 			Temp += _T("The magnetic stripe encoder module is not attached.");	break;
			case ERROR_MAGCARD_WRONG_DATA_TRACK1: 	Temp += _T("The track 1 has invalid characters.");					break;
			case ERROR_MAGCARD_WRONG_DATA_TRACK2: 	Temp += _T("The track 2 has invalid characters.");					break;
			case ERROR_MAGCARD_WRONG_DATA_TRACK3: 	Temp += _T("The track 3 has invalid characters.");					break;
		}
	}
	else
	{
		Temp.Format(_T("Write mag track data success."));
	}

	MessageBox(Temp, _T("OnBtnWriteMagTrackData"), MB_OK);
}

void CDemo1Dlg::OnBtnDirectPrint()
{
	// TODO: Add your control notification handler code here
	DWORD				dwStatus = 0,
						dwError = 0;
	HITI_CARD_PRINT_PARAMETER		JobPara = {0};
	HITI_HEATING_ENERGY				HeatEnergy = {0};

	unsigned long		dwRet = 0;

	HBITMAP				hBmp24 = 0, hBmpK = 0, hBmpO = 0;
	BITMAP				Bmp24 = {0}, BmpK = {0}, BmpO = {0};

	HBITMAP				hBmp24b = 0, hBmpKb = 0, hBmpOb = 0;
	BITMAP				Bmp24b = {0}, BmpKb = {0}, BmpOb = {0};

	CString				Temp;
	TCHAR				szPrinter[256] = {0};

	GetSelectedPrinter(szPrinter);

	//1. prepare image data
	if ( m_bY1 && !m_Bmp24Name.IsEmpty() )
	{
		hBmp24 = (HBITMAP) LoadImage(0, (LPCTSTR)m_Bmp24Name, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
		dwError = GetLastError();
		GetObject(hBmp24, sizeof(BITMAP), &Bmp24);
	}

	if ( m_bK1 && !m_BmpKName.IsEmpty() )
	{
		hBmpK = (HBITMAP) LoadImage(0, (LPCTSTR)m_BmpKName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
		dwError = GetLastError();
		GetObject(hBmpK, sizeof(BITMAP), &BmpK);
	}

	if ( m_bO1 && !m_BmpOName.IsEmpty() )
	{
		hBmpO = (HBITMAP) LoadImage(0, (LPCTSTR)m_BmpOName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
		dwError = GetLastError();
		GetObject(hBmpO, sizeof(BITMAP), &BmpO);
	}

	if ( m_bY2 && !m_Bmp24Name2.IsEmpty() )
	{
		hBmp24b = (HBITMAP) LoadImage(0, (LPCTSTR)m_Bmp24Name2, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
		dwError = GetLastError();
		GetObject(hBmp24b, sizeof(BITMAP), &Bmp24b);
	}

	if ( m_bK2 && !m_BmpKName2.IsEmpty() )
	{
		hBmpKb = (HBITMAP) LoadImage(0, (LPCTSTR)m_BmpKName2, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
		dwError = GetLastError();
		GetObject(hBmpKb, sizeof(BITMAP), &BmpKb);
	}

	if ( m_bO2 && !m_BmpOName2.IsEmpty() )
	{
		hBmpOb = (HBITMAP) LoadImage(0, (LPCTSTR)m_BmpOName2, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
		dwError = GetLastError();
		GetObject(hBmpOb, sizeof(BITMAP), &BmpOb);
	}

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	memset(&JobPara, 0, sizeof(HITI_CARD_PRINT_PARAMETER));

	JobPara.dwSize = sizeof(HITI_CARD_PRINT_PARAMETER);

	JobPara.byOrientation	= m_nOrientation + 1;

	JobPara.byCardThickness	= 2;//0=0.3mm;1=0.5mm;2=0.8mm;3=1.0mm

	if ( m_bTransparentCard )
		JobPara.byTransparentCard = 1;

	if ( m_bFlag6 )//Move card to standby position after printing finished
		JobPara.dwFlags = PAVO_FLAG_MOVE_CARD_TO_STANDBY_AFTER_PRINTED;

	//for portrait printing, all the data has 642 pixels width and 1014 pixels height
	//for landscape printing, all the data has 1014 pixels width and 642 pixels height
	//if the data pointer is null, than the plane will not be printed.

	if ( m_bY1 && Bmp24.bmBits )
		JobPara.lpFrontBGR		= &Bmp24;
	if ( m_bK1 && BmpK.bmBits )
		JobPara.lpFrontK		= &BmpK;
	if ( m_bO1 && BmpO.bmBits )
		JobPara.lpFrontO		= &BmpO;

	if ( m_bY2 && Bmp24b.bmBits )
		JobPara.lpBackBGR		= &Bmp24b;
	if ( m_bK2 && BmpKb.bmBits )
		JobPara.lpBackK			= &BmpKb;
	if ( m_bO2 && BmpOb.bmBits )
		JobPara.lpBackO			= &BmpOb;

	//Heating Energy adjustment, value range of following fields are -127 ~ 127
	//same as driver UI Heating Energy tab
	//for ribbon YMCKO
	HeatEnergy.chFrontDenYMC	= 0;
	HeatEnergy.chFrontDenK		= 0;
	HeatEnergy.chFrontDenO		= 0;

	HeatEnergy.chBackDenYMC		= 0;
	HeatEnergy.chBackDenK		= 0;
	HeatEnergy.chBackDenO		= 0;

	HeatEnergy.chFrontSenYMC	= 0;
	HeatEnergy.chFrontSenK		= 0;
	HeatEnergy.chFrontSenO		= 0;

	HeatEnergy.chBackSenYMC		= 0;
	HeatEnergy.chBackSenK		= 0;
	HeatEnergy.chBackSenO		= 0;

	//for ribbon K
	HeatEnergy.chFrontDenResinK	= 0;
	HeatEnergy.chBackDenResinK	= 0;
	HeatEnergy.chFrontSenResinK	= 0;
	HeatEnergy.chBackSenResinK	= 0;

	//2. check if there is error
	dwStatus = PAVO_DS_BUSY;
	while ( dwStatus == PAVO_DS_BUSY )
	{
		dwRet = PAVO_CheckPrinterStatus(szPrinter, &dwStatus);

		if ( dwStatus == PAVO_DS_BUSY )
			Sleep(1000);
	}

	if ( dwStatus != 0 && dwStatus != PAVO_DS_PRINTING )
	{
		Temp.Format(_T("Printer error => 0x%08X"), dwStatus);
		MessageBox(Temp, _T("OnBtnDirectPrint"), MB_OK);
		return;
	}

	//3. Send print data to printer memory.
	//   If printer is at ready state, it will perform printing immediately.
	dwRet = PAVO_PrintOneCard(szPrinter, &JobPara, &HeatEnergy, 0);

	//release image object
	if ( hBmp24 )
		DeleteObject(hBmp24);

	if ( hBmpK )
		DeleteObject(hBmpK);

	if ( hBmpO )
		DeleteObject(hBmpO);

	if ( hBmp24b )
		DeleteObject(hBmp24b);

	if ( hBmpKb )
		DeleteObject(hBmpKb);

	if ( hBmpOb )
		DeleteObject(hBmpOb);

	//some error happened
	if ( dwRet != 0 )
	{
		Temp.Format(_T("Error happened after PAVO_PrintOneCard() => 0x%08X"), dwRet);
		MessageBox(Temp, _T("OnBtnDirectPrint"), MB_OK);
		return;
	}
	//else
	//{
	//	MessageBox(_T("PAVO_PrintOneCard() return success."), _T("OnBtnDirectPrint"), MB_OK);
	//}


	//4. Optional
	//If you need to do another encoding, please wait printer to print card completely.
	Sleep(5000);//wait for printer firmware to process data
	while ( 1 )
	{
		dwRet = PAVO_CheckPrinterStatus(szPrinter, &dwStatus);

		if ( dwStatus != PAVO_DS_BUSY && dwStatus != PAVO_DS_PRINTING )
			break;

		Sleep(1000);
	}

	if ( dwStatus != 0 )
	{
		Temp.Format(_T("Printer error => 0x%08X"), dwStatus);
		MessageBox(Temp, _T("OnBtnDirectPrint"), MB_OK);
	}
	else
		MessageBox(_T("PAVO_PrintOneCard() return success."), _T("OnBtnDirectPrint"), MB_OK);

}

void CDemo1Dlg::OnBtnRfidGetCardSerial()
{
	// TODO: Add your control notification handler code here
	unsigned long		dwError = 0;

	int					nRet = 0;

	int					nRFPort = 0;
	bool				bSucc = false;

	char				chChipID = 0;
	char				szSerialA[64] = {0};
	long				nCardType = 0;

	UpdateData(TRUE);

	nRFPort = m_nRfidPort + 1;

	if ( nRFPort == 0 )
	{
		MessageBox(_T("Not valid COM port."), _T("OnBtnRfidGetCardSerial"), MB_OK);
		return;
	}

	//open COM port
	nRet = E680_Open_ComPort(nRFPort);
	if ( nRet == 0 )//fail to open COM port
		return;//ERROR_OPEN_FAILED;//=110

	//turn on antenna
	nRet = E680_Set_Working_Mode(1, 1);
	if ( nRet == 0 )
		return;

	//try ISO14443A -----------------------------
	nRet = E680_Set_Readcard_Mode(0);//ISO14443A
	if ( nRet == 1 )
	{
		nRet = E680_Request_CardSN(szSerialA);
		if ( nRet == 1 )
		{
			bSucc = true;
			nCardType = 1;
		}
	}
	else
	{
		bSucc = false;
		dwError = 1884;
	}

	//try ISO14443B -----------------------------
	if ( dwError == 0 && nRet == 0 )
	{
		nRet = E680_Set_Readcard_Mode(1);//ISO14443B

		if ( nRet == 1 )
		{
			nRet = E680_SR_initiate(&chChipID);
		}

		if ( nRet == 1 )
		{
			nRet = E680_SR_select(chChipID);
		}

		if ( nRet == 1 )
		{
			nRet = E680_SR_get_uid(szSerialA);
			if ( nRet == 1 )
			{
				bSucc = true;
				nCardType = 2;
			}
		}
	}

	//try ISO15693 ------------------------------
	if ( dwError == 0 && nRet == 0 )
	{
		nRet = E680_Set_Readcard_Mode(2);//ISO15693
		if ( nRet == 1 )
		{
			nRet = E680_15693_Inventory(szSerialA);
			if ( nRet == 1 )
			{
				bSucc = true;
				nCardType = 3;
			}
			else
			{
				bSucc = false;
				dwError = 1885;
			}
		}
	}

	//turn off antenna
	nRet = E680_Set_Working_Mode(0, 0);

	//close COM port
	E680_Close_ComPort();

	m_StaticCardSerial.SetWindowText(szSerialA);

}

void CDemo1Dlg::OnBtnPrintByDriver()
{
	DWORD				dwStatus = 0,
						dwError = 0;
	PAVO_JOB_PROPERTY	JobProp = {0};
	BYTE				byRibbonType = 0;

	bool				bColorFront = false, bKFront = false;
	bool				bColorBack = false, bKBack = false;
	DWORD				dwFlags = 0;

	TCHAR				szJobName[128] = {0};
	HDC					hDC = 0;
	DOCINFO				DocInfo;
	int					nJobId = 0;
	BITMAPINFO			BmpInfo;
	int					nRet = 0;

	HBITMAP				hBmp24 = 0, hBmpK = 0, hBmpO = 0;
	BITMAP				Bmp24 = {0}, BmpK = {0}, BmpO = {0};

	HBITMAP				hBmp24b = 0, hBmpKb = 0, hBmpOb = 0;
	BITMAP				Bmp24b = {0}, BmpKb = {0}, BmpOb = {0};

	LOGFONT				LogFont = {0};
	HFONT				hFont = 0,
						hDefFont = 0;

	TCHAR				szPrinter[256] = {0};

	GetSelectedPrinter(szPrinter);

	if ( m_nConnectType != 0 )//printer queue name
	{
		MessageBox(_T("Please select printer queue."), _T("OnBtnPrintByDriver"), MB_OK|MB_ICONERROR);
		return;
	}

	//ribbon type
	switch(m_nRibbonType)
	{
		case 0:		byRibbonType = PAVO_RIBBON_TYPE_YMCKO;		break;
		case 1:		byRibbonType = PAVO_RIBBON_TYPE_K;			break;
		case 2:		byRibbonType = PAVO_RIBBON_TYPE_HALF_YMCKO;	break;
		case 3:		byRibbonType = PAVO_RIBBON_TYPE_YMCKOK;		break;
		case 4:		byRibbonType = PAVO_RIBBON_TYPE_KO;			break;
		case 5:		byRibbonType = PAVO_RIBBON_TYPE_YMCKFO;		break;
	}

	//front side
    if ( m_nFrontSide != 0 )
	{
		if ( m_bY1 )
			bColorFront = true;

		if ( m_bK1 )
			bKFront = true;

	}

	//back side
    if ( m_nBackSide != 0 )
	{
		if ( m_bY2 )
			bColorBack = true;

		if ( m_bK2 )
			bKBack = true;

	}

	//flags
	if ( m_bFlag1 )
		dwFlags	|= PAVO_FLAG_NOT_SHOW_ERROR_MSG_DLG;
	if ( m_bFlag2 )
		dwFlags	|= PAVO_FLAG_WAIT_MSG_DONE;
	if ( m_bFlag3 )
		dwFlags	|= PAVO_FLAG_NOT_SHOW_CLEAN_MSG;
	if ( m_bFlag4 )
		dwFlags	|= PAVO_FLAG_WATCH_JOB_PRINTED;
	if ( m_bFlag5 )
		dwFlags |= PAVO_FLAG_NOT_EJECT_CARD_AFTER_PRINTED;
	if ( m_bFlag6 )
		dwFlags	|= PAVO_FLAG_MOVE_CARD_TO_STANDBY_AFTER_PRINTED;
	if ( m_bFlagNotOvercoat )
		dwFlags	|= PAVO_FLAG_NO_OVERCOATING;

	//load image from file
	if ( bColorFront )
	{
		hBmp24 = (HBITMAP) LoadImage(0, (LPCTSTR)m_Bmp24Name, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
		dwError = GetLastError();
		GetObject(hBmp24, sizeof(BITMAP), &Bmp24);
	}

	if ( bKFront )
	{
		hBmpK = (HBITMAP) LoadImage(0, (LPCTSTR)m_BmpKName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
		dwError = GetLastError();
		GetObject(hBmpK, sizeof(BITMAP), &BmpK);
	}

	if ( bColorBack )
	{
		hBmp24b = (HBITMAP) LoadImage(0, (LPCTSTR)m_Bmp24Name2, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
		dwError = GetLastError();
		GetObject(hBmp24b, sizeof(BITMAP), &Bmp24b);
	}

	if ( bKBack )
	{
		hBmpKb = (HBITMAP) LoadImage(0, (LPCTSTR)m_BmpKName2, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
		dwError = GetLastError();
		GetObject(hBmpKb, sizeof(BITMAP), &BmpKb);
	}



	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	//1. If need to change the settings, add codes here
	memset(&JobProp, 0, sizeof(PAVO_JOB_PROPERTY));
	JobProp.dwSize				= sizeof(PAVO_JOB_PROPERTY);
	JobProp.hParentWnd			= this->GetSafeHwnd();
	JobProp.dwCardType			= m_nCardType;
	JobProp.byRibbonType		= byRibbonType;
	JobProp.shOrientation		= m_nOrientation + 1;
	JobProp.shCopies			= 1;
	JobProp.dwFlags				= dwFlags;
	JobProp.dwCustomIndex		= 0;

	if ( m_bTransparentCard )
		JobProp.byTransparentCard = 1;

	//It is not necessary to change all fields value.
	//You can set almost fields by driver UI.
	//You should just set the flag of the field that you want to change.
	JobProp.dwFieldFlag			= FF_CARD_TYPE | FF_FLAGS | FF_PARENT_HWND | FF_ORIENTATION \
								| FF_COPIES | FF_DUPLEX | FF_RIBBON_TYPE | FF_PRINT_COLOR \
								| FF_TRANSPARENT_AND_FLIP | FF_ROTATE180;

/*
	//If you want to use your own job ID, set it to dwCustomIndex.
	JobProp.dwCustomIndex		= 1234;
	JobProp.dwFieldFlag			|= FF_CUSTOM_INDEX;
*/

	if ( bColorFront || bKFront )
		JobProp.byDuplex = PAVO_DUPLEX_PRINT_FRONT_SIDE;

	if ( bColorBack || bKBack )
		JobProp.byDuplex |= PAVO_DUPLEX_PRINT_BACK_SIDE;

	if ( bColorFront )
		JobProp.byPrintColor = 0x01;//front side color image
	if ( bColorBack )
		JobProp.byPrintColor |= 0x02;//back side color image

	if ( bKFront && BmpK.bmBits )
	{
		JobProp.dwFieldFlag		|= FF_DATA_FLAG;
		JobProp.dwDataFlag		|= PAVO_DATAFLAG_RESIN_FRONT;
	}

	if ( bKBack && BmpKb.bmBits )
	{
		JobProp.dwFieldFlag		|= FF_DATA_FLAG;
		JobProp.dwDataFlag		|= PAVO_DATAFLAG_RESIN_BACK;
	}

	//2017.05.11 added by Bill for CS290e print as CS230e
	if (m_bCS290AsCS230)
		JobProp.byPrintAs230e = 1;

	//JobProp.byRotate180 = 1;

/*
	//If you want driver to apply dither effect, then YMC will not be printed.
	JobProp.dwFieldFlag		|= FF_DITHER_K;
	JobProp.byPrintColor = 0;
	if ( m_bDuplexFront )
		JobProp.byDitherK = 0x01;
	if ( m_bDuplexBack )
		JobProp.byDitherK |= 0x02;
*/

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	//2. CreateDC
	hDC = CreateDC(_T("WINSPOOL"), szPrinter, NULL, 0);

	//3. Optional. Apply the job setting into the DC.
	//   Please notice that this function will get the printer's current setting,
	//   and then combine the settings value with JobProp values.
	//   If you want to use the printer's current settings set by driver UI. Please skip this function.
	dwError = PAVO_ApplyJobSetting(szPrinter, hDC, 0, (BYTE*)&JobProp);
	if ( dwError )
		return;// dwError;

	//4. StartDoc
	memset(&DocInfo, 0, sizeof(DOCINFO));
	DocInfo.cbSize = sizeof(DOCINFO);

	lstrcpy(szJobName, _T("DemoVC6 Job"));
	DocInfo.lpszDocName = szJobName;

	nJobId = ::StartDoc(hDC, &DocInfo);

	//-------------------------------------------------------------------------
	//front side part
	//-------------------------------------------------------------------------
	if ( bColorFront || bKFront )
	{
		//5. StartPage
		nRet = ::StartPage(hDC);

		//6.a Send resin K data before any drawing GDIs.
		//	Please notice that the black data must be a 8-bits gray data with size 642x1014 for portrait or 1014x642 for landscape.
		//	And the start position must be at (0, 0).
		//	And please notice that the pixel value 0xFF will print out blank, and 0x00 will print out black.
		if ( bKFront && BmpK.bmBits )
			dwError = PAVO_SetExtraDataToHDC(hDC, PAVO_DATA_RESIN_FRONT, 0, 0, &BmpK);

		if ( bColorFront )
		{
			//6.b Draw anything you want on page between ::StartPage and ::EndPage
			if ( Bmp24.bmBits )
			{
				memset(&BmpInfo, 0, sizeof(BITMAPINFO));
				BmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
				BmpInfo.bmiHeader.biWidth = Bmp24.bmWidth;
				BmpInfo.bmiHeader.biHeight = Bmp24.bmHeight;
				BmpInfo.bmiHeader.biPlanes = Bmp24.bmPlanes;
				BmpInfo.bmiHeader.biBitCount = Bmp24.bmBitsPixel * Bmp24.bmPlanes;
				BmpInfo.bmiHeader.biCompression = BI_RGB;

				nRet = StretchDIBits(hDC, 0, 0, Bmp24.bmWidth, Bmp24.bmHeight, 0, 0, Bmp24.bmWidth, Bmp24.bmHeight, Bmp24.bmBits, &BmpInfo, DIB_RGB_COLORS, SRCCOPY);
 			}

			memset((LPBYTE)&LogFont, 0, sizeof(LOGFONT));
			LogFont.lfHeight = 80;//40;
			LogFont.lfWeight = FW_NORMAL;
			lstrcpy(LogFont.lfFaceName, _T("Arial"));
			hFont = ::CreateFontIndirect(&LogFont);

			hDefFont = (HFONT)::SelectObject(hDC, hFont);

			//::SetTextColor(0x000000FF);
			::TextOut(hDC, 100, 150, _T("Front Side"), 10);
			::SelectObject(hDC, hDefFont);
			DeleteObject(hFont);
	   	}

		//7. If page drawing is finished, set to end page
		nRet = ::EndPage(hDC);
	}

	//-------------------------------------------------------------------------
	//back side part
	//-------------------------------------------------------------------------
	if ( bColorBack || bKBack )
	{
		//5. StartPage
		nRet = ::StartPage(hDC);

		//6.a Send resin K data before drawing GDIs.
		//	Please notice that the black data must be a 8-bits gray data with size 642x1014 for portrait or 1014x642 for landscape.
		//	And the start position must be at (0, 0).
		//	And please notice that the pixel value 0xFF will print out blank, and 0x00 will print out black.
		if ( bKBack && BmpKb.bmBits )
			dwError = PAVO_SetExtraDataToHDC(hDC, PAVO_DATA_RESIN_BACK, 0, 0, &BmpKb);

		if ( bColorBack )
		{
			//6.b Draw anything you want on page between ::StartPage and ::EndPage
			if ( Bmp24b.bmBits )
			{
				memset(&BmpInfo, 0, sizeof(BITMAPINFO));
				BmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
				BmpInfo.bmiHeader.biWidth = Bmp24b.bmWidth;
				BmpInfo.bmiHeader.biHeight = Bmp24b.bmHeight;
				BmpInfo.bmiHeader.biPlanes = Bmp24b.bmPlanes;
				BmpInfo.bmiHeader.biBitCount = Bmp24b.bmBitsPixel * Bmp24b.bmPlanes;
				BmpInfo.bmiHeader.biCompression = BI_RGB;

				nRet = StretchDIBits(hDC, 0, 0, Bmp24b.bmWidth, Bmp24b.bmHeight, 0, 0, Bmp24b.bmWidth, Bmp24b.bmHeight, Bmp24b.bmBits, &BmpInfo, DIB_RGB_COLORS, SRCCOPY);
 			}

			memset((LPBYTE)&LogFont, 0, sizeof(LOGFONT));
			LogFont.lfHeight = 40;
			LogFont.lfWeight = FW_NORMAL;
			lstrcpy(LogFont.lfFaceName, _T("Arial"));
			hFont = ::CreateFontIndirect(&LogFont);

			hDefFont = (HFONT)::SelectObject(hDC, hFont);

			//::SetTextColor(0x000000FF);
			::TextOut(hDC, 100, 300, _T("Back Side"), 9);
			::SelectObject(hDC, hDefFont);
			DeleteObject(hFont);
		}

		//7. If page drawing is finished, set to end page
		nRet = ::EndPage(hDC);
	}

	//8. If job done, set end of the job
	nRet = ::EndDoc(hDC);

	::DeleteDC(hDC);

	//release image object
	if ( hBmp24 )
		DeleteObject(hBmp24);

	if ( hBmpK )
		DeleteObject(hBmpK);

	if ( hBmp24b )
		DeleteObject(hBmp24b);

	if ( hBmpKb )
		DeleteObject(hBmpKb);

}

void CDemo1Dlg::OnBtnSetStandbyParameter()
{
	// TODO: Add your control notification handler code here
	DWORD				dwRet = 0;
	CString				Temp;

	TCHAR				szPrinter[256] = {0};

	GetSelectedPrinter(szPrinter);

	dwRet = PAVO_SetStandbyParameters(szPrinter, m_byStandbyPos, m_byStandbyTime);

	Temp.Format(_T("PAVO_SetStandbyParameters() ok.\n\nPrinter = \"%s\",\n\ndwRet = %d,"), szPrinter, dwRet);
	MessageBox(Temp, _T("OnBtnSetStandbyParameter"), MB_OK);
}

void CDemo1Dlg::OnBtnDoCommand()
{
	// TODO: Add your control notification handler code here
	DWORD				dwRet = 0;

	DWORD				dwCommand = 0;
	CString				Temp;

	DWORD				dwStatus = 0;

	TCHAR				szPrinter[256] = {0};

	GetSelectedPrinter(szPrinter);

	switch(m_nCommand)
	{
		case 0:		dwCommand = PAVO_COMMAND_RESET_PRINTER;					break;
		case 1:		dwCommand = PAVO_COMMAND_CLEAN_CARD_PATH;				break;
		case 2:		dwCommand = PAVO_COMMAND_RESET_PRINT_COUNT;				break;
		case 3:		dwCommand = PAVO_COMMAND_FLIP_CARD;						break;
		case 4:		dwCommand = PAVO_COMMAND_AUTO_FEED_FROM_FLIPPER_ON;		break;
		case 5:		dwCommand = PAVO_COMMAND_AUTO_FEED_FROM_FLIPPER_OFF;	break;
		case 6:		dwCommand = PAVO_COMMAND_RESET_PRINTER_CLEAR_JAM;		break;
		case 7:		dwCommand = PAVO_COMMAND_TIGHTEN_RIBBON;				break;
		case 8:		dwCommand = PAVO_COMMAND_ERASE_CARD_BY_DRIVER;			break;
		case 9:		dwCommand = PAVO_COMMAND_DETECT_CARD_EMPTY;				break;
	}

	if ( dwCommand == 0 )
		return;

	dwRet = PAVO_DoCommand(szPrinter, dwCommand);

	if ( m_nCommand == 1 )//clean card path
	{
		//check if there is error
		dwStatus = PAVO_DS_BUSY;
		while ( dwStatus == PAVO_DS_BUSY )
		{
			dwRet = PAVO_CheckPrinterStatus(szPrinter, &dwStatus);

			if ( dwStatus == PAVO_DS_BUSY )
				Sleep(1000);
		}

		if ( dwStatus != 0 && dwStatus != PAVO_DS_PRINTING )
		{
			Temp.Format(_T("Printer error => 0x%08X"), dwStatus);
		}
		else
		{
			Temp = _T("Clean Card Path finished.");
		}
	}
	else if ( m_nCommand == 9 )//detect card empty
	{
		//check if there is error
		dwStatus = PAVO_DS_BUSY;
		while ( dwStatus == PAVO_DS_BUSY )
		{
			dwRet = PAVO_CheckPrinterStatus(szPrinter, &dwStatus);

			if ( dwStatus == PAVO_DS_BUSY )
				Sleep(1000);
		}

		if ( dwStatus != 0 && dwStatus != PAVO_DS_PRINTING )
		{
			Temp.Format(_T("Printer error => 0x%08X"), dwStatus);
		}
		else
		{
			Temp = _T("Card is not empty!");
		}
	}
	else
	{
		Temp.Format(_T("PrinterName = \"%s\",\n\nPAVO_DoCommand() return %d,"), szPrinter, dwRet);
	}

	MessageBox(Temp, _T("OnBtnDoCommand"), MB_OK);
}

void CDemo1Dlg::OnBtnSavePrinterSettingToFile()
{
	// TODO: Add your control notification handler code here
	DWORD				dwRet = 0;
	CString				Temp;

	TCHAR				szPrinter[256] = {0};
	TCHAR				szFileName[256] = {0};

	GetSelectedPrinter(szPrinter);

	if ( m_nConnectType != 0 )//printer queue name
	{
		MessageBox(_T("Please select printer queue."), _T("OnBtnSavePrinterSettingToFile"), MB_OK);
		return;
	}

	lstrcpy(szFileName, _T("c:\\mysetting.bin"));

	dwRet = PAVO_SavePrinterSettingToFileA(szPrinter, szFileName);

	Temp.Format(_T("PAVO_SavePrinterSettingToFileA() return %d."), dwRet);

	MessageBox(Temp, _T("PAVO_SavePrinterSettingToFile"), MB_OK);
}

void CDemo1Dlg::OnBtnApplyPrinterSettingFromFile()
{
	// TODO: Add your control notification handler code here
	DWORD				dwRet = 0;
	CString				Temp;

	TCHAR				szPrinter[256] = {0};
	TCHAR				szFileName[256] = {0};

	GetSelectedPrinter(szPrinter);

	if ( m_nConnectType != 0 )//printer queue name
	{
		MessageBox(_T("Please select printer queue."), _T("OnBtnApplyPrinterSettingFromFile"), MB_OK);
		return;
	}

	lstrcpy(szFileName, _T("c:\\mysetting.bin"));

	dwRet = PAVO_ApplyPrinterSettingFromFileA(szPrinter, szFileName);

	Temp.Format(_T("PAVO_ApplyPrinterSettingFromFileA() return %d."), dwRet);

	MessageBox(Temp, _T("OnBtnApplyPrinterSettingFromFile"), MB_OK);
}

void CDemo1Dlg::OnBtnEraseCard()
{
	// TODO: Add your control notification handler code here
	DWORD				dwRet = 0;
	CString				Temp;
	DWORD				dwStatus = 0;
	TCHAR				szPrinter[256] = {0};
	RECT				aRect = {0};

	GetSelectedPrinter(szPrinter);

	aRect.left		= m_nLeft;
	aRect.top		= m_nTop;
	aRect.right		= m_nRight;
	aRect.bottom	= m_nBottom;

	dwRet = PAVO_EraseCardA(szPrinter, &aRect, 1);

	Temp.Format(_T("PrinterName = \"%s\",\n\n PAVO_EraseCardA() return %d,"), szPrinter, dwRet);

	MessageBox(Temp, _T("OnBtnEraseCard"), MB_OK);
}

void CDemo1Dlg::OnBtnQueryIOValue()
{
	DWORD				dwRet = 0;
	CString				Temp;
	DWORD				dwStatus = 0;
	TCHAR				szPrinter[256] = {0};
	BYTE				byValue;

	GetSelectedPrinter(szPrinter);

	
	dwRet = PAVO_QueryIOValueA(szPrinter, &byValue);

	Temp.Format(_T("PrinterName = \"%s\",\n\n OnBtnQueryIOValue() return %d, value %d"), szPrinter, dwRet, byValue);

	MessageBox(Temp, _T("OnBtnQueryIOValue"), MB_OK);
}


void CDemo1Dlg::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	CDialog::OnSize(nType, cx, cy);

	// TODO: Add your message handler code here.
	m_nCurHeight = cy;
	int nScrollMax;
	if (cy < m_rect.Height())
	{
	     nScrollMax = m_rect.Height() - cy;
	}
	else
	     nScrollMax = 0;

	SCROLLINFO si;
	si.cbSize = sizeof(SCROLLINFO);
	si.fMask = SIF_ALL; // SIF_ALL = SIF_PAGE | SIF_RANGE | SIF_POS;
	si.nMin = 0;
	si.nMax = nScrollMax;
	si.nPage = si.nMax/10;
	si.nPos = 0;
        SetScrollInfo(SB_VERT, &si, TRUE); 
}

void CDemo1Dlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	// TODO: Add your message handler code here and/or call default
	int nDelta;
	int nMaxPos = m_rect.Height() - m_nCurHeight;

	switch (nSBCode)
	{
	case SB_LINEDOWN:
		if (m_nScrollPos >= nMaxPos)
			return;
		nDelta = min(nMaxPos/100,nMaxPos-m_nScrollPos);
		break;

	case SB_LINEUP:
		if (m_nScrollPos <= 0)
			return;
		nDelta = -min(nMaxPos/100,m_nScrollPos);
		break;

         case SB_PAGEDOWN:
		if (m_nScrollPos >= nMaxPos)
			return;
		nDelta = min(nMaxPos/10,nMaxPos-m_nScrollPos);
		break;

	case SB_THUMBPOSITION:
		nDelta = (int)nPos - m_nScrollPos;
		break;

	case SB_PAGEUP:
		if (m_nScrollPos <= 0)
			return;
		nDelta = -min(nMaxPos/10,m_nScrollPos);
		break;
	
         default:
		return;
	}
	m_nScrollPos += nDelta;
	SetScrollPos(SB_VERT,m_nScrollPos,TRUE);
	ScrollWindow(0,-nDelta);
	
	CDialog::OnVScroll(nSBCode, nPos, pScrollBar);

}

void CDemo1Dlg::OnCheck290As230() 
{
	// TODO: Add your control notification handler code here
	
}

void CDemo1Dlg::OnBUTTONCS290eMODE1() 
{
	// TODO: Add your control notification handler code here
	TCHAR				szPrinter[256] = {0};
	DWORD				dwRet = 0;
	CString				Temp;

	GetSelectedPrinter(szPrinter);

	dwRet = PAVO_SetCS290eModeA(szPrinter, 1);
	
	Temp.Format(_T("Set CS290e to CS230e mode.\n\ndwRet = 0x%08X,"), dwRet);
	MessageBox(Temp, _T("OnBUTTONCS290eMODE1"), MB_OK);
}

void CDemo1Dlg::OnBUTTONCS290eMODE0() 
{
	// TODO: Add your control notification handler code here
	TCHAR				szPrinter[256] = {0};
	DWORD				dwRet = 0;
	CString				Temp;

	GetSelectedPrinter(szPrinter);

	dwRet = PAVO_SetCS290eModeA(szPrinter, 0);
	
	Temp.Format(_T("Set CS290e back to CS290e mode.\n\ndwRet = 0x%08X,"), dwRet);
	MessageBox(Temp, _T("OnBUTTONCS290eMODE0"), MB_OK);
}

void CDemo1Dlg::OnBttnDcm() 
{
	// TODO: Add your control notification handler code here
	if((m_uiRetryDcm < 256) && (m_uiTimeOutDcm > 0) && (m_uiTimeOutDcm < 256))
	{
		
	}
}
