// DataMatrixVc6TestDlg.cpp : implementation file
//

#include "stdafx.h"
#include "DataMatrixVc6Test.h"
#include "DataMatrixVc6TestDlg.h"
#include "../../DataMatrixEncodeLib.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
HBITMAP hbmp = NULL;
/////////////////////////////////////////////////////////////////////////////
// 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
	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)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDataMatrixVc6TestDlg dialog

CDataMatrixVc6TestDlg::CDataMatrixVc6TestDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDataMatrixVc6TestDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDataMatrixVc6TestDlg)
	m_nColumns = -1;
	m_nMargin = 10;
	m_nModuleSize = 4;
	m_nRows = 1;
	m_strText = _T("http://www.aipsys.com");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CDataMatrixVc6TestDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDataMatrixVc6TestDlg)
	DDX_Control(pDX, IDC_ENCODEMODE, m_EncodeMode);
	DDX_Control(pDX, IDC_FORECOLOR, m_ForeColor);
	DDX_Control(pDX, IDC_BACKCOLOR, m_BackColor);
	DDX_Text(pDX, IDC_COLUMNS, m_nColumns);
	DDX_Text(pDX, IDC_MARGIN, m_nMargin);
	DDX_Text(pDX, IDC_MODULESIZE, m_nModuleSize);
	DDX_Text(pDX, IDC_TEXT, m_strText);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CDataMatrixVc6TestDlg, CDialog)
	//{{AFX_MSG_MAP(CDataMatrixVc6TestDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDENCODE, OnEncode)
	ON_BN_CLICKED(IDSAVE, OnSave)
	ON_BN_CLICKED(IDBUY, OnBuy)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDataMatrixVc6TestDlg message handlers

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

	// 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
	
	m_BackColor.SetColor(RGB(255,255,255));
    m_ForeColor.SetColor(RGB(0,0,0));
	SetDropDownSize(m_EncodeMode, 5);
	m_EncodeMode.SetCurSel(0);
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CDataMatrixVc6TestDlg::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 CDataMatrixVc6TestDlg::OnPaint() 
{
	CBitmap m_OffscreenBitmap, *m_pOldBitmap;

	CPaintDC dc(this); // device context for painting

	if (IsIconic())
	{

		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();
	}
	dc.TextOut(100,150,"Trial version will replace some elements of input ing with '*' randomly");
    if (hbmp)
	{
		CDC m_dcOffscreen;

		m_dcOffscreen.CreateCompatibleDC(&dc);
		m_OffscreenBitmap.Attach(hbmp);
		m_pOldBitmap = m_dcOffscreen.SelectObject(&m_OffscreenBitmap);
		dc.BitBlt(10, 10, 300, 300,&m_dcOffscreen, 0, 0, SRCCOPY);
		m_pOldBitmap = m_dcOffscreen.SelectObject(m_pOldBitmap);
		m_OffscreenBitmap.Detach();
		ReleaseDC(&m_dcOffscreen);
	}
}

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

void CDataMatrixVc6TestDlg::SetDropDownSize(CComboBox &box, UINT LinesToDisplay)
{
    ASSERT(IsWindow(box));	// Window must exist or SetWindowPos won't work

    CRect cbSize;			// current size of combo box
    int Height;				// new height for drop-down portion of combo box

    box.GetClientRect(cbSize);
    Height = box.GetItemHeight(-1);      // start with size of the edit-box portion
    Height += box.GetItemHeight(0) * LinesToDisplay;	// add height of lines of text

    // Note: The use of SM_CYEDGE assumes that we're using Windows '95
    // Now add on the height of the border of the edit box
    Height += GetSystemMetrics(SM_CYEDGE) * 2; // top & bottom edges

    // The height of the border of the drop-down box
    Height += GetSystemMetrics(SM_CYEDGE) * 2; // top & bottom edges

    // now set the size of the window
    box.SetWindowPos(NULL,            // not relative to any other windows
        0, 0,                         // TopLeft corner doesn't change
        cbSize.right, Height,         // existing width, new height
        SWP_NOMOVE | SWP_NOZORDER     // don't move box or change z-ordering.
        );
}

void CDataMatrixVc6TestDlg::OnEncode() 
{
   	_DATAMATRIXCONTEXT tDmCtx;

    UpdateData();	
	
	_InitDataMatrixContext(&tDmCtx);

	tDmCtx.encoding = m_EncodeMode.GetCurSel();

	tDmCtx.nMargin = m_nMargin;
	tDmCtx.sizePattern = m_nColumns;
	tDmCtx.dotPixel = m_nModuleSize;
	tDmCtx.clBackGround = m_BackColor.GetColor();
	tDmCtx.clForeGround = m_ForeColor.GetColor();
	if (m_strText != "") memcpy(tDmCtx.code,m_strText.GetBuffer(0),m_strText.GetLength());
	tDmCtx.size = m_strText.GetLength();
	
	_FreeDataMatrixContext();
	hbmp =_DataMatrixEncode2Bitmap(&tDmCtx);

    
	Invalidate();	
}

void CDataMatrixVc6TestDlg::OnSave() 
{
	CFileDialog dlgFile(FALSE);
	if (dlgFile.DoModal() == IDOK)
	{
		CString sFile = dlgFile.GetFileName();
		int nPos = sFile.ReverseFind('.');
		CString sExt = sFile.Right(sFile.GetLength() - nPos);
		sExt.MakeUpper();
		if (sExt == ".GIF")
			MessageBox("Only support BMP format","alert",MB_OK);
		else if (sExt == ".PNG")
			MessageBox("Only support BMP format","alert",MB_OK);
		else if (sExt == ".BMP")
			SaveBitmapToFile(hbmp,sFile.GetBuffer(0));
//			xImage.Save(sFile,CXIMAGE_FORMAT_BMP);
		else	//		xImage.Save(sFile,CXIMAGE_FORMAT_BMP);
			SaveBitmapToFile(hbmp,sFile.GetBuffer(0));

	}		
}

void CDataMatrixVc6TestDlg::OnBuy() 
{
	   	_DATAMATRIXCONTEXT tDmCtx;
	
	_InitDataMatrixContext(&tDmCtx);

	tDmCtx.encoding = m_EncodeMode.GetCurSel();

    tDmCtx.nMargin = 10;
	tDmCtx.sizePattern = -1;
	tDmCtx.dotPixel = 4;
	tDmCtx.encoding = 0;
	tDmCtx.clBackGround = 0xffffff;
	tDmCtx.clForeGround = 0;

	memcpy(tDmCtx.code,"0011201034",10);


    tDmCtx.code[0]=232;
    tDmCtx.code[5]=232;

	tDmCtx.size = 10;
		
	_FreeDataMatrixContext();
	_DataMatrixEncode2File(&tDmCtx,"c:\\tt.bmp");


//   ShellExecute(this->GetSafeHwnd(),"open","http://www.aipsys.com/order.htm",NULL,NULL,SW_SHOW);	
}

BOOL CDataMatrixVc6TestDlg::SaveBitmapToFile(HBITMAP hBitmap , LPCTSTR lpFileName) 
{

	HDC hDC; 


	int iBits; 


	WORD wBitCount; 

	DWORD dwPaletteSize=0,
	dwBmBitsSize,
	dwDIBSize, dwWritten;


	BITMAP Bitmap; 


	BITMAPFILEHEADER bmfHdr; 


	BITMAPINFOHEADER bi; 


	LPBITMAPINFOHEADER lpbi;


	HANDLE fh, hDib;
	HPALETTE hPal,hOldPal=NULL;


	hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
	iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
	DeleteDC(hDC);

	if (iBits <= 1)
		wBitCount = 1;
	else if (iBits <= 4)
		wBitCount = 4;
	else if (iBits <= 8)
		wBitCount = 8;
	else if (iBits <= 24)
		wBitCount = 24;
	else 
		wBitCount = 32;

	if (wBitCount <= 8)
		dwPaletteSize = (1 << wBitCount) *sizeof(RGBQUAD);


	GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
	bi.biSize = sizeof(BITMAPINFOHEADER);
	bi.biWidth = Bitmap.bmWidth;
	bi.biHeight = Bitmap.bmHeight;
	bi.biPlanes = 1;
	bi.biBitCount = wBitCount;
	bi.biCompression = BI_RGB;
	bi.biSizeImage = 0;
	bi.biXPelsPerMeter = 0;
	bi.biYPelsPerMeter = 0;
	bi.biClrUsed = 0;
	bi.biClrImportant = 0;

	dwBmBitsSize = ((Bitmap.bmWidth *wBitCount+31)/32)* 4*Bitmap.bmHeight ;


	hDib = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
	*lpbi = bi;


	hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
	if (hPal)
	{
		hDC = ::GetDC(NULL);
		hOldPal = SelectPalette(hDC, hPal, FALSE);
		RealizePalette(hDC);
	}


	GetDIBits(hDC, hBitmap, 0, (UINT)Bitmap.bmHeight,(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);


	if (hOldPal)
	{
		SelectPalette(hDC, hOldPal, TRUE);
		RealizePalette(hDC);
		::ReleaseDC(NULL, hDC);
	}


	fh = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
	FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

	if (fh == INVALID_HANDLE_VALUE)
		return FALSE;


	bmfHdr.bfType = 0x4D42; // "BM"
	dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize; 
	bmfHdr.bfSize = dwDIBSize;
	bmfHdr.bfReserved1 = 0;
	bmfHdr.bfReserved2 = 0;
	bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER)+ dwPaletteSize;


	WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);


	WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);


	GlobalUnlock(hDib);
	GlobalFree(hDib);
	CloseHandle(fh);

	return TRUE;
}
