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