SoundGraphAccess.cpp
author lenclud@WUE-9BW295J.ad.garmin.com
Fri, 08 Feb 2013 18:40:08 +0100
changeset 4 0b9403db32ef
parent 3 e4cac218e73f
child 5 d8eb6be0f3d5
permissions -rw-r--r--
Basic support for VFD text API.
     1 // SoundGraphAccess.cpp : Defines the entry point for the application.
     2 //
     3 
     4 #include "stdafx.h"
     5 #include "SoundGraphAccess.h"
     6 #include "iMONDisplayAPI.h"
     7 #include <stdio.h>
     8 
     9 #define WM_DSP_PLUGIN_NOTIFY			WM_APP + 1100
    10 #define WM_IMON_INIT					WM_APP + 1101
    11 #define WM_IMON_UNINIT					WM_APP + 1102
    12 #define WM_IMON_IS_INIT					WM_APP + 1103
    13 #define WM_IMON_IS_PLUGIN_MODE_ENABLED	WM_APP + 1104
    14 #define WM_IMON_DISPLAY_SET_VFD_TEXT	WM_APP + 1105
    15 
    16 //
    17 #define MAX_LOADSTRING 100
    18 
    19 
    20 // Global Variables:
    21 HINSTANCE hInst = 0;								// current instance
    22 TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
    23 TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name
    24 HANDLE gThreadReceiver = INVALID_HANDLE_VALUE;
    25 //HANDLE gThreadSender = INVALID_HANDLE_VALUE;
    26 BOOL gQuit=FALSE;
    27 
    28 LPTSTR gPipeNameSender = TEXT("\\\\.\\pipe\\sga-sender"); 
    29 LPTSTR gPipeNameReceiver = TEXT("\\\\.\\pipe\\sga-receiver"); 
    30 HANDLE gPipeSender=INVALID_HANDLE_VALUE;
    31 HANDLE gPipeReceiver=INVALID_HANDLE_VALUE;
    32 
    33 char gBufferReceiver[256];
    34 char gBufferSender[256];
    35 //
    36 char gTextFirstLine[256];
    37 char gTextSecondLine[256];
    38 wchar_t gTextFirstLine16[256];
    39 wchar_t gTextSecondLine16[256];
    40 
    41 //
    42 HWND gWnd;
    43 
    44 //
    45 BOOL m_bVfdConnected;
    46 BOOL m_bLcdConnected;
    47 
    48 // Forward declarations of functions included in this code module:
    49 ATOM				MyRegisterClass(HINSTANCE hInstance);
    50 BOOL				InitInstance(HINSTANCE, int);
    51 LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
    52 INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);
    53 
    54 //Supported responses
    55 const char KRspDone[]="done:";
    56 const char KRspPending[]="pending:";
    57 const char KRspError[]="error:";
    58 const char KRspClose[]="close:";
    59 const char KRspOpen[]="open:";
    60 const char KRspUnknown[]="unknown:";
    61 const char KRspTrue[]="true:";
    62 const char KRspFalse[]="false:";
    63 //Supported incoming messages
    64 const char KMsgInit[]="init:";
    65 const char KMsgUninit[]="uninit:";
    66 const char KMsgIsInit[]="is-init:";
    67 const char KMsgIsPluginModeEnabled[]="is-plugin-mode-enabled:";
    68 const char KMsgSetVfdText[]="set-vfd-text:";
    69 
    70 
    71 /**
    72 Send a message to our server.
    73 */
    74 void SendMessageToServer(const char* aResponse)
    75 	{
    76 	DWORD cbWritten=0;
    77 	char msg[512];
    78 	sprintf(msg,"%s\n",aResponse);
    79 	OutputDebugStringA(msg);
    80 	WriteFile(gPipeSender, aResponse, strlen(aResponse), &cbWritten, NULL);		
    81 	}
    82 
    83 
    84 /**
    85 Handle messages from our server.
    86 */
    87 void MessageReceived(const char* aMsg)
    88 	{
    89 	//
    90 	if (strcmp(aMsg,KMsgInit)==0)
    91 		{
    92 		//IMON API call need to be done from window thread for some reason
    93 		SendMessageToServer(KRspPending);
    94 		PostMessage(gWnd,WM_IMON_INIT,0,0);
    95 		}
    96 	else if (strcmp(aMsg,KMsgUninit)==0)
    97 		{
    98 		//IMON API call need to be done from window thread for some reason
    99 		SendMessageToServer(KRspPending);
   100 		PostMessage(gWnd,WM_IMON_UNINIT,0,0);		
   101 		}
   102 	else if (strcmp(aMsg,KMsgIsPluginModeEnabled)==0)
   103 		{
   104 		//IMON API call need to be done from window thread for some reason
   105 		SendMessageToServer(KRspPending);
   106 		PostMessage(gWnd,WM_IMON_IS_PLUGIN_MODE_ENABLED,0,0);		
   107 		}
   108 	else if (strcmp(aMsg,KMsgIsInit)==0)
   109 		{
   110 		//IMON API call need to be done from window thread for some reason
   111 		SendMessageToServer(KRspPending);
   112 		PostMessage(gWnd,WM_IMON_IS_INIT,0,0);		
   113 		}
   114 	else if (strstr(aMsg,KMsgSetVfdText)==aMsg)
   115 		{
   116 		int textLen=strlen(aMsg)-strlen(KMsgSetVfdText);
   117 		strncpy(gTextFirstLine,aMsg+strlen(KMsgSetVfdText),textLen);
   118 		gTextFirstLine[textLen]='\0';
   119 		OutputDebugStringA(gTextFirstLine);
   120 		int convertedChars = MultiByteToWideChar(CP_UTF8, 0, gTextFirstLine, -1, gTextFirstLine16, sizeof(gTextFirstLine16));
   121 		OutputDebugString(gTextFirstLine16);
   122 		//IMON API call need to be done from window thread for some reason
   123 		SendMessageToServer(KRspPending);
   124 		PostMessage(gWnd,WM_IMON_DISPLAY_SET_VFD_TEXT,0,0);		
   125 		}
   126 	else
   127 		{		
   128 		SendMessageToServer(KRspUnknown);
   129 		}
   130 	}
   131 
   132 
   133 
   134 /**
   135 Connect our named pipes from here.
   136 First connect our read pipe then our write pipe.
   137 Then notify our server we are connected.
   138 Then keep on waiting for incoming messages.
   139 */
   140 DWORD WINAPI ThreadReceiver( LPVOID lpParam )
   141 	{
   142 	//Keep on trying to connect on our read pipe
   143 	while (gPipeReceiver==INVALID_HANDLE_VALUE && !gQuit)
   144 		{
   145 		OutputDebugStringA("Trying to connect...\n");
   146 		gPipeReceiver=CreateFile(gPipeNameReceiver,	GENERIC_READ ,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
   147 		Sleep(1000);
   148 		}
   149 	
   150 	OutputDebugStringA("Read pipe open!\n");
   151 	//Now try connecting on our write pipe
   152 	gPipeSender=CreateFile(gPipeNameSender,	GENERIC_WRITE ,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
   153 	if (gPipeSender==INVALID_HANDLE_VALUE)
   154 		{
   155 		OutputDebugStringA("ERROR: Write pipe failure!\n");
   156 		gQuit=TRUE;
   157 		}
   158 	else
   159 		{
   160 		OutputDebugStringA("Write pipe opened.\n");
   161 		OutputDebugStringA("Connected.\n");
   162 		SendMessageToServer(KRspOpen);
   163 		}
   164 	//
   165 
   166 	while(!gQuit)
   167 		{
   168 		DWORD cbRead;
   169 		BOOL success=ReadFile(gPipeReceiver,gBufferReceiver,sizeof(gBufferReceiver),&cbRead, NULL); 
   170 		if(success)
   171 			{
   172 			gBufferReceiver[cbRead]='\0';
   173 			OutputDebugStringA(gBufferReceiver);
   174 			MessageReceived(gBufferReceiver);
   175 			}
   176 		//if (!success && GetLastError() != ERROR_MORE_DATA) 
   177 		//	{
   178 		//	OutputDebugStringA("Can't Read\n");
   179 		//	}
   180 		//
   181 		//Sleep(500);
   182 
   183 		if (!success)
   184 			{
   185 			gQuit=TRUE;
   186 			}
   187 		}
   188 
   189 	//Try tell our server
   190 	SendMessageToServer(KRspClose);
   191 	//Close our pipes
   192 	CloseHandle(gPipeReceiver);	
   193 	gPipeReceiver=INVALID_HANDLE_VALUE;
   194 	CloseHandle(gPipeSender);	
   195 	gPipeSender=INVALID_HANDLE_VALUE;
   196 	//Quit our application
   197 	PostMessage(gWnd,WM_CLOSE,0,0);
   198 		
   199 	return 0;
   200 	}
   201 
   202 
   203 
   204 /**
   205 */
   206 int APIENTRY _tWinMain(HINSTANCE hInstance,
   207                      HINSTANCE hPrevInstance,
   208                      LPTSTR    lpCmdLine,
   209                      int       nCmdShow)
   210 {
   211 	UNREFERENCED_PARAMETER(hPrevInstance);
   212 	UNREFERENCED_PARAMETER(lpCmdLine);
   213 
   214 	gTextFirstLine[0]='\0';
   215 	gTextSecondLine[0]='\0';
   216 	gTextFirstLine16[0]='\0';
   217 	gTextSecondLine16[0]='\0';
   218 
   219 
   220 	// TODO: Place code here.
   221 	MSG msg;
   222 	HACCEL hAccelTable;
   223 
   224 	// Initialize global strings
   225 	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
   226 	LoadString(hInstance, IDC_SOUNDGRAPHACCESS, szWindowClass, MAX_LOADSTRING);
   227 	MyRegisterClass(hInstance);
   228 
   229 	// Perform application initialization:
   230 	if (!InitInstance (hInstance, /*SW_HIDE*/ nCmdShow))
   231 		{
   232 		return FALSE;
   233 		}
   234 
   235 
   236 
   237 	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SOUNDGRAPHACCESS));
   238 
   239 	// Main message loop:
   240 	while (GetMessage(&msg, NULL, 0, 0))
   241 		{
   242 		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
   243 			{
   244 			TranslateMessage(&msg);
   245 			DispatchMessage(&msg);
   246 			}
   247 		}
   248 
   249 	return (int) msg.wParam;
   250 	}
   251 
   252 /**
   253 */
   254 void DisplayPluginMessage(UINT uErrCode, BOOL bError)
   255 	{
   256 	char* strErrMsg = "";
   257 
   258 	if(bError)
   259 		{
   260 		switch(uErrCode)
   261 			{
   262 			case DSPN_ERR_IN_USED:			strErrMsg = ("Display Plug-in is Already Used by Other Application.");		break;
   263 			case DSPN_ERR_HW_DISCONNECTED:	strErrMsg = ("iMON HW is Not Connected.");									break;
   264 			case DSPN_ERR_NOT_SUPPORTED_HW:	strErrMsg = ("The Connected iMON HW doesn't Support Display Plug-in.");		break;
   265 			case DSPN_ERR_PLUGIN_DISABLED:	strErrMsg = ("Display Plug-in Mode Option is Disabled.");					break;
   266 			case DSPN_ERR_IMON_NO_REPLY:	strErrMsg = ("The Latest iMON is Not Installed or iMON Not Running.");		break;
   267 			case DSPN_ERR_UNKNOWN:			strErrMsg = ("Unknown Failure.");											break;
   268 			}
   269 		}
   270 	else
   271 		{
   272 		switch(uErrCode)
   273 			{
   274 			case DSPNM_PLUGIN_SUCCEED:		strErrMsg = ("Plug-in Mode Inited Successfully.");			break;
   275 			case DSPNM_IMON_RESTARTED:		strErrMsg = ("iMON Started and Plug-in Mode Inited.");		break;
   276 			case DSPNM_HW_CONNECTED:		strErrMsg = ("iMON HW Connected and Plug-in Mode Inited.");	break;
   277 			}
   278 		}
   279 	//
   280 	OutputDebugStringA(strErrMsg);
   281 
   282 	char msg[256];
   283 	if (bError)
   284 		{
   285 		sprintf(msg,"error:%s",strErrMsg);
   286 		}
   287 	else
   288 		{
   289 		sprintf(msg,"done:%s",strErrMsg);	
   290 		}	
   291 	SendMessageToServer(msg);
   292 	}
   293 
   294 
   295 
   296 //
   297 //  FUNCTION: MyRegisterClass()
   298 //
   299 //  PURPOSE: Registers the window class.
   300 //
   301 //  COMMENTS:
   302 //
   303 //    This function and its usage are only necessary if you want this code
   304 //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
   305 //    function that was added to Windows 95. It is important to call this function
   306 //    so that the application will get 'well formed' small icons associated
   307 //    with it.
   308 //
   309 ATOM MyRegisterClass(HINSTANCE hInstance)
   310 {
   311 	WNDCLASSEX wcex;
   312 
   313 	wcex.cbSize = sizeof(WNDCLASSEX);
   314 
   315 	wcex.style			= CS_HREDRAW | CS_VREDRAW;
   316 	wcex.lpfnWndProc	= WndProc;
   317 	wcex.cbClsExtra		= 0;
   318 	wcex.cbWndExtra		= 0;
   319 	wcex.hInstance		= hInstance;
   320 	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SOUNDGRAPHACCESS));
   321 	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
   322 	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
   323 	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_SOUNDGRAPHACCESS);
   324 	wcex.lpszClassName	= szWindowClass;
   325 	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
   326 
   327 	return RegisterClassEx(&wcex);
   328 }
   329 
   330 //
   331 //   FUNCTION: InitInstance(HINSTANCE, int)
   332 //
   333 //   PURPOSE: Saves instance handle and creates main window
   334 //
   335 //   COMMENTS:
   336 //
   337 //        In this function, we save the instance handle in a global variable and
   338 //        create and display the main program window.
   339 //
   340 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
   341 {
   342    
   343 
   344    hInst = hInstance; // Store instance handle in our global variable
   345 
   346    gWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
   347       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
   348 
   349    if (!gWnd)
   350    {
   351       return FALSE;
   352    }
   353 
   354    ShowWindow(gWnd, nCmdShow);
   355    UpdateWindow(gWnd);
   356 
   357    return TRUE;
   358 }
   359 
   360 //
   361 //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
   362 //
   363 //  PURPOSE:  Processes messages for the main window.
   364 //
   365 //  WM_COMMAND	- process the application menu
   366 //  WM_PAINT	- Paint the main window
   367 //  WM_DESTROY	- post a quit message and return
   368 //
   369 //
   370 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
   371 {
   372 	int wmId, wmEvent;
   373 	PAINTSTRUCT ps;
   374 	HDC hdc;
   375 
   376 	switch (message)
   377 	{
   378 	case WM_CREATE:
   379 		//IMON_Display_Uninit();
   380 		//IMON_Display_Init(hWnd, WM_DSP_PLUGIN_NOTIFY);
   381 		gThreadReceiver = CreateThread( NULL, 0, ThreadReceiver, NULL/*data pointer*/, 0, NULL);
   382 		break;
   383 	case WM_COMMAND:
   384 		wmId    = LOWORD(wParam);
   385 		wmEvent = HIWORD(wParam);
   386 		// Parse the menu selections:
   387 		switch (wmId)
   388 		{
   389 		case IDM_ABOUT:
   390 			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
   391 			break;
   392 		case IDM_EXIT:
   393 			DestroyWindow(hWnd);
   394 			break;
   395 		default:
   396 			return DefWindowProc(hWnd, message, wParam, lParam);
   397 		}
   398 		break;
   399 	case WM_PAINT:
   400 		hdc = BeginPaint(hWnd, &ps);
   401 		// TODO: Add any drawing code here...
   402 		EndPaint(hWnd, &ps);
   403 		break;
   404 	case WM_DESTROY:
   405 		gQuit=TRUE;
   406 		//To complete write op
   407 		if (gPipeSender!=INVALID_HANDLE_VALUE)
   408 			{
   409 			CloseHandle(gPipeSender);
   410 			gPipeSender=INVALID_HANDLE_VALUE;
   411 			}
   412 		//To complete read op
   413 		if (gPipeReceiver!=INVALID_HANDLE_VALUE)
   414 			{
   415 			CloseHandle(gPipeReceiver);
   416 			gPipeReceiver=INVALID_HANDLE_VALUE;
   417 			}
   418 
   419 		WaitForSingleObject(gThreadReceiver,INFINITE);
   420 		CloseHandle(gThreadReceiver);
   421 		//IMON_Display_Uninit();
   422 		PostQuitMessage(0);
   423 		break;
   424 
   425 	case WM_IMON_UNINIT:
   426 		IMON_Display_Uninit();
   427 		SendMessageToServer(KRspDone);
   428 		break;
   429 
   430 	case WM_IMON_INIT:
   431 		IMON_Display_Uninit();
   432 		IMON_Display_Init(hWnd, WM_DSP_PLUGIN_NOTIFY);
   433 		break;
   434 	//
   435 	case WM_IMON_IS_PLUGIN_MODE_ENABLED:
   436 		if (IMON_Display_IsPluginModeEnabled()==DSP_S_IN_PLUGIN_MODE)
   437 			{
   438 			SendMessageToServer(KRspTrue);
   439 			}
   440 		else
   441 			{
   442 			SendMessageToServer(KRspFalse);
   443 			}
   444 		break;
   445 	//
   446 	case WM_IMON_IS_INIT:
   447 		if (IMON_Display_IsInited()==DSP_S_INITED)
   448 			{
   449 			SendMessageToServer(KRspTrue);
   450 			}
   451 		else
   452 			{
   453 			SendMessageToServer(KRspFalse);
   454 			}
   455 		break;
   456 	//
   457 	case WM_IMON_DISPLAY_SET_VFD_TEXT:
   458 		if (DSP_SUCCEEDED==IMON_Display_SetVfdText(gTextFirstLine16,gTextSecondLine16))
   459 			{
   460 			SendMessageToServer(KRspDone);
   461 			}
   462 		else
   463 			{
   464 			SendMessageToServer(KRspError);
   465 			}
   466 		break;
   467 
   468 	case WM_DSP_PLUGIN_NOTIFY:
   469 		switch(wParam)
   470 			{
   471 			case DSPNM_PLUGIN_SUCCEED:
   472 			case DSPNM_IMON_RESTARTED:
   473 			case DSPNM_HW_CONNECTED:
   474 				{
   475 				//GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);
   476 				m_bVfdConnected = FALSE;
   477 				m_bLcdConnected = FALSE;
   478 				if((lParam & DSPN_DSP_VFD) == DSPN_DSP_VFD)		m_bVfdConnected = TRUE;
   479 				if((lParam & DSPN_DSP_LCD) == DSPN_DSP_LCD)		m_bLcdConnected = TRUE;
   480 				//UpdateControlUI();
   481 
   482 				DisplayPluginMessage(wParam, FALSE);
   483 				}
   484 				break;
   485 
   486 			case DSPNM_PLUGIN_FAILED:
   487 			case DSPNM_HW_DISCONNECTED:
   488 			case DSPNM_IMON_CLOSED:
   489 				{
   490 				//GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);
   491 				m_bVfdConnected = FALSE;
   492 				m_bLcdConnected = FALSE;
   493 				//UpdateControlUI();
   494 
   495 				DisplayPluginMessage(lParam, TRUE);
   496 				}
   497 				break;
   498 
   499 			case DSPNM_LCD_TEXT_SCROLL_DONE:
   500 				{
   501 				//TRACE(_T("LCD Text Scroll Finished.\n"));
   502 				}
   503 				break;
   504 			}
   505 		return 0;
   506 		break;
   507 	default:
   508 		return DefWindowProc(hWnd, message, wParam, lParam);
   509 	}
   510 	return 0;
   511 }
   512 
   513 // Message handler for about box.
   514 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
   515 {
   516 	UNREFERENCED_PARAMETER(lParam);
   517 	switch (message)
   518 	{
   519 	case WM_INITDIALOG:
   520 		return (INT_PTR)TRUE;
   521 
   522 	case WM_COMMAND:
   523 		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
   524 		{
   525 			EndDialog(hDlg, LOWORD(wParam));
   526 			return (INT_PTR)TRUE;
   527 		}
   528 		break;
   529 	}
   530 	return (INT_PTR)FALSE;
   531 }
   532