// QRCodeDlg.cpp : 実装ファイル
//

#include "stdafx.h"
#include "QRCode.h"
#include "QRCodeDlg.h"

#include "CAO_i.c" 

CComModule _Module;

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CQRCodeDlg ダイアログ
CQRCodeDlg::CQRCodeDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CQRCodeDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	m_eng  = NULL;
	m_wss  = NULL;
	m_ws   = NULL;
	m_ctrl = NULL;
	m_var  = NULL;

	pICEventSink = NULL;
}

void CQRCodeDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDIT_COM, txtCom);
	DDX_Control(pDX, IDC_COMBO_MODE, cmbMode);
	DDX_Control(pDX, IDC_BUTTON_CONNECT_SCANNER, btnConnect);
	DDX_Control(pDX, IDC_BUTTON_DISCONNECT_SCANNER, btnDisconnect);
	DDX_Control(pDX, IDC_BUTTON_READDATA, btnReadData);
	DDX_Control(pDX, IDC_BUTTON_CLEAR, btnClear);
	DDX_Control(pDX, IDC_LIST_RESULT, lstResult);
}

BEGIN_MESSAGE_MAP(CQRCodeDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BUTTON_CONNECT_SCANNER, &CQRCodeDlg::OnBnClickedButtonConnectScanner)
	ON_BN_CLICKED(IDC_BUTTON_DISCONNECT_SCANNER, &CQRCodeDlg::OnBnClickedButtonDisconnectScanner)
	ON_BN_CLICKED(IDC_BUTTON_READDATA, &CQRCodeDlg::OnBnClickedButtonReaddata)
	ON_BN_CLICKED(IDC_BUTTON_CLEAR, &CQRCodeDlg::OnBnClickedButtonClear)
	ON_WM_DESTROY()
END_MESSAGE_MAP()


// CQRCodeDlg メッセージ ハンドラ

BOOL CQRCodeDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
	//  Framework は、この設定を自動的に行います。
	SetIcon(m_hIcon, TRUE);			// 大きいアイコンの設定
	SetIcon(m_hIcon, FALSE);		// 小さいアイコンの設定

	CoInitialize(0); 
	_Module.Init(NULL, ::GetModuleHandle(NULL));

	HRESULT hr = CoCreateInstance(CLSID_CaoEngine, NULL, CLSCTX_LOCAL_SERVER, IID_ICaoEngine, (void **)&m_eng); 
	if(FAILED(hr)){
		ShowErrorMessage(hr);
		return FALSE;
	}

	m_eng->get_Workspaces(&m_wss); 	
	m_wss->Item(CComVariant(0L), &m_ws);

	// Initialize control
	txtCom.SetWindowText(_T("1"));	// COM1
	cmbMode.SetCurSel(0);			// EVENT

	return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}

void CQRCodeDlg::OnDestroy()
{
	CDialog::OnDestroy();
	
	if(m_ctrl)
	{
		OnBnClickedButtonDisconnectScanner();
	}	

	if(m_ws)
	{
		m_ws->Release();
		m_ws = NULL;
	}

	if(m_wss)
	{  
		m_wss->Release();
		m_wss = NULL;
	}

	if(m_eng)
	{
		m_eng->Release();
		m_eng = NULL;
	}

	_Module.Term();
	CoUninitialize();
}

// ダイアログに最小化ボタンを追加する場合、アイコンを描画するための
//  下のコードが必要です。ドキュメント/ビュー モデルを使う MFC アプリケーションの場合、
//  これは、Framework によって自動的に設定されます。

void CQRCodeDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 描画のデバイス コンテキスト

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// クライアントの四角形領域内の中央
		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;

		// アイコンの描画
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// ユーザーが最小化したウィンドウをドラッグしているときに表示するカーソルを取得するために、
//  システムがこの関数を呼び出します。
HCURSOR CQRCodeDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CQRCodeDlg::OnBnClickedButtonConnectScanner()
{
	HRESULT hr = E_FAIL;
	CString  strCom;
	CString  strConnectMode;
	CString  strOption;
	BOOL bReadData = FALSE;

	// Get com number
	txtCom.GetWindowText(strCom);

	// Check connection mode
	switch(cmbMode.GetCurSel()){
		case 0:	// EVENT
			strConnectMode = "5";
			bReadData = FALSE;
			break;
		case 1:	// COMMAND
			strConnectMode = "4";
			bReadData = TRUE;
			break;
		default:
			break;
	}

	strOption  = _T("Conn=com:") + strCom + _T(":38400:N:8:1,Mode=") + strConnectMode + _T(",Protocol=0:0:0, Timeout=1000");

	// Connect
	hr = m_ws->AddController(CComBSTR(L"QRCode"), CComBSTR(L"CaoProv.DENSO.QRCode"), CComBSTR(L""), CComBSTR(strOption), &m_ctrl);
	if(SUCCEEDED(hr)){
		// Create EventSink object
		CComObject<CEventSink>::CreateInstance(&pICEventSink);
		pICEventSink->SetMainWindow(this->m_hWnd);
		pICEventSink->AddRef();
		pICEventSink->DispEventAdvise(m_ctrl, &DIID__ICaoControllerEvents);

		if(bReadData){
			m_ctrl->AddVariable(CComBSTR(L"ReadData"), CComBSTR(L""), &m_var);
		}

		// Enable buttons
		btnReadData.EnableWindow(bReadData);
		btnDisconnect.EnableWindow(TRUE);
		btnConnect.EnableWindow(FALSE);
		cmbMode.EnableWindow(FALSE);
		txtCom.EnableWindow(FALSE);
	}
	else
	{
		OnBnClickedButtonDisconnectScanner();
		ShowErrorMessage(hr);
	}
}

void CQRCodeDlg::OnBnClickedButtonDisconnectScanner()
{
	if(pICEventSink){
		pICEventSink->DispEventUnadvise(m_ctrl, &DIID__ICaoControllerEvents);
		pICEventSink->Release();
		pICEventSink = NULL;
	}

	// Disconnect
	if(m_var){
		m_var->Release();
		m_var = NULL;
	}

	if(m_ctrl)
	{
		if(m_ws)
		{
			CComVariant vntCtrlName;
			CComPtr<ICaoControllers> ctrls;

			m_ws->get_Controllers(&ctrls);

			vntCtrlName.vt = VT_BSTR;
			m_ctrl->get_Name(&vntCtrlName.bstrVal);

			ctrls->Remove(vntCtrlName);
		}
		m_ctrl->Release();
		m_ctrl = NULL;
	}

	// Disable buttons
	btnReadData.EnableWindow(FALSE);
	btnDisconnect.EnableWindow(FALSE);
	btnConnect.EnableWindow(TRUE);
	cmbMode.EnableWindow(TRUE);
	txtCom.EnableWindow(TRUE);
}

void CQRCodeDlg::OnBnClickedButtonReaddata()
{
	HRESULT hr;
	CString strValue;
	CComVariant vntValue;

	hr = m_var->get_Value(&vntValue);

	if(SUCCEEDED(hr)){
		strValue.Format(_T("%ls"), (LPCWSTR)vntValue.bstrVal);
		lstResult.AddString(strValue);
	}else{
		ShowErrorMessage(hr);
	}
}

void CQRCodeDlg::OnBnClickedButtonClear()
{
	lstResult.ResetContent();
}

void CQRCodeDlg::ShowErrorMessage(HRESULT hr)
{
	CString strMsg;
	strMsg.Format(_T("%X"), hr);
	MessageBox(strMsg, _T("Error"));
}
