<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Windows CE Programming &#187; Utilities</title>
	<atom:link href="http://www.hjgode.de/wp/category/utilities/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.hjgode.de/wp</link>
	<description>Windows Mobile Development and usage</description>
	<lastBuildDate>Fri, 03 Feb 2012 08:53:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<!--CodeProjectFeeder channel--><category>CodeProject</category><generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Windows Mobile &#8211; tasker2 runs and stops applications periodically</title>
		<link>http://www.hjgode.de/wp/2011/12/23/windows-mobile-tasker2-runs-and-stops-applications-periodically/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=windows-mobile-tasker2-runs-and-stops-applications-periodically</link>
		<comments>http://www.hjgode.de/wp/2011/12/23/windows-mobile-tasker2-runs-and-stops-applications-periodically/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 13:11:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[notification API]]></category>
		<category><![CDATA[periodically]]></category>
		<category><![CDATA[schedule]]></category>
		<category><![CDATA[tasker2]]></category>
		<category><![CDATA[windows mobile]]></category>

		<guid isPermaLink="false">http://www.hjgode.de/wp/?p=1286</guid>
		<description><![CDATA[Tasker2 is a tool to launch or kill applications periodically using windows mobile scheduler. It was born to control the running of agent software on windows mobile at specified times. The problem with the agent software was that it does not open/close connections only on usage times but all the time and the device&#8217;s battery [...]]]></description>
			<content:encoded><![CDATA[<p>Tasker2 is a tool to launch or kill applications periodically using windows mobile scheduler. It was born to control the running of agent software on windows mobile at specified times. The problem with the agent software was that it does not open/close connections only on usage times but all the time and the device&#8217;s battery was drain very fast. We decided to write a helper that would launch and kill the agent to have it running only within a defined time frame.</p>
<h2>Background process</h2>
<p>We could have written a background process to run external tasks periodically. But the main disadvantage of timers and threads in background processes is that they do not run, if the device is in suspend mode.<br />
To ensure that tasks will be launched also if the device is sleeping, we decided to use the windows mobile scheduler. There are functions inside the notification API to create notifications that will run an application at a specified time. This is what we call a schedule.</p>
<h2>The scheduler (notification API)</h2>
<p>After a timed schedule has been done by the scheduler, the schedule is removed from the notification database. If you like to have a periodic schedule, you have to ensure that a new schedule is created inside your code.</p>
<h2>Pitfalls</h2>
<p>During development we found many pitfalls in conjunction with the windows mobile scheduler. This is why I decided to write this post.</p>
<h2>The tasks</h2>
<p>Tasker2 is a console application without any GUI but it will write a log with all you need to know. Tasker2 supports up to ten tasks. A task is defined using the registry. Every task has an entry for start and stop times, the application to control, an interval for the schedule and a flag for control if a task is only to be run on external power:</p>
<pre>REGEDIT4

[HKLM\Software\Tasker\Task1]
"active":DWORD=1
"exe":="\Windows\fexplore.exe"
"arg":="\My Documents"
"start":="1423"
"stop":="1523"
"interval":="2400"
"startOnAConly":DWORD=0;</pre>
<p><strong>active</strong>: if active is 0, tasker2 will not kill or start the process<br />
<strong>exe</strong>: name of the process executable to start or kill<br />
<strong>arg</strong>: arguments to be when launching the executable<br />
<strong>start</strong>: when to start the executable the next time<br />
<strong>stop</strong>: when to kill the process the next time<br />
<strong>interval</strong>: when a start or kill has been executed, tasker2 will create a new schedule using this interval. If the interval is &#8220;0010&#8243;, the start process will be scheduled for every 10 minutes.<br />
<strong>startOnAConly</strong>: if 1 and when a process has to be started, the process will only be started if the device is on external power</p>
<h2>The scheduler</h2>
<p>First, tasker2 is normally only launched one time manually and all future calls are made by the scheduler. Tasker2 will clear and schedule all planned tasks as defined in the registry if it is launched without arguments.</p>
<p><a href="http://www.hjgode.de/wp/2011/12/23/windows-mobile-tasker2-runs-and-stops-applications-periodically/notification-schedules/" rel="attachment wp-att-1287"><img class="alignnone size-full wp-image-1287" title="notification-schedules" src="http://www.hjgode.de/wp/wp-content/uploads/2011/12/notification-schedules.gif" alt="" width="320" height="240" /></a></p>
<p><span id="more-1286"></span>The scheduler is a task manager running all the time in windows mobile. If a timed schedule is reached, the scheduler will launch the specified application, see also <a href="http://www.hjgode.de/wp/2009/07/14/howto-run-an-application-periodically/">here</a> . This will also work if the device is in suspend mode (sleeps). The scheduler can also fire on special events like time or hardware changes (ON_RS232_CONNECT for example). See also my post <a href="http://www.hjgode.de/wp/2010/03/06/irunatevent/">here</a> [http://www.hjgode.de/wp/2010/03/06/irunatevent/].</p>
<h2>Theory of operation</h2>
<p>Tasker2 uses command line arguments to control itself. The scheduler launches tasker2 with the specified arguments and tasker2 will then run or kill the defined task.</p>
<p><a href="http://www.hjgode.de/wp/2011/12/23/windows-mobile-tasker2-runs-and-stops-applications-periodically/tasker-function/" rel="attachment wp-att-1288"><img class="alignnone size-full wp-image-1288" title="tasker-function" src="http://www.hjgode.de/wp/wp-content/uploads/2011/12/tasker-function.gif" alt="" width="800" height="502" /></a></p>
<h2>Delayed schedules (pitfall 1)</h2>
<p>If your device supports a real power down, the scheduler will not awake the device and is not able to launch the defined schedules. When the device is later powered on, it will schedule all past schedules at once. This is what we call a &#8216;delayed schedule&#8217; and a flooding of launches. Flooding in the mean of many schedules of tasker2 occurring at the same time for past tasks.<br />
To avoid concurrent changes to the registry and scheduler entries, tasker2 uses a mutex to ensure only one instance is continuing execution. Subsequent instances will wait for existing instances before they do there work.</p>
<div id="wpshdo_1" class="wp-synhighlighter-outer"><div id="wpshdt_1" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_1"></a><a id="wpshat_1" class="wp-synhighlighter-title" href="#codesyntax_1"  onClick="javascript:wpsh_toggleBlock(1)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_1" onClick="javascript:wpsh_code(1)" title="Show code only"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_1" onClick="javascript:wpsh_print(1)" title="Print code"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_1" class="wp-synhighlighter-inner" style="display: block;"><pre class="cpp" style="font-family:monospace;"><ol><li class="li1"><div class="de1"><span class="co1">//##################### dont run if already running #############################</span></div></li><li class="li1"><div class="de1">	nclog<span class="br0">&#40;</span>L<span class="st0">&quot;Checking for Mutex (single instance allowed only)...<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">	hMutex<span class="sy1">=</span>CreateMutex<span class="br0">&#40;</span><span class="kw2">NULL</span>, TRUE, MY_MUTEX<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">	<span class="kw1">if</span><span class="br0">&#40;</span>hMutex<span class="sy1">==</span><span class="kw2">NULL</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">		<span class="co1">//this should never happen</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;Error in CreateMutex! GetLastError()=%i<span class="es1">\n</span>&quot;</span>, GetLastError<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;-------- END -------<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="kw1">return</span> <span class="sy2">-</span><span class="nu0">99</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">	<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">	DWORD dwLast <span class="sy1">=</span> GetLastError<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">	<span class="kw1">if</span><span class="br0">&#40;</span>dwLast<span class="sy1">==</span> ERROR_ALREADY_EXISTS<span class="br0">&#41;</span><span class="br0">&#123;</span><span class="co1">//mutex already exists, wait for mutex release</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;<span class="es1">\t</span>Attached to existing mutex<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;................ Waiting for mutex release......<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		WaitForSingleObject<span class="br0">&#40;</span> hMutex, INFINITE <span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;++++++++++++++++ Mutex released. +++++++++++++++<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">	<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">	<span class="kw1">else</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;<span class="es1">\t</span>Created new mutex<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">	<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">	<span class="co1">//##################### dont run if already running #############################</span></div></li></ol></pre></div></div>
<p>On a delayed, flooding schedule ALL pending tasks are scheduled and possibly a Time_Changed string is sent to the pending tasks. This flooding will be serialized as tasker2 waits for existing tasker2 instances.</p>
<h2>Time and time zone changes (pitfall 2)</h2>
<p>When the time is changed on the device, the scheduler will inform all timed tasks. Tasker2 must then recalculate new schedules based on current local time. The scheduler launches the defined applications with the TIME_CHANGED string as argument.</p>
<div id="wpshdo_2" class="wp-synhighlighter-outer"><div id="wpshdt_2" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_2"></a><a id="wpshat_2" class="wp-synhighlighter-title" href="#codesyntax_2"  onClick="javascript:wpsh_toggleBlock(2)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_2" onClick="javascript:wpsh_code(2)" title="Show code only"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_2" onClick="javascript:wpsh_print(2)" title="Print code"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_2" class="wp-synhighlighter-inner" style="display: block;"><pre class="cpp" style="font-family:monospace;"><ol><li class="li1"><div class="de1"><span class="kw1">else</span> <span class="kw1">if</span><span class="br0">&#40;</span>wcsicmp<span class="br0">&#40;</span>argv<span class="br0">&#91;</span>1<span class="br0">&#93;</span>, APP_RUN_AFTER_TIME_CHANGE<span class="br0">&#41;</span><span class="sy1">==</span>0 <span class="sy3">||</span> wcsicmp<span class="br0">&#40;</span>argv<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, APP_RUN_AFTER_TZ_CHANGE<span class="br0">&#41;</span><span class="sy1">==</span><span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">			nclog<span class="br0">&#40;</span>L<span class="st0">&quot;got '%s' signaled<span class="es1">\n</span>&quot;</span>, argv<span class="br0">&#91;</span>1<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">				<span class="co1">//better to reread the current time we work with, possibly we have been blocked</span></div></li><li class="li1"><div class="de1">				g_tmCurrentStartTime<span class="sy1">=</span>getLocalTime<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_tmCurrentStartTime<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">				<span class="co1">//now again check if we have a valid date</span></div></li><li class="li1"><div class="de1">				nclog<span class="br0">&#40;</span>L<span class="st0">&quot;Checking for valid date/time...<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">				<span class="kw1">if</span><span class="br0">&#40;</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>g_tmCurrentStartTime.<span class="me1">tm_year</span><span class="sy2">+</span><span class="nu0">1900</span><span class="br0">&#41;</span><span class="sy2">*</span><span class="nu0">100</span> <span class="sy2">+</span> g_tmCurrentStartTime.<span class="me1">tm_mon</span><span class="sy2">+</span><span class="nu0">1</span><span class="br0">&#41;</span> <span class="sy1">&lt;</span> <span class="nu0">201111</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">					nclog<span class="br0">&#40;</span>L<span class="st0">&quot;scheduling event notifications<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">					<span class="co1">//clear and renew all event notifications</span></div></li><li class="li1"><div class="de1">					<span class="co2">#ifndef TESTMODE</span></div></li><li class="li1"><div class="de1">						RunAppAtTimeChangeEvents<span class="br0">&#40;</span>szTaskerEXE<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">					<span class="co2">#endif</span></div></li><li class="li1"><div class="de1">					nclog<span class="br0">&#40;</span>L<span class="st0">&quot;Date/Time not valid!<span class="es1">\n</span>*********** END ************<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">					<span class="kw1">return</span> <span class="nu12">0xBADCAB1E</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">				<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">				nclog<span class="br0">&#40;</span>L<span class="st0">&quot;Date/Time after 11 2011. OK<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">			<span class="co1">//schedule all active tasks</span></div></li><li class="li1"><div class="de1">			<span class="kw4">int</span> iCount <span class="sy1">=</span> scheduleAllTasks<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">			nclog<span class="br0">&#40;</span>L<span class="st0">&quot;Scheduled %i Tasks<span class="es1">\n</span>&quot;</span>, iCount<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="br0">&#125;</span></div></li></ol></pre></div></div>
<p>Additionally we found that the time changes may also occur during program launch or as tasker2 instances wait for another tasker2 instance. So tasker2 uses only one (in real two) calls to get the current time. This is essential, as tasker2 uses the current time to re-schedule tasks. The current time is called at the beginning, before tasker2 waits for the mutex. This is the time tasker2 was launched. If there has been a time_changed schedule, tasker2 will use another call to the current time, as it may have changed between the launch and the further execution of the code &#8211; after the mutex is released and the current instance is allowed to run.</p>
<h2>Delayed schedules II (pitfall 3)</h2>
<p>As only one instance of tasker2 is executing, it may happen, that the current time and the task time do not match exactly. Although the scheduler may do its best to launch tasker2 at the right time, the execution may be delayed in regards of the time the task is to be scheduled and the current time. This is another delayed schedule compared to the above flooding of schedules after a power down/up cycle.<br />
It may also happen that a lot of tasker2 instances are waiting for execution, you know that we can have up to ten tasks. This may also lead to &#8216;delayed&#8217; code execution, but should be in a small time frame of some minutes only.<br />
Therefor tasker2 supports a maximum allowed delay time to distinguish between allowed and flooding delayed calls.</p>
<div id="wpshdo_3" class="wp-synhighlighter-outer"><div id="wpshdt_3" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_3"></a><a id="wpshat_3" class="wp-synhighlighter-title" href="#codesyntax_3"  onClick="javascript:wpsh_toggleBlock(3)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_3" onClick="javascript:wpsh_code(3)" title="Show code only"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_3" onClick="javascript:wpsh_print(3)" title="Print code"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_3" class="wp-synhighlighter-inner" style="display: block;"><pre class="cpp" style="font-family:monospace;"><ol><li class="li1"><div class="de1"><span class="co1">//is this a delayed schedule?</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;<span class="es1">\t</span>checking for delayed schedule...<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="kw4">int</span> iDeltaMinutes<span class="sy4">;</span></div></li><li class="li1"><div class="de1">		__time64_t ttStart<span class="sy4">;</span></div></li><li class="li1"><div class="de1">		__time64_t ttStop<span class="sy4">;</span></div></li><li class="li1"><div class="de1">		__time64_t ttCurr<span class="sy4">;</span></div></li><li class="li1"><div class="de1">		ttStop <span class="sy1">=</span> _mktime64<span class="br0">&#40;</span><span class="sy3">&amp;</span><span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stStopTime</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		ttStart <span class="sy1">=</span> _mktime64<span class="br0">&#40;</span><span class="sy3">&amp;</span><span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stStartTime</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		ttCurr <span class="sy1">=</span> _mktime64<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_tmCurrentStartTime<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">		<span class="kw1">if</span><span class="br0">&#40;</span>thisTaskType<span class="sy1">==</span>stopTask<span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">			<span class="co1">//difftime(timer1, timer0) returns the elapsed time in seconds, from timer0 to timer1</span></div></li><li class="li1"><div class="de1">			iDeltaMinutes <span class="sy1">=</span> <span class="kw3">difftime</span><span class="br0">&#40;</span>ttCurr, ttStop<span class="br0">&#41;</span><span class="sy2">/</span><span class="nu0">60</span><span class="sy4">;</span><span class="co1">// stDeltaMinutes(_Tasks[iTask].stStopTime, g_CurrentStartTime);</span></div></li><li class="li1"><div class="de1">			nclog<span class="br0">&#40;</span>L<span class="st0">&quot;stStopTime = '%s', &quot;</span>, getLongStrFromTM<span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stStopTime</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">		<span class="kw1">else</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">			iDeltaMinutes <span class="sy1">=</span> <span class="kw3">difftime</span><span class="br0">&#40;</span>ttStart, ttCurr<span class="br0">&#41;</span><span class="sy2">/</span><span class="nu0">60</span><span class="sy4">;</span><span class="co1">// stDeltaMinutes(_Tasks[iTask].stStartTime, g_CurrentStartTime);</span></div></li><li class="li1"><div class="de1">			nclog<span class="br0">&#40;</span>L<span class="st0">&quot;stStartTime = '%s', &quot;</span>, getLongStrFromTM<span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stStartTime</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="br0">&#125;</span></div></li></ol></pre></div></div>
<h2>Adding a schedule</h2>
<p>I am using central functions in code to add or remove schedules. Here is a sample of how a schedule is added:</p>
<div id="wpshdo_4" class="wp-synhighlighter-outer"><div id="wpshdt_4" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_4"></a><a id="wpshat_4" class="wp-synhighlighter-title" href="#codesyntax_4"  onClick="javascript:wpsh_toggleBlock(4)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_4" onClick="javascript:wpsh_code(4)" title="Show code only"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_4" onClick="javascript:wpsh_print(4)" title="Print code"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_4" class="wp-synhighlighter-inner" style="display: block;"><pre class="cpp" style="font-family:monospace;"><ol><li class="li1"><div class="de1">...</div></li><li class="li1"><div class="de1"><span class="co2">#include &quot;notify.h&quot;</span></div></li><li class="li1"><div class="de1">...</div></li><li class="li1"><div class="de1"><span class="co1">//--------------------------------------------------------------------</span></div></li><li class="li1"><div class="de1"><span class="co1">// Function name  : ScheduleRunApp</span></div></li><li class="li1"><div class="de1"><span class="co1">// Description    : add a schedule for exe with args at the time</span></div></li><li class="li1"><div class="de1"><span class="co1">// Argument       : LPCTSTR szExeName</span></div></li><li class="li1"><div class="de1"><span class="co1">// Argument       : LPCTSTR szArgs</span></div></li><li class="li1"><div class="de1"><span class="co1">// Argument       : struct tm tmTime</span></div></li><li class="li1"><div class="de1"><span class="co1">// Return type    : HRESULT, 0 for no error</span></div></li><li class="li1"><div class="de1"><span class="co1">//--------------------------------------------------------------------</span></div></li><li class="li1"><div class="de1">HRESULT ScheduleRunApp<span class="br0">&#40;</span>LPCTSTR szExeName, LPCTSTR szArgs, <span class="kw4">struct</span> <span class="kw4">tm</span> tmTime<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1"><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">	HRESULT hr <span class="sy1">=</span> S_OK<span class="sy4">;</span></div></li><li class="li1"><div class="de1">	HANDLE hNotify <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">	<span class="co1">// set a CE_NOTIFICATION_TRIGGER</span></div></li><li class="li1"><div class="de1">	CE_NOTIFICATION_TRIGGER notifTrigger<span class="sy4">;</span></div></li><li class="li1"><div class="de1">	<span class="kw3">memset</span><span class="br0">&#40;</span><span class="sy3">&amp;</span>notifTrigger, 0, <span class="kw3">sizeof</span><span class="br0">&#40;</span>CE_NOTIFICATION_TRIGGER<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">	notifTrigger.<span class="me1">dwSize</span> <span class="sy1">=</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>CE_NOTIFICATION_TRIGGER<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">	<span class="co1">// calculate time</span></div></li><li class="li1"><div class="de1">	SYSTEMTIME st <span class="sy1">=</span> <span class="br0">&#123;</span>0<span class="br0">&#125;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">	<span class="co1">//GetLocalTime(&amp;st); //v.2.28</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">	st <span class="sy1">=</span> convertTM2SYSTEMTIME<span class="br0">&#40;</span><span class="sy3">&amp;</span>st, <span class="sy3">&amp;</span>tmTime<span class="br0">&#41;</span><span class="sy4">;</span> <span class="co1">//use provided new datetime</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">	wsprintf<span class="br0">&#40;</span>str, L<span class="st0">&quot;Next run at: %02i.%02i.%02i %02i:%02i:%02i&quot;</span>,</div></li><li class="li1"><div class="de1">										st.<span class="me1">wDay</span>, st.<span class="me1">wMonth</span> , st.<span class="me1">wYear</span>,</div></li><li class="li1"><div class="de1">										st.<span class="me1">wHour</span> , st.<span class="me1">wMinute</span> , st.<span class="me1">wSecond</span> <span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">	nclog<span class="br0">&#40;</span>L<span class="st0">&quot;<span class="es1">\t</span>ScheduleRunApp: %s<span class="es1">\n</span>&quot;</span>, str<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">	notifTrigger.<span class="me1">dwType</span> <span class="sy1">=</span> CNT_TIME<span class="sy4">;</span></div></li><li class="li1"><div class="de1">	notifTrigger.<span class="me1">stStartTime</span> <span class="sy1">=</span> st<span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">	<span class="co1">// timer: execute an exe at specified time</span></div></li><li class="li1"><div class="de1">	notifTrigger.<span class="me1">lpszApplication</span> <span class="sy1">=</span> <span class="br0">&#40;</span>LPTSTR<span class="br0">&#41;</span>szExeName<span class="sy4">;</span></div></li><li class="li1"><div class="de1">	notifTrigger.<span class="me1">lpszArguments</span> <span class="sy1">=</span> <span class="br0">&#40;</span>LPTSTR<span class="br0">&#41;</span>szArgs<span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">	hNotify <span class="sy1">=</span> CeSetUserNotificationEx<span class="br0">&#40;</span>0, <span class="sy3">&amp;</span>notifTrigger, <span class="kw2">NULL</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">	<span class="co1">// NULL because we do not care the action</span></div></li><li class="li1"><div class="de1">	<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>hNotify<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">		hr <span class="sy1">=</span> E_FAIL<span class="sy4">;</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;<span class="es1">\t</span>ScheduleRunApp: CeSetUserNotificationEx FAILED...<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">	<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">		<span class="co1">// close the handle as we do not need to use it further</span></div></li><li class="li1"><div class="de1">		CloseHandle<span class="br0">&#40;</span>hNotify<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;<span class="es1">\t</span>ScheduleRunApp: CeSetUserNotificationEx succeeded...<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">	<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">	<span class="kw1">return</span> hr<span class="sy4">;</span></div></li><li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li></ol></pre></div></div>
<h2>The main code</h2>
<p>The main function is processStartStopCmd() beside createNextSchedule(). It does all the scheduling and time calculations.</p>
<div id="wpshdo_5" class="wp-synhighlighter-outer"><div id="wpshdt_5" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_5"></a><a id="wpshat_5" class="wp-synhighlighter-title" href="#codesyntax_5"  onClick="javascript:wpsh_toggleBlock(5)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_5" onClick="javascript:wpsh_code(5)" title="Show code only"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_5" onClick="javascript:wpsh_print(5)" title="Print code"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_5" class="wp-synhighlighter-inner" style="display: block;"><pre class="cpp" style="font-family:monospace;"><ol><li class="li1"><div class="de1"><span class="coMULTI">/*	########################################################</span></div></li><li class="li1"><div class="de1"><span class="coMULTI">		Process -s and -k comd line args</span></div></li><li class="li1"><div class="de1"><span class="coMULTI">	########################################################</span></div></li><li class="li1"><div class="de1"><span class="coMULTI">*/</span></div></li><li class="li1"><div class="de1"><span class="co1">//--------------------------------------------------------------------</span></div></li><li class="li1"><div class="de1"><span class="co1">// Function name  : processStartStopCmd</span></div></li><li class="li1"><div class="de1"><span class="co1">// Description    : calc new start/stop time, add schedules and start/kill application</span></div></li><li class="li1"><div class="de1"><span class="co1">// Argument       : TCHAR* argv[], the cmdLine array</span></div></li><li class="li1"><div class="de1"><span class="co1">// Return type    : int, 0 for no error</span></div></li><li class="li1"><div class="de1"><span class="co1">//--------------------------------------------------------------------</span></div></li><li class="li1"><div class="de1"><span class="kw4">int</span> processStartStopCmd<span class="br0">&#40;</span>TCHAR<span class="sy2">*</span> argv<span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">	<span class="kw4">int</span> iReturn <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">	BOOL bIsDelayedSchedule <span class="sy1">=</span> TRUE<span class="sy4">;</span> <span class="co1">//used to save a delayed schedule situation</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">	<span class="kw2">enum</span> taskType<span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">		startTask <span class="sy1">=</span> 1,</div></li><li class="li1"><div class="de1">		stopTask <span class="sy1">=</span> 2</div></li><li class="li1"><div class="de1">	<span class="br0">&#125;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">	taskType thisTaskType<span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">	<span class="kw1">if</span><span class="br0">&#40;</span>wcsicmp<span class="br0">&#40;</span>argv<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, L<span class="st0">&quot;-k&quot;</span><span class="br0">&#41;</span><span class="sy1">==</span><span class="nu0">0</span><span class="br0">&#41;</span>	<span class="co1">//kill taskX app</span></div></li><li class="li1"><div class="de1">		thisTaskType<span class="sy1">=</span>stopTask<span class="sy4">;</span></div></li><li class="li1"><div class="de1">	<span class="kw1">else</span></div></li><li class="li1"><div class="de1">		thisTaskType<span class="sy1">=</span>startTask<span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">	<span class="kw4">int</span> iTask <span class="sy1">=</span> getTaskNumber<span class="br0">&#40;</span>argv<span class="br0">&#91;</span>2<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">	<span class="kw1">if</span><span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">iActive</span><span class="sy1">==</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">		<span class="co1">//create a new schedule cmd line for tasker</span></div></li><li class="li1"><div class="de1">		TCHAR strTaskCmdLine<span class="br0">&#91;</span>MAX_PATH<span class="br0">&#93;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">		<span class="kw1">if</span><span class="br0">&#40;</span>thisTaskType<span class="sy1">==</span>stopTask<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">			wsprintf<span class="br0">&#40;</span>strTaskCmdLine, L<span class="st0">&quot;-k task%i&quot;</span>, iTask<span class="sy2">+</span>1<span class="br0">&#41;</span><span class="sy4">;</span> <span class="co1">//the cmdLine for tasker.exe for this task</span></div></li><li class="li1"><div class="de1">		<span class="kw1">else</span></div></li><li class="li1"><div class="de1">			wsprintf<span class="br0">&#40;</span>strTaskCmdLine, L<span class="st0">&quot;-s task%i&quot;</span>, iTask<span class="sy2">+</span>1<span class="br0">&#41;</span><span class="sy4">;</span> <span class="co1">//the cmdLine for tasker.exe for this task	</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">		<span class="co1">//clear all tasker schedules for taskX</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;Clearing all schedules for Task%i with '%s'<span class="es1">\n</span>&quot;</span>, iTask<span class="sy2">+</span>1, strTaskCmdLine<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		notiClearRunApp<span class="br0">&#40;</span>szTaskerEXE, strTaskCmdLine<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">		<span class="kw4">struct</span> <span class="kw4">tm</span> tmNewTime <span class="sy1">=</span> <span class="br0">&#123;</span>0<span class="br0">&#125;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="kw4">short</span> shHour	<span class="sy1">=</span>	_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stDiffTime</span>.<span class="me1">tm_hour</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="kw4">short</span> shMin		<span class="sy1">=</span>	_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stDiffTime</span>.<span class="me1">tm_min</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="kw4">short</span> shDays	<span class="sy1">=</span>	<span class="nu0">0</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="kw1">if</span><span class="br0">&#40;</span>shHour<span class="sy1">&gt;=</span><span class="nu0">24</span><span class="br0">&#41;</span><span class="br0">&#123;</span>	<span class="co1">//hour interval value is one day or more</span></div></li><li class="li1"><div class="de1">			shDays <span class="sy1">=</span> <span class="br0">&#40;</span><span class="kw4">short</span><span class="br0">&#41;</span> <span class="br0">&#40;</span>shHour <span class="sy2">/</span> 24<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">			shHour <span class="sy1">=</span> <span class="br0">&#40;</span><span class="kw4">short</span><span class="br0">&#41;</span> <span class="br0">&#40;</span>shHour <span class="sy2">%</span> 24<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="br0">&#125;</span>				</div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">		<span class="co1">//is this a delayed schedule?</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;<span class="es1">\t</span>checking for delayed schedule...<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="kw4">int</span> iDeltaMinutes<span class="sy4">;</span></div></li><li class="li1"><div class="de1">		__time64_t ttStart<span class="sy4">;</span></div></li><li class="li1"><div class="de1">		__time64_t ttStop<span class="sy4">;</span></div></li><li class="li1"><div class="de1">		__time64_t ttCurr<span class="sy4">;</span></div></li><li class="li1"><div class="de1">		ttStop <span class="sy1">=</span> _mktime64<span class="br0">&#40;</span><span class="sy3">&amp;</span><span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stStopTime</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		ttStart <span class="sy1">=</span> _mktime64<span class="br0">&#40;</span><span class="sy3">&amp;</span><span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stStartTime</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		ttCurr <span class="sy1">=</span> _mktime64<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_tmCurrentStartTime<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">		<span class="kw1">if</span><span class="br0">&#40;</span>thisTaskType<span class="sy1">==</span>stopTask<span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">			<span class="co1">//difftime(timer1, timer0) returns the elapsed time in seconds, from timer0 to timer1</span></div></li><li class="li1"><div class="de1">			iDeltaMinutes <span class="sy1">=</span> <span class="kw3">difftime</span><span class="br0">&#40;</span>ttCurr, ttStop<span class="br0">&#41;</span><span class="sy2">/</span><span class="nu0">60</span><span class="sy4">;</span><span class="co1">// stDeltaMinutes(_Tasks[iTask].stStopTime, g_CurrentStartTime);</span></div></li><li class="li1"><div class="de1">			nclog<span class="br0">&#40;</span>L<span class="st0">&quot;stStopTime = '%s', &quot;</span>, getLongStrFromTM<span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stStopTime</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">		<span class="kw1">else</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">			iDeltaMinutes <span class="sy1">=</span> <span class="kw3">difftime</span><span class="br0">&#40;</span>ttStart, ttCurr<span class="br0">&#41;</span><span class="sy2">/</span><span class="nu0">60</span><span class="sy4">;</span><span class="co1">// stDeltaMinutes(_Tasks[iTask].stStartTime, g_CurrentStartTime);</span></div></li><li class="li1"><div class="de1">			nclog<span class="br0">&#40;</span>L<span class="st0">&quot;stStartTime = '%s', &quot;</span>, getLongStrFromTM<span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stStartTime</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;current time = '%s'<span class="es1">\n</span>&quot;</span>, getLongStrFromTM<span class="br0">&#40;</span>g_tmCurrentStartTime<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;interval is: %id%02ih%02im<span class="es1">\n</span>&quot;</span>, shDays, shHour, shMin<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;<span class="es1">\t</span>delta is %i minutes<span class="es1">\n</span>&quot;</span>, iDeltaMinutes<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">		<span class="co1">//started BEFORE scheduled time, iDelta is negative</span></div></li><li class="li1"><div class="de1">		<span class="kw1">if</span><span class="br0">&#40;</span>iDeltaMinutes<span class="sy1">&lt;</span>0<span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">			<span class="kw1">if</span><span class="br0">&#40;</span>thisTaskType<span class="sy1">==</span>stopTask<span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">				<span class="co1">//calculate new schedules or leave them as is?</span></div></li><li class="li1"><div class="de1">				<span class="co1">//tmNewTime=_Tasks[iTask].stStopTime;	//leave them as is</span></div></li><li class="li1"><div class="de1">				tmNewTime<span class="sy1">=</span>createNextSchedule<span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stStopTime</span>, shDays,shHour,shMin<span class="br0">&#41;</span><span class="sy4">;</span> <span class="co1">//calc new schedule</span></div></li><li class="li1"><div class="de1">			<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">			<span class="kw1">else</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">				<span class="co1">//tmNewTime=_Tasks[iTask].stStartTime;	//leave them as is</span></div></li><li class="li1"><div class="de1">				tmNewTime<span class="sy1">=</span>createNextSchedule<span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stStartTime</span>, shDays,shHour,shMin<span class="br0">&#41;</span><span class="sy4">;</span> <span class="co1">//calc new schedule</span></div></li><li class="li1"><div class="de1">			<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1"><span class="co2">#ifndef TESTMODE</span></div></li><li class="li1"><div class="de1">			ScheduleRunApp<span class="br0">&#40;</span>szTaskerEXE, strTaskCmdLine, tmNewTime<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1"><span class="co2">#endif</span></div></li><li class="li1"><div class="de1">			nclog<span class="br0">&#40;</span>L<span class="st0">&quot;*** re-scheduled future task *** <span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">			<span class="kw1">return</span> <span class="nu0">0</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">		<span class="kw4">int</span> iMaxDelay <span class="sy1">=</span> getMaxDelay<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;<span class="es1">\t</span>max allowed diff for delayed schedule recognition is plus %i<span class="es1">\n</span>&quot;</span>, iMaxDelay<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">		<span class="kw1">if</span><span class="br0">&#40;</span> iDeltaMinutes <span class="sy1">&gt;</span> iMaxDelay <span class="br0">&#41;</span> <span class="co1">//is the time diff greater than 1 minute</span></div></li><li class="li1"><div class="de1">		<span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">			bIsDelayedSchedule <span class="sy1">=</span> TRUE<span class="sy4">;</span></div></li><li class="li1"><div class="de1">			nclog<span class="br0">&#40;</span>L<span class="st0">&quot;*** delayed schedule *** recognized<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">			<span class="co1">//this is a delayed schedule</span></div></li><li class="li1"><div class="de1">			DOUBLE dbTimeDiff <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">			<span class="co1">//it may happen that the schedule is far in the future</span></div></li><li class="li1"><div class="de1">			<span class="co1">//we calc the next schedule on base of the current time by using the saved start/stop time</span></div></li><li class="li1"><div class="de1">			<span class="co1">//is just greater than the current time</span></div></li><li class="li1"><div class="de1">			<span class="kw1">if</span><span class="br0">&#40;</span>thisTaskType<span class="sy1">==</span>stopTask<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">				tmNewTime<span class="sy1">=</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stStopTime</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">			<span class="kw1">else</span></div></li><li class="li1"><div class="de1">				tmNewTime<span class="sy1">=</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stStartTime</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">			tmNewTime <span class="sy1">=</span> createNextSchedule<span class="br0">&#40;</span>tmNewTime, shDays, shHour, shMin<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">		<span class="kw1">else</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">			nclog<span class="br0">&#40;</span>L<span class="st0">&quot;*** NO delayed schedule *** recognized<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">			<span class="kw1">if</span><span class="br0">&#40;</span>thisTaskType<span class="sy1">==</span>stopTask<span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">				tmNewTime <span class="sy1">=</span> createNextSchedule<span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stStopTime</span>, shDays, shHour, shMin<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">			<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">			<span class="kw1">else</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">				tmNewTime <span class="sy1">=</span> createNextSchedule<span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">stStartTime</span>, shDays, shHour, shMin<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">			<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">			bIsDelayedSchedule<span class="sy1">=</span>FALSE<span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">		<span class="co1">//create a new kill or start schedule with new time</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;Creating new schedule for '%s' in Task%i<span class="es1">\n</span>&quot;</span>, _Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">szExeName</span>, iTask<span class="sy2">+</span>1<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1"><span class="co2">#ifndef TESTMODE</span></div></li><li class="li1"><div class="de1">		ScheduleRunApp<span class="br0">&#40;</span>szTaskerEXE, strTaskCmdLine, tmNewTime<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1"><span class="co2">#endif</span></div></li><li class="li1"><div class="de1">		<span class="co1">//save new changed stop/start ime</span></div></li><li class="li1"><div class="de1">		<span class="kw1">if</span><span class="br0">&#40;</span>thisTaskType<span class="sy1">==</span>stopTask<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">			regSetStopTime<span class="br0">&#40;</span>iTask, tmNewTime<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="kw1">else</span></div></li><li class="li1"><div class="de1">			regSetStartTime<span class="br0">&#40;</span>iTask, tmNewTime<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">		<span class="kw1">if</span><span class="br0">&#40;</span><span class="sy3">!</span>bIsDelayedSchedule<span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">			nclog<span class="br0">&#40;</span>L<span class="st0">&quot;Not a delayed schedule<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">			<span class="kw1">if</span><span class="br0">&#40;</span>thisTaskType<span class="sy1">==</span>startTask<span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">				<span class="kw1">if</span><span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">bStartOnAConly</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">					<span class="kw1">if</span><span class="br0">&#40;</span>isACpowered<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">						nclog<span class="br0">&#40;</span>L<span class="st0">&quot;Starting exe '%s' as on AC power<span class="es1">\n</span>&quot;</span>, _Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">szExeName</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">						runExe<span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">szExeName</span>, _Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">szArgs</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">					<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">					<span class="kw1">else</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">						nclog<span class="br0">&#40;</span>L<span class="st0">&quot;Skipping start of exe '%s' as not on AC power<span class="es1">\n</span>&quot;</span>, _Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">szExeName</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">					<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">				<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">				<span class="kw1">else</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">					nclog<span class="br0">&#40;</span>L<span class="st0">&quot;Starting exe '%s'<span class="es1">\n</span>&quot;</span>, _Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">szExeName</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">					runExe<span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">szExeName</span>, _Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">szArgs</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">				<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">			<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">			<span class="kw1">else</span><span class="br0">&#123;</span> <span class="co1">// a stop task</span></div></li><li class="li1"><div class="de1">				<span class="co1">//now kill the task's exe</span></div></li><li class="li1"><div class="de1">				nclog<span class="br0">&#40;</span>L<span class="st0">&quot;Killing exe '%s'<span class="es1">\n</span>&quot;</span>, _Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">szExeName</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">				DWORD iKillRes <span class="sy1">=</span> killExe<span class="br0">&#40;</span>_Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">szExeName</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">				<span class="kw1">switch</span> <span class="br0">&#40;</span>iKillRes<span class="br0">&#41;</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">					<span class="kw1">case</span> ERROR_NOT_FOUND<span class="sy4">:</span></div></li><li class="li1"><div class="de1">						nclog<span class="br0">&#40;</span>L<span class="st0">&quot;<span class="es1">\t</span>exe not running<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">						<span class="kw1">break</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">					<span class="kw1">case</span> <span class="nu0">0</span><span class="sy4">:</span></div></li><li class="li1"><div class="de1">						nclog<span class="br0">&#40;</span>L<span class="st0">&quot;<span class="es1">\t</span>exe killed<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">						<span class="kw1">break</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">					<span class="kw1">default</span><span class="sy4">:</span></div></li><li class="li1"><div class="de1">						nclog<span class="br0">&#40;</span>L<span class="st0">&quot;unable to kill exe. GetLastError=%08x<span class="es1">\n</span>&quot;</span>, iKillRes<span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">						<span class="kw1">break</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">				<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">			<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">		<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">		<span class="kw1">else</span><span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">			nclog<span class="br0">&#40;</span>L<span class="st0">&quot;Exec/Kill skipped as this is a delayed schedule<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">		<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">	<span class="br0">&#125;</span></div></li><li class="li1"><div class="de1">	<span class="kw1">else</span></div></li><li class="li1"><div class="de1">		nclog<span class="br0">&#40;</span>L<span class="st0">&quot;<span class="es1">\t</span>task %i is inactive (0x%02x)<span class="es1">\n</span>&quot;</span>, iTask, _Tasks<span class="br0">&#91;</span>iTask<span class="br0">&#93;</span>.<span class="me1">iActive</span><span class="br0">&#41;</span><span class="sy4">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">		<span class="kw1">return</span> iReturn<span class="sy4">;</span></div></li><li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li></ol></pre></div></div>
<h2> Tasker2 control</h2>
<p>Although you normally dont need to run tasker2 manually, I have added some command line arguments:</p>
<p>&#8220;-c&#8221;    instructs tasker2.exe to remove all tasker2 schedules of the scheduler database<br />
&#8220;-r taskX&#8221;    deactivate processing of task with number X, sets the active flag to 0<br />
&#8220;-a taskX&#8221;    activate processing of task number X, sets the active flag to 1<br />
&#8220;-d&#8221;    dump a list of all active notifications of the windows mobile scheduler</p>
<p>Do not use -s taskX and -k taskX except for testing. The args &#8216;-s taskX&#8217; and &#8216;-k taskX&#8217; are only be used by the scheduler.</p>
<h2>Log file</h2>
<p>The log file will log all activities of tasker2 in the directory of tasker2.exe. It will grow until 1MB and then one log backup file is saved. So you may have two log files, one active and one backup of the previous log.</p>
<div id="wpshdo_6" class="wp-synhighlighter-outer"><div id="wpshdt_6" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_6"></a><a id="wpshat_6" class="wp-synhighlighter-title" href="#codesyntax_6"  onClick="javascript:wpsh_toggleBlock(6)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_6" onClick="javascript:wpsh_code(6)" title="Show code only"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_6" onClick="javascript:wpsh_print(6)" title="Print code"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_6" class="wp-synhighlighter-inner" style="display: block;"><pre class="dos" style="font-family:monospace;"><ol><li class="li1"><div class="de1">0xfacbcab2: ++++++++++++++++ Tasker v300 started +++++++++++++++++++</div></li><li class="li1"><div class="de1">0xfacbcab2: Checking <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> Mutex <span class="br0">&#40;</span>single instance allowed only<span class="br0">&#41;</span>...</div></li><li class="li1"><div class="de1">0xfacbcab2: 	Created new mutex</div></li><li class="li1"><div class="de1">0xfacbcab2: ~~~ using actual localtime:</div></li><li class="li1"><div class="de1">0xfacbcab2: 	 23.12.2011, 12:28</div></li><li class="li1"><div class="de1">0xfacbcab2: CmdLine =</div></li><li class="li1"><div class="de1">0xfacbcab2: Checking <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> valid date/time...</div></li><li class="li1"><div class="de1">0xfacbcab2: Date/Time after 11 2011. OK</div></li><li class="li1"><div class="de1">0xfacbcab2: Clearing Event Notifications...0xfacbcab2: OK</div></li><li class="li1"><div class="de1">0xfacbcab2: ClearRunApp<span class="br0">&#40;</span><span class="br0">&#41;</span>: ...</div></li><li class="li1"><div class="de1">0xfacbcab2: ClearRunApp<span class="br0">&#40;</span><span class="br0">&#41;</span>: CeClearUserNotification <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> handle: 0x3d00000f</div></li><li class="li1"><div class="de1">0xfacbcab2: ClearRunApp<span class="br0">&#40;</span><span class="br0">&#41;</span>: CeClearUserNotification <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> handle: 0x33000025</div></li><li class="li1"><div class="de1">0xfacbcab2: ClearRunApp<span class="br0">&#40;</span><span class="br0">&#41;</span>: CeClearUserNotification <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> handle: 0x3800002a</div></li><li class="li1"><div class="de1">0xfacbcab2: ClearRunApp<span class="br0">&#40;</span><span class="br0">&#41;</span>: CeClearUserNotification <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> handle: 0x3b00001b</div></li><li class="li1"><div class="de1">0xfacbcab2: ClearRunApp<span class="br0">&#40;</span><span class="br0">&#41;</span>: CeClearUserNotification <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> handle: 0x3800002e</div></li><li class="li1"><div class="de1">0xfacbcab2: ClearRunApp<span class="br0">&#40;</span><span class="br0">&#41;</span>: CeClearUserNotification <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> handle: 0x3f00001e</div></li><li class="li1"><div class="de1">0xfacbcab2: ClearRunApp<span class="br0">&#40;</span><span class="br0">&#41;</span>: CeClearUserNotification <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> handle: 0x37000016</div></li><li class="li1"><div class="de1">0xfacbcab2: ClearRunApp<span class="br0">&#40;</span><span class="br0">&#41;</span>: CeClearUserNotification <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> handle: 0x3a000030</div></li><li class="li1"><div class="de1">0xfacbcab2: ClearRunApp<span class="br0">&#40;</span><span class="br0">&#41;</span>: returns 8</div></li><li class="li1"><div class="de1">0xfacbcab2: Cleared 8 Tasker schedules</div></li><li class="li1"><div class="de1">0xfacbcab2: scheduleAllTasks: ClearAllSchedules <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> 8 tasks</div></li><li class="li1"><div class="de1">0xfacbcab2: Clearing Event Notifications...0xfacbcab2: Clearing Event Notifications...0xfacbcab2: OK</div></li><li class="li1"><div class="de1">0xfacbcab2: Adding Time_Change Event Notification...0xfacbcab2: OK</div></li><li class="li1"><div class="de1">0xfacbcab2: Adding TZ_Change Event Notification...0xfacbcab2: OK</div></li><li class="li1"><div class="de1">0xfacbcab2: Creating new Start Task schedule <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> '\Windows\notes.exe' <a href="http://www.ss64.com/nt/in.html"><span class="kw1">in</span></a> Task1</div></li><li class="li1"><div class="de1">0xfacbcab2: 	calculating new schedule <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> '201112231300'...</div></li><li class="li1"><div class="de1">0xfacbcab2: 	interval is: 0d01h00m</div></li><li class="li1"><div class="de1">0xfacbcab2: 	schedule adjusted to '201112231300'</div></li><li class="li1"><div class="de1">0xfacbcab2: 	ScheduleRunApp: Next run at: 23.12.2011 13:00:56</div></li><li class="li1"><div class="de1">0xfacbcab2: 	ScheduleRunApp: CeSetUserNotificationEx succeeded...</div></li><li class="li1"><div class="de1">0xfacbcab2: Creating new Kill Task schedule <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> '\Windows\notes.exe' <a href="http://www.ss64.com/nt/in.html"><span class="kw1">in</span></a> Task1</div></li><li class="li1"><div class="de1">0xfacbcab2: 	calculating new schedule <a href="http://www.ss64.com/nt/for.html"><span class="kw1">for</span></a> '<span class="nu0">201112231300</span>'...</div></li><li class="li1"><div class="de1">0xfacbcab2: 	interval is: 0d01h00m</div></li><li class="li1"><div class="de1">0xfacbcab2: 	schedule adjusted to '<span class="nu0">201112231300</span>'</div></li><li class="li1"><div class="de1">0xfacbcab2: 	ScheduleRunApp: Next run at: 23.12.2011 <span class="nu0">13</span>:00:<span class="nu0">56</span></div></li><li class="li1"><div class="de1">0xfacbcab2: 	ScheduleRunApp: CeSetUserNotificationEx succeeded...</div></li><li class="li1"><div class="de1">...</div></li></ol></pre></div></div>
<p>The first entry in the log file is the current logging instance. As multiple instances may write randomly at the log, the instance number is needed to idetify which instance has written the current log line.</p>
<h2>Changes</h2>
<p>There are two variants of tasker2, one is using SYSTEMTIME and the other, new one uses time_t. I switched to time_t as it is more easy to do operations like add-one-day with time_t vars than with SYSTEMTIME.</p>
<p>The old variant (v234a) is available as a branch in the code repository: http://code.google.com/p/tasker2/source/browse/#svn%2Fbranch%2Fversion232%2FTasker</p>
<h2>Tests</h2>
<p>Fortunately I had great help by a tester of the software. Many thanks to Thomas B.</p>
<p>I built my only automatic test suite using batch files and a special build of tasker2.exe. If you uncomment the line //#define TESTMODE at the beginning of tasker2.cpp, the compiled app will be in test mode. That means it will not add or remove schedules to/from the windows mobile scheduler. There is another tool used in the test_run.bat that sets the date and time of the device remotely (ActiveSync or Windows Mobile Device Center connection).</p>
<p>The automatic test uses the great tools of itsutils and will set registry values, change date/time, launch tasker2, get the log and build a merged log with all essential data to check the function of tasker2:</p>
<p>http://code.google.com/p/tasker2/source/browse/#svn%2Ftrunk%2FTasker%2Ftest</p>
<p>Here is a snippet from the test_bat.bat:</p>
<div id="wpshdo_7" class="wp-synhighlighter-outer"><div id="wpshdt_7" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_7"></a><a id="wpshat_7" class="wp-synhighlighter-title" href="#codesyntax_7"  onClick="javascript:wpsh_toggleBlock(7)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_7" onClick="javascript:wpsh_code(7)" title="Show code only"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_7" onClick="javascript:wpsh_print(7)" title="Print code"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://www.hjgode.de/wp/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_7" class="wp-synhighlighter-inner" style="display: block;"><pre class="php" style="font-family:monospace;"><ol><li class="li1"><div class="de1"><span class="sy0">@</span><span class="kw1">echo</span> off</div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1"><span class="kw1">ECHO</span> <span class="co2">############## START ###############</span></div></li><li class="li1"><div class="de1"><span class="kw1">echo</span>  MAKE SHURE THE RADIOS ARE OFF TO</div></li><li class="li1"><div class="de1"><span class="kw1">echo</span>  AVOID AUTOMATIC <a href="http://www.php.net/time"><span class="kw3">TIME</span></a> SYNCS<span class="sy0">!</span></div></li><li class="li1"><div class="de1"><span class="kw1">echo</span> <span class="sy0">.</span></div></li><li class="li1"><div class="de1">PAUSE Press any <a href="http://www.php.net/key"><span class="kw3">key</span></a> to start</div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1"><span class="kw1">ECHO</span> <span class="co2">############## START ############### &gt;test_run.txt</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1"><span class="kw1">echo</span> Importing test reg keys<span class="sy0">...</span></div></li><li class="li1"><div class="de1"><span class="kw1">echo</span> Importing test reg keys<span class="sy0">...</span> <span class="sy0">&gt;&gt;</span>test_run<span class="sy0">.</span>txt</div></li><li class="li1"><div class="de1">pregutl <span class="sy0">@</span>tasker2<span class="sy0">.</span>reg <span class="sy0">&gt;&gt;</span>test_run<span class="sy0">.</span>txt</div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">pdel \tasker2<span class="sy0">.</span>exe<span class="sy0">.</span><a href="http://www.php.net/log"><span class="kw3">log</span></a><span class="sy0">.</span>txt <span class="sy0">&gt;</span>NUL</div></li><li class="li1"><div class="de1">pput <span class="sy0">-</span>f <span class="sy0">./</span>tasker2<span class="sy0">.</span>exe \tasker2<span class="sy0">.</span>exe</div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1"><span class="kw1">ECHO</span> TEST1<span class="sy0">...</span></div></li><li class="li1"><div class="de1"><span class="kw1">ECHO</span> 	set <a href="http://www.php.net/time"><span class="kw3">time</span></a> manually to 01<span class="sy0">.</span>01<span class="sy0">.</span>2003 12<span class="sy0">:</span>00</div></li><li class="li1"><div class="de1"><span class="kw1">echo</span> 	run tasker2<span class="sy0">.</span>exe</div></li><li class="li1"><div class="de1"><span class="kw1">ECHO</span> <span class="sy0">++++++++++++++</span> TEST1 <span class="sy0">++++++++++++++++</span> <span class="sy0">&gt;&gt;</span>test_run<span class="sy0">.</span>txt</div></li><li class="li1"><div class="de1">pregutl HKLM\Software\Tasker  <span class="sy0">&gt;&gt;</span>test_run<span class="sy0">.</span>txt</div></li><li class="li1"><div class="de1"><span class="kw1">ECHO</span> <span class="sy0">-------------------------------------</span> <span class="sy0">&gt;&gt;</span>test_run<span class="sy0">.</span>txt</div></li><li class="li1"><div class="de1"><span class="kw1">ECHO</span> set <a href="http://www.php.net/time"><span class="kw3">time</span></a> manually to 01<span class="sy0">.</span>01<span class="sy0">.</span>2003 12<span class="sy0">:</span>00 <span class="sy0">&gt;&gt;</span>test_run<span class="sy0">.</span>txt</div></li><li class="li1"><div class="de1"><span class="kw1">ECHO</span> <span class="sy0">-------------------------------------</span> <span class="sy0">&gt;&gt;</span>test_run<span class="sy0">.</span>txt</div></li><li class="li1"><div class="de1">prun \SetDateTime<span class="sy0">.</span>exe 200301011200</div></li><li class="li1"><div class="de1">CALL <span class="sy0">:</span>MYWAIT</div></li><li class="li1"><div class="de1">prun \tasker2<span class="sy0">.</span>exe</div></li><li class="li1"><div class="de1"><span class="kw1">ECHO</span> <span class="st0">&quot;############# Result:&quot;</span> <span class="sy0">&gt;&gt;</span>test_run<span class="sy0">.</span>txt</div></li><li class="li1"><div class="de1">pregutl HKLM\Software\Tasker <span class="sy0">&gt;&gt;</span>test_run<span class="sy0">.</span>txt</div></li><li class="li1"><div class="de1"><span class="kw1">ECHO</span> <span class="sy0">***************</span> <a href="http://www.php.net/log"><span class="kw3">LOG</span></a>  <span class="sy0">****************</span> <span class="sy0">&gt;&gt;</span>test_run<span class="sy0">.</span>txt</div></li><li class="li1"><div class="de1">pget <span class="sy0">-</span>f \tasker2<span class="sy0">.</span>exe<span class="sy0">.</span><a href="http://www.php.net/log"><span class="kw3">log</span></a><span class="sy0">.</span>txt</div></li><li class="li1"><div class="de1">type tasker2<span class="sy0">.</span>exe<span class="sy0">.</span><a href="http://www.php.net/log"><span class="kw3">log</span></a><span class="sy0">.</span>txt <span class="sy0">&gt;&gt;</span>test_run<span class="sy0">.</span>txt</div></li><li class="li1"><div class="de1">pdel \tasker2<span class="sy0">.</span>exe<span class="sy0">.</span><a href="http://www.php.net/log"><span class="kw3">log</span></a><span class="sy0">.</span>txt</div></li><li class="li1"><div class="de1"><span class="kw1">ECHO</span> <span class="sy0">---------------</span>TEST1  <span class="sy0">---------------</span> <span class="sy0">&gt;&gt;</span>test_run<span class="sy0">.</span>txt</div></li><li class="li1"><div class="de1"><span class="kw1">ECHO</span> <span class="sy0">.&gt;&gt;</span>test_run<span class="sy0">.</span>txt</div></li></ol></pre></div></div>
<h2>Downloads</h2>
<p>The full tasker2 source code is available at http://code.google.com/p/tasker2/source/browse</p>
<p>Tool to look at the scheduler database [NotificationList]: <b>DOWNLOAD:</b><a href="http://www.hjgode.de/wp/wp-content/plugins/download-monitor/download.php?id=149" title="Downloaded 23 times">NotificationList</a> - A tool to list notifications (Hits: 23, size: 153.42 kB)</p>
<p>&nbsp;</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Bookmark It</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F12%2F23%2Fwindows-mobile-tasker2-runs-and-stops-applications-periodically%2F&amp;title=Windows+Mobile+%26%238211%3B+tasker2+runs+and+stops+applications+periodically" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F12%2F23%2Fwindows-mobile-tasker2-runs-and-stops-applications-periodically%2F&amp;title=Windows+Mobile+%26%238211%3B+tasker2+runs+and+stops+applications+periodically" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F12%2F23%2Fwindows-mobile-tasker2-runs-and-stops-applications-periodically%2F&amp;title=Windows+Mobile+%26%238211%3B+tasker2+runs+and+stops+applications+periodically" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F12%2F23%2Fwindows-mobile-tasker2-runs-and-stops-applications-periodically%2F&amp;T=Windows+Mobile+%26%238211%3B+tasker2+runs+and+stops+applications+periodically" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F12%2F23%2Fwindows-mobile-tasker2-runs-and-stops-applications-periodically%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F12%2F23%2Fwindows-mobile-tasker2-runs-and-stops-applications-periodically%2F&amp;t=Windows+Mobile+%26%238211%3B+tasker2+runs+and+stops+applications+periodically" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.hjgode.de/wp/2011/12/23/windows-mobile-tasker2-runs-and-stops-applications-periodically/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>KeyToggleStart: Yet another usage for keyboard hook</title>
		<link>http://www.hjgode.de/wp/2011/09/08/keytogglestart-yet-another-usage-for-keyboard-hook/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=keytogglestart-yet-another-usage-for-keyboard-hook</link>
		<comments>http://www.hjgode.de/wp/2011/09/08/keytogglestart-yet-another-usage-for-keyboard-hook/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 10:56:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Keyboard]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[function keys]]></category>
		<category><![CDATA[hook]]></category>
		<category><![CDATA[keyboard]]></category>
		<category><![CDATA[windows mobile]]></category>

		<guid isPermaLink="false">http://www.hjgode.de/wp/?p=1204</guid>
		<description><![CDATA[Hello Windows Mobile Users recently the following was requested: How can I start an application by just hitting some keys in sequence? The answer: Just use a keyboard hook. So I started to code this hook tool based on my KeyToggleBoot2 code. There was not too much to change. The new tool is called KeyToggleStart [...]]]></description>
			<content:encoded><![CDATA[<p>Hello Windows Mobile Users</p>
<p>recently the following was requested:</p>
<p>How can I start an application by just hitting some keys in sequence?</p>
<p>The answer: Just use a keyboard hook.</p>
<p>So I started to code this hook tool based on my KeyToggleBoot2 code. There was not too much to change. The new tool is called KeyToggleStart and it is configured by the registry:</p>
<pre>            REGEDIT4

            [HKEY_LOCAL_MACHINE\Software\Intermec\KeyToggleStart]
            "ForbiddenKeys"=hex:\
                  72 73 00
            ;max 10 keys!
            "KeySeq"="123"
            "Timeout"=dword:00000003
            "LEDid"=dword:00000001
            "Exe"="\\Windows\\iexplore.exe"
            "Arg"=""</pre>
<h2>Reg keys meaning:</h2>
<p><strong>Forbiddenkeys</strong> is just an addon feature: key codes entered in this list will not be processed any more by your Windows Mobile device. For example, to disable the use of the F3(VK_TTALK) and F4 (VK_TEND) keys you have to enter a binary list of 0&#215;72,0&#215;73,0&#215;00 (the zero is needed to terminate the list).</p>
<p><strong>KeySeq</strong> list the char sequence you want to use to start an application. For example if this is the string &#8220;123&#8243;, everytime you enter 123 in sequence within the given time, the application defined will be started.</p>
<p><strong>TimeOut</strong> is the time in seconds you have to enter the sequence. So do not use a long key sequence as &#8220;starteiexplorenow&#8221; and a short timeout (except you are a very fast type writer). The timeout is started with the first char matching and ends after the time or when you enter a non-matching char of the sequence.</p>
<p>With <strong>LEDid</strong> you can specify a LED index number. LED&#8217;s on Windows Mobile are controlled by an index number, each LED has one or more ID assigned to it. So, with LEDid you can control, which LED will lit, when the matching process is running. You can even find an ID to control a vibration motor, if your Windows Mobile device is equipped with one.</p>
<p>The <strong>Exe</strong> registry string value is used to specify which application will be started when the key sequence is matched.</p>
<p>If the application you want have to be started needs some arguments, you can enter these using the <strong>Arg</strong> registry value.</p>
<p>When you start the KeyToggleStart tool, you will not see any window except for a notification symbol on your Start/Home screen of the device.</p>
<p><a href="http://www.hjgode.de/wp/2011/09/08/keytogglestart-yet-another-usage-for-keyboard-hook/keytogglestart/" rel="attachment wp-att-1205"><img class="alignnone size-medium wp-image-1205" title="KeyToggleStart" src="http://www.hjgode.de/wp/wp-content/uploads/2011/09/KeyToggleStart-225x300.png" alt="" width="225" height="300" /></a></p>
<p>If you tap this icon (redirection sign) you have the chance to end the hook tool.</p>
<p><span id="more-1204"></span>The code itself is nothing special. Only the sequence matching code is a little bit special. As the chars in the sequence do not match keystrokes in a ont-to-one manner, I have to check the shift state of the keyboard and if the current char of the seqeunce is a char needing a shift. For example: the asterisk char (&#8220;*&#8221;) is a combination of the &#8220;8&#8243; key plus the Shift key. So, if you have the &#8220;*&#8221; in the char sequence, the code has to check for the &#8220;8&#8243; key and if the keyboard is in shift state:</p>
<pre lang="cpp">// The command below tells the OS that this EXE has an export function so we can use the global hook without a DLL
__declspec(dllexport) LRESULT CALLBACK g_LLKeyboardHookCallback(
   int nCode,      // The hook code
   WPARAM wParam,  // The window message (WM_KEYUP, WM_KEYDOWN, etc.)
   LPARAM lParam   // A pointer to a struct with information about the pressed key
)
{
    /*    typedef struct {
        DWORD vkCode;
        DWORD scanCode;
        DWORD flags;
        DWORD time;
        ULONG_PTR dwExtraInfo;
    } KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;*/

    // Get out of hooks ASAP; no modal dialogs or CPU-intensive processes!
    // UI code really should be elsewhere, but this is just a test/prototype app
    // In my limited testing, HC_ACTION is the only value nCode is ever set to in CE
    static int iActOn = HC_ACTION;
    static bool isShifted=false;

#ifdef DEBUG
    static TCHAR str[MAX_PATH];
#endif

    PKBDLLHOOKSTRUCT pkbhData = (PKBDLLHOOKSTRUCT)lParam;
    //DWORD vKey;
    if (nCode == iActOn)
    {
        //only process unflagged keys
        if (pkbhData-&gt;flags != 0x00)
            return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
        //check vkCode against forbidden key list
        if(pForbiddenKeyList!=NULL)
        {
            BOOL bForbidden=false;
            int j=0;
            do{
                if(pForbiddenKeyList[j]==(BYTE)pkbhData-&gt;vkCode)
                {
                    bForbidden=true;
                    DEBUGMSG(1, (L"suppressing forbidden key: 0x%0x\n",pkbhData-&gt;vkCode));
                    continue;
                }
                j++;
            }while(!bForbidden &amp;&amp; pForbiddenKeyList[j]!=0x00);
            if(bForbidden){
                return true;
            }
        }

        SHORT sShifted = GetAsyncKeyState(VK_SHIFT);
        if((sShifted &amp; 0x800) == 0x800)
            isShifted = true;
        else
            isShifted = false;

        //check and toggle for Shft Key
        //do not process shift key
        if (pkbhData-&gt;vkCode == VK_SHIFT){
            DEBUGMSG(1, (L"Ignoring VK_SHIFT\n"));
            return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
        }

        //################################################################
        //check if the actual key is a match key including the shift state
        if ((byte)pkbhData-&gt;vkCode == (byte)szVKeySeq[iMatched]){
            DEBUGMSG(1 , (L"==== char match\n"));
            if (bCharShiftSeq[iMatched] == isShifted){
                DEBUGMSG(1 , (L"==== shift match\n"));
            }
            else{
                DEBUGMSG(1 , (L"==== shift not match\n"));
            }
        }

        if( wParam == WM_KEYUP ){
            DEBUGMSG(1, (L"---&gt; szVKeySeq[iMatched] = 0x%02x\n", (byte)szVKeySeq[iMatched]));

            if ( ((byte)pkbhData-&gt;vkCode == (byte)szVKeySeq[iMatched]) &amp;&amp; (isShifted == bCharShiftSeq[iMatched]) ) {

                //the first match?
                if(iMatched==0){
                    //start the timer and lit the LED
                    LedOn(LEDid,1);
                    tID=SetTimer(NULL, 0, matchTimeout, (TIMERPROC)Timer2Proc);
                }
                iMatched++;

                DEBUGMSG(1, (L"iMatched is now=%i\n", iMatched));
                //are all keys matched
                if (iMatched == iKeyCount){
                    //show modeless dialog
                    DEBUGMSG(1, (L"FULL MATCH, starting ...\n"));
                    PostMessage(g_hWnd, WM_SHOWMYDIALOG, 0, 0);
                    //reset match pos and stop timer
                    DEBUGMSG(1, (L"FULL MATCH: Reset matching\n"));
                    LedOn(LEDid,0);
                    iMatched=0; //reset match pos
                    KillTimer(NULL, tID);
                    //return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
                }
                //return -1; //do not forward key?
            }
            else
            {
                KillTimer(NULL, tID);
                LedOn(LEDid,0);
                iMatched=0; //reset match pos
                DEBUGMSG(1, (L"FULL MATCH missed. Reseting matching\n"));
            }
        } //if wParam == WM_KEY..
    }
    return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
}</pre>
<p>Enjoy the code</p>
<p>Download VS2008 Source code for Windows Mobile 6.5.3 SDK<br />
<b>DOWNLOAD:</b><a href="http://www.hjgode.de/wp/wp-content/plugins/download-monitor/download.php?id=143" title="Downloaded 92 times">KeyToggleStart</a> -  (Hits: 92, size: 30.06 kB)</p>
<p>Download KeyToggleStart executable (Windows Mobile 6)<br />
<b>DOWNLOAD:</b><a href="http://www.hjgode.de/wp/wp-content/plugins/download-monitor/download.php?id=144" title="Downloaded 78 times">KeyToggleStart WM6 Executable</a> -  (Hits: 78, size: 12.38 kB)</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Bookmark It</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F09%2F08%2Fkeytogglestart-yet-another-usage-for-keyboard-hook%2F&amp;title=KeyToggleStart%3A+Yet+another+usage+for+keyboard+hook" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F09%2F08%2Fkeytogglestart-yet-another-usage-for-keyboard-hook%2F&amp;title=KeyToggleStart%3A+Yet+another+usage+for+keyboard+hook" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F09%2F08%2Fkeytogglestart-yet-another-usage-for-keyboard-hook%2F&amp;title=KeyToggleStart%3A+Yet+another+usage+for+keyboard+hook" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F09%2F08%2Fkeytogglestart-yet-another-usage-for-keyboard-hook%2F&amp;T=KeyToggleStart%3A+Yet+another+usage+for+keyboard+hook" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F09%2F08%2Fkeytogglestart-yet-another-usage-for-keyboard-hook%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F09%2F08%2Fkeytogglestart-yet-another-usage-for-keyboard-hook%2F&amp;t=KeyToggleStart%3A+Yet+another+usage+for+keyboard+hook" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.hjgode.de/wp/2011/09/08/keytogglestart-yet-another-usage-for-keyboard-hook/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remote Desktop Mobile on VGA devices: QVGA applications do not scale well</title>
		<link>http://www.hjgode.de/wp/2011/09/05/remote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=remote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well</link>
		<comments>http://www.hjgode.de/wp/2011/09/05/remote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well/#comments</comments>
		<pubDate>Mon, 05 Sep 2011 11:37:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Int*rm*c]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[HI_RES_AWARE]]></category>
		<category><![CDATA[QVGA]]></category>
		<category><![CDATA[rdp]]></category>
		<category><![CDATA[remote desktop mobile]]></category>
		<category><![CDATA[VGA]]></category>
		<category><![CDATA[Windows Mobile 6.5.3]]></category>
		<category><![CDATA[wpctsc.exe]]></category>

		<guid isPermaLink="false">http://www.hjgode.de/wp/?p=1184</guid>
		<description><![CDATA[Hi there are now more and more full VGA rugged devices coming. And some customers are still using Remote Desktop Mobile to run there application on the small screens. Unfortunately some of the coders use application screen layouts hard coded to QVGA (240&#215;320). Now with a VGA capable Windows Mobile device they get weird screens [...]]]></description>
			<content:encoded><![CDATA[<p>Hi</p>
<p>there are now more and more full VGA rugged devices coming. And some customers are still using Remote Desktop Mobile to run there application on the small screens. Unfortunately some of the coders use application screen layouts hard coded to QVGA (240&#215;320). Now with a VGA capable Windows Mobile device they get weird screens on the device.</p>
<p>The client (Remote Desktop Mobile) sends the server information about there screen sizes. As a VGA device can display 480&#215;640 pixels, the hard coded 240&#215;320 applications only use a quarter of the screen. The texts are very small and more or less unreadable.</p>
<p><span id="more-1184"></span>The terminal server gets client resolution information:</p>
<p><a href="http://www.hjgode.de/wp/2011/09/05/remote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well/tsmanager_vga_unhacked/" rel="attachment wp-att-1186"><img class="aligncenter size-full wp-image-1186" title="TSManager_VGA_unhacked" src="http://www.hjgode.de/wp/wp-content/uploads/2011/09/TSManager_VGA_unhacked.gif" alt="" width="637" height="353" /></a> Unscaled (left) VGA display of a QVGA application (with &#8220;Fit remote desktop to screen&#8221; NOT CHECKED) and on the right the same application with internal autoadjust to workscreen size:</p>
<p><a href="http://www.hjgode.de/wp/2011/09/05/remote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well/qvga_fixed_form_on_vga_screen_nofittoscreen/" rel="attachment wp-att-1187"><img class="alignnone size-medium wp-image-1187" title="QVGA_fixed_form_on_VGA_screen_noFitToScreen" src="http://www.hjgode.de/wp/wp-content/uploads/2011/09/QVGA_fixed_form_on_VGA_screen_noFitToScreen-225x300.gif" alt="" width="225" height="300" /></a>  <a href="http://www.hjgode.de/wp/2011/09/05/remote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well/rdm_options/" rel="attachment wp-att-1189"><img class="alignnone size-medium wp-image-1189" title="RDM_options" src="http://www.hjgode.de/wp/wp-content/uploads/2011/09/RDM_options-225x300.gif" alt="" width="225" height="300" /></a>  <a href="http://www.hjgode.de/wp/2011/09/05/remote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well/qvga_autoscale_form_on_vga_screen/" rel="attachment wp-att-1190"><img class="alignnone size-medium wp-image-1190" title="QVGA_autoscale_form_on_VGA_screen" src="http://www.hjgode.de/wp/wp-content/uploads/2011/09/QVGA_autoscale_form_on_VGA_screen-225x300.gif" alt="" width="225" height="300" /></a></p>
<p>As you can see in the right image above this line, it is no problem to show a form designed for QVGA to scale nice with the use of some code (as using WorkingArea.Width/Height and a table layout). But in the left image you see what happens to hard coded designed applications.</p>
<p>If you have the source code, you should change the design of your dialogs to be resolution aware, so it scales fine for QVGA and VGA (and whatever comes next).</p>
<p>If you do not have the code or can not change the application, you have to tell Windows Mobile to behave like the Remote Desktop Mobile application is NOT <a href="http://msdn.microsoft.com/en-us/library/bb416287.aspx" target="_blank">HI_RES_AWARE</a>. That means you need to hack the exe file. I took a look at the Windows Mobile 6.5.3 wpctsc.exe (the Remote Desktop Mobile executable) and did not find the HI_RES_AWARE resource, so the OS must use the other mark to see that wpctsc.exe is HI_RES_AWARE. And yes, indeed, the PE header shows that wpctsc.exe has a subystem version of 5.2. With some PEInfo tool, you can hack the major subsystem version and just change it from 5 to 4.</p>
<p>When you start a application that is not HI_RES_AWARE, the Windows Mobile 6.5.3 OS will scale all UI elements for the application and the app will look fine and not only fill a quarter of the VGA screen. After changing the major subsystem version number, the first thing you will notice is the more coarse display of the menu items in the menu bar:</p>
<p><a href="http://www.hjgode.de/wp/2011/09/05/remote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well/rdm_startscreen_vga/" rel="attachment wp-att-1193"><img class="alignnone size-medium wp-image-1193" title="RDM_startscreen_VGA" src="http://www.hjgode.de/wp/wp-content/uploads/2011/09/RDM_startscreen_VGA-225x300.gif" alt="" width="225" height="300" /></a>   <a href="http://www.hjgode.de/wp/2011/09/05/remote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well/rdm_startscreen_qvga/" rel="attachment wp-att-1194"><img class="alignnone size-medium wp-image-1194" title="RDM_startscreen_QVGA" src="http://www.hjgode.de/wp/wp-content/uploads/2011/09/RDM_startscreen_QVGA-225x300.gif" alt="" width="225" height="300" /></a></p>
<p>Left is the HI_RES_AWARE original app and on the right we have the hacked one (take a closer look ate the ellipses around the menu items).</p>
<p>When you use the hacked, not HI_RES_AWARE, application, the terminal server will see the client supports QVGA only (Client Resolution) and your hard coded application screens will look the same as on a QVGA capable device:</p>
<p><a href="http://www.hjgode.de/wp/2011/09/05/remote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well/qvga-form_on_qvga-screen/" rel="attachment wp-att-1195"><img class="alignnone size-medium wp-image-1195" title="QVGA-form_on_QVGA-screen" src="http://www.hjgode.de/wp/wp-content/uploads/2011/09/QVGA-form_on_QVGA-screen-225x300.gif" alt="" width="225" height="300" /></a>   <a href="http://www.hjgode.de/wp/2011/09/05/remote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well/tsmanager_qvga_hacked_nofittoscreen-2/" rel="attachment wp-att-1197"><img class="alignnone size-full wp-image-1197" title="TSManager_QVGA_hacked_noFitToScreen" src="http://www.hjgode.de/wp/wp-content/uploads/2011/09/TSManager_QVGA_hacked_noFitToScreen1.gif" alt="" width="637" height="354" /></a></p>
<p>The attached wpctsc.exe is the hacked one with a subsystem major version number of 4 instead of 5. Use this on your Windows Mobile 6.5.3 device at your own risk. The file is not signed as the device I work with are not requiring signed exe files. The change to the exe file (after I dumped the OS files to my PC using itsutils) was simply done with mgeeky&#8217;s PEinfo code at <a href="https://github.com/mgeeky/PEInfo" target="_blank">GitHub</a>.</p>
<p>If you can not copy the file on top of the original one on the device (\Windows\wpctsc.exe), you can use the syscache feature. Copy the wpctsc.exe to \Windows\System\SysCache directory and reboot the device. If the directory does not exist you just have to create it manually.</p>
<p>If you want to get the old wpctsc.exe back, just delete the file you copied. As the original wpctsc.exe is part of the OS (a XIP file), you can not delete the file but you can copy a file with the same name on top of it. When you delete this copied file, the original is back in place. So, there is no harm in testinng the exe.</p>
<b>DOWNLOAD:</b><a href="http://www.hjgode.de/wp/wp-content/plugins/download-monitor/download.php?id=142" title="Downloaded 245 times">wpctsc.exe with major subsystem version number = 4</a> -  (Hits: 245, size: 40.21 kB)
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Bookmark It</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F09%2F05%2Fremote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well%2F&amp;title=Remote+Desktop+Mobile+on+VGA+devices%3A+QVGA+applications+do+not+scale+well" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F09%2F05%2Fremote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well%2F&amp;title=Remote+Desktop+Mobile+on+VGA+devices%3A+QVGA+applications+do+not+scale+well" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F09%2F05%2Fremote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well%2F&amp;title=Remote+Desktop+Mobile+on+VGA+devices%3A+QVGA+applications+do+not+scale+well" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F09%2F05%2Fremote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well%2F&amp;T=Remote+Desktop+Mobile+on+VGA+devices%3A+QVGA+applications+do+not+scale+well" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F09%2F05%2Fremote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F09%2F05%2Fremote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well%2F&amp;t=Remote+Desktop+Mobile+on+VGA+devices%3A+QVGA+applications+do+not+scale+well" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.hjgode.de/wp/2011/09/05/remote-desktop-mobile-on-vga-devices-qvga-applications-do-not-scale-well/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WM 6.5: Remote Desktop Client disconnects after 10 minutes</title>
		<link>http://www.hjgode.de/wp/2011/07/04/wm-6-5-remote-desktop-client-disconnects-after-10-minutes/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wm-6-5-remote-desktop-client-disconnects-after-10-minutes</link>
		<comments>http://www.hjgode.de/wp/2011/07/04/wm-6-5-remote-desktop-client-disconnects-after-10-minutes/#comments</comments>
		<pubDate>Mon, 04 Jul 2011 12:15:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Int*rm*c]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[10 minutes]]></category>
		<category><![CDATA[disconnect]]></category>
		<category><![CDATA[idle time]]></category>
		<category><![CDATA[RDM]]></category>
		<category><![CDATA[rdp]]></category>
		<category><![CDATA[remote desktop mobile]]></category>
		<category><![CDATA[windows embedded handheld]]></category>
		<category><![CDATA[windows mobile]]></category>
		<category><![CDATA[wpctsc.exe]]></category>

		<guid isPermaLink="false">http://www.hjgode.de/wp/?p=1157</guid>
		<description><![CDATA[Hi as MS does not change it, the Remote Desktop Mobile application still disconnects a session after 10 minutes idle time. Although there is a solution for Windows Mobile 6.1 (http://www.hjgode.de/wp/2009/09/18/wm6-1-remote-desktop-client-disconnects-after-10-minutes/) based on the posting of Rafael (MS Support), this will not work with Windows Embedded Handheld (WM6.5). The TSSHELLWND will not react on mouse_event [...]]]></description>
			<content:encoded><![CDATA[<p>Hi</p>
<p>as MS does not change it, the Remote Desktop Mobile application still disconnects a session after 10 minutes idle time.</p>
<p>Although there is a solution for Windows Mobile 6.1 (http://www.hjgode.de/wp/2009/09/18/wm6-1-remote-desktop-client-disconnects-after-10-minutes/) based on the posting of Rafael (MS Support), this will not work with Windows Embedded Handheld (WM6.5).</p>
<p>The TSSHELLWND will not react on mouse_event and you have to replace the calls by SendMessage and send the WM_MOUSEMOVE to the Terminal Server Input window.</p>
<p>The attached application will do so but it will start only on Int*rm*c devices. It sends a mouse_move message all 4 minutes to the TS input window and so the idle timer will not timeout.</p>
<p>If you ever need to stop RDMKeepbusy from running in the background, you will need StopKeepBusy which is part of the executable download.</p>
<p>For visual control, RDMKeepbusy shows a small blinking line in the task bar:<br />
green = Remote Desktop window found and input window is active<br />
yellow = Remote Desktop window found, but no input window active<br />
red = Remote Desktop window not found</p>
<b>DOWNLOAD:</b><a href="http://www.hjgode.de/wp/wp-content/plugins/download-monitor/download.php?id=139" title="Downloaded 122 times">RDM Keepbusy</a> - Windows Embedded Handheld application to avoid idle timeouts (Hits: 122, size: 8.07 kB)
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Bookmark It</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F07%2F04%2Fwm-6-5-remote-desktop-client-disconnects-after-10-minutes%2F&amp;title=WM+6.5%3A+Remote+Desktop+Client+disconnects+after+10+minutes" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F07%2F04%2Fwm-6-5-remote-desktop-client-disconnects-after-10-minutes%2F&amp;title=WM+6.5%3A+Remote+Desktop+Client+disconnects+after+10+minutes" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F07%2F04%2Fwm-6-5-remote-desktop-client-disconnects-after-10-minutes%2F&amp;title=WM+6.5%3A+Remote+Desktop+Client+disconnects+after+10+minutes" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F07%2F04%2Fwm-6-5-remote-desktop-client-disconnects-after-10-minutes%2F&amp;T=WM+6.5%3A+Remote+Desktop+Client+disconnects+after+10+minutes" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F07%2F04%2Fwm-6-5-remote-desktop-client-disconnects-after-10-minutes%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F07%2F04%2Fwm-6-5-remote-desktop-client-disconnects-after-10-minutes%2F&amp;t=WM+6.5%3A+Remote+Desktop+Client+disconnects+after+10+minutes" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.hjgode.de/wp/2011/07/04/wm-6-5-remote-desktop-client-disconnects-after-10-minutes/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Mobile Development: AutoHide Windows Mobile Device Center</title>
		<link>http://www.hjgode.de/wp/2011/05/13/mobile-development-autohide-windows-mobile-device-center/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mobile-development-autohide-windows-mobile-device-center</link>
		<comments>http://www.hjgode.de/wp/2011/05/13/mobile-development-autohide-windows-mobile-device-center/#comments</comments>
		<pubDate>Fri, 13 May 2011 12:54:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[autohide]]></category>
		<category><![CDATA[hide]]></category>
		<category><![CDATA[Windows 7]]></category>
		<category><![CDATA[Windows Mopbile Device Center]]></category>
		<category><![CDATA[WMDC]]></category>

		<guid isPermaLink="false">http://www.hjgode.de/wp/?p=1121</guid>
		<description><![CDATA[Do you like the Windows Mobile Device Center (WMDC) does popup every time you connect a mobile device to your (development) PC? If yes, don&#8217;t read further. The attached application (including VS 2008 C++ source code) simply watches the Window list for Windows Mobile Device Center and Windows Mobile Member Center. If a window is [...]]]></description>
			<content:encoded><![CDATA[<p>Do you like the Windows Mobile Device Center (WMDC) does popup every time you connect a mobile device to your (development) PC? If yes, don&#8217;t read further.</p>
<p><a rel="attachment wp-att-1134" href="http://www.hjgode.de/wp/2011/05/13/mobile-development-autohide-windows-mobile-device-center/wmdcstarted/"><img class="alignnone size-medium wp-image-1134" title="WMDCstarted" src="http://www.hjgode.de/wp/wp-content/uploads/2011/05/WMDCstarted-300x106.gif" alt="" width="300" height="106" /></a></p>
<p>The attached application (including VS 2008 C++ source code) simply watches the Window list for Windows Mobile Device Center and Windows Mobile Member Center. If a window is found, it will be hidden automatically. Very simple application.</p>
<p><a rel="attachment wp-att-1135" href="http://www.hjgode.de/wp/2011/05/13/mobile-development-autohide-windows-mobile-device-center/wmdc_contextmenu/"><img class="alignnone size-full wp-image-1135" title="WMDC_contextmenu" src="http://www.hjgode.de/wp/wp-content/uploads/2011/05/WMDC_contextmenu.gif" alt="" width="182" height="172" /></a></p>
<p>WMDCautohide will reside in the notification area of your Windows 7 PC after you started it. If Mobile Device Center has been found and hidden, there will be a short notification.</p>
<p><a rel="attachment wp-att-1136" href="http://www.hjgode.de/wp/2011/05/13/mobile-development-autohide-windows-mobile-device-center/wmdc_options/"><img class="alignnone size-full wp-image-1136" title="WMDC_options" src="http://www.hjgode.de/wp/wp-content/uploads/2011/05/WMDC_options.gif" alt="" width="239" height="166" /></a></p>
<p>You can right click the notification symbol and then either show/hide WMDC, show the main window, set the watch interval or exit the tool.</p>
<p><a rel="attachment wp-att-1123" href="http://www.hjgode.de/wp/2011/05/13/mobile-development-autohide-windows-mobile-device-center/wmdc_mainwin/"><img class="alignnone size-full wp-image-1123" title="WMDC_mainwin" src="http://www.hjgode.de/wp/wp-content/uploads/2011/05/WMDC_mainwin.gif" alt="" width="240" height="120" /></a> <a rel="attachment wp-att-1137" href="http://www.hjgode.de/wp/2011/05/13/mobile-development-autohide-windows-mobile-device-center/wmdc_mainwin_menu/"><img class="alignnone size-full wp-image-1137" title="WMDC_mainwin_menu" src="http://www.hjgode.de/wp/wp-content/uploads/2011/05/WMDC_mainwin_menu.gif" alt="" width="242" height="148" /></a></p>
<p>Download: <b>DOWNLOAD:</b><a href="http://www.hjgode.de/wp/wp-content/plugins/download-monitor/download.php?id=137" title="Downloaded 126 times">WMDC Source and Exe</a> -  (Hits: 126, size: 45.5 kB)</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Bookmark It</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F05%2F13%2Fmobile-development-autohide-windows-mobile-device-center%2F&amp;title=Mobile+Development%3A+AutoHide+Windows+Mobile+Device+Center" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F05%2F13%2Fmobile-development-autohide-windows-mobile-device-center%2F&amp;title=Mobile+Development%3A+AutoHide+Windows+Mobile+Device+Center" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F05%2F13%2Fmobile-development-autohide-windows-mobile-device-center%2F&amp;title=Mobile+Development%3A+AutoHide+Windows+Mobile+Device+Center" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F05%2F13%2Fmobile-development-autohide-windows-mobile-device-center%2F&amp;T=Mobile+Development%3A+AutoHide+Windows+Mobile+Device+Center" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F05%2F13%2Fmobile-development-autohide-windows-mobile-device-center%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F05%2F13%2Fmobile-development-autohide-windows-mobile-device-center%2F&amp;t=Mobile+Development%3A+AutoHide+Windows+Mobile+Device+Center" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.hjgode.de/wp/2011/05/13/mobile-development-autohide-windows-mobile-device-center/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mobile Development-PingAlert: watch your servers</title>
		<link>http://www.hjgode.de/wp/2011/03/01/mobile-development-pingalert-watch-your-servers-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mobile-development-pingalert-watch-your-servers-2</link>
		<comments>http://www.hjgode.de/wp/2011/03/01/mobile-development-pingalert-watch-your-servers-2/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 21:23:32 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[Hosts]]></category>
		<category><![CDATA[notification]]></category>
		<category><![CDATA[ping]]></category>
		<category><![CDATA[PingAlert]]></category>
		<category><![CDATA[schedule]]></category>
		<category><![CDATA[windows mobile]]></category>

		<guid isPermaLink="false">http://www.hjgode.de/wp/?p=1037</guid>
		<description><![CDATA[Three tools to peridically launch an app, ping a list of hosts and show a notification.]]></description>
			<content:encoded><![CDATA[<p>Are you looking for a tool that periodically pings a list of hosts? Here is a toolset that will reschedule a ping utilitiy. This ping utility pings a list of hosts and will create notifications if one or most hosts failed to answer.</p>
<p>I have done this toolset with three separate applications. The scheduler and the notification tool are written in C/C++ win32 API cause this API provided the best access to all the possibilities of the used functions. The user notification API is only supported with basic functionality by CF2. The CEUserNotification API is not supported by CF2 at all.</p>
<p>Although OpenNetCF provides an C# interface to the used APIs, I did not like to include all the unneeded stuff. On the other hand the scheduler is fast and small written in C/C++. With C# I had problems with the notification, especially for removing existing notifications and why should the main tool reside in memory just for showing the notification.</p>
<p>The ping tool is written in C# targeting Compact Framework 2. C# was the easiest to implement the GUI.</p>
<p>All source is available thru one Visual Studio 2008 solution. Yes, you can mix C/C++ and CF2 within one solution.</p>
<p><a rel="attachment wp-att-1039" href="http://www.hjgode.de/wp/2011/03/01/mobile-development-pingalert-watch-your-servers-2/vs2008solution/"><img class="alignnone size-full wp-image-1039" title="vs2008solution" src="http://www.hjgode.de/wp/wp-content/uploads/2011/03/vs2008solution.gif" alt="" width="203" height="123" /></a></p>
<p><a rel="attachment wp-att-1042" href="http://www.hjgode.de/wp/2011/03/01/mobile-development-pingalert-watch-your-servers-2/pingreport/"><img class="alignnone size-medium wp-image-1042" title="PingReport" src="http://www.hjgode.de/wp/wp-content/uploads/2011/03/PingReport-192x300.gif" alt="" width="192" height="300" /></a><a rel="attachment wp-att-1040" href="http://www.hjgode.de/wp/2011/03/01/mobile-development-pingalert-watch-your-servers-2/pingalert/"><img class="alignnone size-medium wp-image-1040" title="PingAlert" src="http://www.hjgode.de/wp/wp-content/uploads/2011/03/PingAlert-193x300.gif" alt="" width="193" height="300" /></a></p>
<p><span id="more-1037"></span>The code of the scheduler called PingAlertScheduler is based on my code <a href="http://www.hjgode.de/wp/2009/07/14/howto-run-an-application-periodically/" target="_blank">How to run an application periodically</a>. The code first clears all existing schedules of themself and then creates a new schedule for xx minutes in the future. If the scheduler is run from the schedule event, it will get a special arg transmitted &#8220;PingAlert&#8221;</p>
<pre lang="cpp">...
    TCHAR szExtApp[] = L"\\Windows\\PingAlert.exe";
    TCHAR szExtArg[] = L"pingsweep";
    TCHAR szScheduleArg[] = L"PingAlert";
...
    if (_wcsicmp(szScheduleArg, lpCmdLine)==0)
    {

        nclog(L"PingAlertScheduler: processing CmdLine=%s...\n", szScheduleArg);
        nclog(L"PingAlertScheduler: ...will wakeup again after reschedule...\n");
        //schedule next run
        if ( !FAILED(ScheduleRunApp(lpFileName, szScheduleArg)) )
        {
            //the worker application should be launched here!
            nclog(L"PingAlertScheduler: starting target app %s...\n", szExtApp);
            //is the target already running, then send WM_USER msg
            //else start a new instance with cmdLine="pingsweep"
            PROCESS_INFORMATION pi;
            if( CreateProcess(szExtApp,szExtArg,
                    NULL,NULL,NULL, 0, NULL,NULL,NULL,
                    &amp;pi)!=0)
            {
                nclog(L"PingAlertScheduler: CreateProcess for '%s' OK\n", szExtApp);
                CloseHandle(pi.hThread);
                CloseHandle(pi.hProcess);
            }
            else
                nclog(L"PingAlertScheduler: CreateProcess for '%s' FAILED: %u\n", szExtApp, GetLastError());
            //inform target
            //iRet=signalEvent();
            goto MainExit;
        }
        else{
            MessageBox(NULL, L"error in ScheduleRunApp", lpFileName, MB_TOPMOST | MB_SETFOREGROUND);
            nclog(L"PingAlertScheduler: error in ScheduleRunApp\n");
            iRet=-2;
            goto MainExit; //OK
        }
    }
</pre>
<p>This code also calls the reschedule to run itself again in the specified time interval.</p>
<pre lang="cpp">static HRESULT ScheduleRunApp(
  LPCTSTR szExeName,
  LPCTSTR szArgs)
{
    //do not add a schedule if actual date is 21.3.2003
    SYSTEMTIME t;
    memset(&amp;t, 0, sizeof(SYSTEMTIME));
    GetLocalTime(&amp;t);
    //check if the system clock is at factory default, device specific!
    if ( (t.wYear == 2003) &amp;&amp; (t.wMonth == 3) &amp;&amp; (t.wDay == 21) )
    {
        nclog(L"PingAlertScheduler: # no next run schedule as date is 21.03.2003!\n");
        return NOERROR;
    }

    HRESULT hr = S_OK;
    HANDLE hNotify = NULL;

    // set a CE_NOTIFICATION_TRIGGER
    CE_NOTIFICATION_TRIGGER notifTrigger;
    memset(&amp;notifTrigger, 0, sizeof(CE_NOTIFICATION_TRIGGER));
    notifTrigger.dwSize = sizeof(CE_NOTIFICATION_TRIGGER);

    // calculate time
    SYSTEMTIME st = {0};
    GetLocalTime(&amp;st);

    st = AddDiff(&amp;st, iScheduleInterval); //wake in x minutes
    wsprintf(str, L"Next run at: %02i.%02i.%02i %02i:%02i:%02i\n",
                                        st.wDay, st.wMonth , st.wYear,
                                        st.wHour , st.wMinute , st.wSecond );
    nclog(L"PingAlertScheduler: %s\n", str);

    notifTrigger.dwType = CNT_TIME;
    notifTrigger.stStartTime = st;

    // timer: execute an exe at specified time
    notifTrigger.lpszApplication = (LPTSTR)szExeName;
    notifTrigger.lpszArguments = (LPTSTR)szArgs;

    hNotify = CeSetUserNotificationEx(0, &amp;notifTrigger, NULL);
    // NULL because we do not care the action
    if (!hNotify) {
        hr = E_FAIL;
        nclog(L"PingAlertScheduler: CeSetUserNotificationEx FAILED...\n");
    } else {
        // close the handle as we do not need to use it further
        CloseHandle(hNotify);
        nclog(L"PingAlertScheduler: CeSetUserNotificationEx succeeded...\n");
    }
    return hr;
}
</pre>
<p>When PingAlertScheduler.exe ist started with &#8220;PingAlert&#8221; it will also launch the second application of the toolset called PingAlert. The Compact Framework application PingAlert can be started normally to manage the hosts list and it can be started with the argument &#8220;pingsweep&#8221; and then will automatically start to ping all hosts and then exits itself. If there were ping errors, PingAlert will create a HTML file with a report and then start the notification application of this toolset, which is called PingAlertToast.</p>
<p>How do we handle program arguments in compact framework. See program.cs:</p>
<pre lang="csharp">        [MTAThread]
        static void Main(String[] args)
        {
            Application.Run(new Form1(args));
        }
</pre>
<p>and then I change the form constructor code to receive the args string list:</p>
<pre lang="csharp">        public Form1(String[] args)
        {
            InitializeComponent();

            paSettings = new PingAlertSettings();
            readSettings();

            //get cmdLine
            String myArg="";
            if (args.Length == 1)
            {
                myArg = args[0];
                if (myArg.Equals("pingsweep", StringComparison.OrdinalIgnoreCase))
                    bRunAndQuit = true;
            }
</pre>
<p>At the end of pinging the host list, another boolean signals a timer tick event handler, that it is time to quit the app.</p>
<pre lang="csharp">        private void exitTimer1_Tick(object sender, EventArgs e)
        {
            //is it OK to quit now
            if(bQuitIsOK){
                exitTimer1.Enabled = false;
                this.Close();//exit form
            }
        }
</pre>
<p>At the end of the host pings, the third app, PingAlertToast will be started, if there was at least one error:</p>
<pre lang="csharp">...
            if (bte.qData._iCount == numberOfQueuedData)
            {
                //end html
                closeHTML();
                //write report file
                //System.IO.TextWriter stringWriter = new System.IO.StringWriter();
                try
                {
                    System.IO.TextWriter streamWriter = new System.IO.StreamWriter(szHtmlFile);
                    streamWriter.WriteLine(sbHTML);
                    streamWriter.Flush();
                    streamWriter.Close();
                }
                catch (Exception x)
                {
                    addLog("Exception in write HTML: " + x.Message);
                }

                //start notification
                showNotification();
                bQuitIsOK = true;
            }
...
</pre>
<p>Ah, what is this qData? To have the GUI still responsive during the ping process, the PingAlert uses a queue to add hosts to ping. The background process reads this queue and ping one by the other as long as there are hosts in the queue.</p>
<p>bgThread2.cs:</p>
<pre lang="csharp">...
    //The blocking function...
    if (_theQueue.Count &amp;gt; 0)
    {
        //dequeue one IP to ping
        lock (_theQueue.SyncRoot)// syncedCollection.SyncRoot)
        {
            _qData = (queueData)_theQueue.Dequeue();// get object from queue
        }

        //System.Net.IPAddress ip;
        try
        {
            _qData.IP = System.Net.Dns.Resolve(_qData.sHost).AddressList[0];
            iPreplies = myPing.PingQdata(ref _qData);
        }
...
</pre>
<p>To be able to have some extra information with the hosts I use a class called QueueData which will hold the hosts to ping, the number of ping retries etc.. You can add hosts using there DNS name or there IP address.</p>
<p><a rel="attachment wp-att-1040" href="http://www.hjgode.de/wp/2011/03/01/mobile-development-pingalert-watch-your-servers-2/pingalert/"><img class="alignnone size-medium wp-image-1040" title="PingAlert" src="http://www.hjgode.de/wp/wp-content/uploads/2011/03/PingAlert-193x300.gif" alt="" width="193" height="300" /></a></p>
<p>How can you you disable the schedule? As you know, PingAlertScheduler can be launched with different args. If it is launched without args, it will create a new schedule and terminates itself. If it is launched with &#8220;PingAlert&#8221; it will reschedule itself and launch PingAlert with the arg &#8220;pingsweep&#8221;. If it is launched with the argument &#8220;clear&#8221;, it will clear all existing schedules to PingAlertScheduler.</p>
<p>So, if you want to stop the scheduling, you have to launch PingAlertScheduler with the argument &#8220;clear&#8221;. To do so, you can simply use the button &#8220;Clear Schedule&#8221; in the main PingAlert application.</p>
<p>If you need to start the schedule, you use the button &#8220;Schedule&#8221;. It will simply launch PingAlertSchedule without an argument.</p>
<p>Now to the last of the trio, PingAlertToast. It is written in C/C++ and creates a user notification. You will get a nice symbol in the taskbar and if you click (tap) it, it will show the notification. This is only a reminder notification signaling that some ping failed.</p>
<p><a rel="attachment wp-att-1041" href="http://www.hjgode.de/wp/2011/03/01/mobile-development-pingalert-watch-your-servers-2/pingalerttoast/"><img class="alignnone size-medium wp-image-1041" title="PingAlertToast" src="http://www.hjgode.de/wp/wp-content/uploads/2011/03/PingAlertToast-193x300.gif" alt="" width="193" height="300" /></a></p>
<p>If you dont like to keep the notification, just tap (Dismiss). To only hide it tap on (Hide). To get the notification back on screen, tap the small symbol in the taskbar.</p>
<p>Within the notification text is a link which should open your internet browser on the device and that shows the report.</p>
<p><a rel="attachment wp-att-1042" href="http://www.hjgode.de/wp/2011/03/01/mobile-development-pingalert-watch-your-servers-2/pingreport/"><img class="alignnone size-medium wp-image-1042" title="PingReport" src="http://www.hjgode.de/wp/wp-content/uploads/2011/03/PingReport-192x300.gif" alt="" width="192" height="300" /></a></p>
<p>The notification API is very strong and enables you to configure nearly everything of the notification. As the API is not fully available in Compact Framework, I did code PingAlertToast in C/C++. Here is the main part creating the notification:</p>
<pre lang="cpp">int showNotification(TCHAR* szText){
	LRESULT lRes=0;
    // This code will add an SHNotification notificaion
    SHNOTIFICATIONDATA sn  = g_shNotificationData;
    sn.cbStruct = sizeof(sn);
    sn.dwID = g_NotificationID;
    sn.npPriority = SHNP_INFORM;
    sn.csDuration = -1;
    sn.hicon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_SAMPLEICON));
    sn.clsid = guidNotifyApp;
    sn.grfFlags = 0;
    sn.pszTitle = TEXT("PingAlert");
	sn.pszHTML = TEXT("&lt;html&gt;&lt;body&gt;There was at least one error. Please click &lt;a href=\"file:///Windows\\PingAlertReport.html\"&gt;PingAlert Report&lt;/a&gt; for more details.&lt;/body&gt;&lt;/html&gt;");
    sn.rgskn[0].pszTitle = TEXT("Dismiss");
    sn.rgskn[0].skc.wpCmd = g_dwNotificationCmdID1;
	sn.rgskn[0].skc.grfFlags = NOTIF_SOFTKEY_FLAGS_STAYOPEN;
    sn.rgskn[1].pszTitle = TEXT("Hide");
    sn.rgskn[1].skc.wpCmd = g_dwNotificationCmdID2;
	sn.rgskn[1].skc.grfFlags = NOTIF_SOFTKEY_FLAGS_HIDE;
	sn.hwndSink=g_hWnd;
    //Add the notification to the tray
    lRes = SHNotificationAdd(&amp;sn);

    return lRes;
}
</pre>
<p>Take a deeper look at PingAlertToast.cpp to see more details on handling menu taps etc.</p>
<p>Not to forget, the settings are persistent in the registry at HKLM\Software\PingAlert</p>
<pre>REGEDIT4

[HKEY_LOCAL_MACHINE\Software\PingAlert]
"Log2File"=dword:00000000
"TimeInterval"=dword:0000000F
"Hosts"=hex(7):\
67,6F,6F,67,6C,65,2E,63,6F,6D,00,31,39,32,2E,31,36,38,2E,31,32,38,2E,35,\
00,73,6D,61,72,74,00,00
</pre>
<ul>
<li>Log2File specifies if you like to have a log file for PingAlert&#8217;s action in \PingAlert.Log.txt.</li>
<li>TimeInterval specifies the interval between reschedules.</li>
<li>Hosts is a Multi_SZ registry key holding the list of hosts to ping.</li>
</ul>
<hr />
<p><a href="http://code.google.com/p/win-mobile-code/source/browse/#svn%2Ftrunk%2FPingAlert" target="_blank">Code at code.google.com</a></p>
<p>Executable set (copy all into \Windows dir on the device): <b>DOWNLOAD:</b><a href="http://www.hjgode.de/wp/wp-content/plugins/download-monitor/download.php?id=131" title="Downloaded 201 times">PingAlert Executables Set</a> - PingAlertScheduler, PingAlert and PingAlertToast (Hits: 201, size: 24.02 kB)</p>
<p>Installable CAB file (will place a link in your program folder):  New version 1.1 4. March 2011: <b>DOWNLOAD:</b><a href="http://www.hjgode.de/wp/wp-content/plugins/download-monitor/download.php?id=133" title="Downloaded 56 times">PingAlert Setup CAB v1.1</a> - fixed minor bugs (Hits: 56, size: 24.57 kB)</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Bookmark It</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F03%2F01%2Fmobile-development-pingalert-watch-your-servers-2%2F&amp;title=Mobile+Development-PingAlert%3A+watch+your+servers" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F03%2F01%2Fmobile-development-pingalert-watch-your-servers-2%2F&amp;title=Mobile+Development-PingAlert%3A+watch+your+servers" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F03%2F01%2Fmobile-development-pingalert-watch-your-servers-2%2F&amp;title=Mobile+Development-PingAlert%3A+watch+your+servers" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F03%2F01%2Fmobile-development-pingalert-watch-your-servers-2%2F&amp;T=Mobile+Development-PingAlert%3A+watch+your+servers" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F03%2F01%2Fmobile-development-pingalert-watch-your-servers-2%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2011%2F03%2F01%2Fmobile-development-pingalert-watch-your-servers-2%2F&amp;t=Mobile+Development-PingAlert%3A+watch+your+servers" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.hjgode.de/wp/2011/03/01/mobile-development-pingalert-watch-your-servers-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mobile Development: a native remote desktop client (rdesktop port win32)</title>
		<link>http://www.hjgode.de/wp/2010/11/20/mobile-development-a-native-remote-desktop-client-rdesktop-port-win32/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mobile-development-a-native-remote-desktop-client-rdesktop-port-win32</link>
		<comments>http://www.hjgode.de/wp/2010/11/20/mobile-development-a-native-remote-desktop-client-rdesktop-port-win32/#comments</comments>
		<pubDate>Sat, 20 Nov 2010 06:51:47 +0000</pubDate>
		<dc:creator>josef</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Int*rm*c]]></category>
		<category><![CDATA[kiosk mode]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[mstsc]]></category>
		<category><![CDATA[rdesktop]]></category>
		<category><![CDATA[rdesktop-ce]]></category>
		<category><![CDATA[rdp]]></category>
		<category><![CDATA[rdp_autologin]]></category>
		<category><![CDATA[remote desktop mobile]]></category>
		<category><![CDATA[terminal service client]]></category>
		<category><![CDATA[tsc]]></category>
		<category><![CDATA[win32]]></category>
		<category><![CDATA[windows mobile]]></category>
		<category><![CDATA[wpctsc.exe]]></category>

		<guid isPermaLink="false">http://www.hjgode.de/wp/?p=899</guid>
		<description><![CDATA[A native rdesktop port for windows ce and windows mobile to replace Remote Desktop Mobile]]></description>
			<content:encoded><![CDATA[<p><span style="font-size: medium;"><strong>The famous <a href="http://sourceforge.net/projects/rdesktop/" target="_blank">rdesktop</a> running natively on windows ce and windows mobile</strong></span></p>
<h2>Intro and Background</h2>
<p>Some times ago I found that <a href="http://osdir.com/ml/network.rdesktop.user/2006-04/msg00004.html">message of Jay Sorg</a> and retrieved a copy of his code for a native <a href="http://sourceforge.net/projects/rdesktop/" target="_blank">rdesktop</a> win32 version.  I played a little and got the code compile with Visual Studio 2005 with the Windows Mobile SDK.</p>
<p>I tried to implement windows clipboard support to enhance the transfer of texts between the client and server, but unfortunately I was not successful yet. Hopefully someone jumps in and helps enhancing the code and adds some features.</p>
<p>Rdesktop is open source and you can go with the wince implementation here, but if it does not work for you, you have either change the code yourself (and publish it) or find someone that is able to do for you.</p>
<p>There is a template uiports/xxxwin.c in the actual rdesktop source you can use as a starter to compile the actual rdesktop version for windows mobile if you manage to get all the dependencies to work. If you success, forget this post and go with this version (maybe you leave me a note?).</p>
<p><a rel="attachment wp-att-900" href="http://www.hjgode.de/wp/2010/11/20/mobile-development-a-native-remote-desktop-client-rdesktop-port-win32/screenshot01/"><img class="alignnone size-medium wp-image-900" title="ScreenShot01" src="http://www.hjgode.de/wp/wp-content/uploads/2010/11/ScreenShot01-225x300.gif" alt="" width="225" height="300" /></a></p>
<h2>Why another Remote Desktop/Terminal Server Client?</h2>
<p><span id="more-899"></span>The Windows Mobile Remote Desktop Client (or Remote Desktop Mobile, RDM) lacks some useful features available in the Windows CE version or the Desktop Windows version:</p>
<ul>
<li>No automated login</li>
<li>No kiosk mode</li>
<li>Function keys are not sent to server</li>
<li>&#8230;</li>
</ul>
<p>The first item is essential if you like to start a Terminal Server session without user intervention.</p>
<p>The second item is important for using RDM in a production environment.</p>
<p>The third item is useful to run applications on the Terminal Server (TS) that use Function keys.</p>
<h2>Commercial RDM</h2>
<p>There are some commercial remote desktop clients available for windows mobile:</p>
<ul>
<li><a href="http://www.mochasoft.dk/rd.htm">Mochasoft RDP client</a><br />
 &#8220;Windows 200x servers and terminal servers are not supported, as to a Microsoft patent license.&#8221;</li>
<li><a href="http://www.zatelnet.com/zadesktop/main.php">zaDesktop</a><br />
 This is currently in an early state.</li>
<li><a href="http://forum.xda-developers.com/showthread.php?t=292895">RDP Finster</a><br />
 Not really clear where this comes from. </li>
</ul>
<p>I assume some of the commercials are either using mstscax or rdesktop code. Some time ago MS published the <a href="http://msdn.microsoft.com/en-us/library/cc240445%28PROT.10%29.aspx">RDP documentation</a>. Maybe the commercial apps did start from there. Going with the TSC COM library mststcax would be great, but who has the doc for this? For desktop PCs it is documented but not for windows mobile. If someone has a doc to this leave me a note. Then we can start to write a TSC around this library.</p>
<p>There are also some rewritten TSC for the desktop not using mstscax. One is called ProperJavaRDP and maybe a good starting point to rewrite a dotnet based native TSC for windows mobile.</p>
<h2>Usage of the free opensource rdesktop-ce</h2>
<p>You can start winrdesktop on windows mobile either with an ini file or with command line arguments:</p>
<h3>Sample winrdesktop.ini</h3>
<p>(place either in program dir or in root)</p>
<pre>[main]
server=<em>192.168.128.5</em>
port=<em>3389</em>
username=<em>YourUserName</em>
password=<em>YourPassword</em>
bpp=<em>16</em>
geometry=<em>1024x768</em>
#fullscreen
</pre>
<p>server : provide the server IP or DNS host name<br />
 port : provide the port to use for RDP, usually 3389<br />
 username : provide the login user name for the terminal client session<br />
 password : provide the password of the user<br />
 bpp : define the bits per pixel to be used (number of colors per pixel)<br />
 geometry : define the size of the remote desktop window width x height An application to be used on windows mobile devices should match the screen size of the device. For example 240&#215;320 (QVGA). Otherwise the user has to scroll the window to get access to all of the remote screen.<br />
 fullscreen : <span style="text-decoration: line-through;">currently not supported</span></p>
<hr />
<h3>UPDATE 23. nov 2010:</h3>
<p>fullscreen now supported. Fullscreen will switch rdesktop to not show a caption and no menu bar. If geometry matches the device&#8217;s screen size, there will also be no scrollbars.</p>
<p><a rel="attachment wp-att-914" href="http://www.hjgode.de/wp/2010/11/20/mobile-development-a-native-remote-desktop-client-rdesktop-port-win32/screenshotfullscreen/"><img class="alignnone size-medium wp-image-914" title="ScreenShotFullscreen" src="http://www.hjgode.de/wp/wp-content/uploads/2010/11/ScreenShotFullscreen-225x300.gif" alt="" width="225" height="300" /></a></p>
<p>This screenshot was taken of an app I wrote running on a Windows 2003 server of a QVGA device with following winrdesktop.ini:</p>
<pre>[main]
server=192.168.128.5
port=3389
username=rdesktop
password=rdesktop
bpp=16
geometry=240x320
fullscreen
</pre>
<hr />
<h2>Rdesktop usage</h2>
<h3>Command line</h3>
<pre>WinRDesktop [-g widthxheight] [-t port] [-a bpp]
    [-f] [-u username] [-p password] [-d domain]
    [-s shell] [-c working directory] [-n host name]
    server-name-or-ip
</pre>
<p>options are the same as in winrdesktop.ini plus:</p>
<pre>-d <em>domain</em> : specify the domain of the user login
-s <em>shell</em> : define a shell to use on TSC
-c <em>working directory</em> : define a working directory for the session
-n <em>host name</em> : specify the host name to use for the client (visible on TSC)
</pre>
<h2>Restrictions of current code</h2>
<p>See <a href="http://code.google.com/p/rdesktop-ce/issues/list?thanks=2&amp;ts=1290249303" target="_blank">googlecode issues</a> for a list of known restrictions.</p>
<h2>Downloads</h2>
<p><a href="http://code.google.com/p/rdesktop-ce/downloads/list">Windows Mobile Executable and INI sample file at googlecode</a><br />
 Source code: see <a href="http://code.google.com/p/rdesktop-ce/source/checkout">googlecode</a></p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Bookmark It</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F11%2F20%2Fmobile-development-a-native-remote-desktop-client-rdesktop-port-win32%2F&amp;title=Mobile+Development%3A+a+native+remote+desktop+client+%28rdesktop+port+win32%29" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F11%2F20%2Fmobile-development-a-native-remote-desktop-client-rdesktop-port-win32%2F&amp;title=Mobile+Development%3A+a+native+remote+desktop+client+%28rdesktop+port+win32%29" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F11%2F20%2Fmobile-development-a-native-remote-desktop-client-rdesktop-port-win32%2F&amp;title=Mobile+Development%3A+a+native+remote+desktop+client+%28rdesktop+port+win32%29" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F11%2F20%2Fmobile-development-a-native-remote-desktop-client-rdesktop-port-win32%2F&amp;T=Mobile+Development%3A+a+native+remote+desktop+client+%28rdesktop+port+win32%29" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F11%2F20%2Fmobile-development-a-native-remote-desktop-client-rdesktop-port-win32%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F11%2F20%2Fmobile-development-a-native-remote-desktop-client-rdesktop-port-win32%2F&amp;t=Mobile+Development%3A+a+native+remote+desktop+client+%28rdesktop+port+win32%29" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.hjgode.de/wp/2010/11/20/mobile-development-a-native-remote-desktop-client-rdesktop-port-win32/feed/</wfw:commentRss>
		<slash:comments>39</slash:comments>
		</item>
		<item>
		<title>Mobile Development: Disable Windows Mobile 6.5 Start and Close Button</title>
		<link>http://www.hjgode.de/wp/2010/11/18/mobile-development-disable-windows-mobile-6-5-start-and-close-button/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mobile-development-disable-windows-mobile-6-5-start-and-close-button</link>
		<comments>http://www.hjgode.de/wp/2010/11/18/mobile-development-disable-windows-mobile-6-5-start-and-close-button/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 13:03:47 +0000</pubDate>
		<dc:creator>josef</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[kiosk mode]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[6.5.3]]></category>
		<category><![CDATA[Close Button]]></category>
		<category><![CDATA[DotNet]]></category>
		<category><![CDATA[hook]]></category>
		<category><![CDATA[sender-as-rectangle-windows-ce]]></category>
		<category><![CDATA[Start Button]]></category>
		<category><![CDATA[Subclassing]]></category>
		<category><![CDATA[taskbar]]></category>
		<category><![CDATA[windows mobile]]></category>
		<category><![CDATA[WM65]]></category>

		<guid isPermaLink="false">http://www.hjgode.de/wp/?p=888</guid>
		<description><![CDATA[Windows Mobile 6.5.3. Class to subclass menu toolbar to disable Start and Close button clicks.]]></description>
			<content:encoded><![CDATA[<p>Hello</p>
<p>here is one other way to write a kios mode .NET application using a technique called SubClassing. The idea was born by a comment of redwolf2222 on this blog about how to <a href="http://www.hjgode.de/wp/2010/10/11/windows-mobile-hide-startbutton-in-winmo-6-5-x/">Hide Start and Close buttons on Windows Mobile 6.5 devices</a>. Redwolf2222 also provided a code snippet. Unfortunately it was incomplete and so I wrote my own class.</p>
<p><strong>Disable clicks on Start and Close button</strong></p>
<p>The demo project shows one dialog with two check boxes and you can easily test the function. If &#8220;StartButton Disabled&#8221; or &#8220;Close Button disabled&#8221; is checked, you cannot &#8216;click&#8217; the corresponding button any more:</p>
<p><a rel="attachment wp-att-889" href="http://www.hjgode.de/wp/2010/11/18/mobile-development-disable-windows-mobile-6-5-start-and-close-button/startbuttoncontrolwm65_2/"><img class="alignnone size-medium wp-image-889" title="StartButtonControlWM65" src="http://www.hjgode.de/wp/wp-content/uploads/2010/11/StartButtonControlWM65_2-225x300.gif" alt="" width="225" height="300" /></a></p>
<p>You still &#8216;click&#8217; the buttons but the subclassed window will not &#8216;execute&#8217; your click. The buttons are part of the toolbar32 window which is a child of the menu_worker window. So first we have to follow the window tree.</p>
<p><strong>Find the right window</strong></p>
<pre escaped="true" line="1" lang="csharp">/// &lt;summary&gt;
/// SubClassing: Install the wndproc hook
/// &lt;/summary&gt;
/// &lt;returns&gt;&lt;/returns&gt;
private bool hookWindow()
{
    //find taskbar
    IntPtr hWndTaskbar = FindWindow("HHTaskbar", IntPtr.Zero);
    if (hWndTaskbar == IntPtr.Zero)
        return false;
    //enable the taskbar, not realy necessary
    EnableWindow(hWndTaskbar, true);
    //already installed?
    if (oldWndProc == IntPtr.Zero)
    {
        //find the menu_worker window
        IntPtr hwndMenu_Worker = FindWindow("menu_worker", IntPtr.Zero);
        if (hwndMenu_Worker != IntPtr.Zero)
        {
            //get the child window which has the buttons on it
            IntPtr hwndToolbar = GetWindow(hwndMenu_Worker, GetWindow_Cmd.GW_CHILD);
            if (hwndToolbar != IntPtr.Zero)
            {
                _mHwnd = hwndToolbar;       //store to remember
                SubclassHWnd(hwndToolbar);  //subclass the wndproc
            }
        }
    }
    return true;
}
</pre>
<p><strong>Subclassing</strong></p>
<p>Now, as we have the window handle, the subclassing can be started:<br />
 <span id="more-888"></span></p>
<pre escaped="true" line="1" lang="csharp">private void SubclassHWnd(IntPtr hWnd)
{
    // hWnd is the window you want to subclass..., create a new
    // delegate for the new wndproc
    newWndProc = new Win32WndProc(MyWndProc);
    // subclass
    oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, newWndProc);
}
</pre>
<p>The installation of the &#8216;hook&#8217; is very simple. Just use SetWindowLong with the new window procedure. The old, original window procedure is saved for later use. We need it for example to call it for clicks outside the buttons and for all messages we don&#8217;t care about.</p>
<p>The &#8216;hook&#8217; or better the redirection will remain active until you install the old window procedure. So your device&#8217;s start and close button will not &#8216;work&#8217; as long as the hook is in place.</p>
<p><strong>The new window procedure</strong></p>
<pre escaped="true" line="1" lang="csharp">// this is the new wndproc, just show a messagebox on left button down:
private IntPtr MyWndProc(IntPtr hWnd, int msg, int wParam, int lParam)
{
    //is this a message for us?
    if (((msg == (int)WM_LBUTTONDOWN) || (msg == (int)WM_LBUTTONUP)) &amp;&amp; (this._mIsStartButtonDisabled || this._mIsCloseButtonDisabled) )
    {
        int x = ((int)lParam) &amp; 0xFFFF;
        int y = ((int)lParam) &gt;&gt; 16;

        bool isVGA;
        bool isQVGA;
        using (System.Windows.Forms.Control detector = new System.Windows.Forms.Control())
        {
            using (System.Drawing.Graphics gr = detector.CreateGraphics())
            {
                isVGA = gr.DpiY == 192;
                isQVGA = gr.DpiY == 96;
            }
        }

        RECT rect;
        GetWindowRect(hWnd, out rect); //get the rectangle of the menu_bar

        int width = Math.Max(rect.Left, rect.Right) - Math.Min(rect.Left, rect.Right);
        int height = Math.Max(rect.Bottom, rect.Top) - Math.Min(rect.Bottom, rect.Top);

        //width values are assumed
        int buttonWidth = (isQVGA | isVGA) ? 92 : 46;
        int buttonHeight = height; //(isQVGA | isVGA) ? 72 : 36;

        System.Drawing.Rectangle rectStartButton = new System.Drawing.Rectangle(0, 0, buttonWidth, buttonHeight);
        System.Drawing.Rectangle rectCloseButton = new System.Drawing.Rectangle(width - buttonWidth, 0, buttonWidth, buttonHeight);

        //check if enabled and click is inside the start or close button rectangle
        if(this._mIsStartButtonDisabled &amp;&amp; rectStartButton.Contains(x, y))
            return IntPtr.Zero;
        if (this._mIsCloseButtonDisabled &amp;&amp; rectCloseButton.Contains(x, y))
            return IntPtr.Zero;

        //if both are false, we have to provide the click to windows
        return CallWindowProc(oldWndProc, hWnd, msg, wParam, lParam);
    }
    else
        return CallWindowProc(oldWndProc, hWnd, msg, wParam, lParam);
}
</pre>
<p>Subclassing the window means that we redirect the window message procedure of the found window to our own, custom window procedure. This new procedure checks for WM_LBUTTONDOWN and WM_LBUTTONUP messages. Then the click position is checked and discarded if within the rectangle area of the Start and/or Close button. If the position is outside the calculated rectangles, the original window procedure is called.</p>
<p><strong>The demo code</strong></p>
<pre escaped="true" line="1" lang="csharp">public partial class StartButtonControl : Form
{
    StartButtonWM65.hwndutils _hwndutils = new StartButtonWM65.hwndutils();
    private bool _bInitializing = true;
    public StartButtonControl()
    {
        InitializeComponent();
        this.chkDisableStartButton.Checked = this._hwndutils.StartButtonDisabled;
        _bInitializing = false;
    }

    private void chkDisableStartButton_CheckStateChanged(object sender, EventArgs e)
    {
        if (_bInitializing)
            return;
        this._hwndutils.StartButtonDisabled = chkDisableStartButton.Checked;
    }

    private void mnuExit_Click(object sender, EventArgs e)
    {
        _hwndutils.Dispose();
        Application.Exit();
    }

    private void StartButtonControl_Closing(object sender, CancelEventArgs e)
    {
        _hwndutils.Dispose();
        Application.Exit();
    }

    private void chkCloseButton_CheckStateChanged(object sender, EventArgs e)
    {
        if (_bInitializing)
            return;
        this._hwndutils.CloseButtonDisabled = chkCloseButton.Checked;
    }
}
</pre>
<p>As you see, the usage of the class hwndutils is very simple. Dont forget to Dispose the hwndutils object before you exit your app.</p>
<p><strong>Downloads</strong><br />
 Visual Studion 2008 solution with demo project targeting Windows Mobile 6 SDK: <b>DOWNLOAD:</b><a href="http://www.hjgode.de/wp/wp-content/plugins/download-monitor/download.php?id=128" title="Downloaded 834 times">StartButtonHookWM65 VS2008 source code and demo project</a> -  (Hits: 834, size: 18.53 kB)</p>
<p>Thanks to redwolf2222 for the great idea.</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Bookmark It</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F11%2F18%2Fmobile-development-disable-windows-mobile-6-5-start-and-close-button%2F&amp;title=Mobile+Development%3A+Disable+Windows+Mobile+6.5+Start+and+Close+Button" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F11%2F18%2Fmobile-development-disable-windows-mobile-6-5-start-and-close-button%2F&amp;title=Mobile+Development%3A+Disable+Windows+Mobile+6.5+Start+and+Close+Button" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F11%2F18%2Fmobile-development-disable-windows-mobile-6-5-start-and-close-button%2F&amp;title=Mobile+Development%3A+Disable+Windows+Mobile+6.5+Start+and+Close+Button" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F11%2F18%2Fmobile-development-disable-windows-mobile-6-5-start-and-close-button%2F&amp;T=Mobile+Development%3A+Disable+Windows+Mobile+6.5+Start+and+Close+Button" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F11%2F18%2Fmobile-development-disable-windows-mobile-6-5-start-and-close-button%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F11%2F18%2Fmobile-development-disable-windows-mobile-6-5-start-and-close-button%2F&amp;t=Mobile+Development%3A+Disable+Windows+Mobile+6.5+Start+and+Close+Button" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.hjgode.de/wp/2010/11/18/mobile-development-disable-windows-mobile-6-5-start-and-close-button/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mobile Development: another keyboard hooking tool: keyToggleCtrl</title>
		<link>http://www.hjgode.de/wp/2010/08/01/mobile-development-another-keyboard-hooking-tool-keytogglectrl/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mobile-development-another-keyboard-hooking-tool-keytogglectrl</link>
		<comments>http://www.hjgode.de/wp/2010/08/01/mobile-development-another-keyboard-hooking-tool-keytogglectrl/#comments</comments>
		<pubDate>Sun, 01 Aug 2010 14:41:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Int*rm*c]]></category>
		<category><![CDATA[Keyboard]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Utilities]]></category>

		<guid isPermaLink="false">http://www.hjgode.de/wp/?p=732</guid>
		<description><![CDATA[This is again a keyToggle application. An application that works in background using a keyboard hook. After keyToggleCtrl has been started, it will install a keyboard hook and watches the keyboard messages for the appearance of the toggle, or as I call it, the sticky key. When the sticky key is detected, keyToggle Ctrl will [...]]]></description>
			<content:encoded><![CDATA[<p>This is again a keyToggle application. An application that works in background using a keyboard hook.</p>
<p>After keyToggleCtrl has been started, it will install a keyboard hook and watches the keyboard messages for the appearance of the toggle, or as I call it, the sticky key.</p>
<p>When the sticky key is detected, keyToggle Ctrl will watch the keyboard messages for the keys listed in a keytable (default is watching for presses of the number keys 0 to 9). If the pressed key matches a key in the keytable, keytogglectrl will remove the message from the window message queue and instead send the key found in CharTable with Control pressed before and released after the replaced key.</p>
<p>For example, you press the sticky key, the LED defined by LedID should light and if you then press 0, keyToggleCtrl will send instead Control+C to the active application.</p>
<h4>KeyTest3AK IMAGE</h4>
<p><a rel="attachment wp-att-733" href="http://www.hjgode.de/wp/2010/08/01/mobile-development-another-keyboard-hooking-tool-keytogglectrl/keytest3ak-2/"><img class="alignnone size-medium wp-image-733" title="KeyTest3AK" src="http://www.hjgode.de/wp/wp-content/uploads/2010/08/KeyTest3AK-227x300.gif" alt="" width="227" height="300" /></a></p>
<p><span id="more-732"></span>Without keyToggleCtrl you have to show the SoftwareInputPanel (SIP), tap the [Ctrl] button and then the &#8216;C&#8217; and then hide the SIP. With keyToggleCtrl you can just use the hardware keyboard and have Ctrl+C (Copy to Clipboard) and Ctrl+V (Paste from Clipboard) at your fingers.</p>
<p>After you started keyToggleControl you will only notice a small symbol on the Today Screen of your device. If you tap the symbol, you have the chance to end the keyboard hook and the keyToggleCtrl application.</p>
<h4>KeyToggleCtrl Today Screen</h4>
<p><a rel="attachment wp-att-734" href="http://www.hjgode.de/wp/2010/08/01/mobile-development-another-keyboard-hooking-tool-keytogglectrl/today-keytogglectrl/"><img class="alignnone size-medium wp-image-734" title="today-keyToggleCtrl" src="http://www.hjgode.de/wp/wp-content/uploads/2010/08/today-keyToggleCtrl-227x300.gif" alt="" width="227" height="300" /></a></p>
<p><span style="text-decoration: underline;">Default key mapping with use of -writereg:</span></p>
<pre style="padding-left: 30px;">Keytable 0 0x30 -&gt; 0x0043, '0 -&gt; 'C'
Keytable 1 0x31 -&gt; 0x0058, '1 -&gt; 'X'
Keytable 2 0x32 -&gt; 0x0057, '2 -&gt; 'W'
Keytable 3 0x33 -&gt; 0x0054, '3 -&gt; 'T'
Keytable 4 0x34 -&gt; 0x0045, '4 -&gt; 'E'
Keytable 5 0x35 -&gt; 0x0058, '5 -&gt; 'X'
Keytable 6 0x36 -&gt; 0x0057, '6 -&gt; 'W'
Keytable 7 0x37 -&gt; 0x0054, '7 -&gt; 'T'
Keytable 8 0x38 -&gt; 0x0045, '8 -&gt; 'E'
Keytable 9 0x39 -&gt; 0x0056, '9 -&gt; 'V'</pre>
<p>These values are the same as ANSI codes or VK_ values found in winuser.h.</p>
<p><br class="spacer_" /></p>
<ul>
<li>Default sticky key is VK_PERIOD</li>
<li>Sticky timeout is 3 seconds</li>
<li>Autofallback is 0</li>
<li>LedID default is 1</li>
</ul>
<p><br class="spacer_" /></p>
<p>To find a usable LedID you may use another tool called LED_Control. Funny, that the vibrate motor is also controlled with the same LED API calls.</p>
<h4>LED_control IMAGE</h4>
<div><a rel="attachment wp-att-735" href="http://www.hjgode.de/wp/2010/08/01/mobile-development-another-keyboard-hooking-tool-keytogglectrl/led_control/"><img class="alignnone size-medium wp-image-735" title="LED_control" src="http://www.hjgode.de/wp/wp-content/uploads/2010/08/LED_control-227x300.gif" alt="" width="227" height="300" /></a></div>
<h4>LED_control DOWNLOAD</h4>
<div><b>DOWNLOAD:</b><a href="http://www.hjgode.de/wp/wp-content/plugins/download-monitor/download.php?id=112" title="Downloaded 275 times">LED_Control</a> - A tool to test the LED API on Windows Mobile devices (Hits: 275, size: 11.5 kB)</div>
<h4>keyToggleCtrl Downloads</h4>
<p>VS2005/WM6 SDK source code solution: <b>DOWNLOAD:</b><a href="http://www.hjgode.de/wp/wp-content/plugins/download-monitor/download.php?id=113" title="Downloaded 324 times">keyToggleCtrl VS2005 Source (WM6 SDK)</a> -  (Hits: 324, size: 42.77 kB)</p>
<p>keyToggleCtrl installation CAB file: <b>DOWNLOAD:</b><a href="http://www.hjgode.de/wp/wp-content/plugins/download-monitor/download.php?id=114" title="Downloaded 259 times">keyToggleCtrl Installer CAB</a> - Installs keyToggleCtrl with default values onto your Windows Mobile device. It is installed to Programs and StartUp (Hits: 259, size: 22.59 kB)</p>
<p><br class="spacer_" /></p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Bookmark It</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F08%2F01%2Fmobile-development-another-keyboard-hooking-tool-keytogglectrl%2F&amp;title=Mobile+Development%3A+another+keyboard+hooking+tool%3A+keyToggleCtrl" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F08%2F01%2Fmobile-development-another-keyboard-hooking-tool-keytogglectrl%2F&amp;title=Mobile+Development%3A+another+keyboard+hooking+tool%3A+keyToggleCtrl" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F08%2F01%2Fmobile-development-another-keyboard-hooking-tool-keytogglectrl%2F&amp;title=Mobile+Development%3A+another+keyboard+hooking+tool%3A+keyToggleCtrl" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F08%2F01%2Fmobile-development-another-keyboard-hooking-tool-keytogglectrl%2F&amp;T=Mobile+Development%3A+another+keyboard+hooking+tool%3A+keyToggleCtrl" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F08%2F01%2Fmobile-development-another-keyboard-hooking-tool-keytogglectrl%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F08%2F01%2Fmobile-development-another-keyboard-hooking-tool-keytogglectrl%2F&amp;t=Mobile+Development%3A+another+keyboard+hooking+tool%3A+keyToggleCtrl" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.hjgode.de/wp/2010/08/01/mobile-development-another-keyboard-hooking-tool-keytogglectrl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress Plugin to feed CodeProject Technical Blogs</title>
		<link>http://www.hjgode.de/wp/2010/03/01/wordpress-plugin-to-feed-codeproject-technical-blogs/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wordpress-plugin-to-feed-codeproject-technical-blogs</link>
		<comments>http://www.hjgode.de/wp/2010/03/01/wordpress-plugin-to-feed-codeproject-technical-blogs/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 14:01:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[CodeProject Technical Blogs]]></category>
		<category><![CDATA[codeprojectfeeder]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.hjgode.de/wp/?p=366</guid>
		<description><![CDATA[A WordPress plugin for CodeProject Technical Blogs feeding.]]></description>
			<content:encoded><![CDATA[<h1><strong>CodeProjectFeeder</strong></h1>
<p>Update 3. sept. 2011:<br />
Fixed a bug according to WeBiscuit&#8217;s post at the <a title="Codeproject CodeprojectFeederPlugin" href="http://www.codeproject.com/Articles/62235/Wordpress-Plugin-to-feed-CodeProject-Technical-Blo" target="_blank">CodeProject Technical Blog Article</a>. See download of version 1.11.</p>
<p>In the beginning, <a href="http://www.codeproject.com/Messages/3326349/Re-Any-HowTo-for-Add-your-technical-blog-from-Word.aspx" target="_blank">everything was done manually</a>.</p>
<p>After the third time I had to edit feed-rss2.php of wordpress to fulfill CodeProjects Technical Blogs requirements I now wrote my first (and last?) wordpress plugin.</p>
<p>As you may know, CodeProject allows you to publish articles through your current blog. See here for the <a href="http://www.codeproject.com/script/Articles/BlogFAQ.aspx" target="_blank">FAQ</a>.</p>
<p>As I am using wordpress, I started some time ago to submit blog entries into CodeProject. I had to find out myself, where to change which file.</p>
<h3>Limit published articles</h3>
<p>To limit the range of blog entries that are published at CodeProject Technical Blogs I use a <a href="http://wordpress-as-cms.com/permalinks/hidden-feeds-categories-tags-authors-search-terms-links/" target="_blank">&#8216;hidden&#8217; feature</a> and created a category named &#8216;CodeProject&#8217; in my WordPress blog. On <a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=1522794" target="_blank">my Technical Blogs</a> site in CodeProject I then used <a class="linkification-ext" title="Linkification: http://www.hjgode.de/wp/category/codeproject/feed/" href="http://www.hjgode.de/wp/category/codeproject/feed/">http://www.hjgode.de/wp/category/codeproject/feed/</a> for the feed input. Now only the articles marked with WordPress category &#8216;codepoject&#8217; are feed to CodeProject.</p>
<h3>Manually changes required in WordPress for CodeProject Technical Blogs</h3>
<p>In feed-rss2.php I always had to add a &lt;category&gt;CodeProject&lt;/category&gt; line below &lt;channel&gt;. Further I had to change the footer.php of the wordpress theme Win7blog that I use. There I added a rel=&#8221;tag&#8221; line as recommended by CodeProject.</p>
<h3>The pain of doing it again and again</h3>
<p>Now, the first manual change has to be done everytime you update your wordpress release. I had to to this at least three times before I start now with a plugin to I avoid changing the file again manually.</p>
<h3>The idea of a WordPress plugin</h3>
<p>I never wrote a WordPress plugin before, but I did some html, php and mysql coding before (ie the calendar on <a href="http://fewo-britta.de/kalender/index.php" target="_blank">www.fewo-britta.de</a> or the static pages at <a href="www.derbiedermann.de" target="_blank">www.derbiedermann.de</a>, which are generated from a db). But the learning curve was hard and it took me several hours to get the plugin working. I started with the plugin described at DevLounge in there &#8220;<a href="http://www.devlounge.net/extras/how-to-write-a-wordpress-plugin" target="_blank">How to write a WordPress plugin</a>&#8221; series. The article was the <strong>only </strong>one I could find that describes wordpress plugin development from scratch with a <strong>working</strong> example.</p>
<p>As I had problems adopting the code to my needs, especially the AdminPage, I had to rewrite the code a little bit.</p>
<p><span id="more-366"></span></p>
<h3>My first WordPress plugin</h3>
<p>OK, what does the plugin do?</p>
<p><a href="http://www.hjgode.de/wp/2010/03/01/wordpress-plugin-to-feed-codeproject-technical-blogs/codeprojectfeeder_02/" rel="attachment wp-att-367"><img class="alignnone size-full wp-image-367" title="codeprojectfeeder_02" src="http://www.hjgode.de/wp/wp-content/uploads/2010/03/codeprojectfeeder_02.gif" alt="" width="692" height="406" /></a></p>
<p>The plugin inserts a rel=&#8221;tag&#8221; in your blogs page footer. This may look more or less good, depending on the theme you use. The footer always appears outside the themes footer. I could not find a way to let it appear inside the themes footer, if the theme uses the action hook wp_footer() ouside there footer block (here after the &lt;/div&gt;:</p>
<pre>&lt;div id="footer"&gt;
 &lt;p&gt;&lt;?php bloginfo('name'); ?&gt;@&lt;?php echo date('Y'); ?&gt;
 &lt;br&gt;
 &lt;a href="&lt;?php bloginfo('home') ?&gt;/"&gt;&lt;?php bloginfo('home'); ?&gt;&lt;/a&gt;
 &lt;br&gt;
 Designed by &lt;a href="<a class="linkification-ext" title="Linkification: http://www.kamiyeye.com/" href="http://www.kamiyeye.com/">http://www.kamiyeye.com/</a>"&gt;kamiyeye&lt;/a&gt;
 &lt;br&gt;
 &lt;?php StatPress_Print("%totalvisits% Hits."); ?&gt;
 &lt;/p&gt;
&lt;/div&gt;

&lt;/div&gt;&lt;!-- #wrapper .hfeed --&gt;

&lt;?php wp_footer(); ?&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<p>The plugin provides some checkbox options, so you can a) hide the rel=&#8221;tag&#8221; or b) dont use it at all.<br />
To feed your publications to CodeProject technical blogs, you are recommended to add a category tag with the contents CodeProject in your RSS2 feed. To get this done by the plugin it installs two action hooks: the channel one: rss2_head and the &#8216;item&#8217; one called rss2_item.</p>
<p>Here are the hooks I use in the plugin:</p>
<pre>//Actions and Filters
if (isset($hgo_codeprojectfeeder)) {
 //Actions
 add_action('admin_menu', 'CodeProjectFeeder_ap');
 add_action('wp_footer', array(&amp;$hgo_codeprojectfeeder, 'addFooterCode'), 1);
 add_action('activate_codeprojectfeeder/codeprojectfeeder.php', array(&amp;$hgo_codeprojectfeeder, 'init'));
 add_action('rss2_head', array(&amp;$hgo_codeprojectfeeder, 'addChannelCode'), 1);
 add_action('rss2_item', array(&amp;$hgo_codeprojectfeeder, 'addItemCode'), 1);
 //Filters
}</pre>
<p>The first hook is for the &#8216;Admin&#8217; settings page.<br />
The second one for the blog footer page.<br />
The &#8216;activate_&#8230;&#8217; hook is for initializing the plugin.<br />
The rss2_head and rss2_item hooks are used to insert &lt;category&gt;codeproject&lt;/category&gt; into the RSS2 header (&lt;channel&gt;) or &lt;item&gt; code.</p>
<h3>Formatting of the rel=&#8221;tag&#8221; link</h3>
<p>If you dont like the formatting of the rel=&#8221;tag&#8221; link, you can edit the plugin file codeprojectfeeder.php from inside WordPress, just click &#8220;Edit&#8221; below the &#8220;CodeProject Feeder Plugin&#8221; on the Manage Plugins page in your WordPress installation:</p>
<p><a href="http://www.hjgode.de/wp/2010/03/01/wordpress-plugin-to-feed-codeproject-technical-blogs/codeprojectfeeder_01/" rel="attachment wp-att-368"><img class="alignnone size-full wp-image-368" title="codeprojectfeeder_01" src="http://www.hjgode.de/wp/wp-content/uploads/2010/03/codeprojectfeeder_01.gif" alt="" width="727" height="423" /></a></p>
<p><a href="http://www.hjgode.de/wp/2010/03/01/wordpress-plugin-to-feed-codeproject-technical-blogs/codeprojectfeeder_04/" rel="attachment wp-att-371"><img class="alignnone size-full wp-image-371" title="codeprojectfeeder_04" src="http://www.hjgode.de/wp/wp-content/uploads/2010/03/codeprojectfeeder_04.gif" alt="" width="723" height="478" /></a></p>
<pre>/*
 Adds the rel TAG to the footer
 */
 function addFooterCode() {
   $content = '';
   //debug
   //echo '&lt;!-- addFooterCode was called --&gt;';
   $devOptions = $this-&gt;getAdminOptions();
   if ($devOptions['use_reltag'] == "true") {
     if($devOptions['hide_reltag'] == "true"){
       //using the style option you can adjust the link appearance
       $content = '&lt;a <strong>style="display:none; text-align:center; font-size:x-small; "</strong> href="'.stripslashes($devOptions['reltag_content']).'" rel="tag"&gt;CodeProject&lt;/a&gt;';
       echo $content;
     }
     else{
       $content = '&lt;a <strong>style=" text-align:center; font-size:x-small; "</strong> href="'.stripslashes($devOptions['reltag_content']).'" rel="tag"&gt;CodeProject&lt;/a&gt;';
       echo $content;
     }
   }
 }</pre>
<p>You can change the appearance of the footer text with the css inline style statements, as there are already &#8220;text-align:center; font-size:x-small;&#8221;</p>
<p>With the other options of the plugins admin settings page you specify, if you like to have the category tag within channel for all pubilcations or inside every item. You should not use both, it does not make sense.</p>
<h3>Plugin uses checkboxes instead of options</h3>
<p>As you can see from the codeprojectfeeder.php code, I have changed the way yes/no options are used in the settings admin form. Instead of the very long, hard to manage lines, I use the shorter form and checkboxes:</p>
<pre>&lt;p&gt;&lt;INPUT TYPE="CHECKBOX" id="codeprojectfeederUseRelTag" name="codeprojectfeederUseRelTag" value="true" &lt;?php if ($devOptions['use_reltag'] == "true") { echo 'CHECKED'; }?&gt;&gt;Use rel tag in footer&lt;/p&gt;</pre>
<p>instead of</p>
<pre>&lt;p&gt;&lt;label for="devloungeHeader_yes"&gt;&lt;input type="radio" id="devloungeHeader_yes" name="devloungeHeader" value="true" &lt;?php if ($devOptions['show_header'] == "true") { _e('checked="checked"', "DevloungePluginSeries"); }?&gt; /&gt; Yes&lt;/label&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;label for="devloungeHeader_no"&gt;&lt;input type="radio" id="devloungeHeader_no" name="devloungeHeader" value="false" &lt;?php if ($devOptions['show_header'] == "false") { _e('checked="checked"', "DevloungePluginSeries"); }?&gt;/&gt; No&lt;/label&gt;&lt;/p&gt;</pre>
<p>You can download the codeprojectfeeder plugin as zip: <b>DOWNLOAD:</b><a href="http://www.hjgode.de/wp/wp-content/plugins/download-monitor/download.php?id=81" title="Downloaded 195 times">CodeProjectFeeder</a> - A Wordpress plugin (Hits: 195, size: 3.38 kB)</p>
<p>Version 1.11: <b>DOWNLOAD:</b><a href="http://www.hjgode.de/wp/wp-content/plugins/download-monitor/download.php?id=141" title="Downloaded 19 times">CodeprojectFeeder 1.11</a> - A wordpress plugin (Hits: 19, size: 3.53 kB)</p>
<h3>Development and debugging</h3>
<p>As you can see in codeprojectfeeder.php, there are some comment lines with a //debug line before. I used these during development to find my typos and bugs.</p>
<p>The plugin was tested on a lampp system (an Acer Aspire One A150 netbook), a windows xampp system and finally in my blog. Just be warned that due to caches or whatever of the testing lampp/xampp systems, sometimes the output was not altered and nothing changed, although source code was changed. I had to restart apache/mysql to get correct results. The RSS2 feed was sometimes cached by firefox/ie and was hard to debug, as the contents did not change although the source code was changed.</p>
<h2>Installation</h2>
<p>Just unzip the files into a dir called codeprojectfeeder below your wordpress wp-content/plugins dir or unzip the directory codeprojectfeeder into your wordpress plugins dir. Then Activate the plugin and select the CodeProjectFeeder settings you like.</p>
<h3>Finally</h3>
<p>Now, you and me dont need to change the feed-rss2.php file manually any more for CodeProject Technical Blogs.</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Bookmark It</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F03%2F01%2Fwordpress-plugin-to-feed-codeproject-technical-blogs%2F&amp;title=WordPress+Plugin+to+feed+CodeProject+Technical+Blogs" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F03%2F01%2Fwordpress-plugin-to-feed-codeproject-technical-blogs%2F&amp;title=WordPress+Plugin+to+feed+CodeProject+Technical+Blogs" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F03%2F01%2Fwordpress-plugin-to-feed-codeproject-technical-blogs%2F&amp;title=WordPress+Plugin+to+feed+CodeProject+Technical+Blogs" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F03%2F01%2Fwordpress-plugin-to-feed-codeproject-technical-blogs%2F&amp;T=WordPress+Plugin+to+feed+CodeProject+Technical+Blogs" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F03%2F01%2Fwordpress-plugin-to-feed-codeproject-technical-blogs%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fwww.hjgode.de%2Fwp%2F2010%2F03%2F01%2Fwordpress-plugin-to-feed-codeproject-technical-blogs%2F&amp;t=WordPress+Plugin+to+feed+CodeProject+Technical+Blogs" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://www.hjgode.de/wp/wp-content/plugins/social-bookmarks0/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.hjgode.de/wp/2010/03/01/wordpress-plugin-to-feed-codeproject-technical-blogs/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

