Yes the communication protocol we used between Microcontroller and GUI is gRPC
gRPC client act as Microcontroller and gRPC server act as a GUI
PostThraedMessage() function was intended ONLY to exchange data from the gRPC thread to GUI thread. - Yes we using the same.
This has to occur within the same GUI process :
There is one file gRPCservice.cpp where all the data resides so i have implemented ThreadProc function in this file
#define WM_YOUR_MESSAGE ( WM_USER + 1 )
/* Some data structure intended to store the message content. */
typedef struct
{
int SomeData1;
int SomeData2;
int SomeDataN;
} MessageData;
/* Global variable identifying the GUI thread. */
static volatile DWORD ThreadID_GUI;
/* Some worker function running in context of a foreign thread. GUIService.cpp - setSplash */
static void __cdecl ThreadProc( void* aArg ) // main.c //RunGUIService
{
MessageData* data;
for ( ;; )
{
Sleep( 500 );
/* Allocate memory for a new message data structure */
data = (MessageData*)malloc( sizeof( *data ));
/* Initialize the message data structure with some information to transfer
to the GUI thread. */
data->SomeData1 = 1234;
data->SomeData2 = 4567;
data->SomeDataN = 7894;
/* Post a message to the GUI thread together with the just initialized
data structure */
PostThreadMessage( ThreadID_GUI, WM_YOUR_MESSAGE, 0, (LPARAM)data );
}
}
///////////////////////////
From main .c ()
#include <gRPCService.h>
int APIENTRY WinMain( HINSTANCE aInstance, HINSTANCE aPrevInstance,
LPSTR aCmdLine, int aCmdShow )
{
MSG msg;
CoreRoot rootObject;
EW_UNUSED_ARG( aInstance );
EW_UNUSED_ARG( aPrevInstance );
EW_UNUSED_ARG( aCmdLine );
EW_UNUSED_ARG( aCmdShow );
/* STEP 2: Start the worker thread */
{
/* Store the ID of the GUI thread in a global variable */
// ThreadID_GUI = GetCurrentThreadId();
/* Start some background thread */
_beginthread( ThreadProc, 0, 0 );
}
/* END STEP 2 */
/* Before we initialize the GUI application, configure caches, queues and
memory allocation strategies of Graphics Engine and Runtime Environment
according to settings from the ewconfig.h file or Make file. */
EwConfigRuntimeEnvironment();
EwConfigGraphicsEngine();
/* The following EwOpenConsole() call is optional. It opens a console window
for printf() outputs. */
#ifdef EW_OPEN_CONSOLE
EwOpenConsole();
#endif
/* Initialize the Graphics Engine and Runtime Environment */
EwInitGraphicsEngine( 0 );
/* Create the applications root object ... */
rootObject = (CoreRoot)EwNewObjectIndirect( EwApplicationClass, 0 );
EwLockObject( rootObject );
/* ... and initialize the application object. */
CoreRoot__Initialize( rootObject, EwScreenSize );
/* Open the viewer window to display the framebuffer's content */
EwOpenViewer( rootObject );
/* Process MS-Windows messages */
while( GetMessage( &msg, NULL, 0, 0 ))
{
/* STEP 3: React on the message sent from the foreign thread */
if ( msg.message == WM_YOUR_MESSAGE )
{
MessageData* data = (MessageData*)msg.lParam;
ExampleDeviceClass object = EwGetAutoObject( &ExampleDevice, ExampleDeviceClass );
/* Evaluate the data found in the associated data structure and e.g. trigger
an Embedded Wizard System Event */
if ( data->SomeData1 == 1234 )
ExampleDeviceClass__TriggerEvent( object );
/* Free the data structure associated to the message */
free( data );
}
/* END STEP 3 */
TranslateMessage( &msg );
DispatchMessage( &msg );
/* Process expired timers */
EwProcessTimers();
/* The following do/while loop is responsible for the idle processing.
This loop is executed as long as any signals are pending and no other
user inputs are received by the Viewer application. */
do
{
/* Process the pending signals */
EwProcessSignals();
/* Refresh the screen, if something has changed and draw its content in
the viewer window */
EwUpdateViewer();
/* After each processed message start the garbage collection */
EwReclaimMemory();
}
while ( EwAnyPendingSignals() &&
#if WINVER >= 0x0602
!GetQueueStatus( QS_KEY | QS_MOUSE | QS_TIMER ) &&
!GetQueueStatus( QS_TOUCH ));
#else
!GetQueueStatus( QS_KEY | QS_MOUSE | QS_TIMER ));
#endif
/* Show the memory statistic */
#ifdef EW_PRINT_MEMORY_USAGE
EwPrintProfilerStatistic( 0 );
#endif
}
/* Finished -> release unused resources */
EwUnlockObject( rootObject );
EwReclaimMemory();
/* ... and deinitialize the Graphics Engine */
EwDoneGraphicsEngine();
/* Show the finaly memory statistic */
#ifdef EW_PRINT_MEMORY_USAGE
EwPrintProfilerStatistic( 0 );
#endif
/* Return the exit-code of the viewer */
return msg.wParam;
}
and also
if ( msg.message == WM_YOUR_MESSAGE )
this above condition does not get satisfied and msg.lparam is null