<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Fernsteuern eines Programms &amp;amp; Timer]]></title><description><![CDATA[<p>Hallo!</p>
<p>ich habe ein kleines C/C++ Programm erstellt welches ein anderes Programm &quot;fernsteuern&quot; soll. Das funktioniert auch wunderbar. Über eine Steuerdatei wird definiert welche tastendrücke in welchen Zeitabständen an das zu fernsteuernde Programm geschickt werden sollen.<br />
Hin und wieder passen die Timings zwar nicht ganz (d.h. eine taste wird zu spät (vllt. auch zu früh?) gedrückt bzw. losgelassen) aber das kommt nicht all zu oft vor.</p>
<p>Jedoch habe ich auch ein Programm erstellt welches diese Steuerdateien automatisch erstellen soll in dem es einfach die tastaturaktivität in einem gewissen zeitraum aufzeichnet und diese in die Form der Steuerdatei hinein presst - funktioniert auch wunderbar.</p>
<p>Jedoch passen die Timings dann überhaupt nicht mehr wenn ich das Wiedergabe-Programm die automatisch erstellte Steuerdatei durchlaufen lasse. Dabei ist es auch interessant anzumerken dass für die händisch erstellte Steuerdatei nur eine genauigkeit von Zehntelsekunden verwendet wird (welche anscheinend ausreicht), die automatisch generierte Steuerdatei arbeitet aber mit Millisekunden - und hier reichen diese merkwürdigerweise nicht!</p>
<p><strong>Technischer Hintergund</strong>:<br />
- Tastaturaktivität wird mit einem globalen Hook überwacht - die wesentlichen Teile des Codes dafür:</p>
<pre><code class="language-cpp">hhook=SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hThisInstance, 0);  
   	while (GetMessage(&amp;messages, NULL, 0, 0))
   	{
        	TranslateMessage(&amp;messages);

        	DispatchMessage(&amp;messages);
    }
	UnhookWindowsHookEx(hhook);
</code></pre>
<p>und</p>
<pre><code class="language-cpp">LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{	
	static int calls=0;

	calls++;

	KBDLLHOOKSTRUCT *pKeyBoard = (KBDLLHOOKSTRUCT *)lParam;
    switch( wParam )
  	{
       	case WM_KEYUP: 
   		{
   			switch( pKeyBoard-&gt;vkCode ) 
  			{
				case 'N':
					p(&quot;ende/exit&quot;);
					myexit(0);
					break;
				case LEFT_VK:
				case RIGHT_VK:	
				case SHIFTR_VK:
				case SHIFTL_VK:
				case Z_VK:
					p(&quot;PUP&quot;);
					p(pKeyBoard-&gt;vkCode, calls);
					pup(pKeyBoard-&gt;vkCode); //tastendruck registrieren
					break;
			}
			break;
		}
       	case WM_KEYDOWN: 
   		{
   			switch( pKeyBoard-&gt;vkCode )
  			{
				case LEFT_VK:
				case RIGHT_VK:	
				case SHIFTR_VK:
				case SHIFTL_VK:
				case Z_VK:
					p(&quot;PDWN&quot;); 
					p(pKeyBoard-&gt;vkCode, calls); 
					pdown(pKeyBoard-&gt;vkCode); //tastendruck registrieren
					break;
			}
		}
        default:
        	return CallNextHookEx( NULL, nCode, wParam, lParam );
		}
        return 0;
}
</code></pre>
<p>interessant sind auch die funktionen die die tastendrücke handhaben:</p>
<pre><code class="language-cpp">void pdown(DWORD key) {
	//if (timer[key]!=null)
	//	timer[key] = GetTickCount();
	if (!pstate[key]) { //wenn taste nicht gedrückt
		if (timer==0L) {
			timer = GetTickCount();
			r(downAsoc[key]); // Aktion in der Steuerdatei für den druck dieser taste vermerken
		} else {
			unsigned long timer2 = GetTickCount();
			r('w',timer2-timer); // Warte-Anweisung in die Steuerdatei schreiben
			timer=GetTickCount();
			//timer=timer2;
			r(downAsoc[key]); // Aktion in der Steuerdatei für den druck dieser taste vermerken
		}
		pstate[key]=true;
	}
}

void pup(DWORD key) {
	if (pstate[key]){ // wenn taste gedrückt
		unsigned long timer2 = GetTickCount();
		r('w',timer2-timer); // Warte-Anweisung in die Steuerdatei schreiben
		timer=GetTickCount();
		//timer=timer2;
		r(upAsoc[key]); // Aktion in der Steuerdatei für das loslassen dieser taste vermerken
		pstate[key] = false;
	}
}
</code></pre>
<p>- auf der anderen Seite (beim wiedergeben) werden die erzeugten anweisungen dann durchgelaufen und mit sleep(zeit) die zeit die beim aufzeichnen zwischen den tastendrücken gemessen worden ist ebenfalls jeweils abgewartet</p>
<pre><code class="language-cpp">while(!feof(f)) {
					i++;
					fgets(line,7,f); // nächste Zeile/Anweisung der steuerdatei lesen
					char instr = line[0];
					if (instr=='-') { // Kommentar in der Steuerdatei überspringen
						fgets(c,1000,f);
						continue; //Kommentar
					}
					int param = 0;
					if ((instr!='j')&amp;&amp;(instr!='J')) { // Anweisungen ohne Parameter
						char *prm = line+1;
						param = atoi(prm);
					} else param = 0;
					if (instr=='%') { // Timer genauigkeit setzen
						timeEndPeriod(delay);
						delay = param;
						printf(&quot;%d/CONFIG: %c/%d \n&quot;,i,instr,param);
						timeBeginPeriod(delay);
						continue;
					}
					printf(&quot;%d: %c/%d \n&quot;,i,instr,param);
					hdl(instr,param); //Anweisung ausführen
				}
				fclose(f);
</code></pre>
<p>und die funktion die die Anweisungen handhabt:</p>
<pre><code class="language-cpp">inline void hdl(char instr,int param) {
	static INPUT rid;
	static INPUT lid;
        [...]

	if (instr=='L'){ // Taste für die Anweisung L drücken
		lid = StartLeft();
	}
	if (instr=='K'){ // Taste für die Anweisung L loslassen
		EndIndication(lid);
	}
        [...]

	if (instr=='w') { // Warte-Anweisung
		wait(param);
	}	
}

inline INPUT StartLeft() {
	return KeyDown(LEFT_VK, LEFT_SC, hwnd); //LEFT_VK/SC: VirtualKey/ScanCode, hwnd: Zielfenster
}
inline void EndIndication(INPUT ip) {
	KeyUp(ip);
}

inline INPUT KeyDown(WORD vk, WORD sc, HWND hwnd) {
	INPUT ipSignal;
	ipSignal.type           = INPUT_KEYBOARD;
	ipSignal.ki.wVk         = vk;
	ipSignal.ki.wScan       = sc;
	ipSignal.ki.dwFlags     = 0L;
	ipSignal.ki.time        = 0L;
	ipSignal.ki.dwExtraInfo = (ULONG_PTR)hwnd;
	//ipSignal.ki.dwExtraInfo = 0; //Fenster mit dem Fokus
	SendInput(1, &amp;ipSignal, sizeof(ipSignal));
	return ipSignal;
}
inline INPUT KeyUp(INPUT ip) {
	ip.ki.dwFlags     = KEYEVENTF_KEYUP;
	SendInput(1, &amp;ip, sizeof(ip)); 
	return ip;
}

inline void wait(int steps) {
	Sleep(steps*delay);
}
</code></pre>
<p>Hat wer eine Idee warum die Anweisungen nicht mit den selben Verzögerungen wiedergegeben werden, mit welchen sie aufgenommen wurden?<br />
Habe ich vielleicht einen Fehler gemacht? Bzw. hat wer einen Lösungsvorschlag?</p>
<p>Ich hab auch schon versucht mit den Prioritäten im Task-Manager herum zu spielen, das hat jedoch leider nicht wirklich geholfen.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/204348/fernsteuern-eines-programms-amp-timer</link><generator>RSS for Node</generator><lastBuildDate>Sun, 19 Apr 2026 12:24:14 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/204348.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 01 Feb 2008 23:29:54 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Fernsteuern eines Programms &amp;amp; Timer on Fri, 01 Feb 2008 23:33:41 GMT]]></title><description><![CDATA[<p>Hallo!</p>
<p>ich habe ein kleines C/C++ Programm erstellt welches ein anderes Programm &quot;fernsteuern&quot; soll. Das funktioniert auch wunderbar. Über eine Steuerdatei wird definiert welche tastendrücke in welchen Zeitabständen an das zu fernsteuernde Programm geschickt werden sollen.<br />
Hin und wieder passen die Timings zwar nicht ganz (d.h. eine taste wird zu spät (vllt. auch zu früh?) gedrückt bzw. losgelassen) aber das kommt nicht all zu oft vor.</p>
<p>Jedoch habe ich auch ein Programm erstellt welches diese Steuerdateien automatisch erstellen soll in dem es einfach die tastaturaktivität in einem gewissen zeitraum aufzeichnet und diese in die Form der Steuerdatei hinein presst - funktioniert auch wunderbar.</p>
<p>Jedoch passen die Timings dann überhaupt nicht mehr wenn ich das Wiedergabe-Programm die automatisch erstellte Steuerdatei durchlaufen lasse. Dabei ist es auch interessant anzumerken dass für die händisch erstellte Steuerdatei nur eine genauigkeit von Zehntelsekunden verwendet wird (welche anscheinend ausreicht), die automatisch generierte Steuerdatei arbeitet aber mit Millisekunden - und hier reichen diese merkwürdigerweise nicht!</p>
<p><strong>Technischer Hintergund</strong>:<br />
- Tastaturaktivität wird mit einem globalen Hook überwacht - die wesentlichen Teile des Codes dafür:</p>
<pre><code class="language-cpp">hhook=SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hThisInstance, 0);  
   	while (GetMessage(&amp;messages, NULL, 0, 0))
   	{
        	TranslateMessage(&amp;messages);

        	DispatchMessage(&amp;messages);
    }
	UnhookWindowsHookEx(hhook);
</code></pre>
<p>und</p>
<pre><code class="language-cpp">LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{	
	static int calls=0;

	calls++;

	KBDLLHOOKSTRUCT *pKeyBoard = (KBDLLHOOKSTRUCT *)lParam;
    switch( wParam )
  	{
       	case WM_KEYUP: 
   		{
   			switch( pKeyBoard-&gt;vkCode ) 
  			{
				case 'N':
					p(&quot;ende/exit&quot;);
					myexit(0);
					break;
				case LEFT_VK:
				case RIGHT_VK:	
				case SHIFTR_VK:
				case SHIFTL_VK:
				case Z_VK:
					p(&quot;PUP&quot;);
					p(pKeyBoard-&gt;vkCode, calls);
					pup(pKeyBoard-&gt;vkCode); //tastendruck registrieren
					break;
			}
			break;
		}
       	case WM_KEYDOWN: 
   		{
   			switch( pKeyBoard-&gt;vkCode )
  			{
				case LEFT_VK:
				case RIGHT_VK:	
				case SHIFTR_VK:
				case SHIFTL_VK:
				case Z_VK:
					p(&quot;PDWN&quot;); 
					p(pKeyBoard-&gt;vkCode, calls); 
					pdown(pKeyBoard-&gt;vkCode); //tastendruck registrieren
					break;
			}
		}
        default:
        	return CallNextHookEx( NULL, nCode, wParam, lParam );
		}
        return 0;
}
</code></pre>
<p>interessant sind auch die funktionen die die tastendrücke handhaben:</p>
<pre><code class="language-cpp">void pdown(DWORD key) {
	//if (timer[key]!=null)
	//	timer[key] = GetTickCount();
	if (!pstate[key]) { //wenn taste nicht gedrückt
		if (timer==0L) {
			timer = GetTickCount();
			r(downAsoc[key]); // Aktion in der Steuerdatei für den druck dieser taste vermerken
		} else {
			unsigned long timer2 = GetTickCount();
			r('w',timer2-timer); // Warte-Anweisung in die Steuerdatei schreiben
			timer=GetTickCount();
			//timer=timer2;
			r(downAsoc[key]); // Aktion in der Steuerdatei für den druck dieser taste vermerken
		}
		pstate[key]=true;
	}
}

void pup(DWORD key) {
	if (pstate[key]){ // wenn taste gedrückt
		unsigned long timer2 = GetTickCount();
		r('w',timer2-timer); // Warte-Anweisung in die Steuerdatei schreiben
		timer=GetTickCount();
		//timer=timer2;
		r(upAsoc[key]); // Aktion in der Steuerdatei für das loslassen dieser taste vermerken
		pstate[key] = false;
	}
}
</code></pre>
<p>- auf der anderen Seite (beim wiedergeben) werden die erzeugten anweisungen dann durchgelaufen und mit sleep(zeit) die zeit die beim aufzeichnen zwischen den tastendrücken gemessen worden ist ebenfalls jeweils abgewartet</p>
<pre><code class="language-cpp">while(!feof(f)) {
					i++;
					fgets(line,7,f); // nächste Zeile/Anweisung der steuerdatei lesen
					char instr = line[0];
					if (instr=='-') { // Kommentar in der Steuerdatei überspringen
						fgets(c,1000,f);
						continue; //Kommentar
					}
					int param = 0;
					if ((instr!='j')&amp;&amp;(instr!='J')) { // Anweisungen ohne Parameter
						char *prm = line+1;
						param = atoi(prm);
					} else param = 0;
					if (instr=='%') { // Timer genauigkeit setzen
						timeEndPeriod(delay);
						delay = param;
						printf(&quot;%d/CONFIG: %c/%d \n&quot;,i,instr,param);
						timeBeginPeriod(delay);
						continue;
					}
					printf(&quot;%d: %c/%d \n&quot;,i,instr,param);
					hdl(instr,param); //Anweisung ausführen
				}
				fclose(f);
</code></pre>
<p>und die funktion die die Anweisungen handhabt:</p>
<pre><code class="language-cpp">inline void hdl(char instr,int param) {
	static INPUT rid;
	static INPUT lid;
        [...]

	if (instr=='L'){ // Taste für die Anweisung L drücken
		lid = StartLeft();
	}
	if (instr=='K'){ // Taste für die Anweisung L loslassen
		EndIndication(lid);
	}
        [...]

	if (instr=='w') { // Warte-Anweisung
		wait(param);
	}	
}

inline INPUT StartLeft() {
	return KeyDown(LEFT_VK, LEFT_SC, hwnd); //LEFT_VK/SC: VirtualKey/ScanCode, hwnd: Zielfenster
}
inline void EndIndication(INPUT ip) {
	KeyUp(ip);
}

inline INPUT KeyDown(WORD vk, WORD sc, HWND hwnd) {
	INPUT ipSignal;
	ipSignal.type           = INPUT_KEYBOARD;
	ipSignal.ki.wVk         = vk;
	ipSignal.ki.wScan       = sc;
	ipSignal.ki.dwFlags     = 0L;
	ipSignal.ki.time        = 0L;
	ipSignal.ki.dwExtraInfo = (ULONG_PTR)hwnd;
	//ipSignal.ki.dwExtraInfo = 0; //Fenster mit dem Fokus
	SendInput(1, &amp;ipSignal, sizeof(ipSignal));
	return ipSignal;
}
inline INPUT KeyUp(INPUT ip) {
	ip.ki.dwFlags     = KEYEVENTF_KEYUP;
	SendInput(1, &amp;ip, sizeof(ip)); 
	return ip;
}

inline void wait(int steps) {
	Sleep(steps*delay);
}
</code></pre>
<p>Hat wer eine Idee warum die Anweisungen nicht mit den selben Verzögerungen wiedergegeben werden, mit welchen sie aufgenommen wurden?<br />
Habe ich vielleicht einen Fehler gemacht? Bzw. hat wer einen Lösungsvorschlag?</p>
<p>Ich hab auch schon versucht mit den Prioritäten im Task-Manager herum zu spielen, das hat jedoch leider nicht wirklich geholfen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1447886</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1447886</guid><dc:creator><![CDATA[Timmy 0]]></dc:creator><pubDate>Fri, 01 Feb 2008 23:33:41 GMT</pubDate></item><item><title><![CDATA[Reply to Fernsteuern eines Programms &amp;amp; Timer on Tue, 05 Feb 2008 23:30:03 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/1488">@Timmy</a>: keine Ahnung was es da hat. Dein Code ist IMO auch einigermassen schauderhaft. Es gibt einige Kleinigkeiten die mir aufgefallen sind, aber nix wo ich mir jetzt denken würde dass es was bringt. Versuch vielleicht erstmal rauszufinden ob der Fehler bei der Aufnahme oder beim Abspielen entsteht.</p>
<p>Paar Kleinigkeiten:</p>
<ol>
<li>
<p>verwende timeGetTime() statt GetTickCount().</p>
</li>
<li>
<p>ruf beim Programmbeginn 1x timeBeginPeriod(2) (oder 1) auf, und bei Programmende 1x timeEndPeriod.</p>
</li>
<li>
<p>IO machst du am besten erst nachdem du die Zeit ermittelt hast, sonst entsteht ein unnötiges Delay zwischen dem Event und dem &quot;auf die Uhr gucken&quot;.</p>
</li>
<li>
<p>Stell die Priorität des Replay-Threads mit SetThreadPriority auf THREAD_PRIORITY_HIGHEST oder sogar THREAD_PRIORITY_TIME_CRITICAL.</p>
</li>
<li>
<p>Hier 2x GetTickCount() aufzurufen könnte zu weiteren Ungenauigkeiten führen:</p>
</li>
</ol>
<pre><code class="language-cpp">unsigned long timer2 = GetTickCount();
            r('w',timer2-timer); // Warte-Anweisung in die Steuerdatei schreiben
         //   timer=GetTickCount(); // nö, so nicht
            timer=timer2; // so schon
</code></pre>
<ol start="6">
<li>Verwende Zeitangaben die mit 0 = Skriptbeginn anfangen</li>
<li>Hol dir die aktuelle Zeit, und berechne daraus dein Delay zum Warten</li>
<li>Verwende ordentliche Funktionsnamen<br />
...</li>
</ol>
]]></description><link>https://www.c-plusplus.net/forum/post/1450174</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1450174</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 05 Feb 2008 23:30:03 GMT</pubDate></item><item><title><![CDATA[Reply to Fernsteuern eines Programms &amp;amp; Timer on Wed, 06 Feb 2008 00:08:30 GMT]]></title><description><![CDATA[<p>ohne mir ehrlichgesagt den code durchgelesen zuhaben <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /> ein kleiner tipp am rande. du solltest den highperformance counter für synchronisationszeugs unter windows benutzen. also zb.:</p>
<pre><code class="language-cpp">LARGE_INTEGER m_CounterFrequency;
LARGE_INTEGER m_LastCount;
LARGE_INTEGER lCurrent;

QueryPerformanceFrequency(&amp;m_CounterFrequency);

QueryPerformanceCounter(&amp;m_LastCount);
// code to measure
QueryPerformanceCounter(&amp;lCurrent);
// time in microseconds
time = ((float)(lCurrent.QuadPart - m_LastCount.QuadPart)*1000000.0/(float)(m_CounterFrequency.QuadPart));
</code></pre>
<p>auf meinem system unter windows xp hat dieser timer allerdings immernoch per default 55ms auflösung <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    />! also ggf mit:</p>
<pre><code class="language-cpp">TIMECAPS	tc;
timeGetDevCaps(&amp;tc, sizeof(TIMECAPS));
timeBeginPeriod(tc.wPeriodMin);
</code></pre>
<p>auf die kleinstmögliche auflösung stellen, aber nicht vergessen dies beim beenden des programmes zu revidieren (sonst ist windows irgendwann b0rken :P):</p>
<pre><code class="language-cpp">timeEndPeriod(tc.wPeriodMin);
</code></pre>
<p>um für einen zeitraum zu warten, solltest du nicht sleep() und konsorten benutzen, sondern einen waitable timer, also:</p>
<pre><code class="language-cpp">HANDLE        timer = NULL;
LARGE_INTEGER liDueTime;

timer = CreateWaitableTimer(NULL, TRUE, L&quot;timer01&quot;);

liDueTime.QuadPart = -10000; // sollte 1 millisekunde sein, wenn ich nicht irre :)
SetWaitableTimer(timer, &amp;liDueTime, 0, NULL, NULL, 0);
WaitForSingleObject(timer, INFINITE);
</code></pre>
<p>das alles im allem gibt genügend genauigkeit ohne prioritäten auf critical setzen zu müssen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1450180</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1450180</guid><dc:creator><![CDATA[sothis_]]></dc:creator><pubDate>Wed, 06 Feb 2008 00:08:30 GMT</pubDate></item><item><title><![CDATA[Reply to Fernsteuern eines Programms &amp;amp; Timer on Fri, 08 Feb 2008 22:34:19 GMT]]></title><description><![CDATA[<p>Sry dass es so lang gedauert hat, aber ich hab einiges ausprobiert und das braucht seine zeit...</p>
<p>hustbaer schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/1488">@Timmy</a>: keine Ahnung was es da hat. Dein Code ist IMO auch einigermassen schauderhaft.</p>
</blockquote>
<p>Ich würde mich über Anregungen wie es besser aussehen könnte freuen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Paar Kleinigkeiten:</p>
<p>hustbaer schrieb:</p>
<blockquote>
<ol>
<li>verwende timeGetTime() statt GetTickCount().</li>
</ol>
</blockquote>
<p>Gibt es Unterschiede zw. den beiden Funktionen? ich hab in der MSDN keine finden können</p>
<p>hustbaer schrieb:</p>
<blockquote>
<ol start="2">
<li>ruf beim Programmbeginn 1x timeBeginPeriod(2) (oder 1) auf, und bei Programmende 1x timeEndPeriod.</li>
</ol>
</blockquote>
<p>mach ich...</p>
<p>hustbaer schrieb:</p>
<blockquote>
<ol start="3">
<li>IO machst du am besten erst nachdem du die Zeit ermittelt hast, sonst entsteht ein unnötiges Delay zwischen dem Event und dem &quot;auf die Uhr gucken&quot;.</li>
</ol>
</blockquote>
<p>ebenfalls schon umgesetzt...</p>
<p>hustbaer schrieb:</p>
<blockquote>
<ol start="4">
<li>Stell die Priorität des Replay-Threads mit SetThreadPriority auf THREAD_PRIORITY_HIGHEST oder sogar THREAD_PRIORITY_TIME_CRITICAL.</li>
</ol>
</blockquote>
<p>Hab das über den Task-Manager probiert, habe aber keinen Unterschied feststellen können.</p>
<p>hustbaer schrieb:</p>
<blockquote>
<ol start="6">
<li>Verwende Zeitangaben die mit 0 = Skriptbeginn anfangen</li>
<li>Hol dir die aktuelle Zeit, und berechne daraus dein Delay zum Warten</li>
</ol>
</blockquote>
<p>ebenfalls schon umgesetzt...</p>
<p>sothis_ schrieb:</p>
<blockquote>
<p>ohne mir ehrlichgesagt den code durchgelesen zuhaben <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /> ein kleiner tipp am rande. du solltest den highperformance counter für synchronisationszeugs unter windows benutzen.</p>
</blockquote>
<p>Danke! Hab zwar nach einem genauen Timer gesucht, aber nur dieses GetTickCount gefunden <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":\"
      alt="😕"
    /></p>
<p>sothis_ schrieb:</p>
<blockquote>
<p>auf meinem system unter windows xp hat dieser timer allerdings immernoch per default 55ms auflösung</p>
</blockquote>
<p>Dieses Prolem hab ich nicht, bei mir ist 1/HighPerformanceFrequency() irgendwo bei 1,6*10^-07 s</p>
<p>sothis_ schrieb:</p>
<blockquote>
<p>um für einen zeitraum zu warten, solltest du nicht sleep() und konsorten benutzen, sondern einen waitable timer</p>
</blockquote>
<p>Der liefert leider genau so schlechte Ergebnisse wie Sleep <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":\"
      alt="😕"
    /></p>
<p>sothis_ schrieb:</p>
<blockquote>
<p>das alles im allem gibt genügend genauigkeit</p>
</blockquote>
<p>Tut es leider nicht - die Zeiten passen immer noch nicht...</p>
<p>ich hab mir allerdings eine eigene Funktion erstellt GetMyTicks() welche folgendes zurück gibt:</p>
<p>double_zu_long((double)m_LastCount.QuadPart*10000.0/(double)m_CounterFrequency.QuadPart);</p>
<p>dies verwende ich nun statt GetTickCount()</p>
<p>ebenfalls habe ich das warten in Form von einem Busy-Wait umgesetzt (dank Dual-Core nur halb so schlimm, auf &quot;normalen&quot; CPUs hab ich es noch nicht getestet)</p>
<pre><code class="language-cpp">long sl = schlafeBisZeitstempel - (GetMyTicks() - programmstartZeitstempel);
while (sl &gt; 0) {
  sl = schlafeBisZeitstempel - (GetMyTicks() - programmstartZeitstempel)
}
</code></pre>
<p>damit schläft das programm (zumindest laut logs) genau so lange wie es soll - allerdings passen die ausgelösten Tastendrücke zeitlich immer noch nicht zusammen (erkennt man am Verhalten der Anwendung) <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":\"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1452327</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1452327</guid><dc:creator><![CDATA[Timmy 0]]></dc:creator><pubDate>Fri, 08 Feb 2008 22:34:19 GMT</pubDate></item></channel></rss>