SoundGraphAccess.cpp
author StephaneLenclud
Sat, 13 Apr 2013 00:45:13 +0200
changeset 7 ad71cf47d037
parent 6 f1413622948f
child 8 3031cd3ebd1e
permissions -rw-r--r--
Now parses second line of text from set VFD text messages.
     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 		OutputDebugString(gTextFirstLine16);
   198 		//Convert second line
   199 		OutputDebugStringA(gTextSecondLine);
   200 		convertedChars = MultiByteToWideChar(CP_UTF8, 0, gTextSecondLine, -1, gTextSecondLine16, sizeof(gTextSecondLine16));
   201 		OutputDebugString(gTextSecondLine16);
   202 
   203 		//IMON API call need to be done from window thread for some reason
   204 		SendMessageToServer(KRspPending);
   205 		if (!m_IsInit)
   206 			{
   207 			PostMessage(gWnd,WM_IMON_INIT,0,0);		
   208 			}
   209 		PostMessage(gWnd,WM_IMON_DISPLAY_SET_VFD_TEXT,0,0);		
   210 		}
   211 	else
   212 		{		
   213 		SendMessageToServer(KRspUnknown);
   214 		}
   215 	}
   216 
   217 
   218 
   219 /**
   220 Connect our named pipes from here.
   221 First connect our read pipe then our write pipe.
   222 Then notify our server we are connected.
   223 Then keep on waiting for incoming messages.
   224 */
   225 DWORD WINAPI ThreadReceiver( LPVOID lpParam )
   226 	{
   227 
   228 	/*
   229 	//Keep on trying to connect on our read pipe
   230 	while (gPipeInbound==INVALID_HANDLE_VALUE && !gQuit)
   231 		{
   232 		OutputDebugStringA("Trying to connect...\n");
   233 		gPipeInbound=CreateFile(gPipeNameInbound,	GENERIC_READ ,0,NULL,OPEN_EXISTING,0,NULL);
   234 		Sleep(1000);
   235 		}
   236 	
   237 	OutputDebugStringA("Read pipe open!\n");
   238 	//Now try connecting on our write pipe
   239 	gPipeOutbound=CreateFile(gPipeNameOutbound,	GENERIC_WRITE ,0,NULL,OPEN_EXISTING,0,NULL);
   240 	if (gPipeOutbound==INVALID_HANDLE_VALUE)
   241 		{
   242 		int err=GetLastError();
   243 		OutputDebugStringA("ERROR: Write pipe failure!\n");
   244 		//gQuit=TRUE;
   245 		}
   246 	else
   247 		{
   248 		OutputDebugStringA("Write pipe opened.\n");
   249 		OutputDebugStringA("Connected.\n");
   250 		SendMessageToServer(KRspOpen);
   251 		}
   252 	//
   253 	*/
   254 
   255 	
   256 	CreateOutboundPipe();
   257 	CreateInboundPipe();
   258 
   259 	while(!gQuit)
   260 		{
   261 		DWORD cbRead;
   262 		BOOL success=ReadFile(gPipeInbound,gBufferReceiver,sizeof(gBufferReceiver),&cbRead, NULL); 
   263 		if(success)
   264 			{
   265 			gBufferReceiver[cbRead]='\0';
   266 			OutputDebugStringA(gBufferReceiver);
   267 			MessageReceived(gBufferReceiver);
   268 			}
   269 		//if (!success && GetLastError() != ERROR_MORE_DATA) 
   270 		//	{
   271 		//	OutputDebugStringA("Can't Read\n");
   272 		//	}
   273 		//
   274 		//Sleep(500);
   275 
   276 		if (!success)
   277 			{
   278 			gQuit=TRUE;
   279 			}
   280 		}
   281 
   282 	//Try tell our server
   283 	SendMessageToServer(KRspClose);
   284 	//Close our pipes
   285 	DisconnectNamedPipe(gPipeInbound);
   286 	CloseHandle(gPipeInbound);
   287 	gPipeInbound=INVALID_HANDLE_VALUE;
   288 	DisconnectNamedPipe(gPipeOutbound);
   289 	CloseHandle(gPipeOutbound);	
   290 	gPipeOutbound=INVALID_HANDLE_VALUE;
   291 	//Quit our application
   292 	PostMessage(gWnd,WM_CLOSE,0,0);
   293 		
   294 	return 0;
   295 	}
   296 
   297 
   298 
   299 /**
   300 */
   301 int APIENTRY _tWinMain(HINSTANCE hInstance,
   302                      HINSTANCE hPrevInstance,
   303                      LPTSTR    lpCmdLine,
   304                      int       nCmdShow)
   305 {
   306 	UNREFERENCED_PARAMETER(hPrevInstance);
   307 	UNREFERENCED_PARAMETER(lpCmdLine);
   308 
   309 	gTextFirstLine[0]='\0';
   310 	gTextSecondLine[0]='\0';
   311 	gTextFirstLine16[0]='\0';
   312 	gTextSecondLine16[0]='\0';
   313 
   314 
   315 	// TODO: Place code here.
   316 	MSG msg;
   317 	HACCEL hAccelTable;
   318 
   319 	// Initialize global strings
   320 	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
   321 	LoadString(hInstance, IDC_SOUNDGRAPHACCESS, szWindowClass, MAX_LOADSTRING);
   322 	MyRegisterClass(hInstance);
   323 
   324 	// Perform application initialization:
   325 	if (!InitInstance (hInstance, /*SW_HIDE*/ nCmdShow))
   326 		{
   327 		return FALSE;
   328 		}
   329 
   330 
   331 
   332 	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SOUNDGRAPHACCESS));
   333 
   334 	// Main message loop:
   335 	while (GetMessage(&msg, NULL, 0, 0))
   336 		{
   337 		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
   338 			{
   339 			TranslateMessage(&msg);
   340 			DispatchMessage(&msg);
   341 			}
   342 		}
   343 
   344 	return (int) msg.wParam;
   345 	}
   346 
   347 /**
   348 */
   349 void DisplayPluginMessage(UINT uErrCode, BOOL bError)
   350 	{
   351 	char* strErrMsg = "";
   352 
   353 	if(bError)
   354 		{
   355 		switch(uErrCode)
   356 			{
   357 			case DSPN_ERR_IN_USED:			strErrMsg = ("Display Plug-in is Already Used by Other Application.");		break;
   358 			case DSPN_ERR_HW_DISCONNECTED:	strErrMsg = ("iMON HW is Not Connected.");									break;
   359 			case DSPN_ERR_NOT_SUPPORTED_HW:	strErrMsg = ("The Connected iMON HW doesn't Support Display Plug-in.");		break;
   360 			case DSPN_ERR_PLUGIN_DISABLED:	strErrMsg = ("Display Plug-in Mode Option is Disabled.");					break;
   361 			case DSPN_ERR_IMON_NO_REPLY:	strErrMsg = ("The Latest iMON is Not Installed or iMON Not Running.");		break;
   362 			case DSPN_ERR_UNKNOWN:			strErrMsg = ("Unknown Failure.");											break;
   363 			}
   364 		}
   365 	else
   366 		{
   367 		switch(uErrCode)
   368 			{
   369 			case DSPNM_PLUGIN_SUCCEED:		strErrMsg = ("Plug-in Mode Inited Successfully.");			break;
   370 			case DSPNM_IMON_RESTARTED:		strErrMsg = ("iMON Started and Plug-in Mode Inited.");		break;
   371 			case DSPNM_HW_CONNECTED:		strErrMsg = ("iMON HW Connected and Plug-in Mode Inited.");	break;
   372 			}
   373 
   374 		m_IsInit=TRUE;
   375 		}
   376 	//
   377 	OutputDebugStringA(strErrMsg);
   378 
   379 	char msg[256];
   380 	if (bError)
   381 		{
   382 		sprintf(msg,"error:%s",strErrMsg);
   383 		}
   384 	else
   385 		{
   386 		sprintf(msg,"done:%s",strErrMsg);	
   387 		}	
   388 	SendMessageToServer(msg);
   389 	}
   390 
   391 
   392 
   393 //
   394 //  FUNCTION: MyRegisterClass()
   395 //
   396 //  PURPOSE: Registers the window class.
   397 //
   398 //  COMMENTS:
   399 //
   400 //    This function and its usage are only necessary if you want this code
   401 //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
   402 //    function that was added to Windows 95. It is important to call this function
   403 //    so that the application will get 'well formed' small icons associated
   404 //    with it.
   405 //
   406 ATOM MyRegisterClass(HINSTANCE hInstance)
   407 {
   408 	WNDCLASSEX wcex;
   409 
   410 	wcex.cbSize = sizeof(WNDCLASSEX);
   411 
   412 	wcex.style			= CS_HREDRAW | CS_VREDRAW;
   413 	wcex.lpfnWndProc	= WndProc;
   414 	wcex.cbClsExtra		= 0;
   415 	wcex.cbWndExtra		= 0;
   416 	wcex.hInstance		= hInstance;
   417 	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SOUNDGRAPHACCESS));
   418 	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
   419 	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
   420 	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_SOUNDGRAPHACCESS);
   421 	wcex.lpszClassName	= szWindowClass;
   422 	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
   423 
   424 	return RegisterClassEx(&wcex);
   425 }
   426 
   427 //
   428 //   FUNCTION: InitInstance(HINSTANCE, int)
   429 //
   430 //   PURPOSE: Saves instance handle and creates main window
   431 //
   432 //   COMMENTS:
   433 //
   434 //        In this function, we save the instance handle in a global variable and
   435 //        create and display the main program window.
   436 //
   437 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
   438 {
   439    
   440 
   441    hInst = hInstance; // Store instance handle in our global variable
   442 
   443    gWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
   444       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
   445 
   446    if (!gWnd)
   447    {
   448       return FALSE;
   449    }
   450 
   451    ShowWindow(gWnd, nCmdShow);
   452    UpdateWindow(gWnd);
   453 
   454    return TRUE;
   455 }
   456 
   457 //
   458 //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
   459 //
   460 //  PURPOSE:  Processes messages for the main window.
   461 //
   462 //  WM_COMMAND	- process the application menu
   463 //  WM_PAINT	- Paint the main window
   464 //  WM_DESTROY	- post a quit message and return
   465 //
   466 //
   467 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
   468 {
   469 	int wmId, wmEvent;
   470 	PAINTSTRUCT ps;
   471 	HDC hdc;
   472 
   473 	switch (message)
   474 	{
   475 	case WM_CREATE:
   476 		//IMON_Display_Uninit();
   477 		//IMON_Display_Init(hWnd, WM_DSP_PLUGIN_NOTIFY);
   478 		gThreadReceiver = CreateThread( NULL, 0, ThreadReceiver, NULL/*data pointer*/, 0, NULL);
   479 		break;
   480 	case WM_COMMAND:
   481 		wmId    = LOWORD(wParam);
   482 		wmEvent = HIWORD(wParam);
   483 		// Parse the menu selections:
   484 		switch (wmId)
   485 		{
   486 		case IDM_ABOUT:
   487 			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
   488 			break;
   489 		case IDM_EXIT:
   490 			DestroyWindow(hWnd);
   491 			break;
   492 		default:
   493 			return DefWindowProc(hWnd, message, wParam, lParam);
   494 		}
   495 		break;
   496 	case WM_PAINT:
   497 		hdc = BeginPaint(hWnd, &ps);
   498 		// TODO: Add any drawing code here...
   499 		EndPaint(hWnd, &ps);
   500 		break;
   501 	case WM_DESTROY:
   502 		gQuit=TRUE;
   503 		//To complete write op
   504 		if (gPipeOutbound!=INVALID_HANDLE_VALUE)
   505 			{
   506 			DisconnectNamedPipe(gPipeOutbound);
   507 			CloseHandle(gPipeOutbound);
   508 			gPipeOutbound=INVALID_HANDLE_VALUE;
   509 			}
   510 		//To complete read op
   511 		if (gPipeInbound!=INVALID_HANDLE_VALUE)
   512 			{
   513 			DisconnectNamedPipe(gPipeInbound);
   514 			CloseHandle(gPipeInbound);
   515 			gPipeInbound=INVALID_HANDLE_VALUE;
   516 			}
   517 
   518 		WaitForSingleObject(gThreadReceiver,INFINITE);
   519 		CloseHandle(gThreadReceiver);
   520 		//IMON_Display_Uninit();
   521 		PostQuitMessage(0);
   522 		break;
   523 
   524 	case WM_IMON_UNINIT:
   525 		m_IsInit=FALSE;
   526 		IMON_Display_Uninit();
   527 		SendMessageToServer(KRspDone);
   528 		break;
   529 
   530 	case WM_IMON_INIT:
   531 		IMON_Display_Uninit();
   532 		IMON_Display_Init(hWnd, WM_DSP_PLUGIN_NOTIFY);
   533 		break;
   534 	//
   535 	case WM_IMON_IS_PLUGIN_MODE_ENABLED:
   536 		if (IMON_Display_IsPluginModeEnabled()==DSP_S_IN_PLUGIN_MODE)
   537 			{
   538 			SendMessageToServer(KRspTrue);
   539 			}
   540 		else
   541 			{
   542 			SendMessageToServer(KRspFalse);
   543 			}
   544 		break;
   545 	//
   546 	case WM_IMON_IS_INIT:
   547 		if (IMON_Display_IsInited()==DSP_S_INITED)
   548 			{
   549 			SendMessageToServer(KRspTrue);
   550 			}
   551 		else
   552 			{
   553 			SendMessageToServer(KRspFalse);
   554 			}
   555 		break;
   556 	//
   557 	case WM_IMON_DISPLAY_SET_VFD_TEXT:
   558 		if (DSP_SUCCEEDED==IMON_Display_SetVfdText(gTextFirstLine16,gTextSecondLine16))
   559 			{
   560 			SendMessageToServer(KRspDone);
   561 			}
   562 		else
   563 			{
   564 			SendMessageToServer(KRspError);
   565 			}
   566 		break;
   567 
   568 	case WM_DSP_PLUGIN_NOTIFY:
   569 		switch(wParam)
   570 			{
   571 			case DSPNM_PLUGIN_SUCCEED:
   572 			case DSPNM_IMON_RESTARTED:
   573 			case DSPNM_HW_CONNECTED:
   574 				{
   575 				//GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);
   576 				m_bVfdConnected = FALSE;
   577 				m_bLcdConnected = FALSE;
   578 				if((lParam & DSPN_DSP_VFD) == DSPN_DSP_VFD)		m_bVfdConnected = TRUE;
   579 				if((lParam & DSPN_DSP_LCD) == DSPN_DSP_LCD)		m_bLcdConnected = TRUE;
   580 				//UpdateControlUI();
   581 
   582 				DisplayPluginMessage(wParam, FALSE);
   583 				}
   584 				break;
   585 
   586 			case DSPNM_PLUGIN_FAILED:
   587 			case DSPNM_HW_DISCONNECTED:
   588 			case DSPNM_IMON_CLOSED:
   589 				{
   590 				//GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);
   591 				m_bVfdConnected = FALSE;
   592 				m_bLcdConnected = FALSE;
   593 				//UpdateControlUI();
   594 
   595 				DisplayPluginMessage(lParam, TRUE);
   596 				}
   597 				break;
   598 
   599 			case DSPNM_LCD_TEXT_SCROLL_DONE:
   600 				{
   601 				//TRACE(_T("LCD Text Scroll Finished.\n"));
   602 				}
   603 				break;
   604 			}
   605 		return 0;
   606 		break;
   607 	default:
   608 		return DefWindowProc(hWnd, message, wParam, lParam);
   609 	}
   610 	return 0;
   611 }
   612 
   613 // Message handler for about box.
   614 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
   615 {
   616 	UNREFERENCED_PARAMETER(lParam);
   617 	switch (message)
   618 	{
   619 	case WM_INITDIALOG:
   620 		return (INT_PTR)TRUE;
   621 
   622 	case WM_COMMAND:
   623 		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
   624 		{
   625 			EndDialog(hDlg, LOWORD(wParam));
   626 			return (INT_PTR)TRUE;
   627 		}
   628 		break;
   629 	}
   630 	return (INT_PTR)FALSE;
   631 }
   632