<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>http://www.fsdeveloper.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Naruto-kun</id>
	<title>FSDeveloper Wiki - User contributions [en-gb]</title>
	<link rel="self" type="application/atom+xml" href="http://www.fsdeveloper.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Naruto-kun"/>
	<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php/Special:Contributions/Naruto-kun"/>
	<updated>2026-05-09T00:34:35Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=10479</id>
		<title>C: C++ timers</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=10479"/>
		<updated>2017-06-14T09:52:02Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| P3D4 = true&lt;br /&gt;
| P3D2 = true&lt;br /&gt;
| P3D = true&lt;br /&gt;
| FSXI = unknown&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| FSX = true&lt;br /&gt;
| FS2004 = false&lt;br /&gt;
| FS2002 = false&lt;br /&gt;
| FS2000 = unknown&lt;br /&gt;
| FS98 = unknown&lt;br /&gt;
| XP10 = false &lt;br /&gt;
| XP9 = false &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Most of you may be familiar with the TICK18 token variable which is incremented at 18Hz. Another option to make use of the 18Hz increment system (like making 0.5 second timers and such) is to call a function from the PANEL_SERVICE_PRE_UPDATE case of your callback function which increments your timing variable which you simply reset to 0 when it is equal to 9 (for a 0.5 second timer). &lt;br /&gt;
&lt;br /&gt;
The following however is an undocumented function in the simulator which returns total time elapsed in seconds with sub-18Hz accuracy.&lt;br /&gt;
&lt;br /&gt;
In your choice of your project&#039;s header files, do the following function prototype:&lt;br /&gt;
&lt;br /&gt;
 typedef double (__stdcall *fGetSimTime)();&lt;br /&gt;
&lt;br /&gt;
Then in your module_init function:&lt;br /&gt;
 &lt;br /&gt;
 #ifdef _M_X64&lt;br /&gt;
 #define PWORDX unsigned __int64&lt;br /&gt;
 #else&lt;br /&gt;
 #define PWORDX DWORD&lt;br /&gt;
 #end&lt;br /&gt;
 HMODULE hsimsched = NULL;&lt;br /&gt;
 fGetSimTime GetSimTime6 = NULL;&lt;br /&gt;
 void FSAPI module_init(void)&lt;br /&gt;
 {&lt;br /&gt;
  GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
  if(hsimsched)&lt;br /&gt;
   GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));//Note, for FSX SP2 use 4 instead of 6. Also since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals.  }&lt;br /&gt;
&lt;br /&gt;
Now wherever you wish to call this function, include the header where the prototype is contained and add:&lt;br /&gt;
&lt;br /&gt;
 extern fGetSimTime GetSimTime6;&lt;br /&gt;
&lt;br /&gt;
To call it and find out how much time has passed:&lt;br /&gt;
&lt;br /&gt;
 double time = GetSimTime6();&lt;br /&gt;
&lt;br /&gt;
UPDATE:&lt;br /&gt;
&lt;br /&gt;
The ordinal used by P3D v2.5 is different to that of FSXA. Also, the format is such that the decorated function name is available from the dll. So for P3D v2.5, use the following:&lt;br /&gt;
 GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Complete example for automatic function selection:&lt;br /&gt;
&lt;br /&gt;
 GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
 if(hsimsched)&lt;br /&gt;
 {&lt;br /&gt;
 	PWORDX fsxa = (PWORDX)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 	PWORDX p3dv2 = (PWORDX)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
 	PWORDX p3dv4 = (PWORDX)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YANXZ&amp;quot;);&lt;br /&gt;
 	if (p3dv4)&lt;br /&gt;
 		p3dv2 = p3dv4, fsxa = 0;&lt;br /&gt;
 	if(fsxa-(PWORDX)hsimsched == 0x1530)&lt;br /&gt;
 		GetSimTime6 = (fGetSimTime)fsxa;//FSX Acceleration version&lt;br /&gt;
 	else&lt;br /&gt;
 	{&lt;br /&gt;
 		if(p3dv2)&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)p3dv2;&lt;br /&gt;
 		else&lt;br /&gt;
 		{&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(4));//FSX SP2. &lt;br /&gt;
 			//Since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals. &lt;br /&gt;
 			if(PWORDX(GetSimTime6)-PWORDX(hsimsched) != 0x14D0)&lt;br /&gt;
 				GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 }&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=10478</id>
		<title>C: C++ timers</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=10478"/>
		<updated>2017-06-11T11:26:05Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| P3D4 = true&lt;br /&gt;
| P3D2 = true&lt;br /&gt;
| P3D = true&lt;br /&gt;
| FSXI = unknown&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| FSX = true&lt;br /&gt;
| FS2004 = false&lt;br /&gt;
| FS2002 = false&lt;br /&gt;
| FS2000 = unknown&lt;br /&gt;
| FS98 = unknown&lt;br /&gt;
| XP10 = false &lt;br /&gt;
| XP9 = false &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Most of you may be familiar with the TICK18 token variable which is incremented at 18Hz. Another option to make use of the 18Hz increment system (like making 0.5 second timers and such) is to call a function from the PANEL_SERVICE_PRE_UPDATE case of your callback function which increments your timing variable which you simply reset to 0 when it is equal to 9 (for a 0.5 second timer). &lt;br /&gt;
&lt;br /&gt;
The following however is an undocumented function in the simulator which returns total time elapsed in seconds with sub-18Hz accuracy.&lt;br /&gt;
&lt;br /&gt;
In your choice of your project&#039;s header files, do the following function prototype:&lt;br /&gt;
&lt;br /&gt;
 typedef double (__stdcall *fGetSimTime)();&lt;br /&gt;
&lt;br /&gt;
Then in your module_init function:&lt;br /&gt;
 &lt;br /&gt;
 #ifdef _M_X64&lt;br /&gt;
 #define PWORDX unsigned __int64&lt;br /&gt;
 #else&lt;br /&gt;
 #define PWORDX DWORD&lt;br /&gt;
 #end&lt;br /&gt;
 HMODULE hsimsched = NULL;&lt;br /&gt;
 fGetSimTime GetSimTime6 = NULL;&lt;br /&gt;
 void FSAPI module_init(void)&lt;br /&gt;
 {&lt;br /&gt;
  GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
  if(hsimsched)&lt;br /&gt;
   GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));//Note, for FSX SP2 use 4 instead of 6. Also since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals.  }&lt;br /&gt;
&lt;br /&gt;
Now wherever you wish to call this function, include the header where the prototype is contained and add:&lt;br /&gt;
&lt;br /&gt;
 extern fGetSimTime GetSimTime6;&lt;br /&gt;
&lt;br /&gt;
To call it and find out how much time has passed:&lt;br /&gt;
&lt;br /&gt;
 double time = GetSimTime6();&lt;br /&gt;
&lt;br /&gt;
UPDATE:&lt;br /&gt;
&lt;br /&gt;
The ordinal used by P3D v2.5 is different to that of FSXA. Also, the format is such that the decorated function name is available from the dll. So for P3D v2.5, use the following:&lt;br /&gt;
 GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Complete example for automatic function selection:&lt;br /&gt;
&lt;br /&gt;
 GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
 if(hsimsched)&lt;br /&gt;
 {&lt;br /&gt;
 	PWORDX fsxa = (DWORD)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 	PWORDX p3dv2 = (DWORD)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
 	PWORDX p3dv4 = (PWORDX)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YANXZ&amp;quot;);&lt;br /&gt;
 	if (p3dv4)&lt;br /&gt;
 		p3dv2 = p3dv4, fsxa = 0;&lt;br /&gt;
 	if(fsxa-(PWORDX)hsimsched == 0x1530)&lt;br /&gt;
 		GetSimTime6 = (fGetSimTime)fsxa;//FSX Acceleration version&lt;br /&gt;
 	else&lt;br /&gt;
 	{&lt;br /&gt;
 		if(p3dv2)&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)p3dv2;&lt;br /&gt;
 		else&lt;br /&gt;
 		{&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(4));//FSX SP2. &lt;br /&gt;
 			//Since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals. &lt;br /&gt;
 			if(PWORDX(GetSimTime6)-PWORDX(hsimsched) != 0x14D0)&lt;br /&gt;
 				GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 }&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=10477</id>
		<title>C: C++ timers</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=10477"/>
		<updated>2017-06-11T11:14:24Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| P3D2 = true&lt;br /&gt;
| P3D = true&lt;br /&gt;
| FSXI = unknown&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| FSX = true&lt;br /&gt;
| FS2004 = false&lt;br /&gt;
| FS2002 = false&lt;br /&gt;
| FS2000 = unknown&lt;br /&gt;
| FS98 = unknown&lt;br /&gt;
| XP10 = false &lt;br /&gt;
| XP9 = false &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Most of you may be familiar with the TICK18 token variable which is incremented at 18Hz. Another option to make use of the 18Hz increment system (like making 0.5 second timers and such) is to call a function from the PANEL_SERVICE_PRE_UPDATE case of your callback function which increments your timing variable which you simply reset to 0 when it is equal to 9 (for a 0.5 second timer). &lt;br /&gt;
&lt;br /&gt;
The following however is an undocumented function in the simulator which returns total time elapsed in seconds with sub-18Hz accuracy.&lt;br /&gt;
&lt;br /&gt;
In your choice of your project&#039;s header files, do the following function prototype:&lt;br /&gt;
&lt;br /&gt;
 typedef double (__stdcall *fGetSimTime)();&lt;br /&gt;
&lt;br /&gt;
Then in your module_init function:&lt;br /&gt;
 &lt;br /&gt;
 #ifdef _M_X64&lt;br /&gt;
 #define PWORDX unsigned __int64&lt;br /&gt;
 #else&lt;br /&gt;
 #define PWORDX DWORD&lt;br /&gt;
 #end&lt;br /&gt;
 HMODULE hsimsched = NULL;&lt;br /&gt;
 fGetSimTime GetSimTime6 = NULL;&lt;br /&gt;
 void FSAPI module_init(void)&lt;br /&gt;
 {&lt;br /&gt;
  GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
  if(hsimsched)&lt;br /&gt;
   GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));//Note, for FSX SP2 use 4 instead of 6. Also since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals.  }&lt;br /&gt;
&lt;br /&gt;
Now wherever you wish to call this function, include the header where the prototype is contained and add:&lt;br /&gt;
&lt;br /&gt;
 extern fGetSimTime GetSimTime6;&lt;br /&gt;
&lt;br /&gt;
To call it and find out how much time has passed:&lt;br /&gt;
&lt;br /&gt;
 double time = GetSimTime6();&lt;br /&gt;
&lt;br /&gt;
UPDATE:&lt;br /&gt;
&lt;br /&gt;
The ordinal used by P3D v2.5 is different to that of FSXA. Also, the format is such that the decorated function name is available from the dll. So for P3D v2.5, use the following:&lt;br /&gt;
 GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Complete example for automatic function selection:&lt;br /&gt;
&lt;br /&gt;
 GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
 if(hsimsched)&lt;br /&gt;
 {&lt;br /&gt;
 	PWORDX fsxa = (DWORD)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 	PWORDX p3dv2 = (DWORD)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
 	PWORDX p3dv4 = (PWORDX)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YANXZ&amp;quot;);&lt;br /&gt;
 	if (p3dv4)&lt;br /&gt;
 		p3dv2 = p3dv4, fsxa = 0;&lt;br /&gt;
 	if(fsxa-(PWORDX)hsimsched == 0x1530)&lt;br /&gt;
 		GetSimTime6 = (fGetSimTime)fsxa;//FSX Acceleration version&lt;br /&gt;
 	else&lt;br /&gt;
 	{&lt;br /&gt;
 		if(p3dv2)&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)p3dv2;&lt;br /&gt;
 		else&lt;br /&gt;
 		{&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(4));//FSX SP2. &lt;br /&gt;
 			//Since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals. &lt;br /&gt;
 			if(PWORDX(GetSimTime6)-PWORDX(hsimsched) != 0x14D0)&lt;br /&gt;
 				GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 }&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=10476</id>
		<title>C: C++ timers</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=10476"/>
		<updated>2017-06-11T11:14:02Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| P3D2 = true&lt;br /&gt;
| P3D = true&lt;br /&gt;
| FSXI = unknown&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| FSX = true&lt;br /&gt;
| FS2004 = false&lt;br /&gt;
| FS2002 = false&lt;br /&gt;
| FS2000 = unknown&lt;br /&gt;
| FS98 = unknown&lt;br /&gt;
| XP10 = false &lt;br /&gt;
| XP9 = false &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Most of you may be familiar with the TICK18 token variable which is incremented at 18Hz. Another option to make use of the 18Hz increment system (like making 0.5 second timers and such) is to call a function from the PANEL_SERVICE_PRE_UPDATE case of your callback function which increments your timing variable which you simply reset to 0 when it is equal to 9 (for a 0.5 second timer). &lt;br /&gt;
&lt;br /&gt;
The following however is an undocumented function in the simulator which returns total time elapsed in seconds with sub-18Hz accuracy.&lt;br /&gt;
&lt;br /&gt;
In your choice of your project&#039;s header files, do the following function prototype:&lt;br /&gt;
&lt;br /&gt;
 typedef double (__stdcall *fGetSimTime)();&lt;br /&gt;
&lt;br /&gt;
Then in your module_init function:&lt;br /&gt;
 &lt;br /&gt;
 #ifdef _M_X64&lt;br /&gt;
 #define PWORDX unsigned __int64&lt;br /&gt;
 #else&lt;br /&gt;
 #define PWORDX DWORD&lt;br /&gt;
 #end&lt;br /&gt;
 HMODULE hsimsched = NULL;&lt;br /&gt;
 fGetSimTime GetSimTime6 = NULL;&lt;br /&gt;
 void FSAPI module_init(void)&lt;br /&gt;
 {&lt;br /&gt;
  GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
  if(hsimsched)&lt;br /&gt;
   GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));//Note, for FSX SP2 use 4 instead of 6. Also since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals.  }&lt;br /&gt;
&lt;br /&gt;
Now wherever you wish to call this function, include the header where the prototype is contained and add:&lt;br /&gt;
&lt;br /&gt;
 extern fGetSimTime GetSimTime6;&lt;br /&gt;
&lt;br /&gt;
To call it and find out how much time has passed:&lt;br /&gt;
&lt;br /&gt;
 double time = GetSimTime6();&lt;br /&gt;
&lt;br /&gt;
UPDATE:&lt;br /&gt;
&lt;br /&gt;
The ordinal used by P3D v2.5 is different to that of FSXA. Also, the format is such that the decorated function name is available from the dll. So for P3D v2.5, use the following:&lt;br /&gt;
 GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Complete example for automatic function selection:&lt;br /&gt;
&lt;br /&gt;
 GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
 if(hsimsched)&lt;br /&gt;
 {&lt;br /&gt;
 	PWORDX fsxa = (DWORD)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 	PWORDX p3dv2 = (DWORD)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
 	PWORDX p3dv4 = (PWORDX)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YANXZ&amp;quot;);&lt;br /&gt;
	if (p3dv4)&lt;br /&gt;
		p3dv2 = p3dv4, fsxa = 0;&lt;br /&gt;
 	if(fsxa-(PWORDX)hsimsched == 0x1530)&lt;br /&gt;
 		GetSimTime6 = (fGetSimTime)fsxa;//FSX Acceleration version&lt;br /&gt;
 	else&lt;br /&gt;
 	{&lt;br /&gt;
 		if(p3dv2)&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)p3dv2;&lt;br /&gt;
 		else&lt;br /&gt;
 		{&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(4));//FSX SP2. &lt;br /&gt;
 			//Since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals. &lt;br /&gt;
 			if(PWORDX(GetSimTime6)-PWORDX(hsimsched) != 0x14D0)&lt;br /&gt;
 				GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 }&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=10475</id>
		<title>C: C++ timers</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=10475"/>
		<updated>2017-05-23T19:04:35Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| P3D2 = true&lt;br /&gt;
| P3D = true&lt;br /&gt;
| FSXI = unknown&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| FSX = true&lt;br /&gt;
| FS2004 = false&lt;br /&gt;
| FS2002 = false&lt;br /&gt;
| FS2000 = unknown&lt;br /&gt;
| FS98 = unknown&lt;br /&gt;
| XP10 = false &lt;br /&gt;
| XP9 = false &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Most of you may be familiar with the TICK18 token variable which is incremented at 18Hz. Another option to make use of the 18Hz increment system (like making 0.5 second timers and such) is to call a function from the PANEL_SERVICE_PRE_UPDATE case of your callback function which increments your timing variable which you simply reset to 0 when it is equal to 9 (for a 0.5 second timer). &lt;br /&gt;
&lt;br /&gt;
The following however is an undocumented function in the simulator which returns total time elapsed in seconds with sub-18Hz accuracy.&lt;br /&gt;
&lt;br /&gt;
In your choice of your project&#039;s header files, do the following function prototype:&lt;br /&gt;
&lt;br /&gt;
 typedef double (__stdcall *fGetSimTime)();&lt;br /&gt;
&lt;br /&gt;
Then in your module_init function:&lt;br /&gt;
 &lt;br /&gt;
 #ifdef _M_X64&lt;br /&gt;
 #define PWORDX unsigned __int64&lt;br /&gt;
 #else&lt;br /&gt;
 #define PWORDX DWORD&lt;br /&gt;
 #end&lt;br /&gt;
 HMODULE hsimsched = NULL;&lt;br /&gt;
 fGetSimTime GetSimTime6 = NULL;&lt;br /&gt;
 void FSAPI module_init(void)&lt;br /&gt;
 {&lt;br /&gt;
  GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
  if(hsimsched)&lt;br /&gt;
   GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));//Note, for FSX SP2 use 4 instead of 6. Also since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals.  }&lt;br /&gt;
&lt;br /&gt;
Now wherever you wish to call this function, include the header where the prototype is contained and add:&lt;br /&gt;
&lt;br /&gt;
 extern fGetSimTime GetSimTime6;&lt;br /&gt;
&lt;br /&gt;
To call it and find out how much time has passed:&lt;br /&gt;
&lt;br /&gt;
 double time = GetSimTime6();&lt;br /&gt;
&lt;br /&gt;
UPDATE:&lt;br /&gt;
&lt;br /&gt;
The ordinal used by P3D v2.5 is different to that of FSXA. Also, the format is such that the decorated function name is available from the dll. So for P3D v2.5, use the following:&lt;br /&gt;
 GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Complete example for automatic function selection:&lt;br /&gt;
&lt;br /&gt;
 GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
 if(hsimsched)&lt;br /&gt;
 {&lt;br /&gt;
 	PWORDX fsxa = (DWORD)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 	PWORDX p3dv2 = (DWORD)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
	PWORDX p3dv4 = (PWORDX)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YANXZ&amp;quot;);&lt;br /&gt;
	if (p3dv4)&lt;br /&gt;
		p3dv2 = p3dv4, fsxa = 0;&lt;br /&gt;
 	if(fsxa-(PWORDX)hsimsched == 0x1530)&lt;br /&gt;
 		GetSimTime6 = (fGetSimTime)fsxa;//FSX Acceleration version&lt;br /&gt;
 	else&lt;br /&gt;
 	{&lt;br /&gt;
 		if(p3dv2)&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)p3dv2;&lt;br /&gt;
 		else&lt;br /&gt;
 		{&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(4));//FSX SP2. &lt;br /&gt;
 			//Since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals. &lt;br /&gt;
 			if(PWORDX(GetSimTime6)-PWORDX(hsimsched) != 0x14D0)&lt;br /&gt;
 				GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 }&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_PMDG-style_keyboard_entry&amp;diff=10016</id>
		<title>C: PMDG-style keyboard entry</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_PMDG-style_keyboard_entry&amp;diff=10016"/>
		<updated>2015-12-06T08:59:12Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| P3D2 = true&lt;br /&gt;
| P3D = true&lt;br /&gt;
| FSXI = unknown&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| FSX = true&lt;br /&gt;
| FS2004 = false&lt;br /&gt;
| FS2002 = false&lt;br /&gt;
| FS2000 = unknown&lt;br /&gt;
| FS98 = unknown&lt;br /&gt;
| XP10 = false &lt;br /&gt;
| XP9 = false &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
If you have flown any of the PMDG aircraft, you may have found it quite convenient to be able to type your entries into the FMC with the keyboard by holding down the Tab key. Here is an example how to do this in a gauge using SimConnect. This sample is based on the blank multi thread D2D gauge template available in the FSDeveloper resources: http://www.fsdeveloper.com/forum/resources/blank-multi-thread-d2d-gauge-template.155/&lt;br /&gt;
&lt;br /&gt;
First off, it helps to have an array of strings to loop through when setting up your key assignments in SimConnect:&lt;br /&gt;
&lt;br /&gt;
 const char* kstr[58] = &lt;br /&gt;
 {&lt;br /&gt;
 	&amp;quot;Backspace\0&amp;quot;, &amp;quot;Tab\0&amp;quot;, &amp;quot;Space\0&amp;quot;, &amp;quot;Num_Del\0&amp;quot;, &amp;quot;0\0&amp;quot;, &amp;quot;1\0&amp;quot;, &amp;quot;2\0&amp;quot;, &amp;quot;3\0&amp;quot;, &amp;quot;4\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;5\0&amp;quot;, &amp;quot;6\0&amp;quot;, &amp;quot;7\0&amp;quot;, &amp;quot;8\0&amp;quot;, &amp;quot;9\0&amp;quot;, &amp;quot;A\0&amp;quot;, &amp;quot;B\0&amp;quot;, &amp;quot;C\0&amp;quot;, &amp;quot;D\0&amp;quot;, &amp;quot;E\0&amp;quot;, &amp;quot;F\0&amp;quot;, &amp;quot;G\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;H\0&amp;quot;, &amp;quot;I\0&amp;quot;, &amp;quot;J\0&amp;quot;, &amp;quot;K\0&amp;quot;, &amp;quot;L\0&amp;quot;, &amp;quot;M\0&amp;quot;, &amp;quot;N\0&amp;quot;, &amp;quot;O\0&amp;quot;, &amp;quot;P\0&amp;quot;,	&amp;quot;Q\0&amp;quot;, &amp;quot;R\0&amp;quot;, &amp;quot;S\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;T\0&amp;quot;, &amp;quot;U\0&amp;quot;, &amp;quot;V\0&amp;quot;, &amp;quot;W\0&amp;quot;, &amp;quot;X\0&amp;quot;, &amp;quot;Y\0&amp;quot;, &amp;quot;Z\0&amp;quot;, &amp;quot;VK_NUMPAD0\0&amp;quot;, &amp;quot;VK_NUMPAD1\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;VK_NUMPAD2\0&amp;quot;, &amp;quot;VK_NUMPAD3\0&amp;quot;, &amp;quot;VK_NUMPAD4\0&amp;quot;, &amp;quot;VK_NUMPAD5\0&amp;quot;, &amp;quot;VK_NUMPAD6\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;VK_NUMPAD7\0&amp;quot;, &amp;quot;VK_NUMPAD8\0&amp;quot;, &amp;quot;VK_NUMPAD9\0&amp;quot;, &amp;quot;VK_ADD\0&amp;quot;, &amp;quot;VK_SUBTRACT\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;VK_DECIMAL\0&amp;quot;, &amp;quot;VK_DIVIDE\0&amp;quot;, &amp;quot;VK_PLUS\0&amp;quot;, &amp;quot;VK_MINUS\0&amp;quot;, &amp;quot;VK_PERIOD\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;VK_SLASH\0&amp;quot;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Next, you need to define your event ID and group ID enumerations (see CSimConnectData.h in the D2D sample)&lt;br /&gt;
&lt;br /&gt;
 static enum EVENT_ID &lt;br /&gt;
 {&lt;br /&gt;
 	EVK_KBBASE = 1000,//This is for Key Down events&lt;br /&gt;
 	EVK_KBBASEUP = 1100,//This is for Key Up events. Only used for the Tab key so we can know when to capture keyboard input.&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 static enum GROUP_ID&lt;br /&gt;
 {&lt;br /&gt;
 	G_KTOG,//This group only contains the Tab key.&lt;br /&gt;
 	G_KEYS,//This group contains all the other keys used.&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 static enum INPUT_ID&lt;br /&gt;
 {&lt;br /&gt;
 	I_KTOG,//This group only contains the Tab key.&lt;br /&gt;
 	I_KEYS,//This group contains all the other keys used.&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
In the AddDataDefs function in the D2D sample, set up your key definitions as shown:&lt;br /&gt;
 void AddDataDefs(HANDLE hs)&lt;br /&gt;
 {&lt;br /&gt;
 	for(int i = 0; i &amp;lt; 58; i ++)&lt;br /&gt;
 	{&lt;br /&gt;
 		SimConnect_MapClientEventToSimEvent(hs, EVK_KBBASE+i);&lt;br /&gt;
 		SimConnect_AddClientEventToNotificationGroup(hs, i==1?G_KTOG:G_KEYS, EVK_KBBASE+i, true);&lt;br /&gt;
 		SimConnect_MapClientEventToSimEvent(hs, EVK_KBBASEUP+i);&lt;br /&gt;
 		SimConnect_AddClientEventToNotificationGroup(hs, i==1?G_KTOG:G_KEYS, EVK_KBBASEUP+i, true);&lt;br /&gt;
 	}&lt;br /&gt;
 	//Note we have 2 key groups. The KTOG group contains only 1 key, the &amp;quot;Tab&amp;quot; key.&lt;br /&gt;
 	//This is so that the other key group will only mask inputs from the sim and redirect into our code if the Tab key is held down&lt;br /&gt;
 	SimConnect_SetNotificationGroupPriority(hs, G_KTOG, SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE);&lt;br /&gt;
 	SimConnect_SetNotificationGroupPriority(hs, G_KEYS, SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE);&lt;br /&gt;
 	for(int i = 0; i &amp;lt; 58; i ++)&lt;br /&gt;
 	{&lt;br /&gt;
 		SimConnect_MapInputEventToClientEvent(hs, i==1?I_KTOG:I_KEYS, kstr[i], EVK_KBBASE+i, 0, EVK_KBBASEUP+i, 0, 1);&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 	SimConnect_SetInputGroupState(hs, I_KTOG, SIMCONNECT_STATE_ON);&lt;br /&gt;
 	SimConnect_SetInputGroupState(hs, I_KEYS, SIMCONNECT_STATE_OFF);&lt;br /&gt;
 	SimConnect_SetInputGroupPriority(hs, I_KTOG, SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE);&lt;br /&gt;
 	SimConnect_SetInputGroupPriority(hs, I_KEYS, SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Next, in your SimConnect callback under the SIMCONNECT_RECV_ID_EVENT case, call the event handler and toggle the keyboard input state as required:&lt;br /&gt;
 case SIMCONNECT_RECV_ID_EVENT:&lt;br /&gt;
 {&lt;br /&gt;
 	SIMCONNECT_RECV_EVENT *evt = (SIMCONNECT_RECV_EVENT*)pData;&lt;br /&gt;
 	if(evt-&amp;gt;uGroupID == G_KTOG)&lt;br /&gt;
 	{&lt;br /&gt;
 		//if the Tab key is down, activate the masked keyboard key system so our key input will receive events&lt;br /&gt;
 		if(evt-&amp;gt;uEventID == EVK_KBBASE+1)&lt;br /&gt;
 			SimConnect_SetInputGroupState(hSc, I_KEYS, SIMCONNECT_STATE_ON);&lt;br /&gt;
 		else&lt;br /&gt;
 			SimConnect_SetInputGroupState(hSc, I_KEYS, SIMCONNECT_STATE_OFF);&lt;br /&gt;
 	}&lt;br /&gt;
 	//Subtract 1000 from the key event id to match our key identifier system&lt;br /&gt;
 	if(evt-&amp;gt;uGroupID == G_KEYS)&lt;br /&gt;
 		KeyInput(evt-&amp;gt;uEventID-1000);&lt;br /&gt;
 }&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
Finally, set up your key input function where you can convert from key input ID to ASCII string as shown:&lt;br /&gt;
&lt;br /&gt;
 #define MAXINPUT 20&lt;br /&gt;
 char istring[MAXINPUT];&lt;br /&gt;
 int cursor = 0;&lt;br /&gt;
 void KeyInput(int val)&lt;br /&gt;
 {&lt;br /&gt;
 	if(val &amp;lt; 100)//Note, we only accept Key Down events&lt;br /&gt;
 	{&lt;br /&gt;
 		//0 is Backspace, 3 is Delete. If you want Delete to wipe out the whole string, use memset(istring, 0x00, MAXINPUT); when val == 3&lt;br /&gt;
 		if(val == 0 || val == 3)&lt;br /&gt;
 		{&lt;br /&gt;
 			cursor = cursor&amp;gt;0?cursor-1:cursor;&lt;br /&gt;
 			istring[cursor] = 0x00;&lt;br /&gt;
 		}&lt;br /&gt;
 		else&lt;br /&gt;
 		{&lt;br /&gt;
 			//If val == 2, the value to put in is a blank space &#039; &#039;.&lt;br /&gt;
 			if(val == 2)&lt;br /&gt;
 				istring[cursor]=&#039; &#039;;&lt;br /&gt;
 			else&lt;br /&gt;
 			{&lt;br /&gt;
 				char kv = 0x00;&lt;br /&gt;
 				//Values 4 to 13 are top row of numbers on keyboard. ASCII values are 0x30 to 0x39 for &amp;quot;0-9&amp;quot;&lt;br /&gt;
 				if(val &amp;gt; 3 &amp;amp;&amp;amp; val &amp;lt; 14)&lt;br /&gt;
 					kv = 0x30+char(val-4);&lt;br /&gt;
 				//Values 14 to 39 are letters on keyboard. ASCII values are 0x41 to 0x5A for &amp;quot;A-Z&amp;quot;. Uppercase only in this case. If you want lowercase, use ASCII values 0x61 to 0x7A&lt;br /&gt;
 				if(val &amp;gt; 13 &amp;amp;&amp;amp; val &amp;lt; 40)&lt;br /&gt;
 					kv = 0x41+char(val-14);&lt;br /&gt;
 				//Values 40 to 49 are NUMPAD numbers. ASCII values are again 0x30 to 0x39 for &amp;quot;0-9&amp;quot;&lt;br /&gt;
 				if(val &amp;gt; 39 &amp;amp;&amp;amp; val &amp;lt; 50)&lt;br /&gt;
 					kv = 0x30+char(val-40);&lt;br /&gt;
 				//Values 50 to 51 are + and - respectively on top row of keyboard. Values 54 and 55 are + and - respectively on NUMPAD. ASCII values are 0x2B for &amp;quot;+&amp;quot; and 0x2D for &amp;quot;-&amp;quot;.&lt;br /&gt;
 				//Note that most CDUs have both on the same key, hence pressing either of these keys will not necessarely set the value of the screen to that of the keyboard, but rather toggle between  them.&lt;br /&gt;
 				//Also note that the cursor will step back to the previous value to check if it is a + or -.&lt;br /&gt;
 				if(val == 50 || val == 51 || val == 54 || val == 55)&lt;br /&gt;
 				{&lt;br /&gt;
 					if(istring[cursor-(cursor&amp;gt;0?1:0)] == 0x2B || istring[cursor-(cursor&amp;gt;0?1:0)] == 0x2D)&lt;br /&gt;
 					{&lt;br /&gt;
 						kv = istring[cursor-(cursor&amp;gt;0?1:0)]==0x2B?0x2D:0x2B;&lt;br /&gt;
 						if(cursor&amp;gt;0)&lt;br /&gt;
 							cursor--;&lt;br /&gt;
 					}&lt;br /&gt;
 					else&lt;br /&gt;
 						kv = 0x2B;&lt;br /&gt;
 				}&lt;br /&gt;
 				//Values 52 to 53 are . and / respectively on main keyboard. Values 56 and 57 are . and / respectively on NUMPAD. ASCII values are 0x2E for &amp;quot;.&amp;quot; and 0x2F for &amp;quot;/&amp;quot;. &lt;br /&gt;
 				if(val == 52 || val == 53 || val == 56 || val == 57)&lt;br /&gt;
 					kv = 0x2E+char(val%2);&lt;br /&gt;
 				istring[cursor] = kv;&lt;br /&gt;
 			}&lt;br /&gt;
 			if(cursor &amp;lt; MAXINPUT-1)&lt;br /&gt;
 				cursor++;&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;br /&gt;
[[Category:SimConnect]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_PMDG-style_keyboard_entry&amp;diff=10014</id>
		<title>C: PMDG-style keyboard entry</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_PMDG-style_keyboard_entry&amp;diff=10014"/>
		<updated>2015-11-29T11:18:49Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| P3D2 = true&lt;br /&gt;
| P3D = true&lt;br /&gt;
| FSXI = unknown&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| FSX = true&lt;br /&gt;
| FS2004 = false&lt;br /&gt;
| FS2002 = false&lt;br /&gt;
| FS2000 = unknown&lt;br /&gt;
| FS98 = unknown&lt;br /&gt;
| XP10 = false &lt;br /&gt;
| XP9 = false &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
If you have flown any of the PMDG aircraft, you may have found it quite convenient to be able to type your entries into the FMC with the keyboard by holding down the Tab key. Here is an example how to do this in a gauge using SimConnect. This sample is based on the blank multi thread D2D gauge template available in the FSDeveloper resources: http://www.fsdeveloper.com/forum/resources/blank-multi-thread-d2d-gauge-template.155/&lt;br /&gt;
&lt;br /&gt;
First off, it helps to have an array of strings to loop through when setting up your key assignments in SimConnect:&lt;br /&gt;
&lt;br /&gt;
 const char* kstr[58] = &lt;br /&gt;
 {&lt;br /&gt;
 	&amp;quot;Backspace\0&amp;quot;, &amp;quot;Tab\0&amp;quot;, &amp;quot;Space\0&amp;quot;, &amp;quot;Num_Del\0&amp;quot;, &amp;quot;0\0&amp;quot;, &amp;quot;1\0&amp;quot;, &amp;quot;2\0&amp;quot;, &amp;quot;3\0&amp;quot;, &amp;quot;4\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;5\0&amp;quot;, &amp;quot;6\0&amp;quot;, &amp;quot;7\0&amp;quot;, &amp;quot;8\0&amp;quot;, &amp;quot;9\0&amp;quot;, &amp;quot;A\0&amp;quot;, &amp;quot;B\0&amp;quot;, &amp;quot;C\0&amp;quot;, &amp;quot;D\0&amp;quot;, &amp;quot;E\0&amp;quot;, &amp;quot;F\0&amp;quot;, &amp;quot;G\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;H\0&amp;quot;, &amp;quot;I\0&amp;quot;, &amp;quot;J\0&amp;quot;, &amp;quot;K\0&amp;quot;, &amp;quot;L\0&amp;quot;, &amp;quot;M\0&amp;quot;, &amp;quot;N\0&amp;quot;, &amp;quot;O\0&amp;quot;, &amp;quot;P\0&amp;quot;,	&amp;quot;Q\0&amp;quot;, &amp;quot;R\0&amp;quot;, &amp;quot;S\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;T\0&amp;quot;, &amp;quot;U\0&amp;quot;, &amp;quot;V\0&amp;quot;, &amp;quot;W\0&amp;quot;, &amp;quot;X\0&amp;quot;, &amp;quot;Y\0&amp;quot;, &amp;quot;Z\0&amp;quot;, &amp;quot;VK_NUMPAD0\0&amp;quot;, &amp;quot;VK_NUMPAD1\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;VK_NUMPAD2\0&amp;quot;, &amp;quot;VK_NUMPAD3\0&amp;quot;, &amp;quot;VK_NUMPAD4\0&amp;quot;, &amp;quot;VK_NUMPAD5\0&amp;quot;, &amp;quot;VK_NUMPAD6\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;VK_NUMPAD7\0&amp;quot;, &amp;quot;VK_NUMPAD8\0&amp;quot;, &amp;quot;VK_NUMPAD9\0&amp;quot;, &amp;quot;VK_ADD\0&amp;quot;, &amp;quot;VK_SUBTRACT\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;VK_DECIMAL\0&amp;quot;, &amp;quot;VK_DIVIDE\0&amp;quot;, &amp;quot;VK_PLUS\0&amp;quot;, &amp;quot;VK_MINUS\0&amp;quot;, &amp;quot;VK_PERIOD\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;VK_SLASH\0&amp;quot;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Next, you need to define your event ID and group ID enumerations (see CSimConnectData.h in the D2D sample)&lt;br /&gt;
&lt;br /&gt;
 static enum EVENT_ID &lt;br /&gt;
 {&lt;br /&gt;
 	EVK_KBBASE = 1000,//This is for Key Down events&lt;br /&gt;
 	EVK_KBBASEUP = 1100,//This is for Key Up events. Only used for the Tab key so we can know when to capture keyboard input.&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 static enum GROUP_ID&lt;br /&gt;
 {&lt;br /&gt;
 	G_KTOG,//This group only contains the Tab key.&lt;br /&gt;
 	G_KEYS,//This group contains all the other keys used.&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 static enum INPUT_ID&lt;br /&gt;
 {&lt;br /&gt;
 	I_KTOG,//This group only contains the Tab key.&lt;br /&gt;
 	I_KEYS,//This group contains all the other keys used.&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
In the AddDataDefs function in the D2D sample, set up your key definitions as shown:&lt;br /&gt;
 void AddDataDefs(HANDLE hs)&lt;br /&gt;
 {&lt;br /&gt;
 	for(int i = 0; i &amp;lt; 58; i ++)&lt;br /&gt;
 	{&lt;br /&gt;
 		SimConnect_MapClientEventToSimEvent(hs, EVK_KBBASE+i);&lt;br /&gt;
 		SimConnect_AddClientEventToNotificationGroup(hs, i==1?G_KTOG:G_KEYS, EVK_KBBASE+i, true);&lt;br /&gt;
 		SimConnect_MapClientEventToSimEvent(hs, EVK_KBBASEUP+i);&lt;br /&gt;
 		SimConnect_AddClientEventToNotificationGroup(hs, i==1?G_KTOG:G_KEYS, EVK_KBBASEUP+i, true);&lt;br /&gt;
 	}&lt;br /&gt;
 	//Note we have 2 key groups. The KTOG group contains only 1 key, the &amp;quot;Tab&amp;quot; key.&lt;br /&gt;
 	//This is so that the other key group will only mask inputs from the sim and redirect into our code if the Tab key is held down&lt;br /&gt;
 	SimConnect_SetNotificationGroupPriority(hs, G_KTOG, SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE);&lt;br /&gt;
 	SimConnect_SetNotificationGroupPriority(hs, G_KEYS, SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE);&lt;br /&gt;
 	for(int i = 0; i &amp;lt; 58; i ++)&lt;br /&gt;
 	{&lt;br /&gt;
 		SimConnect_MapInputEventToClientEvent(hs, i==1?I_KTOG:I_KEYS, kstr[i], EVK_KBBASE+i, 0, EVK_KBBASEUP+i, 0, 1);&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 	SimConnect_SetInputGroupState(hs, I_KTOG, SIMCONNECT_STATE_ON);&lt;br /&gt;
 	SimConnect_SetInputGroupState(hs, I_KEYS, SIMCONNECT_STATE_OFF);&lt;br /&gt;
 	SimConnect_SetInputGroupPriority(hs, I_KTOG, SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE);&lt;br /&gt;
 	SimConnect_SetInputGroupPriority(hs, I_KEYS, SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Next, in your SimConnect callback under the SIMCONNECT_RECV_ID_EVENT case, call the event handler and toggle the keyboard input state as required:&lt;br /&gt;
 case SIMCONNECT_RECV_ID_EVENT:&lt;br /&gt;
 {&lt;br /&gt;
 	SIMCONNECT_RECV_EVENT *evt = (SIMCONNECT_RECV_EVENT*)pData;&lt;br /&gt;
 	if(evt-&amp;gt;uGroupID == G_KTOG)&lt;br /&gt;
 	{&lt;br /&gt;
 		//if the Tab key is down, activate the masked keyboard key system so our key input will receive events&lt;br /&gt;
 		if(evt-&amp;gt;uEventID == EVK_KBBASE+1)&lt;br /&gt;
 			SimConnect_SetInputGroupState(hSc, I_KEYS, SIMCONNECT_STATE_ON);&lt;br /&gt;
 		else&lt;br /&gt;
 			SimConnect_SetInputGroupState(hSc, I_KEYS, SIMCONNECT_STATE_OFF);&lt;br /&gt;
 	}&lt;br /&gt;
 	//Subtract 1000 from the key event id to match our key identifier system&lt;br /&gt;
 	if(evt-&amp;gt;uGroupID == G_KEYS)&lt;br /&gt;
 		KeyInput(evt-&amp;gt;uEventID-1000);&lt;br /&gt;
 }&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
Finally, set up your key input function where you can convert from key input ID to ASCII string as shown:&lt;br /&gt;
&lt;br /&gt;
 #define MAXINPUT 20&lt;br /&gt;
 char istring[MAXINPUT];&lt;br /&gt;
 int cursor = 0;&lt;br /&gt;
 void KeyInput(int val)&lt;br /&gt;
 {&lt;br /&gt;
 	if(val &amp;lt; 100)//Note, we only accept Key Down events&lt;br /&gt;
 	{&lt;br /&gt;
 		//0 is Backspace, 3 is Delete. If you want Delete to wipe out the whole string, use memset(istring, 0x00, MAXINPUT); when val == 3&lt;br /&gt;
 		if(val == 0 || val == 3)&lt;br /&gt;
 		{&lt;br /&gt;
 			istring[cursor] = 0x00;&lt;br /&gt;
 			cursor = cursor&amp;gt;0?cursor-1:cursor;&lt;br /&gt;
 		}&lt;br /&gt;
 		else&lt;br /&gt;
 		{&lt;br /&gt;
 			//If val == 2, the value to put in is a blank space &#039; &#039;.&lt;br /&gt;
 			if(val == 2)&lt;br /&gt;
 				istring[cursor]=&#039; &#039;;&lt;br /&gt;
 			else&lt;br /&gt;
 			{&lt;br /&gt;
 				char kv = 0x00;&lt;br /&gt;
 				//Values 4 to 13 are top row of numbers on keyboard. ASCII values are 0x30 to 0x39 for &amp;quot;0-9&amp;quot;&lt;br /&gt;
 				if(val &amp;gt; 3 &amp;amp;&amp;amp; val &amp;lt; 14)&lt;br /&gt;
 					kv = 0x30+char(val-4);&lt;br /&gt;
 				//Values 14 to 39 are letters on keyboard. ASCII values are 0x41 to 0x5A for &amp;quot;A-Z&amp;quot;. Uppercase only in this case. If you want lowercase, use ASCII values 0x61 to 0x7A&lt;br /&gt;
 				if(val &amp;gt; 13 &amp;amp;&amp;amp; val &amp;lt; 40)&lt;br /&gt;
 					kv = 0x41+char(val-14);&lt;br /&gt;
 				//Values 40 to 49 are NUMPAD numbers. ASCII values are again 0x30 to 0x39 for &amp;quot;0-9&amp;quot;&lt;br /&gt;
 				if(val &amp;gt; 39 &amp;amp;&amp;amp; val &amp;lt; 50)&lt;br /&gt;
 					kv = 0x30+char(val-40);&lt;br /&gt;
 				//Values 50 to 51 are + and - respectively on top row of keyboard. Values 54 and 55 are + and - respectively on NUMPAD. ASCII values are 0x2B for &amp;quot;+&amp;quot; and 0x2D for &amp;quot;-&amp;quot;.&lt;br /&gt;
 				//Note that most CDUs have both on the same key, hence pressing either of these keys will not necessarely set the value of the screen to that of the keyboard, but rather toggle between  them.&lt;br /&gt;
 				//Also note that the cursor will step back to the previous value to check if it is a + or -.&lt;br /&gt;
 				if(val == 50 || val == 51 || val == 54 || val == 55)&lt;br /&gt;
 				{&lt;br /&gt;
 					if(istring[cursor-(cursor&amp;gt;0?1:0)] == 0x2B || istring[cursor-(cursor&amp;gt;0?1:0)] == 0x2D)&lt;br /&gt;
 					{&lt;br /&gt;
 						kv = istring[cursor-(cursor&amp;gt;0?1:0)]==0x2B?0x2D:0x2B;&lt;br /&gt;
 						if(cursor&amp;gt;0)&lt;br /&gt;
 							cursor--;&lt;br /&gt;
 					}&lt;br /&gt;
 					else&lt;br /&gt;
 						kv = 0x2B;&lt;br /&gt;
 				}&lt;br /&gt;
 				//Values 52 to 53 are . and / respectively on main keyboard. Values 56 and 57 are . and / respectively on NUMPAD. ASCII values are 0x2E for &amp;quot;.&amp;quot; and 0x2F for &amp;quot;/&amp;quot;. &lt;br /&gt;
 				if(val == 52 || val == 53 || val == 56 || val == 57)&lt;br /&gt;
 					kv = 0x2E+char(val%2);&lt;br /&gt;
 				istring[cursor] = kv;&lt;br /&gt;
 			}&lt;br /&gt;
 			if(cursor &amp;lt; MAXINPUT-1)&lt;br /&gt;
 				cursor++;&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_PMDG-style_keyboard_entry&amp;diff=10013</id>
		<title>C: PMDG-style keyboard entry</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_PMDG-style_keyboard_entry&amp;diff=10013"/>
		<updated>2015-11-29T11:17:05Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: Created page with &amp;quot;If you have flown any of the PMDG aircraft, you may have found it quite convenient to be able to type your entries into the FMC with the keyboard by holding down the Tab key. ...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you have flown any of the PMDG aircraft, you may have found it quite convenient to be able to type your entries into the FMC with the keyboard by holding down the Tab key. Here is an example how to do this in a gauge using SimConnect. This sample is based on the blank multi thread D2D gauge template available in the FSDeveloper resources: http://www.fsdeveloper.com/forum/resources/blank-multi-thread-d2d-gauge-template.155/&lt;br /&gt;
&lt;br /&gt;
First off, it helps to have an array of strings to loop through when setting up your key assignments in SimConnect:&lt;br /&gt;
&lt;br /&gt;
 const char* kstr[58] = &lt;br /&gt;
 {&lt;br /&gt;
 	&amp;quot;Backspace\0&amp;quot;, &amp;quot;Tab\0&amp;quot;, &amp;quot;Space\0&amp;quot;, &amp;quot;Num_Del\0&amp;quot;, &amp;quot;0\0&amp;quot;, &amp;quot;1\0&amp;quot;, &amp;quot;2\0&amp;quot;, &amp;quot;3\0&amp;quot;, &amp;quot;4\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;5\0&amp;quot;, &amp;quot;6\0&amp;quot;, &amp;quot;7\0&amp;quot;, &amp;quot;8\0&amp;quot;, &amp;quot;9\0&amp;quot;, &amp;quot;A\0&amp;quot;, &amp;quot;B\0&amp;quot;, &amp;quot;C\0&amp;quot;, &amp;quot;D\0&amp;quot;, &amp;quot;E\0&amp;quot;, &amp;quot;F\0&amp;quot;, &amp;quot;G\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;H\0&amp;quot;, &amp;quot;I\0&amp;quot;, &amp;quot;J\0&amp;quot;, &amp;quot;K\0&amp;quot;, &amp;quot;L\0&amp;quot;, &amp;quot;M\0&amp;quot;, &amp;quot;N\0&amp;quot;, &amp;quot;O\0&amp;quot;, &amp;quot;P\0&amp;quot;,	&amp;quot;Q\0&amp;quot;, &amp;quot;R\0&amp;quot;, &amp;quot;S\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;T\0&amp;quot;, &amp;quot;U\0&amp;quot;, &amp;quot;V\0&amp;quot;, &amp;quot;W\0&amp;quot;, &amp;quot;X\0&amp;quot;, &amp;quot;Y\0&amp;quot;, &amp;quot;Z\0&amp;quot;, &amp;quot;VK_NUMPAD0\0&amp;quot;, &amp;quot;VK_NUMPAD1\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;VK_NUMPAD2\0&amp;quot;, &amp;quot;VK_NUMPAD3\0&amp;quot;, &amp;quot;VK_NUMPAD4\0&amp;quot;, &amp;quot;VK_NUMPAD5\0&amp;quot;, &amp;quot;VK_NUMPAD6\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;VK_NUMPAD7\0&amp;quot;, &amp;quot;VK_NUMPAD8\0&amp;quot;, &amp;quot;VK_NUMPAD9\0&amp;quot;, &amp;quot;VK_ADD\0&amp;quot;, &amp;quot;VK_SUBTRACT\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;VK_DECIMAL\0&amp;quot;, &amp;quot;VK_DIVIDE\0&amp;quot;, &amp;quot;VK_PLUS\0&amp;quot;, &amp;quot;VK_MINUS\0&amp;quot;, &amp;quot;VK_PERIOD\0&amp;quot;,&lt;br /&gt;
 	&amp;quot;VK_SLASH\0&amp;quot;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Next, you need to define your event ID and group ID enumerations (see CSimConnectData.h in the D2D sample)&lt;br /&gt;
&lt;br /&gt;
 static enum EVENT_ID &lt;br /&gt;
 {&lt;br /&gt;
 	EVK_KBBASE = 1000,//This is for Key Down events&lt;br /&gt;
 	EVK_KBBASEUP = 1100,//This is for Key Up events. Only used for the Tab key so we can know when to capture keyboard input.&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 static enum GROUP_ID&lt;br /&gt;
 {&lt;br /&gt;
 	G_KTOG,//This group only contains the Tab key.&lt;br /&gt;
 	G_KEYS,//This group contains all the other keys used.&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 static enum INPUT_ID&lt;br /&gt;
 {&lt;br /&gt;
 	I_KTOG,//This group only contains the Tab key.&lt;br /&gt;
 	I_KEYS,//This group contains all the other keys used.&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
In the AddDataDefs function in the D2D sample, set up your key definitions as shown:&lt;br /&gt;
 void AddDataDefs(HANDLE hs)&lt;br /&gt;
 {&lt;br /&gt;
 	for(int i = 0; i &amp;lt; 58; i ++)&lt;br /&gt;
 	{&lt;br /&gt;
 		SimConnect_MapClientEventToSimEvent(hs, EVK_KBBASE+i);&lt;br /&gt;
 		SimConnect_AddClientEventToNotificationGroup(hs, i==1?G_KTOG:G_KEYS, EVK_KBBASE+i, true);&lt;br /&gt;
 		SimConnect_MapClientEventToSimEvent(hs, EVK_KBBASEUP+i);&lt;br /&gt;
 		SimConnect_AddClientEventToNotificationGroup(hs, i==1?G_KTOG:G_KEYS, EVK_KBBASEUP+i, true);&lt;br /&gt;
 	}&lt;br /&gt;
 	//Note we have 2 key groups. The KTOG group contains only 1 key, the &amp;quot;Tab&amp;quot; key.&lt;br /&gt;
 	//This is so that the other key group will only mask inputs from the sim and redirect into our code if the Tab key is held down&lt;br /&gt;
 	SimConnect_SetNotificationGroupPriority(hs, G_KTOG, SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE);&lt;br /&gt;
 	SimConnect_SetNotificationGroupPriority(hs, G_KEYS, SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE);&lt;br /&gt;
 	for(int i = 0; i &amp;lt; 58; i ++)&lt;br /&gt;
 	{&lt;br /&gt;
 		SimConnect_MapInputEventToClientEvent(hs, i==1?I_KTOG:I_KEYS, kstr[i], EVK_KBBASE+i, 0, EVK_KBBASEUP+i, 0, 1);&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 	SimConnect_SetInputGroupState(hs, I_KTOG, SIMCONNECT_STATE_ON);&lt;br /&gt;
 	SimConnect_SetInputGroupState(hs, I_KEYS, SIMCONNECT_STATE_OFF);&lt;br /&gt;
 	SimConnect_SetInputGroupPriority(hs, I_KTOG, SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE);&lt;br /&gt;
 	SimConnect_SetInputGroupPriority(hs, I_KEYS, SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Next, in your SimConnect callback under the SIMCONNECT_RECV_ID_EVENT case, call the event handler and toggle the keyboard input state as required:&lt;br /&gt;
 case SIMCONNECT_RECV_ID_EVENT:&lt;br /&gt;
 {&lt;br /&gt;
 	SIMCONNECT_RECV_EVENT *evt = (SIMCONNECT_RECV_EVENT*)pData;&lt;br /&gt;
 	if(evt-&amp;gt;uGroupID == G_KTOG)&lt;br /&gt;
 	{&lt;br /&gt;
 		//if the Tab key is down, activate the masked keyboard key system so our key input will receive events&lt;br /&gt;
 		if(evt-&amp;gt;uEventID == EVK_KBBASE+1)&lt;br /&gt;
 			SimConnect_SetInputGroupState(hSc, I_KEYS, SIMCONNECT_STATE_ON);&lt;br /&gt;
 		else&lt;br /&gt;
 			SimConnect_SetInputGroupState(hSc, I_KEYS, SIMCONNECT_STATE_OFF);&lt;br /&gt;
 	}&lt;br /&gt;
 	//Subtract 1000 from the key event id to match our key identifier system&lt;br /&gt;
 	if(evt-&amp;gt;uGroupID == G_KEYS)&lt;br /&gt;
 		KeyInput(evt-&amp;gt;uEventID-1000);&lt;br /&gt;
 }&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
Finally, set up your key input function where you can convert from key input ID to ASCII string as shown:&lt;br /&gt;
&lt;br /&gt;
 #define MAXINPUT 20&lt;br /&gt;
 char istring[MAXINPUT];&lt;br /&gt;
 int cursor = 0;&lt;br /&gt;
 void KeyInput(int val)&lt;br /&gt;
 {&lt;br /&gt;
 	if(val &amp;lt; 100)//Note, we only accept Key Down events&lt;br /&gt;
 	{&lt;br /&gt;
 		//0 is Backspace, 3 is Delete. If you want Delete to wipe out the whole string, use memset(istring, 0x00, MAXINPUT); when val == 3&lt;br /&gt;
 		if(val == 0 || val == 3)&lt;br /&gt;
 		{&lt;br /&gt;
 			istring[cursor] = 0x00;&lt;br /&gt;
 			cursor = cursor&amp;gt;0?cursor-1:cursor;&lt;br /&gt;
 		}&lt;br /&gt;
 		else&lt;br /&gt;
 		{&lt;br /&gt;
 			//If val == 2, the value to put in is a blank space &#039; &#039;.&lt;br /&gt;
 			if(val == 2)&lt;br /&gt;
 				istring[cursor]=&#039; &#039;;&lt;br /&gt;
 			else&lt;br /&gt;
 			{&lt;br /&gt;
 				char kv = 0x00;&lt;br /&gt;
 				//Values 4 to 13 are top row of numbers on keyboard. ASCII values are 0x30 to 0x39 for &amp;quot;0-9&amp;quot;&lt;br /&gt;
 				if(val &amp;gt; 3 &amp;amp;&amp;amp; val &amp;lt; 14)&lt;br /&gt;
 					kv = 0x30+char(val-4);&lt;br /&gt;
 				//Values 14 to 39 are letters on keyboard. ASCII values are 0x41 to 0x5A for &amp;quot;A-Z&amp;quot;. Uppercase only in this case. If you want lowercase, use ASCII values 0x61 to 0x7A&lt;br /&gt;
 				if(val &amp;gt; 13 &amp;amp;&amp;amp; val &amp;lt; 40)&lt;br /&gt;
 					kv = 0x41+char(val-14);&lt;br /&gt;
 				//Values 40 to 49 are NUMPAD numbers. ASCII values are again 0x30 to 0x39 for &amp;quot;0-9&amp;quot;&lt;br /&gt;
 				if(val &amp;gt; 39 &amp;amp;&amp;amp; val &amp;lt; 50)&lt;br /&gt;
 					kv = 0x30+char(val-40);&lt;br /&gt;
 				//Values 50 to 51 are + and - respectively on top row of keyboard. Values 54 and 55 are + and - respectively on NUMPAD. ASCII values are 0x2B for &amp;quot;+&amp;quot; and 0x2D for &amp;quot;-&amp;quot;.&lt;br /&gt;
 				//Note that most CDUs have both on the same key, hence pressing either of these keys will not necessarely set the value of the screen to that of the keyboard, but rather toggle between  them.&lt;br /&gt;
 				//Also note that the cursor will step back to the previous value to check if it is a + or -.&lt;br /&gt;
 				if(val == 50 || val == 51 || val == 54 || val == 55)&lt;br /&gt;
 				{&lt;br /&gt;
 					if(istring[cursor-(cursor&amp;gt;0?1:0)] == 0x2B || istring[cursor-(cursor&amp;gt;0?1:0)] == 0x2D)&lt;br /&gt;
 					{&lt;br /&gt;
 						kv = istring[cursor-(cursor&amp;gt;0?1:0)]==0x2B?0x2D:0x2B;&lt;br /&gt;
 						if(cursor&amp;gt;0)&lt;br /&gt;
 							cursor--;&lt;br /&gt;
 					}&lt;br /&gt;
 					else&lt;br /&gt;
 						kv = 0x2B;&lt;br /&gt;
 				}&lt;br /&gt;
 				//Values 52 to 53 are . and / respectively on main keyboard. Values 56 and 57 are . and / respectively on NUMPAD. ASCII values are 0x2E for &amp;quot;.&amp;quot; and 0x2F for &amp;quot;/&amp;quot;. &lt;br /&gt;
 				if(val == 52 || val == 53 || val == 56 || val == 57)&lt;br /&gt;
 					kv = 0x2E+char(val%2);&lt;br /&gt;
 				istring[cursor] = kv;&lt;br /&gt;
 			}&lt;br /&gt;
 			if(cursor &amp;lt; MAXINPUT-1)&lt;br /&gt;
 				cursor++;&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9973</id>
		<title>C: C++ timers</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9973"/>
		<updated>2015-08-11T13:22:39Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| P3D2 = true&lt;br /&gt;
| P3D = true&lt;br /&gt;
| FSXI = unknown&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| FSX = true&lt;br /&gt;
| FS2004 = false&lt;br /&gt;
| FS2002 = false&lt;br /&gt;
| FS2000 = unknown&lt;br /&gt;
| FS98 = unknown&lt;br /&gt;
| XP10 = false &lt;br /&gt;
| XP9 = false &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Most of you may be familiar with the TICK18 token variable which is incremented at 18Hz. Another option to make use of the 18Hz increment system (like making 0.5 second timers and such) is to call a function from the PANEL_SERVICE_PRE_UPDATE case of your callback function which increments your timing variable which you simply reset to 0 when it is equal to 9 (for a 0.5 second timer). &lt;br /&gt;
&lt;br /&gt;
The following however is an undocumented function in the simulator which returns total time elapsed in seconds with sub-18Hz accuracy.&lt;br /&gt;
&lt;br /&gt;
In your choice of your project&#039;s header files, do the following function prototype:&lt;br /&gt;
&lt;br /&gt;
 typedef double (__stdcall *fGetSimTime)();&lt;br /&gt;
&lt;br /&gt;
Then in your module_init function:&lt;br /&gt;
 &lt;br /&gt;
 HMODULE hsimsched = NULL;&lt;br /&gt;
 fGetSimTime GetSimTime6 = NULL;&lt;br /&gt;
 void FSAPI module_init(void)&lt;br /&gt;
 {&lt;br /&gt;
  GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
  if(hsimsched)&lt;br /&gt;
   GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));//Note, for FSX SP2 use 4 instead of 6. Also since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals.  }&lt;br /&gt;
&lt;br /&gt;
Now wherever you wish to call this function, include the header where the prototype is contained and add:&lt;br /&gt;
&lt;br /&gt;
 extern fGetSimTime GetSimTime6;&lt;br /&gt;
&lt;br /&gt;
To call it and find out how much time has passed:&lt;br /&gt;
&lt;br /&gt;
 double time = GetSimTime6();&lt;br /&gt;
&lt;br /&gt;
UPDATE:&lt;br /&gt;
&lt;br /&gt;
The ordinal used by P3D v2.5 is different to that of FSXA. Also, the format is such that the decorated function name is available from the dll. So for P3D v2.5, use the following:&lt;br /&gt;
 GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Complete example for automatic function selection:&lt;br /&gt;
&lt;br /&gt;
 GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
 if(hsimsched)&lt;br /&gt;
 {&lt;br /&gt;
 	DWORD fsxa = (DWORD)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 	DWORD p3dv2 = (DWORD)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
 	if(fsxa-(DWORD)hsimsched == 0x1530)&lt;br /&gt;
 		GetSimTime6 = (fGetSimTime)fsxa;//FSX Acceleration version&lt;br /&gt;
 	else&lt;br /&gt;
 	{&lt;br /&gt;
 		if(p3dv2)&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)p3dv2;&lt;br /&gt;
 		else&lt;br /&gt;
 		{&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(4));//FSX SP2. &lt;br /&gt;
 			//Since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals. &lt;br /&gt;
 			if(DWORD(GetSimTime6)-DWORD(hsimsched) != 0x14D0)&lt;br /&gt;
 				GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 }&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9970</id>
		<title>C: C++ timers</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9970"/>
		<updated>2015-07-27T13:01:55Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| P3D2 = true&lt;br /&gt;
| P3D = true&lt;br /&gt;
| FSXI = unknown&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| FSX = true&lt;br /&gt;
| FS2004 = false&lt;br /&gt;
| FS2002 = false&lt;br /&gt;
| FS2000 = unknown&lt;br /&gt;
| FS98 = unknown&lt;br /&gt;
| XP10 = false &lt;br /&gt;
| XP9 = false &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Most of you may be familiar with the TICK18 token variable which is incremented at 18Hz. Another option to make use of the 18Hz increment system (like making 0.5 second timers and such) is to call a function from the PANEL_SERVICE_PRE_UPDATE case of your callback function which increments your timing variable which you simply reset to 0 when it is equal to 9 (for a 0.5 second timer). &lt;br /&gt;
&lt;br /&gt;
The following however is an undocumented function in the simulator which returns total time elapsed in seconds with sub-18Hz accuracy.&lt;br /&gt;
&lt;br /&gt;
In your choice of your project&#039;s header files, do the following function prototype:&lt;br /&gt;
&lt;br /&gt;
 typedef double (__cdecl *fGetSimTime)();&lt;br /&gt;
&lt;br /&gt;
Then in your module_init function:&lt;br /&gt;
 &lt;br /&gt;
 HMODULE hsimsched = NULL;&lt;br /&gt;
 fGetSimTime GetSimTime6 = NULL;&lt;br /&gt;
 void FSAPI module_init(void)&lt;br /&gt;
 {&lt;br /&gt;
  GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
  if(hsimsched)&lt;br /&gt;
   GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));//Note, for FSX SP2 use 4 instead of 6. Also since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals.  }&lt;br /&gt;
&lt;br /&gt;
Now wherever you wish to call this function, include the header where the prototype is contained and add:&lt;br /&gt;
&lt;br /&gt;
 extern fGetSimTime GetSimTime6;&lt;br /&gt;
&lt;br /&gt;
To call it and find out how much time has passed:&lt;br /&gt;
&lt;br /&gt;
 double time = GetSimTime6();&lt;br /&gt;
&lt;br /&gt;
UPDATE:&lt;br /&gt;
&lt;br /&gt;
The ordinal used by P3D v2.5 is different to that of FSXA. Also, the format is such that the decorated function name is available from the dll. So for P3D v2.5, use the following:&lt;br /&gt;
 GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Complete example for automatic function selection:&lt;br /&gt;
&lt;br /&gt;
 GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
 if(hsimsched)&lt;br /&gt;
 {&lt;br /&gt;
 	DWORD fsxa = (DWORD)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 	DWORD p3dv2 = (DWORD)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
 	if(fsxa-(DWORD)hsimsched == 0x1530)&lt;br /&gt;
 		GetSimTime6 = (fGetSimTime)fsxa;//FSX Acceleration version&lt;br /&gt;
 	else&lt;br /&gt;
 	{&lt;br /&gt;
 		if(p3dv2)&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)p3dv2;&lt;br /&gt;
 		else&lt;br /&gt;
 		{&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(4));//FSX SP2. &lt;br /&gt;
 			//Since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals. &lt;br /&gt;
 			if(DWORD(GetSimTime6)-DWORD(hsimsched) != 0x14D0)&lt;br /&gt;
 				GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 }&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9947</id>
		<title>C: C++ timers</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9947"/>
		<updated>2015-06-04T10:33:59Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| P3D2 = true&lt;br /&gt;
| P3D = true&lt;br /&gt;
| FSXI = unknown&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| FSX = true&lt;br /&gt;
| FS2004 = false&lt;br /&gt;
| FS2002 = false&lt;br /&gt;
| FS2000 = unknown&lt;br /&gt;
| FS98 = unknown&lt;br /&gt;
| XP10 = false &lt;br /&gt;
| XP9 = false &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Most of you may be familiar with the TICK18 token variable which is incremented at 18Hz. Another option to make use of the 18Hz increment system (like making 0.5 second timers and such) is to call a function from the PANEL_SERVICE_PRE_UPDATE case of your callback function which increments your timing variable which you simply reset to 0 when it is equal to 9 (for a 0.5 second timer). &lt;br /&gt;
&lt;br /&gt;
The following however is an undocumented function in the simulator which returns total time elapsed in seconds with sub-18Hz accuracy.&lt;br /&gt;
&lt;br /&gt;
In your choice of your project&#039;s header files, do the following function prototype:&lt;br /&gt;
&lt;br /&gt;
 typedef double (__cdecl *fGetSimTime)();&lt;br /&gt;
&lt;br /&gt;
Then in your module_init function:&lt;br /&gt;
 &lt;br /&gt;
 HMODULE hsimsched = NULL;&lt;br /&gt;
 fGetSimTime GetSimTime6 = NULL;&lt;br /&gt;
 void FSAPI module_init(void)&lt;br /&gt;
 {&lt;br /&gt;
  GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
  if(hsimsched)&lt;br /&gt;
   GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));//Note, for FSX SP2 use 4 instead of 6. Also note that if you wish to distinguish dynamically between sim versions, FSX Acceleration has a offset (function address-hsimsched value) of 0x1530, and SP2 of 0x14D0. FSX SE may vary as builds get released but since FSXA and SP2 aren&#039;t likely to change you can check if it is not equal to their offsets and the P3D v2 function isn&#039;t located by function name, you can assume FSX SE and use ordinal 6.&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now wherever you wish to call this function, include the header where the prototype is contained and add:&lt;br /&gt;
&lt;br /&gt;
 extern fGetSimTime GetSimTime6;&lt;br /&gt;
&lt;br /&gt;
To call it and find out how much time has passed:&lt;br /&gt;
&lt;br /&gt;
 double time = GetSimTime6();&lt;br /&gt;
&lt;br /&gt;
UPDATE:&lt;br /&gt;
&lt;br /&gt;
The ordinal used by P3D v2.5 is different to that of FSXA. Also, the format is such that the decorated function name is available from the dll. So for P3D v2.5, use the following:&lt;br /&gt;
 GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Complete example for automatic function selection:&lt;br /&gt;
&lt;br /&gt;
 GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
 if(hsimsched)&lt;br /&gt;
 {&lt;br /&gt;
 	DWORD fsxa = (DWORD)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 	DWORD p3dv2 = (DWORD)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
 	if(fsxa-(DWORD)hsimsched == 0x1530)&lt;br /&gt;
 		GetSimTime6 = (fGetSimTime)fsxa;//FSX Acceleration version&lt;br /&gt;
 	else&lt;br /&gt;
 	{&lt;br /&gt;
 		if(p3dv2)&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)p3dv2;&lt;br /&gt;
 		else&lt;br /&gt;
 		{&lt;br /&gt;
 			GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(4));//FSX SP2. &lt;br /&gt;
 			//Since neither Acceleration nor SP 2 are likely to be updated,&lt;br /&gt;
 			//one can assume the offsets (0x14D0 for SP2 and 0x1530 for acceleration) will remain constant, thus leaving only P3D and FSX SE with offsets that vary.&lt;br /&gt;
 			//P3D can be retrieved with the function name thus elliminating confusion of function ordinals. &lt;br /&gt;
 			if(DWORD(GetSimTime6)-DWORD(hsimsched) != 0x14D0)&lt;br /&gt;
 				GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 }&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9931</id>
		<title>C: C++ timers</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9931"/>
		<updated>2015-05-13T19:01:26Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| P3D2 = true&lt;br /&gt;
| P3D = true&lt;br /&gt;
| FSXI = unknown&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| FSX = true&lt;br /&gt;
| FS2004 = false&lt;br /&gt;
| FS2002 = false&lt;br /&gt;
| FS2000 = unknown&lt;br /&gt;
| FS98 = unknown&lt;br /&gt;
| XP10 = false &lt;br /&gt;
| XP9 = false &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Most of you may be familiar with the TICK18 token variable which is incremented at 18Hz. Another option to make use of the 18Hz increment system (like making 0.5 second timers and such) is to call a function from the PANEL_SERVICE_PRE_UPDATE case of your callback function which increments your timing variable which you simply reset to 0 when it is equal to 9 (for a 0.5 second timer). &lt;br /&gt;
&lt;br /&gt;
The following however is an undocumented function in the simulator which returns total time elapsed in seconds with sub-18Hz accuracy.&lt;br /&gt;
&lt;br /&gt;
In your choice of your project&#039;s header files, do the following function prototype:&lt;br /&gt;
&lt;br /&gt;
 typedef double (__cdecl *fGetSimTime)();&lt;br /&gt;
&lt;br /&gt;
Then in your module_init function:&lt;br /&gt;
 &lt;br /&gt;
 HMODULE hsimsched = NULL;&lt;br /&gt;
 fGetSimTime GetSimTime6 = NULL;&lt;br /&gt;
 void FSAPI module_init(void)&lt;br /&gt;
 {&lt;br /&gt;
  GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
  if(hsimsched)&lt;br /&gt;
   GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));//Note, for FSX SP2 use 4 instead of 6. Also note that if you wish to distinguish dynamically between sim versions, FSX Acceleration has a offset (function address-hsimsched value) of 0x1530, and SP2 of 0x14D0. FSX SE may vary as builds get released but since FSXA and SP2 aren&#039;t likely to change you can check if it is not equal to their offsets and the P3D v2 function isn&#039;t located by function name, you can assume FSX SE and use ordinal 6.&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now wherever you wish to call this function, include the header where the prototype is contained and add:&lt;br /&gt;
&lt;br /&gt;
 extern fGetSimTime GetSimTime6;&lt;br /&gt;
&lt;br /&gt;
To call it and find out how much time has passed:&lt;br /&gt;
&lt;br /&gt;
 double time = GetSimTime6();&lt;br /&gt;
&lt;br /&gt;
UPDATE:&lt;br /&gt;
&lt;br /&gt;
The ordinal used by P3D v2.5 is different to that of FSXA. Also, the format is such that the decorated function name is available from the dll. So for P3D v2.5, use the following:&lt;br /&gt;
 GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9907</id>
		<title>C: C++ timers</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9907"/>
		<updated>2015-04-23T11:38:07Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| FSXI = true&lt;br /&gt;
| FSX = true&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| P3D2 = true&lt;br /&gt;
| P3D = true&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Most of you may be familiar with the TICK18 token variable which is incremented at 18Hz. Another option to make use of the 18Hz increment system (like making 0.5 second timers and such) is to call a function from the PANEL_SERVICE_PRE_UPDATE case of your callback function which increments your timing variable which you simply reset to 0 when it is equal to 9 (for a 0.5 second timer). &lt;br /&gt;
&lt;br /&gt;
The following however is an undocumented function in the simulator which returns total time elapsed in seconds with sub-18Hz accuracy.&lt;br /&gt;
&lt;br /&gt;
In your choice of your project&#039;s header files, do the following function prototype:&lt;br /&gt;
&lt;br /&gt;
 typedef double (__cdecl *fGetSimTime)();&lt;br /&gt;
&lt;br /&gt;
Then in your module_init function:&lt;br /&gt;
 &lt;br /&gt;
 HMODULE hsimsched = NULL;&lt;br /&gt;
 fGetSimTime GetSimTime6 = NULL;&lt;br /&gt;
 void FSAPI module_init(void)&lt;br /&gt;
 {&lt;br /&gt;
  GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
  if(hsimsched)&lt;br /&gt;
   GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));//Note, for FSX SP2 use 4 instead of 6&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now wherever you wish to call this function, include the header where the prototype is contained and add:&lt;br /&gt;
&lt;br /&gt;
 extern fGetSimTime GetSimTime6;&lt;br /&gt;
&lt;br /&gt;
To call it and find out how much time has passed:&lt;br /&gt;
&lt;br /&gt;
 double time = GetSimTime6();&lt;br /&gt;
&lt;br /&gt;
UPDATE:&lt;br /&gt;
&lt;br /&gt;
The ordinal used by P3D v2.5 is different to that of FSXA. Also, the format is such that the decorated function name is available from the dll. So for P3D v2.5, use the following:&lt;br /&gt;
 GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9906</id>
		<title>C: C++ timers</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9906"/>
		<updated>2015-04-23T08:06:35Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| FSXI = true&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| P3D2 = true&lt;br /&gt;
| P3D = true&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Most of you may be familiar with the TICK18 token variable which is incremented at 18Hz. Another option to make use of the 18Hz increment system (like making 0.5 second timers and such) is to call a function from the PANEL_SERVICE_PRE_UPDATE case of your callback function which increments your timing variable which you simply reset to 0 when it is equal to 9 (for a 0.5 second timer). &lt;br /&gt;
&lt;br /&gt;
The following however is an undocumented function in the simulator which returns total time elapsed in seconds with sub-18Hz accuracy.&lt;br /&gt;
&lt;br /&gt;
In your choice of your project&#039;s header files, do the following function prototype:&lt;br /&gt;
&lt;br /&gt;
 typedef double (__cdecl *fGetSimTime)();&lt;br /&gt;
&lt;br /&gt;
Then in your module_init function:&lt;br /&gt;
 &lt;br /&gt;
 HMODULE hsimsched = NULL;&lt;br /&gt;
 fGetSimTime GetSimTime6 = NULL;&lt;br /&gt;
 void FSAPI module_init(void)&lt;br /&gt;
 {&lt;br /&gt;
  GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
  if(hsimsched)&lt;br /&gt;
   GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now wherever you wish to call this function, include the header where the prototype is contained and add:&lt;br /&gt;
&lt;br /&gt;
 extern fGetSimTime GetSimTime6;&lt;br /&gt;
&lt;br /&gt;
To call it and find out how much time has passed:&lt;br /&gt;
&lt;br /&gt;
 double time = GetSimTime6();&lt;br /&gt;
&lt;br /&gt;
UPDATE:&lt;br /&gt;
&lt;br /&gt;
The ordinal used by P3D v2.5 is different to that of FSXA. Also, the format is such that the decorated function name is available from the dll. So for P3D v2.5, use the following:&lt;br /&gt;
 GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, &amp;quot;?GetElapsedSimTimeSec@@YGNXZ&amp;quot;);&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9864</id>
		<title>C: C++ timers</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9864"/>
		<updated>2015-03-15T15:26:02Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| FSXI = true&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| P3D2 = true&lt;br /&gt;
| P3D = true&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Most of you may be familiar with the TICK18 token variable which is incremented at 18Hz. Another option to make use of the 18Hz increment system (like making 0.5 second timers and such) is to call a function from the PANEL_SERVICE_PRE_UPDATE case of your callback function which increments your timing variable which you simply reset to 0 when it is equal to 9 (for a 0.5 second timer). &lt;br /&gt;
&lt;br /&gt;
The following however is an undocumented function in the simulator which returns total time elapsed in seconds with sub-18Hz accuracy.&lt;br /&gt;
&lt;br /&gt;
In your choice of your project&#039;s header files, do the following function prototype:&lt;br /&gt;
&lt;br /&gt;
 typedef double (__cdecl *fGetSimTime)();&lt;br /&gt;
&lt;br /&gt;
Then in your module_init function:&lt;br /&gt;
 &lt;br /&gt;
 HMODULE hsimsched = NULL;&lt;br /&gt;
 fGetSimTime GetSimTime6 = NULL;&lt;br /&gt;
 void FSAPI module_init(void)&lt;br /&gt;
 {&lt;br /&gt;
  GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
  if(hsimsched)&lt;br /&gt;
   GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now wherever you wish to call this function, include the header where the prototype is contained and add:&lt;br /&gt;
&lt;br /&gt;
 extern fGetSimTime GetSimTime6;&lt;br /&gt;
&lt;br /&gt;
To call it and find out how much time has passed:&lt;br /&gt;
&lt;br /&gt;
 double time = GetSimTime6();&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9863</id>
		<title>C: C++ timers</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9863"/>
		<updated>2015-03-15T15:25:07Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| FSXI = true&lt;br /&gt;
| FSXA = true&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Most of you may be familiar with the TICK18 token variable which is incremented at 18Hz. Another option to make use of the 18Hz increment system (like making 0.5 second timers and such) is to call a function from the PANEL_SERVICE_PRE_UPDATE case of your callback function which increments your timing variable which you simply reset to 0 when it is equal to 9 (for a 0.5 second timer). &lt;br /&gt;
&lt;br /&gt;
The following however is an undocumented function in the simulator which returns total time elapsed in seconds with sub-18Hz accuracy.&lt;br /&gt;
&lt;br /&gt;
In your choice of your project&#039;s header files, do the following function prototype:&lt;br /&gt;
&lt;br /&gt;
 typedef double (__cdecl *fGetSimTime)();&lt;br /&gt;
&lt;br /&gt;
Then in your module_init function:&lt;br /&gt;
 &lt;br /&gt;
 HMODULE hsimsched = NULL;&lt;br /&gt;
 fGetSimTime GetSimTime6 = NULL;&lt;br /&gt;
 void FSAPI module_init(void)&lt;br /&gt;
 {&lt;br /&gt;
  GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
  if(hsimsched)&lt;br /&gt;
   GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now wherever you wish to call this function, include the header where the prototype is contained and add:&lt;br /&gt;
&lt;br /&gt;
 extern fGetSimTime GetSimTime6;&lt;br /&gt;
&lt;br /&gt;
To call it and find out how much time has passed:&lt;br /&gt;
&lt;br /&gt;
 double time = GetSimTime6();&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
	<entry>
		<id>http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9850</id>
		<title>C: C++ timers</title>
		<link rel="alternate" type="text/html" href="http://www.fsdeveloper.com/wiki/index.php?title=C:_C%2B%2B_timers&amp;diff=9850"/>
		<updated>2015-03-15T12:39:21Z</updated>

		<summary type="html">&lt;p&gt;Naruto-kun: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox-Applicable-FSVersion&lt;br /&gt;
| FSXI = true&lt;br /&gt;
| FSXA = true&lt;br /&gt;
| FSX = true&lt;br /&gt;
| FS2004 = true&lt;br /&gt;
| FS2002 = true&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Most of you may be familiar with the TICK18 token variable which is incremented at 18Hz. Another option to make use of the 18Hz increment system (like making 0.5 second timers and such) is to call a function from the PANEL_SERVICE_PRE_UPDATE case of your callback function which increments your timing variable which you simply reset to 0 when it is equal to 9 (for a 0.5 second timer). &lt;br /&gt;
&lt;br /&gt;
The following however is an undocumented function in the simulator which returns total time elapsed in seconds with sub-18Hz accuracy.&lt;br /&gt;
&lt;br /&gt;
In your choice of your project&#039;s header files, do the following function prototype:&lt;br /&gt;
&lt;br /&gt;
 typedef double (__cdecl *fGetSimTime)();&lt;br /&gt;
&lt;br /&gt;
Then in your module_init function:&lt;br /&gt;
 &lt;br /&gt;
 HMODULE hsimsched = NULL;&lt;br /&gt;
 fGetSimTime GetSimTime6 = NULL;&lt;br /&gt;
 void FSAPI module_init(void)&lt;br /&gt;
 {&lt;br /&gt;
  GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L&amp;quot;simscheduler.dll&amp;quot;, &amp;amp;hsimsched);&lt;br /&gt;
  if(hsimsched)&lt;br /&gt;
   GetSimTime6 = (fGetSimTime)GetProcAddress(hsimsched, MAKEINTRESOURCEA(6));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now wherever you wish to call this function, include the header where the prototype is contained and add:&lt;br /&gt;
&lt;br /&gt;
 extern fGetSimTime GetSimTime6;&lt;br /&gt;
&lt;br /&gt;
To call it and find out how much time has passed:&lt;br /&gt;
&lt;br /&gt;
 double time = GetSimTime6();&lt;br /&gt;
[[Category:Aircraft Design]]&lt;br /&gt;
[[Category:Panel and Gauge Design]]&lt;/div&gt;</summary>
		<author><name>Naruto-kun</name></author>
	</entry>
</feed>