
//	IT4xxx.dllサンプルプログラム（メッセージ処理）


#include <windows.h>
#include <stdio.h>
#include <commctrl.h>

#include "resource.h"
#include "IT4xxx.h"

char	*lpszAppName = "VCSample(Message)" ;

HANDLE  g_hInst;
HWND	g_hOwnerWnd;
HANDLE	g_hDlg  = NULL;
HANDLE  g_hProgDlg = NULL ;

int		g_CmndF = 0 ;
long	ComId = -1 ;

#define	RECVBUFSIZE		2048

#define	ID_PROGTIMER	30000

#define	RECVMSG			WM_APP+10

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM) ;
LRESULT CALLBACK MainDlgProc(HWND, UINT, WPARAM, LPARAM) ;
LRESULT CALLBACK ProgressDlgProc(HWND, UINT, WPARAM, LPARAM) ;

static	void	ErrMessageDisp( int errcode ) ;

//===================================================================================

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hInstPrev,
                                LPSTR lpstrCmdLine, int cmdShow)
{
	WNDCLASS	wc;
	BOOL		bRet ;
	MSG			msg ;
	RECT		rc;
	RECT		dlgrc;

	wc.style            = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc      = WndProc;
	wc.cbClsExtra       = 0;
	wc.cbWndExtra       = 0;
	wc.hInstance        = hInstance;
	wc.hIcon            = LoadIcon(hInstance, IDI_APPLICATION);
	wc.hCursor          = LoadCursor (NULL, IDC_ARROW);
	wc.hbrBackground    = (HBRUSH) (COLOR_APPWORKSPACE+1);
	wc.lpszMenuName     = NULL;
	wc.lpszClassName    = lpszAppName;

	if (!RegisterClass (&wc) )
		return FALSE;

	g_hOwnerWnd = CreateWindow (lpszAppName, lpszAppName,
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, CW_USEDEFAULT,
                        500, 360,
                        NULL, NULL, hInstance, NULL);
	g_hInst = hInstance;

	g_hDlg = CreateDialog(g_hInst, "SAMPLEDIALOG", g_hOwnerWnd, (DLGPROC)MainDlgProc);

	GetWindowRect( g_hOwnerWnd, &rc ) ;
	GetWindowRect( g_hDlg, &dlgrc ) ;
	MoveWindow( g_hOwnerWnd, rc.left, rc.top, dlgrc.right - dlgrc.left, dlgrc.bottom - dlgrc.top + 30, FALSE ) ;

	ShowWindow( g_hDlg, cmdShow ) ;
	ShowWindow( g_hOwnerWnd, cmdShow ) ;
	UpdateWindow( g_hOwnerWnd ) ;

	while( ( bRet = GetMessage( &msg, NULL, 0, 0 ) ) != 0 ){
		if( bRet == -1 )
			break ;

		if( !IsDialogMessage(g_hDlg, &msg) &&
			( !g_hProgDlg || !IsDialogMessage(g_hProgDlg, &msg) )){
			TranslateMessage( &msg ) ;
			DispatchMessage( &msg ) ;
		}
	}

	return( 0 ) ;
}

//===================================================================================
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	switch (uMsg) {
		case WM_CREATE:
			break;

		case WM_CLOSE:
			if( g_CmndF == 2 )
				break ;

			DestroyWindow( g_hDlg ) ;
			DestroyWindow( hWnd ) ;
			break;

		case WM_DESTROY:
			PostQuitMessage(0);
			break;

		default:
			return (DefWindowProc(hWnd, uMsg, wParam, lParam));
	}
	return 0L;
}

//===================================================================================
LRESULT CALLBACK MainDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	unsigned char	recvdata[RECVBUFSIZE+1] ;
	unsigned char	senddata[RECVBUFSIZE+1] ;
	int		portno ;
	int		ret ;
	char	editbuf[10] ;
	int		idx ;
	int		recvcnt ;
	int		chcnt ;
	int		length ;
	long	editid ;

	switch (uMsg) {
		case WM_INITDIALOG:
			SendDlgItemMessage (hDlg, IDC_SEND_DATA, EM_SETLIMITTEXT, RECVBUFSIZE, 0 );

			for( portno = 1; portno <= 10; portno++ ){
				sprintf( editbuf, "COM%d", portno ) ;
				SendMessage(GetDlgItem(hDlg, IDC_PORTNO), CB_ADDSTRING, (WPARAM)0, (LPARAM)editbuf);
			}

			SendDlgItemMessage( hDlg, IDC_PORTNO, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);

			EnableWindow (GetDlgItem (hDlg, IDC_PORTNO ),    TRUE );
			EnableWindow (GetDlgItem (hDlg, IDC_BTN_OPEN ),  TRUE );

			EnableWindow (GetDlgItem (hDlg, IDC_BTN_SEND),   FALSE);
			EnableWindow (GetDlgItem (hDlg, IDC_BTN_CLOSE ), FALSE);
			EnableWindow (GetDlgItem (hDlg, IDC_BTN_STOP ),  FALSE);

			break ;

		case WM_DESTROY:
			IT4xxx_RecvStop( ComId ) ;
			IT4xxx_PortClose( ComId ) ;
			return FALSE ;

		case WM_COMMAND:
			switch( LOWORD( wParam ) ) {
				case IDC_BTN_OPEN :		//	開始−ポートオープンおよびタイマー設定
						EnableWindow (GetDlgItem (hDlg, IDC_PORTNO ),   FALSE );
						EnableWindow (GetDlgItem (hDlg, IDC_BTN_OPEN ), FALSE);

						//	ポートオープン（非同期）
						portno = SendDlgItemMessage (hDlg, IDC_PORTNO, CB_GETCURSEL , 0, 0L ) + 1 ;
						if( ( ComId = IT4xxx_PortOpen( portno, IT4xxx_BAUD_9600, IT4xxx_DATABIT_8, IT4xxx_STOPBIT_1,
							IT4xxx_PARITY_NONE, IT4xxx_FLOW_RTSCTS) ) < 0 ) {
							MessageBox ( hDlg, "ポートがオープンできません", "VCTest", MB_OK ) ;
							EnableWindow (GetDlgItem (hDlg, IDC_PORTNO ),   TRUE );
							EnableWindow (GetDlgItem (hDlg, IDC_BTN_OPEN ), TRUE);
							break ;
						}

						//	キャラクタ間のタイムアウトを100msに設定
						IT4xxx_TimeoutSet( ComId, -1, 100 ) ;

						//	受信ポートをチェックするためのスレッドを作成
						if( IT4xxx_RecvStart( ComId, hDlg, RECVMSG ) != IT4xxx_NORMAL_END ){
							MessageBox ( hDlg, "スレッドが作成できません", "VCTest", MB_OK ) ;
							IT4xxx_PortClose( ComId ) ;
							EnableWindow (GetDlgItem (hDlg, IDC_PORTNO ), TRUE );
							EnableWindow (GetDlgItem (hDlg, IDC_BTN_OPEN ), TRUE);
							EnableWindow (GetDlgItem (hDlg, IDC_BTN_SEND), FALSE);
							break ;
						}

						g_CmndF = 0 ;

						EnableWindow (GetDlgItem (hDlg, IDC_BTN_SEND),  TRUE );
						EnableWindow (GetDlgItem (hDlg, IDC_BTN_CLOSE), TRUE );
						EnableWindow (GetDlgItem (hDlg, IDC_BTN_STOP),  TRUE );
						break ;

				case IDC_BTN_CLOSE :
						//	イメージ受信中は終了しない
						if( g_CmndF == 2 )
							break ;

						//	通信終了−スレッド終了およびポートクローズ
						IT4xxx_RecvStop( ComId ) ;
						IT4xxx_PortClose( ComId ) ;

						EnableWindow (GetDlgItem (hDlg, IDC_PORTNO ),    TRUE );
						EnableWindow (GetDlgItem (hDlg, IDC_BTN_OPEN ),  TRUE );
						EnableWindow (GetDlgItem (hDlg, IDC_BTN_SEND),   FALSE);
						EnableWindow (GetDlgItem (hDlg, IDC_BTN_CLOSE ), FALSE);
						EnableWindow (GetDlgItem (hDlg, IDC_BTN_STOP ),  FALSE);
						break ;

				case IDC_BTN_STOP :
						IT4xxx_ComCancel( ComId ) ;
						break ;

				case IDC_BTN_SEND :
						SendDlgItemMessage (hDlg, IDC_SEND_DATA, WM_GETTEXT, sizeof(senddata), (long) senddata ) ;
						if( !senddata[0] ){
							MessageBox ( hDlg, "コマンドを入力してください", lpszAppName, MB_OK ) ;
							break ;
						}

						//	コマンド送信
						ret = IT4xxx_CmndSend( ComId, senddata, strlen(senddata) ) ;
						if( ret != IT4xxx_NORMAL_END )
							ErrMessageDisp( ret ) ;
						else{
							EnableWindow (GetDlgItem (hDlg, IDC_BTN_SEND),  FALSE);

							for( chcnt = 0; senddata[chcnt]; chcnt++ )
								senddata[chcnt] = toupper( senddata[chcnt] ) ;

							if( strstr( senddata, "IMG" ) && 
								( strstr( senddata, "SHP")  || strstr( senddata, "BOX") )  &&
								strchr( senddata, '?' ) <= 0 &&
								strchr( senddata, '^' ) <= 0 )
								g_CmndF = 2 ;
							else
								g_CmndF = 1 ;
						}

						break ;

				default:
						return FALSE;
			}
			break ;

		//	受信メッセージの処理
		case RECVMSG:
			//	データ受信のチェック
			if( IT4xxx_RecvChk( ComId ) <= 0 )
				break ;

			switch( g_CmndF ){
				case 0 :	//	データの受信
						editid = IDC_RECV_DATA ;
						recvcnt = IT4xxx_DataRecv( ComId, recvdata, RECVBUFSIZE, NULL, NULL ) ;
						break ;

				case 1 :	//	レスポンスの受信
						editid = IDC_RESPONSE ;
						SendDlgItemMessage( hDlg, IDC_RESPONSE, WM_SETTEXT, (WPARAM)0, (LPARAM)"");
						recvcnt = IT4xxx_ResponseRecv( ComId, recvdata, RECVBUFSIZE ) ;
						break ;

				case 2 :	//	イメージの受信
						editid = IDC_RESPONSE ;
						SendDlgItemMessage( hDlg, IDC_RESPONSE, WM_SETTEXT, (WPARAM)0, (LPARAM)"");

						//	受信状況を表示する
						g_hProgDlg = CreateDialog(g_hInst, "PROGRESSDIALOG", g_hDlg, (DLGPROC)ProgressDlgProc);
						ShowWindow( g_hProgDlg, SW_SHOWNORMAL ) ;

						recvcnt = IT4xxx_ImageRecv( ComId, "RecvImage.jpg", recvdata, RECVBUFSIZE, IT4xxx_PROTOCOL_2P ) ;

						//	受信状況表示の終了
						DestroyWindow( g_hProgDlg ) ; 
						g_hProgDlg = NULL ;

						break ;
			}

			if( recvcnt < 0 )
				ErrMessageDisp( recvcnt ) ;
			else{
				for( idx = 0; idx < recvcnt && recvdata[idx]; idx++ ){
					switch( recvdata[idx] ){
						case 0x06 : strcpy( editbuf, "<ACK>" ) ;	break ;
						case 0x05 : strcpy( editbuf, "<ENQ>" ) ;	break ;
						case 0x0A : strcpy( editbuf, "<LF>" )  ;	break ;
						case 0x0D : strcpy( editbuf, "<CR>" )  ;	break ;
						case 0x15 : strcpy( editbuf, "<NAK>" ) ;	break ;
						case 0x16 : strcpy( editbuf, "<SYN>" ) ;	break ;
						default :
							if( isprint( recvdata[idx] ) ){
								editbuf[0] = recvdata[idx] ;
								editbuf[1] = 0 ;
							}
							else
								sprintf( editbuf, "<%02X>",  (unsigned char)recvdata[idx] ) ;
							break ;
					}

					//	受信したデータの表示
					length=GetWindowTextLength(GetDlgItem(hDlg, editid)) ;
					SendDlgItemMessage( hDlg, editid, EM_SETSEL,length,length) ;
					SendDlgItemMessage( hDlg, editid, EM_REPLACESEL, 0, (LPARAM)editbuf) ;
				}

				if( editid == IDC_RECV_DATA )
					SendDlgItemMessage( hDlg, editid, WM_CHAR, '\n', 0 ) ;
			}

			g_CmndF = 0 ;

			EnableWindow (GetDlgItem (hDlg, IDC_BTN_SEND),  TRUE);

			break;

		default:
			return FALSE;
	}
	return TRUE;
}

static	void	ErrMessageDisp( int errcode )
{
	switch( errcode ){
		case IT4xxx_NORMAL_END    :  break ;
		case IT4xxx_ERR_NOTOPEN	  : MessageBox ( g_hDlg, "ポート未オープン", lpszAppName, MB_OK ) ; break ;
		case IT4xxx_ERR_FILE	  : MessageBox ( g_hDlg, "ファイルエラー",   lpszAppName, MB_OK ) ; break ;
		case IT4xxx_ERR_TIMEOUT	  : MessageBox ( g_hDlg, "受信タイムアウト", lpszAppName, MB_OK ) ; break ;
		case IT4xxx_ERR_CANCEL	  : MessageBox ( g_hDlg, "キャンセル",       lpszAppName, MB_OK ) ; break ;
		case IT4xxx_ERR_PARAMETER : MessageBox ( g_hDlg, "パラメータエラー", lpszAppName, MB_OK ) ; break ;
		case IT4xxx_ERR_COM		  : MessageBox ( g_hDlg, "通信エラー",       lpszAppName, MB_OK ) ; break ;
		case IT4xxx_ERR_FULL	  : IT4xxx_ComClear( ComId ) ;
									MessageBox ( g_hDlg, "バッファフル",     lpszAppName, MB_OK ) ; break ;
		default	                  : MessageBox ( g_hDlg, "エラー発生",       lpszAppName, MB_OK ) ; break ;
	}
}

LRESULT CALLBACK ProgressDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    HWND hProg;
	long ret ;
	long FileSize ;
	long RecvSize ;

	switch (uMsg) {
		case WM_INITDIALOG:
			hProg = GetDlgItem(hDlg, IDC_PROGRESS1);
			SendMessage(hProg, PBM_SETRANGE, (WPARAM)0, MAKELPARAM(0, 100));
            SendMessage(hProg, PBM_SETPOS, 0, 0);
			SendMessage(GetDlgItem(hDlg, IDC_RECVMSG), WM_SETTEXT, (WPARAM)0, (LPARAM)"イメージ受信中．．．");
			SetTimer(hDlg, ID_PROGTIMER, 100, NULL);
			break ;

		case WM_DESTROY:
			return FALSE ;

		case WM_TIMER:
			if( wParam != ID_PROGTIMER )
				return FALSE;

			KillTimer( hDlg, ID_PROGTIMER ) ;

			if( ComId < 0 )
				break ;

		    ret = IT4xxx_ImageProgress(ComId, &FileSize, &RecvSize) ;
    
			hProg = GetDlgItem(hDlg, IDC_PROGRESS1);
			switch (ret){
				case IT4xxx_IMG_BUFFCLEAR:
						SendMessage(GetDlgItem(hDlg, IDC_RECVMSG), WM_SETTEXT, 
										(WPARAM)0, (LPARAM)"受信バッファをクリアしています");
						break ;
				case IT4xxx_IMG_RECEIVING :
						if( FileSize > 0 && RecvSize > 0 ){
							double val = RecvSize ;
							RecvSize = (long)(val / FileSize * 100) ;
				            SendMessage(hProg, PBM_SETPOS, RecvSize, 0 );
						}
						else
				            SendMessage(hProg, PBM_SETPOS, 0, 0);
						break ;
				default :
			            SendMessage(hProg, PBM_SETPOS, 0, 0);
						break ;
			}

			SetTimer(hDlg, ID_PROGTIMER, 100, NULL);

			break;

		default:
			return FALSE;
	}
	return TRUE;
}

