<?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>JEDI Windows API &#187; DidYouKnow</title>
	<atom:link href="http://blog.delphi-jedi.net/tag/didyouknow/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.delphi-jedi.net</link>
	<description>Joint Endeavor of Delphi Innovators of Windows Programming</description>
	<lastBuildDate>Wed, 19 Oct 2011 18:52:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Did you know? #6</title>
		<link>http://blog.delphi-jedi.net/2008/05/15/did-you-know-5/</link>
		<comments>http://blog.delphi-jedi.net/2008/05/15/did-you-know-5/#comments</comments>
		<pubDate>Thu, 15 May 2008 10:00:26 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[CreateProcess]]></category>
		<category><![CDATA[DidYouKnow]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=200</guid>
		<description><![CDATA[If you create a new process without adding the environment block (by calling CreateEnvironmentBlock) the new process may fail to call Shellexecute and some other functions. Don&#8217;t think that the enviroment variables aren&#8217;t that important. Find out more about CreateProcess in the post about &#8220;CreateProcess in full glory&#8220;.]]></description>
			<content:encoded><![CDATA[<p>If you create a new process without adding the environment block (by calling CreateEnvironmentBlock) the new process may fail to call Shellexecute and some other functions. Don&#8217;t think that the enviroment variables aren&#8217;t that important.</p>
<p>Find out more about CreateProcess in the post about &#8220;<a href="http://blog.delphi-jedi.net/2008/04/11/createprocess-in-full-glory/">CreateProcess in full glory</a>&#8220;.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/05/15/did-you-know-5/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Did you know? #5</title>
		<link>http://blog.delphi-jedi.net/2008/05/14/did-you-know-3-2/</link>
		<comments>http://blog.delphi-jedi.net/2008/05/14/did-you-know-3-2/#comments</comments>
		<pubDate>Wed, 14 May 2008 08:35:33 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[DidYouKnow]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=197</guid>
		<description><![CDATA[Did you know that handles are 64 bit wide in native 64 bit applications? While this doesn&#8217;t affect any Delphi developer just yet, things will change next year with the release of Delphi &#8220;Commodore&#8221; as outlined on CodeGear&#8217;s Delphi and C++Builder Roadmap page. This means, among other things, that type-casting a THandle or HANDLE from [...]]]></description>
			<content:encoded><![CDATA[<p>Did you know that handles are 64 bit wide in native 64 bit applications? While this doesn&#8217;t affect any Delphi developer just yet, things will change next year with the release of Delphi &#8220;Commodore&#8221; as outlined on CodeGear&#8217;s <a href="http://dn.codegear.com/article/36620" target="_blank">Delphi and C++Builder Roadmap</a> page. This means, among other things, that type-casting a <code>THandle</code> or <code>HANDLE</code> from or to something like a <code>Cardinal</code>, <code>Longint</code> or <code>DWORD</code> is a sin.</p>
<p>The reason for this becomes clear if you look into the Windows SDK headers, where HANDLE is declared as:</p>
<pre>typedef void *HANDLE;</pre>
<p>Since the processor architecture determines the width of the pointer types, this will be 64 bit. Now Delphi on the other hand (taking Delphi 2006 as an example) declares this:</p>
<pre>THandle = LongWord;</pre>
<p>Which is a non-pointer type of 32 bit width. If memory serves me right, there were some changes over time in how <code>THandle</code> was declared and it juggled between <code>Cardinal</code>, <code>LongWord</code> and some other type. In any case, there will have to be a change in &#8220;Commodore&#8221;, unless <code>LongWord</code> changes its meaning from 32 to 64 bit.</p>
<p>Things get even crazier if you look at how the SDK declares <code>INVALID_HANDLE_VALUE</code>:</p>
<pre>#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)</pre>
<p>Note the explicit type-cast. This is necessary to ensure that the value will not be truncated to <code>$FFFFFFFF</code> instead of <code>$FFFFFFFFFFFFFFFF</code>.</p>
<p>Delphi 2006 declares it as:</p>
<pre>const
  INVALID_HANDLE_VALUE = DWORD(-1);</pre>
<p>&#8230; which is clearly invalid for 64 bit code. So watch out for these caveats <em>in your code</em>. I am sure CodeGear will do their part before the release.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/05/14/did-you-know-3-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Did you know? #3</title>
		<link>http://blog.delphi-jedi.net/2008/05/12/did-you-know-3/</link>
		<comments>http://blog.delphi-jedi.net/2008/05/12/did-you-know-3/#comments</comments>
		<pubDate>Mon, 12 May 2008 11:12:58 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[DidYouKnow]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=196</guid>
		<description><![CDATA[The WinSta0_DesktopSwitch Event allows an application to check for a desktop switch. The following examples demonstrates how we can wait for such an Event. To test it, simply lock and unlock the workstation. Both wait function will return on the two desktop switching. uses &#160; SysUtils &#160; JwaWindows; var H : THandle; begin &#160; H [...]]]></description>
			<content:encoded><![CDATA[<p>The <strong>WinSta0_DesktopSwitch</strong> Event allows an application to check for a desktop switch. The following examples demonstrates how we can wait for such an Event. To test it, simply lock and unlock the workstation. Both wait function will return on the two desktop switching.</p>
<p><span id="more-196"></span></p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span><br />
&nbsp; SysUtils<br />
&nbsp; JwaWindows;</p>
<p><span class="kw1">var</span> H : <span class="kw4">THandle</span>;<br />
<span class="kw1">begin</span><br />
&nbsp; H := OpenEvent<span class="br0">&#40;</span>SYNCHRONIZE, <span class="kw2">false</span>, <span class="st0">&#8216;WinSta0_DesktopSwitch&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">if</span> H = <span class="nu0">0</span> <span class="kw1">then</span><br />
&nbsp; <span class="kw1">begin</span><br />
&nbsp; &nbsp; <span class="kw3">writeln</span><span class="br0">&#40;</span><span class="kw3">SysErrorMessage</span><span class="br0">&#40;</span><span class="kw3">GetLasterror</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw3">readln</span>;<br />
&nbsp; <span class="kw1">end</span>;</p>
<p>&nbsp; WaitForSingleObject<span class="br0">&#40;</span>H,INFINITE<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw3">writeln</span><span class="br0">&#40;</span><span class="st0">&#8216;OK1&#8242;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; WaitForSingleObject<span class="br0">&#40;</span>H,INFINITE<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw3">writeln</span><span class="br0">&#40;</span><span class="st0">&#8216;OK2&#8242;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; <span class="kw3">writeln</span><span class="br0">&#40;</span><span class="st0">&#8216;Switched&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw3">readln</span>;<br />
<span class="kw1">end</span>.</div>
<p>You should know that each session (0&#8230;x) has its own event. You can&#8217;t use this mechanism directly in a service (especially not in Vista due to session isolation).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/05/12/did-you-know-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Did you know? #2</title>
		<link>http://blog.delphi-jedi.net/2008/05/10/did-you-know2/</link>
		<comments>http://blog.delphi-jedi.net/2008/05/10/did-you-know2/#comments</comments>
		<pubDate>Sat, 10 May 2008 14:26:43 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[DidYouKnow]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=195</guid>
		<description><![CDATA[If you include Forms and SvcMgr (Service classes) in the same project (in any sub unit) you may get a memory leak. It happens only if you call the Free method directly. Forms.Application.Free; To make it work, you have to check for a side effect that I describe here. The memory leak results from the [...]]]></description>
			<content:encoded><![CDATA[<p>If you include <strong><em>Forms</em></strong> and <strong><em>SvcMgr</em></strong> (Service classes) in the same project (in any sub unit) you may get a memory leak. <span style="text-decoration: underline;">It happens only if you call the Free method directly.<br />
</span></p>
<div class="dean_ch" style="white-space: wrap;">Forms.<span class="me1">Application</span>.<span class="me1">Free</span>;</div>
<p>To make it work, you have to check for a side effect that I describe here.</p>
<p>The memory leak results from the <em>SvcMgr.TServiceApplication.Destroy</em> destructor which uses the global instance <em>Forms.Application</em>. In detail, it creates a memory block that is maintained by a list in <em>TApplication</em>. If you free the <em>TApplication </em>instance, the internal list is also freed, but the memory block is not! As a remedy you have to free the service object first and then recreate the TApplication instance (and if you need also the <em>TServiceApplication</em>).</p>
<p>The <em>Forms</em> and <em>SvcMgr</em> units creates their objects in the initialization section of the units. So you have to play around them.</p>
<p>Go through your units and check if you include <em>SvcMgr</em> and <em>Forms</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/05/10/did-you-know2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Did you know? #1</title>
		<link>http://blog.delphi-jedi.net/2008/05/08/did-you-know-1/</link>
		<comments>http://blog.delphi-jedi.net/2008/05/08/did-you-know-1/#comments</comments>
		<pubDate>Thu, 08 May 2008 20:05:00 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[CreateProcessAsUser]]></category>
		<category><![CDATA[DidYouKnow]]></category>
		<category><![CDATA[JWA]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=193</guid>
		<description><![CDATA[A call to CreateProcessAsUser will fail with ERROR_INVALID_PARAMETER if your new process belongs to another session and you allowed inheritance of handles. In this case you have to set parameter bInheritHandles to FALSE.]]></description>
			<content:encoded><![CDATA[<p>A call to <a href="http://msdn.microsoft.com/en-us/library/ms682429.aspx">CreateProcessAsUser</a> will fail with <strong>ERROR_INVALID_PARAMETER</strong> if your new process belongs to another session and you allowed inheritance of handles. In this case you have to set parameter <em>bInheritHandles</em> to <strong>FALSE</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/05/08/did-you-know-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

