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