Waugh
-
Posts
4 -
Joined
Content Type
Profiles
Forums
Blogs
Events
vBulletin Articles
News
Downloads
Gallery
Store
Posts posted by Waugh
-
-
Here's a little helpful tip which you can use if you need to
display the hex string of a byte in a tooltip. This can be
handy to display some debugging info, if nothing else during
testing. I used it to display the Direct Input key code in
hex assigned dynamically to a control.
In a typical MOUSE_TOOLTIP_TEXT_STRING() you can use %1!d! to
display a decimal (base 10) integer, but it does not implement
the 'x' format (like printf), ie you can't do %1!x! and have
it display the byte in hex. (At least I haven't been able to
do so)
First, define a global static c-string like this:
static char hexString[] = "00"; // NULL terminated
Be sure to use the "" (not ''), so that it is NULL terminated.
Define the following static function:
static char* byteArrayToHexString(byte in)
{
byte ch = 0x00;
int i = 0;
char pseudo[] = {"0123456789ABCDEF"};
ch = (byte) (in & 0xF0); // Strip off high nibble
ch = (byte) (ch >> 4); // Shift the bits down
ch = (byte) (ch & 0x0F); // In case high order bit was set
hexString[0] = pseudo[ (int)ch ]; // Convert nibble to hex
ch = (byte) (in & 0x0F); // Strip off low nibble
hexString[1] = pseudo[ (int)ch ]; // Convert nibble to hex
hexString[2] = NULL;
return hexString;
}
Now, create a TOOLTIP callback function:
static PCSTRINGZ CALLBACK GetHexString(FLOAT64 number, ID id,
PCSTRINGZ string, MODULE_VAR *source_var, PGAUGEHDR gauge)
{
byteArrayToHexString( byteToConvert );
return hexString;
}
The function uses a global variable (vs. new allocated
memory) to avoid having to unroll the macros to insert
appropriate delete [] pointer statements to avoid memory
leaks.
Now define an appropriate tooltip arg:
MOUSE_TOOLTIP_ARGS (Dynamic_Args)
MOUSE_TOOLTIP_ARG(MODULE_VAR_NONE, 1, NULL, NULL, NULL, NULL, NULL, GetAssignedKey)
MOUSE_TOOLTIP_ARGS_END
And the mouse tooltip string in your mouse section:
MOUSE_BEGIN(gauge_rect, HELP_NONE, 0, 0)
MOUSE_TOOLTIP_TEXT_STRING ("Hex: 0x%1!s!", Dynamic_Args)
MOUSE_CHILD_FUNCT(0, 0, 33, 33, CURSOR_GRAB,
MOUSE_LEFTSINGLE | MOUSE_LEFTRELEASE | MOUSE_DOWN_REPEAT |
MOUSE_LEAVE, Gauge_mcb)
MOUSE_END
You may find other uses for function.
Enjoy!
Patrick
-
The following code can be used to setup a que timer to fire every 20ms (after 1 second wait time), and execute TimerCallback().
// Que timers require Win 2000 min
#define _WIN32_WINNT 0x0500
#include
#include
// link with winmm.lib & kernel32.lib HWND hFsWnd = NULL;
HANDLE hTimer = NULL;
HANDLE hTimerQueue = NULL;
extern GAUGEHDR gauge_header;
void CALLBACK TimerCallback( PVOID lpParameter, BOOLEAN TimerOrWaitFired )
{
// Stuff you want to do every 20ms
DoSomethingReallyQuickOften();
}
void FSAPI module_init(void)
{
HRESULT hr;
hFsWnd = FindWindow( L"FS98MAIN", NULL );
hTimerQueue = CreateTimerQueue();
CreateTimerQueueTimer(
&hTimer,
hTimerQueue,
(WAITORTIMERCALLBACK)TimerCallback,
NULL,
1000, // Start in 1000ms (1sec)
20, // Callback each 20ms
WT_EXECUTEINTIMERTHREAD);
}
void FSAPI module_deinit(void)
{
DeleteTimerQueueTimer( NULL, hTimer, NULL );
CloseHandle( hTimer );
}
Keep in mind that FS updates many things (like nav stuff) at far less than 55ms. So, as Arne has pointed out in the past, if you are trying to find derivatives, you may find that consequetive values need to be checked for no change, and averaged to be able to take a derivative.
Patrick
-
To assist Bill in reducing pinned topic clutter, I decided that I might start this thread for techniques I might contribute.
I would recommend that if someone has feedback on a tip or example that they start a separate thread to comment on it, and then Bill can make any edits to the content to make any corrections if the community finds something better, or a correction, without cluttering the thread.
Thanks, Patrick. I've 'pinned' this topic and deleted the redundant ones now. I will leave this "unlocked" so you can continue to add to it, but I ask anyone else to please respect Patrick's suggestion to start a new thread if you have questions, corrections, or suggestions...
Contributed FS Gauge Techniques - Benchmark Avionics
in Panel & Gauge Design
Posted
I use this method to detect when I need to turn sounds on/off.
Define some globals to capture the state of the key events
you will be monitoring in your callback.
bool bPauseToggle; // Globals
bool bSoundToggle;
Define your CALLBACK EventHandler, and toggle the state
globals on each event. Note, you could use a switch
statement here too, but in any case you want to minimize what
you do here, and process the state changes in your gauge's
gauge callback function instead for maximum performance.
void CALLBACK EventHandler(ID32 event, UINT32 evdata, PVOID
userdata)
{
if (event == KEY_PAUSE_TOGGLE)
{
bPauseToggle = !bPauseToggle; // User hit pause toggle
}
if (event == KEY_SOUND_TOGGLE)
{
bSoundToggle = !bSoundToggle; // User hit sound toggle
}
}
Now, in your gauge callback, do things like so:
void CALLBACK Gcb(PGAUGEHDR pgauge, SINT32 service_id, UINT32
extra_data)
{
switch (service_id)
{
case PANEL_SERVICE_PRE_INITIALIZE:
register_key_event_handler((GAUGE_KEY_EVENT_HANDLER)EventHandler,
0);
break;
case PANEL_SERVICE_PRE_UPDATE:
if ( bPauseToggle || bSoundToggle )
{
PauseAudio( true ); // Your functions here
}
else
{
PauseAudio( false ); // and here.
}
break;
case PANEL_SERVICE_PRE_KILL:
unregister_key_event_handler((GAUGE_KEY_EVENT_HANDLER)EventHandler,
0);
break;
}
}
NOTE: CALLBACK is the same as FSAPI (ie __stdcall), but just
more descriptive of the fact that the function is a Win32
callback requiring the __stdcall method of stack cleanup.
You can use the shorter FSAPI should you desire, or even just
__stdcall.
Patrick