<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CkcGSXc8eyp7ImA9WhRUFEs.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907</id><updated>2012-01-25T04:53:48.973+02:00</updated><category term="Python" /><category term="Delphi 2010" /><category term="jokes" /><category term="Visual Studio" /><category term="uncategorized" /><category term="postgresql" /><category term="Delphi 2009 slip" /><category term="Logical errors" /><category term="Arrays" /><category term="RTTI" /><category term="skype" /><category term="Files" /><category term="Math" /><category term="Indy" /><category term="Threads" /><category term="Callbacks" /><category term="Encryption" /><category term="Windows" /><category term="Custom Loop" /><category term="Firewall" /><category term="Security" /><category term="open source" /><category term="DWMApi" /><category term="Tray Icon" /><category term="Streams" /><category term="Delphi ampersand operator" /><category term="Delphi compiler errors" /><category term="compression" /><category term="Delphi 2010 slip" /><category term="IDE tips" /><category term="Multilnaguage Support" /><category term="new year" /><category term="virtual machine" /><category term="Drag and Drop" /><category term="Delphi Distiller" /><category term="Interpreter" /><category term="Delphi XE Distiller" /><category term="Android" /><category term="File Manager" /><category term="Facebook" /><category term="laptop" /><category term="high tech" /><category term="Automation" /><category term="database" /><category term="contest" /><category term="Huge BS" /><category term="TStringGrid" /><category term="business" /><category term="Reports" /><category term="Internet" /><category term="utility functions" /><category term="Delphi Addons" /><category term="graphics" /><category term="TListView from CSV" /><category term="XML" /><category term="Tips" /><category term="CSV" /><category term="Algorithms" /><category term="TListView" /><category term="DWScript" /><category term="Bits" /><category term="DGTV" /><category term="Multi-Language Support" /><category term="Unicode" /><category term="VirtualTreeview" /><category term="uninteresting" /><category term="Delphi 2010 license" /><category term="generics" /><category term="performance classes" /><category term="Editors" /><category term="MDI" /><category term="Tools" /><category term="Memory" /><category term="network" /><category term="components" /><category term="zombie computers" /><category term="zlib" /><category term="Delphi tutorial" /><category term="Bitmaps" /><category term="management" /><category term="Turbo" /><title>The Spirit of Delphi</title><subtitle type="html">Programming tips, tricks and tools</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.delphigeist.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.delphigeist.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>144</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/TheSpiritOfDelphi" /><feedburner:info uri="thespiritofdelphi" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>TheSpiritOfDelphi</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry gd:etag="W/&quot;CEACQH0zcCp7ImA9WhZXGEQ.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-9184699739207860489</id><published>2011-05-09T01:12:00.000+03:00</published><updated>2011-05-09T01:12:41.388+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-09T01:12:41.388+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Algorithms" /><category scheme="http://www.blogger.com/atom/ns#" term="Unicode" /><title>Boyer-Moore Horspool return all occurrences in one go</title><content type="html">First I would like to say that I'm sorry for not posting for quite some time now, but thanks to Simon H. who found a bug in original algorithm found &lt;a href="http://www.delphigeist.com/2010/04/boyer-moore-horspool-in-delphi-2010.html"&gt;here&lt;/a&gt;, I've managed to also extend the function to return all occurrences of a pattern in a string, without further introduction here's the code!&lt;br /&gt;
&lt;pre&gt;type
  TFSResults = array of Integer;

function FindStringMulti(const Value, Pattern: string;
  const CaseSensitive: Boolean = True;
  const StartPos: Integer = 1): TFSResults;
var
  Index: Integer;
  jIndex: Integer;
  kIndex: Integer;
  LLenPattern: Integer;
  LLenValue: Integer;
  LSkipTable: array[Char] of Integer;
  LChar: Char;

    function __SameChar: Boolean;
    begin
      if CaseSensitive then
        Result := (Value[Index] = Pattern[jIndex])
      else
        Result := (CompareText(Value[Index], Pattern[jIndex]) = 0);
    end; // function __SameChar: Boolean;

begin
  LLenPattern := Length(Pattern);
  if LLenPattern = 0 then
    Exit;
  for LChar := Low(Char) to High(Char) do
    LSkipTable[LChar] := LLenPattern;
  if CaseSensitive then begin
    for kIndex := 1 to LLenPattern -1 do
      LSkipTable[Pattern[kIndex]] := LLenPattern -kIndex;
  end else begin
    for kIndex := 1 to LLenPattern -1 do
      LSkipTable[Windows.CharLower(@Pattern[kIndex])^] := LLenPattern -kIndex;
  end; // if CaseSensitive then begin
  kIndex := LLenPattern + (StartPos -1);
  LLenValue := Length(Value);
  while (kIndex &lt;= LLenValue) do begin
    Index := kIndex;
    jIndex := LLenPattern;
    while (jIndex &gt;= 1) do begin
      if __SameChar then begin
        jIndex := jIndex -1;
        Index := Index -1;
      end else
        jIndex := -1;
      if jIndex = 0 then begin
        SetLength(Result, Length(Result) +1);
        Result[High(Result)] := Index +1;
        jIndex := -1;
      end; // if jIndex = 0 then begin
      kIndex := kIndex + LSkipTable[Value[kIndex]];
    end; // while (jIndex &gt;= 1) do begin
  end; // while (kIndex &lt;= LLenValue) do begin
end;
&lt;/pre&gt;
&lt;br /&gt;
Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-9184699739207860489?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/iUFcJqXCMYti0ygwLQGTB-7Z2xE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/iUFcJqXCMYti0ygwLQGTB-7Z2xE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/iUFcJqXCMYti0ygwLQGTB-7Z2xE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/iUFcJqXCMYti0ygwLQGTB-7Z2xE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/EiP8-AQAbyk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/9184699739207860489/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2011/05/boyer-moore-horspool-return-all.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/9184699739207860489?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/9184699739207860489?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/EiP8-AQAbyk/boyer-moore-horspool-return-all.html" title="Boyer-Moore Horspool return all occurrences in one go" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.delphigeist.com/2011/05/boyer-moore-horspool-return-all.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8MQ3Y5fSp7ImA9Wx9VGEg.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-5577529014940301014</id><published>2011-02-05T00:34:00.001+02:00</published><updated>2011-02-05T00:34:42.825+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-05T00:34:42.825+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="uncategorized" /><title>Remember: anything but random!!</title><content type="html">...as I was saying on December 13th 2010: „&lt;a href="http://www.delphigeist.com/2010/12/politics-is-anything-but-random.html"&gt;Politics is anything but random&lt;/a&gt;¯...&lt;br /&gt;
Well... here's something new &lt;a href="http://edition.cnn.com/2011/WORLD/europe/02/04/wikileaks.assange.defense/index.html"&gt;Lawyers for WikiLeaks founder Julian Assange have set up a Facebook page asking for donations to his legal defense fund&lt;/a&gt;.(source: &lt;a href="http://edition.cnn.com/"&gt;CNN&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
Basically, the reason for this post is that I want to remind some of you the fact that Wikileaks is a total hoax, as I stated before... no &lt;strong&gt;real leaks&lt;/STRONG&gt; were actually released and if there will be any then it means that the Internet will be regulated because of „national/international/interracial/etc. security threat¯ -- you know the two towers that were actually 3(three, tres, trei, drei) and then the &lt;strong&gt;no&lt;/STRONG&gt; warrant thingy? -- but yet, the entire world lost it's focus on the real matters like: the economy, tens of millions of unemployed around the world, people struggling to survive and other &lt;i&gt;unimportant&lt;/I&gt; shit like that... -- I hope you can smell my irony!!&lt;br /&gt;
&lt;br /&gt;
Oh and another thing regarding Egypt and Tunisia, I hope they won't have to deal with what &lt;a href="http://en.wikipedia.org/wiki/Hyperinflation_in_Zimbabwe"&gt;Zimbabwe&lt;/a&gt; had to... keep IMF out of your boarders!&lt;br /&gt;
&lt;br /&gt;
P.S. Big shout out to &lt;a href="http://www.delphigeist.com/2010/01/joke-about-special-agencies.html"&gt;198.81.128.[xxx]&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-5577529014940301014?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0B4t81yKPLGSNHQz12gc-D3kv74/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0B4t81yKPLGSNHQz12gc-D3kv74/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0B4t81yKPLGSNHQz12gc-D3kv74/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0B4t81yKPLGSNHQz12gc-D3kv74/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/eddnaMYmYmI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/5577529014940301014/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2011/02/remember-anything-but-random.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/5577529014940301014?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/5577529014940301014?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/eddnaMYmYmI/remember-anything-but-random.html" title="Remember: anything but random!!" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.delphigeist.com/2011/02/remember-anything-but-random.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIMSHw4eCp7ImA9Wx9VFkg.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-4693975522532632105</id><published>2011-02-02T16:52:00.002+02:00</published><updated>2011-02-02T16:56:29.230+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-02T16:56:29.230+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="uncategorized" /><title>Breaking News: 1st November 2011 RAD Studio deal!</title><content type="html">Here's something that &lt;b&gt;leaked&lt;/B&gt; from Embarcadero's future plans:&lt;br /&gt;
&lt;blockquote&gt;As of 1st November 2011 Embarcadero is proud to announce the release of Embarcadero RAD Studio XE Second Edition for as low as $100,— per year developer license. We will also include some new community based free services for registered customers, the services are: ednMigrate, ednBlogger, ednHelp.&lt;br /&gt;
&lt;br /&gt;
What is included in the Embarcadero RAD Studio XE Second Edition:&lt;br /&gt;
- Delphi XE SE&lt;br /&gt;
- C++ Builder XE SE&lt;br /&gt;
- Rad PHP XE SE&lt;br /&gt;
- Delphi Prism XE SE&lt;br /&gt;
- cross platform: Windows, Mac and Linux&lt;br /&gt;
- full source code for VCL, RTL&lt;br /&gt;
- over 200 demo applications to help you get started&lt;br /&gt;
- latest updates included in the license&lt;br /&gt;
&lt;br /&gt;
What is ednMigrate:&lt;br /&gt;
ednMigrate is a new community based service available for Embarcadero registered customers that will help you migrate your code from a earlier version of Delphi for example to the latest, you don't have to worry anymore about code compatibility.&lt;br /&gt;
You can access ednMigrate at http://ednmigrate.embarcadero.com/ and log in using your Embarcadero customer account.&lt;br /&gt;
&lt;br /&gt;
What is ednBlogger:&lt;br /&gt;
We know that you want to share your knowledge with other developers, therefore Embarcadero will host your blog free of charge(applicable for customers only) for any Embarcadero product.&lt;br /&gt;
You can access ednBlogger at http://ednblogger.embarcadero.com/ and log in using your Embarcadero customer account.&lt;br /&gt;
&lt;br /&gt;
What is ednHelp:&lt;br /&gt;
ednHelp is a new community based service available for Embarcadero registered customers that will host questions and answers related to application development, you can ask and answer as many questions as you like, the service is free of charge for all customers.&lt;br /&gt;
You can access ednHelp at http://ednhelp.embarcadero.com/ and log in using your Embarcadero customer account.&lt;br /&gt;
&lt;br /&gt;
We have done everything we could in order to provide you with best prices for independent developers, students, new companies and existing customers:&lt;br /&gt;
Here are our latest prices:&lt;br /&gt;
&lt;table&gt;&lt;TR&gt;&lt;td&gt;Target&lt;/TD&gt;&lt;td&gt;Price&lt;/TD&gt;&lt;/TR&gt;
&lt;tr&gt; &lt;td&gt;Independent Developers&lt;/TD&gt; &lt;td&gt;$200,—/year&lt;/TD&gt; &lt;/TR&gt;
&lt;tr&gt; &lt;td&gt;Students&lt;/TD&gt; &lt;td&gt;$100,—/year&lt;/TD&gt; &lt;/TR&gt;
&lt;tr&gt; &lt;td&gt;New companies&lt;/TD&gt; &lt;td&gt;$100,—/developer first year and $150,—/year starting from 2nd year&lt;/TD&gt; &lt;/TR&gt;
&lt;tr&gt; &lt;td&gt;Existing customers&lt;/TD&gt; &lt;td&gt;$150,—/year&lt;/TD&gt; &lt;/TR&gt;
&lt;tr&gt; &lt;td&gt;Schools&lt;/TD&gt; &lt;td&gt;$50,—/year&lt;/TD&gt; &lt;/TR&gt;
&lt;/TABLE&gt;If you would like to do a test drive of any of our products before purchasing you can do so by navigating to http://testdrive.embarcadero.com/ select a product to download and don't forget that you can always write us a feedback at http://testdrive.embarcadero.com/feedback/ if you care to help us improve our services.&lt;br /&gt;
&lt;br /&gt;
Because Embarcadero truly cares about it's customers, as of 1st February 2012 we will hold conferences all around the world so that developers can have a taste of latest technologies or share their knowledge, this is also a good opportunity for new businesses to find partners or students and independent developers to find jobs.&lt;br /&gt;
&lt;/BLOCKQUOTE&gt;OK, OK you got me, &lt;b&gt;it's NOT true&lt;/B&gt;, unfortunately... but it would be nice if Embarcadero would do something similar not the "Starter edition" stuff... which I personally disagree with it, first because it comes without source code or debugger(ewww...) and second because the price is still pretty high for students for example.&lt;br /&gt;
Personal appeal to Embarcadero, let's support schools and students shall we guys?! in some schools in Romania the pascal language is STILL present, however I'm NOT sure if that will be true in 1 or 2 years from now, given the fact that Microsoft is doing a terrific job spreading it's software all around the world, I would NOT be surprised if they will have Visual Studio in most schools.&lt;br /&gt;
&lt;br /&gt;
And another thing, I get more than 60% of my blog hits from searches like "Delphi distiller", "Delphi XE distiller" and similar keywords, what does THAT mean to Embarcadero?! shit load of customers and money TOTALLY WASTED, is Embarcadero that rich?! probably...&lt;br /&gt;
&lt;br /&gt;
One more thing, before people will start criticise me, please DO NOT THINK that $140,— per start edition or whatever the price is or will be is NOT a lot of money, you don't take into account countries that have thousands of Delphi developers which earn ~$500,—/month or less, so yes $140,— might not be a lot for US or European citizens but for other parts of the world it is.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-4693975522532632105?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/y4Av1wzKcSCbihI7sXZA5gTGhk8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/y4Av1wzKcSCbihI7sXZA5gTGhk8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/y4Av1wzKcSCbihI7sXZA5gTGhk8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/y4Av1wzKcSCbihI7sXZA5gTGhk8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/TvWL6fnnkAg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/4693975522532632105/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2011/02/breaking-news-1st-november-2011-rad.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/4693975522532632105?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/4693975522532632105?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/TvWL6fnnkAg/breaking-news-1st-november-2011-rad.html" title="Breaking News: 1st November 2011 RAD Studio deal!" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.delphigeist.com/2011/02/breaking-news-1st-november-2011-rad.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YEQnY_eSp7ImA9Wx9VFU4.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-6680936788349170578</id><published>2011-02-01T07:44:00.001+02:00</published><updated>2011-02-01T07:45:03.841+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-01T07:45:03.841+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="laptop" /><category scheme="http://www.blogger.com/atom/ns#" term="utility functions" /><title>Laptop specific functions</title><content type="html">First I would like to thank each and every one of the developers from &lt;a href="http://www.stackoverflow.com"&gt;stackoverflow&lt;/a&gt; who helped me out in detecting if application is running on laptop by answering &lt;a href="http://stackoverflow.com/questions/4849447/detect-if-application-is-running-on-laptop"&gt;my question&lt;/a&gt;.&lt;br /&gt;
I have pushed the envelop further by defining some helper functions which retrieves laptop specific information and some other as well, so without further introduction here's the unit that I've wrote, feel free to use it in commercial and/or personal applications &lt;b&gt;AT YOUR OWN RISK&lt;/B&gt; of course, also if you find some flaws(high probability -- haven't tested enough) please feel free to drop a comment.&lt;br /&gt;
&lt;pre&gt;unit uDGMobileUtils;

interface

(*******************************************************************************

  Author:
    Dorin Duminica

  Note:
    That Parts of the code are Copyright© of Microsoft Corporation.
    All Rights Reserved.

  Disclaimer:
    Using the following code represents your acknowledgement that YOU TAKE
    FULL RESPONSABILITY of any damage it can and/or might cause to your
    system, country, pets, etc.

  Requirements:
    According to Microsoft the following code should work starting from
    Windows 2000 Professional and Server

*******************************************************************************)

uses
  Windows;

{$Z4} // required in order to have 4 byte enumerated type

type
  SYSTEM_POWER_STATE =(
    PowerSystemUnspecified,
    PowerSystemWorking,
    PowerSystemSleeping1,
    PowerSystemSleeping2,
    PowerSystemSleeping3,
    PowerSystemHibernate,
    PowerSystemShutdown,
    PowerSystemMaximum);

{$Z1} // restore enumerated type to 1 byte

const
  SYSTEM_POWER_STATE_NAMES: array[SYSTEM_POWER_STATE] of string = (
    'Unspecified',
    'Working',
    'Sleeping 1',
    'Sleeping 2',
    'Sleeping 3',
    'Hibernate',
    'Shutdown',
    'Maximum');

type
  BATTERY_REPORTING_SCALE = record
    Granularity: ULONG;
    Capacity: ULONG;
  end;

  PBATTERY_REPORTING_SCALE = ^BATTERY_REPORTING_SCALE;

type
  SYSTEM_POWER_CAPABILITIES = record
    // If this member is TRUE, there is a system power button.
    PowerButtonPresent: Boolean;
    // If this member is TRUE, there is a system sleep button.
    SleepButtonPresent: Boolean;
    // If this member is TRUE, there is a lid switch.
    LidPresent: Boolean;
    // for S1 —&gt; S5 check microsoft site
    SystemS1: Boolean;
    SystemS2: Boolean;
    SystemS3: Boolean;
    SystemS4: Boolean;
    SystemS5: Boolean;
    // If this member is TRUE, the operating system supports power off state S5 (soft off).
    HiberFilePresent: Boolean;
    // If this member is TRUE, the system supports wake capabilities.
    FullWake: Boolean;
    // If this member is TRUE, the system supports video display dimming capabilities.
    VideoDimPresent: Boolean;
    // If this member is TRUE, the system supports APM BIOS power management features.
    ApmPresent: Boolean;
    // If this member is TRUE, there is an uninterruptible power supply (UPS).
    UpsPresent: Boolean;
    // If this member is TRUE, the system supports thermal zones.
    ThermalControl: Boolean;
    // If this member is TRUE, the system supports processor throttling.
    ProcessorThrottle: Boolean;
    // The minimum level of system processor throttling supported,
    // expressed as a percentage.
    ProcessorMinThrottle: UCHAR;
    // The maximum level of system processor throttling supported,
    // expressed as a percentage.
    ProcessorMaxThrottle: UCHAR;
    // If this member is TRUE, the system supports the hybrid sleep state.
    // Windows Server 2003 and Windows XP:  Hybrid sleep is not supported.
    // Windows 2000:  This member is not supported.
    FastSystemS4: Boolean;
    // reserved
    spare2: array [0 .. 3] of UCHAR;
    // If this member is TRUE, the system supports allowing the removal of power
    // to fixed disk devices.
    DiskSpinDown: Boolean;
    // reserved
    spare3: array [0 .. 7] of UCHAR;
    // If this member is TRUE, there are one or more batteries in the system.
    SystemBatteriesPresent: Boolean;
    // If this member is TRUE, the system batteries are short-term.
    // Short-term batteries are used in uninterruptible power supplies (UPS).
    BatteriesAreShortTerm: Boolean;
    // A BATTERY_REPORTING_SCALE structure that contains information about
    // how system battery metrics are reported.
    BatteryScale: array [0 .. 2] of BATTERY_REPORTING_SCALE;
    // The lowest system sleep state (Sx) that will generate a wake event when
    // the system is on AC power. This member must be one of the
    // SYSTEM_POWER_STATE enumeration type values.
    AcOnLineWake: SYSTEM_POWER_STATE;
    // The lowest system sleep state (Sx) that will generate a wake event via
    // the lid switch. This member must be one of the SYSTEM_POWER_STATE
    // enumeration type values.
    SoftLidWake: SYSTEM_POWER_STATE;
    // To wake the computer using the RTC, the operating system must also
    // support waking from the sleep state the computer is in when the RTC
    // generates the wake event. Therefore, the effective lowest sleep state
    // from which an RTC wake event can wake the computer is the lowest sleep
    // state supported by the operating system that is equal to or higher than
    // the value of RtcWake. To determine the sleep states that the operating
    // system supports, check the SystemS1, SystemS2, SystemS3, and SystemS4 members.
    RtcWake: SYSTEM_POWER_STATE;
    // The minimum allowable system power state supporting wake events.
    // This member must be one of the SYSTEM_POWER_STATE enumeration type values.
    // Note that this state may change as different device drivers are
    // installed on the system.
    MinDeviceWakeState: SYSTEM_POWER_STATE;
    // The default system power state used if an application calls
    // RequestWakeupLatency with LT_LOWEST_LATENCY. This member must be one of
    // the SYSTEM_POWER_STATE enumeration type values.
    DefaultLowLatencyWake: SYSTEM_POWER_STATE;
  end;

  PSYSTEM_POWER_CAPABILITIES = ^SYSTEM_POWER_CAPABILITIES;

type
  TACLineStatus = (
    // battery
    acsOffline = 0,
    // plugged in
    acsOnline = 1,
    acsUnknown = 255);

type
  TBatteryState = (
    // High—the battery capacity is at more than 66 percent
    bsHigh = 1,
    // Low—the battery capacity is at less than 33 percent
    bsLow = 2,
    // Critical—the battery capacity is at less than five percent
    bsCritical = 4,
    bsCharging = 8,
    bsNoSystemBattery = 128,
    // Unknown status—unable to read the battery flag information
    bsUnknown = 255);

  TBatteryStatus = set of TBatteryState;

  function GetPwrCapabilities(lpSystemPowerCapabilities: PSYSTEM_POWER_CAPABILITIES): Boolean; stdcall;
  function IsAdminOverrideActive: Boolean; stdcall;
  function IsPwrHibernateAllowed: Boolean; stdcall;
  function IsPwrShutdownAllowed: Boolean; stdcall;
  function IsPwrSuspendAllowed: Boolean; stdcall;

  // utility
  function IsLidPresent: Boolean;
  function IsRunningMobile: Boolean;
  function IsRunningOnBattery: Boolean;
  function IsPowerBtnPresent: Boolean;
  function IsApmPresent: Boolean;
  function IsUpsPresent: Boolean;
  function IsThermalControl: Boolean;
  function GetACLineStatus: TACLineStatus;
  function GetACLineStatusName(const AACLineStatus: TACLineStatus): string;
  function GetBatteryStatus: TBatteryStatus;
  function GetBatteryStateName(const ABatteryState: TBatteryState): string;
  function GetBatteryStatusStr(const ABatteryState: TBatteryStatus;
    const ADelimiter: Char = ','): string;
  function GetBatteryLifePercent: Byte;
  function GetBatteryLifeTime: DWORD;
  function GetBatteryLifeTimeFull: DWORD;
  function GetNumberOfProcessors: DWORD;
  function GetSystemPowerStateName(const ASystemPowerState: SYSTEM_POWER_STATE): string;

implementation

uses
  SysUtils,
  Classes;

const
  powrproflib = 'powrprof.dll';

function GetPwrCapabilities(lpSystemPowerCapabilities: PSYSTEM_POWER_CAPABILITIES): Boolean; external powrproflib name 'GetPwrCapabilities';
function IsAdminOverrideActive: Boolean; external powrproflib name 'IsAdminOverrideActive';
function IsPwrHibernateAllowed: Boolean; external powrproflib name 'IsPwrHibernateAllowed';
function IsPwrShutdownAllowed: Boolean; external powrproflib name 'IsPwrShutdownAllowed';
function IsPwrSuspendAllowed: Boolean; external powrproflib name 'IsPwrSuspendAllowed';

function IsLidPresent: Boolean;
var
  LSYSTEM_POWER_CAPABILITIES: SYSTEM_POWER_CAPABILITIES;
begin
  Result := GetPwrCapabilities(@LSYSTEM_POWER_CAPABILITIES);
  if Result then
    Result := LSYSTEM_POWER_CAPABILITIES.LidPresent;
end;

function IsRunningMobile: Boolean;
begin
  Result := IsLidPresent or IsRunningOnBattery;
end;

function IsRunningOnBattery: Boolean;
begin
  Result := (GetACLineStatus = acsOffline);
end;

function IsPowerBtnPresent: Boolean;
var
  LSYSTEM_POWER_CAPABILITIES: SYSTEM_POWER_CAPABILITIES;
begin
  Result := GetPwrCapabilities(@LSYSTEM_POWER_CAPABILITIES);
  if Result then
    Result := LSYSTEM_POWER_CAPABILITIES.PowerButtonPresent;
end;

function IsApmPresent: Boolean;
var
  LSYSTEM_POWER_CAPABILITIES: SYSTEM_POWER_CAPABILITIES;
begin
  Result := GetPwrCapabilities(@LSYSTEM_POWER_CAPABILITIES);
  if Result then
    Result := LSYSTEM_POWER_CAPABILITIES.ApmPresent;
end;

function IsUpsPresent: Boolean;
var
  LSYSTEM_POWER_CAPABILITIES: SYSTEM_POWER_CAPABILITIES;
begin
  Result := GetPwrCapabilities(@LSYSTEM_POWER_CAPABILITIES);
  if Result then
    Result := LSYSTEM_POWER_CAPABILITIES.UpsPresent;
end;

function IsThermalControl: Boolean;
var
  LSYSTEM_POWER_CAPABILITIES: SYSTEM_POWER_CAPABILITIES;
begin
  Result := GetPwrCapabilities(@LSYSTEM_POWER_CAPABILITIES);
  if Result then
    Result := LSYSTEM_POWER_CAPABILITIES.ThermalControl;
end;

function GetACLineStatus: TACLineStatus;
var
  LSystemPowerStatus: TSystemPowerStatus;
begin
  Result := acsUnknown;
  if GetSystemPowerStatus(LSystemPowerStatus) then
    Result := TACLineStatus(LSystemPowerStatus.ACLineStatus);
end;

function GetACLineStatusName(const AACLineStatus: TACLineStatus): string;
begin
  Result := 'Unknown';
  case AACLineStatus of
    acsOffline: Result := 'Offline';
    acsOnline: Result := 'Online';
  end; // case AACLineStatus of
end;

function GetBatteryStatus: TBatteryStatus;
var
  LSystemPowerStatus: TSystemPowerStatus;

    procedure CheckState(const ABatteryState: TBatteryState);
    begin
      if (LSystemPowerStatus.BatteryFlag and Ord(ABatteryState)) = Ord(ABatteryState) then
        Include(Result, ABatteryState);
    end; // procedure CheckState(const ABatteryState: TBatteryState);

begin
  Result := [];
  if GetSystemPowerStatus(LSystemPowerStatus) then begin
    CheckState(bsHigh);
    CheckState(bsLow);
    CheckState(bsCritical);
    CheckState(bsCharging);
    CheckState(bsNoSystemBattery);
    CheckState(bsUnknown);
  end else
    Result := [bsUnknown];
end;

function GetBatteryStateName(const ABatteryState: TBatteryState): string;
begin
  case ABatteryState of
    bsHigh: Result := 'High';
    bsLow: Result := 'Low';
    bsCritical: Result := 'Critical';
    bsCharging: Result := 'Charging';
    bsNoSystemBattery: Result := 'No system battery';
    bsUnknown: Result := 'Unknown';
  end; // case ABatteryState of
end;

function GetBatteryStatusStr(const ABatteryState: TBatteryStatus;
  const ADelimiter: Char): string;
var
  LBatteryState: TBatteryState;
  LNames: TStringList;
begin
  Result := EmptyStr;
  LNames := TStringList.Create;
  try
    LNames.Delimiter := ADelimiter;
    for LBatteryState in ABatteryState do
      LNames.Add(GetBatteryStateName(LBatteryState));
    Result := LNames.DelimitedText;
  finally
    FreeAndNil(LNames);
  end; // tryf
end;

function GetBatteryLifePercent: Byte;
var
  LSystemPowerStatus: TSystemPowerStatus;
begin
  Result := 0;
  if GetSystemPowerStatus(LSystemPowerStatus) then
    // The percentage of full battery charge remaining.
    // This value in the range 0 to 100 or 255 if status is unknown.
    Result := LSystemPowerStatus.BatteryLifePercent;
end;

function GetBatteryLifeTime: DWORD;
var
  LSystemPowerStatus: TSystemPowerStatus;
begin
  Result := DWORD(-1);
  if GetSystemPowerStatus(LSystemPowerStatus) then
    // The number of seconds of battery life remaining,
    // or –1 if remaining seconds are unknown.
    Result := LSystemPowerStatus.BatteryLifeTime;
end;

function GetBatteryLifeTimeFull: DWORD;
var
  LSystemPowerStatus: TSystemPowerStatus;
begin
  Result := DWORD(-1);
  if GetSystemPowerStatus(LSystemPowerStatus) then
    // The number of seconds of battery life when at full charge,
    // or –1 if full battery lifetime is unknown.
    Result := LSystemPowerStatus.BatteryFullLifeTime;
end;

function GetNumberOfProcessors: DWORD;
var
  LSystemInfo: TSystemInfo;
begin
  GetSystemInfo(LSystemInfo);
  // number of processor means number of threads
  // i.e. a processor with 4 cores can have 8 threads
  Result := LSystemInfo.dwNumberOfProcessors;
end;

function GetSystemPowerStateName(const ASystemPowerState: SYSTEM_POWER_STATE): string;
begin
  Result := SYSTEM_POWER_STATE_NAMES[ASystemPowerState];
end;

end.
&lt;/PRE&gt;How to use it:&lt;br /&gt;
a) drop a memo and a button on the form, rename the memo to "edInfo"&lt;br /&gt;
b) double-click the button and copy-paste the following code&lt;br /&gt;
&lt;pre&gt;procedure TForm1.Button1Click(Sender: TObject);

  procedure AddBool(const s: string; const Value: Boolean);
  begin
    edInfo.Lines.Add(Format('%s = %s', [s, BoolToStr(Value, True)]));
  end; // procedure AddBool(const s: string; const Value: Boolean);

  procedure AddString(const s, Value: string);
  begin
     edInfo.Lines.Add(Format('%s = %s', [s, Value]));
  end; // procedure AddString(const s, Value: string);

  procedure AddPercent(const s: string; const Value: Byte);
  begin
    edInfo.Lines.Add(Format('%s = %d%%', [s, Value]));
  end; // procedure AddPercent(const s: string; const Value: Byte);

  procedure AddSeconds(const s: string; const Value: DWORD);
  begin
    edInfo.Lines.Add(Format('%s = %d sec.', [s, Value]));
  end; // procedure AddSeconds(const s: string; const Value: DWORD);

  procedure AddDWord(const s: string; const Value: DWORD);
  begin
    edInfo.Lines.Add(Format('%s = %d', [s, Value]));
  end; // procedure AddDWord(const s: string; const Value: DWORD);

begin
  edInfo.Clear;
  AddBool('IsLidPresent', IsLidPresent);
  AddBool('IsRunningMobile', IsRunningMobile);
  AddBool('IsRunningOnBattery', IsRunningOnBattery);
  AddBool('IsPowerBtnPresent', IsPowerBtnPresent);
  AddBool('IsApmPresent', IsApmPresent);
  AddBool('IsUpsPresent', IsUpsPresent);
  AddBool('IsThermalControl', IsThermalControl);
  AddString('GetACLineStatus', GetACLineStatusName(GetACLineStatus));
  AddString('GetBatteryStatusStr', GetBatteryStatusStr(GetBatteryStatus));
  AddPercent('GetBatteryLifePercent', GetBatteryLifePercent);
  // if GetBatteryLifeTime = -1 it means that laptop is either plugged in OR
  // it is running on battery for a few seconds -- Windows did NOT detect
  // yet or it can't tell for certain how many seconds left
  // also the value might increase in a couple of seconds
  AddSeconds('GetBatteryLifeTime', GetBatteryLifeTime);
  // in my tests GetBatteryLifeTimeFull retrieves only -1 it might have something
  // to do with the fact that my laptop is only a couple of days old
  // or something fails -- I'm NOT 100% sure on this, please feel free to comment
  AddSeconds('GetBatteryLifeTimeFull', GetBatteryLifeTimeFull);
  AddDWord('GetNumberOfProcessors', GetNumberOfProcessors);
end;
&lt;/PRE&gt;c) and last but not least HAVE FUN!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-6680936788349170578?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zWIqRF2SP_hfg-nR4nHoMjNbapI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zWIqRF2SP_hfg-nR4nHoMjNbapI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zWIqRF2SP_hfg-nR4nHoMjNbapI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zWIqRF2SP_hfg-nR4nHoMjNbapI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/0TMpb43kckg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/6680936788349170578/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2011/02/laptop-specific-functions.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/6680936788349170578?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/6680936788349170578?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/0TMpb43kckg/laptop-specific-functions.html" title="Laptop specific functions" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.delphigeist.com/2011/02/laptop-specific-functions.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQGR3ozfSp7ImA9Wx9VEE8.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-929313667260910267</id><published>2011-01-26T09:16:00.001+02:00</published><updated>2011-01-26T09:35:26.485+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-26T09:35:26.485+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="DWMApi" /><category scheme="http://www.blogger.com/atom/ns#" term="generics" /><category scheme="http://www.blogger.com/atom/ns#" term="utility functions" /><title>Fun with DWM</title><content type="html">&lt;a HREF="https://sites.google.com/site/delphigeist/screenshots/dwm_demo1.png"&gt;&lt;img SRC="https://sites.google.com/site/delphigeist/screenshots/dwm_demo1.png"&gt;&lt;/A&gt;&lt;br /&gt;
Sooo... you like the "Peak preview" of Windows 7?! If so, then I bet you would want to play with it in your Delphi application, correct?! cool! here's how you do it in a few steps:&lt;br /&gt;
&lt;br /&gt;
a) create a new VCL forms application;&lt;br /&gt;
b) add Dwmapi to uses clause;&lt;br /&gt;
c) copy and paste and paste from the following code;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;unit Unit1;

interface

uses
  Windows,
  Messages,
  SysUtils,
  Variants,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  Dwmapi,
  StdCtrls,
  ExtCtrls,
  Generics.Collections;

type
  TDGWindow = record
    StrCaption: string;
    StrClassName: string;
    Handle: HWND;
  end;

  TDGWindowList = class(TList&lt;tdgwindow&gt;);

type
  TfrmMain = class(TForm)
    Panel1: TPanel;
    lbWindows: TListBox;
    bnRefresh: TButton;
    bnPreview: TButton;
    procedure FormDestroy(Sender: TObject);
    procedure bnRefreshClick(Sender: TObject);
    procedure bnPreviewClick(Sender: TObject);
    procedure lbWindowsDblClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FWindowList: TDGWindowList;
    FTumbnail: HTHUMBNAIL;
    FPreviewEnabled: Boolean;
  private
    procedure PreviewWindow(const ASource, ADest: HWND; const ARect: TRect);
    procedure PreviewDisable;
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

function FindWindowExtd(partialTitle: string): HWND;
var
  hWndTemp: hWnd;
  iLenText: Integer;
  cTitletemp: array [0..254] of Char;
  sTitleTemp: string;
begin
  hWndTemp := FindWindow(nil, nil);
  while hWndTemp &lt;&gt; 0 do begin
    iLenText := GetWindowText(hWndTemp, cTitletemp, 255);
    sTitleTemp := cTitletemp;
    sTitleTemp := UpperCase(copy( sTitleTemp, 1, iLenText));
    partialTitle := UpperCase(partialTitle);
    if pos( partialTitle, sTitleTemp ) &lt;&gt; 0 then
      Break;
    hWndTemp := GetWindow(hWndTemp, GW_HWNDNEXT);
  end;
  result := hWndTemp;
end;

procedure TfrmMain.bnPreviewClick(Sender: TObject);
var
  Index: Integer;
  LRect: TRect;
begin
  Index := lbWindows.ItemIndex;
  if Index &lt; 0 then
    Exit;
  LRect := Rect(5, 5,
    Self.Width -Panel1.Width -20,
    Self.Height -10);
  PreviewWindow(
    FWindowList[Index].Handle,
    Self.Handle,
    LRect);
end;

procedure TfrmMain.bnRefreshClick(Sender: TObject);
var
  LHDesktop: HWND;
  LHWindow: HWND;
  LHParent: HWND;
  LExStyle: DWORD;
  LBuffer: array[0..255] of char;
  LWindow: TDGWindow;
begin
  lbWindows.Items.BeginUpdate;
  lbWindows.Items.Clear;
  FWindowList.Clear;
  LHDesktop := GetDeskTopWindow;
  LHWindow := GetWindow(LHDesktop, GW_CHILD);
  while LHWindow &lt;&gt; 0 do begin
    LWindow.Handle := LHWindow;
    GetWindowText(LHWindow, LBuffer, Length(LBuffer));
    LHParent := GetWindowLong(LHWindow, GWL_HWNDPARENT);
    LExStyle := GetWindowLong(LHWindow, GWL_EXSTYLE);
    if IsWindowVisible(LHWindow) and (LBuffer &lt;&gt; EmptyStr) and
        ((LHParent = 0) or (LHParent = LHDesktop)) and
        ((LExStyle and WS_EX_TOOLWINDOW = 0) or (LExStyle and WS_EX_APPWINDOW &lt;&gt; 0))
        then begin
      lbWindows.Items.Add(LBuffer);
      LWindow.StrCaption := LBuffer;
      GetClassName(LHWindow, LBuffer, Length(LBuffer));
      LWindow.StrClassName := LBuffer;
      FWindowList.Add(LWindow);
    end; // if IsWindowVisible(LHWindow) and (LBuffer &lt;&gt; EmptyStr) and ...
    LHWindow := GetWindow(LHWindow, GW_HWNDNEXT);
  end; // while LHWindow &lt;&gt; 0 do begin
  lbWindows.Items.EndUpdate;
  if lbWindows.Items.Count &gt; 0 then
    lbWindows.ItemIndex := 0;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  FPreviewEnabled := False;
  FWindowList := TDGWindowList.Create;
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
  FWindowList.Clear;
  FreeAndNil(FWindowList);
  PreviewDisable;
end;

procedure TfrmMain.lbWindowsDblClick(Sender: TObject);
begin
  bnPreview.Click;
end;

procedure TfrmMain.PreviewDisable;
begin
  if FPreviewEnabled then
    FPreviewEnabled := NOT Succeeded(DwmUnregisterThumbnail(FTumbnail));
end;

procedure TfrmMain.PreviewWindow(const ASource, ADest: HWND; const ARect: TRect);
var
  LResult: HRESULT;
  LThumpProp: DWM_THUMBNAIL_PROPERTIES;
begin
  if NOT DwmCompositionEnabled then begin
    MessageDlg('DWM composition is NOT enabled.', mtWarning, [mbOK], 0);
    Exit;
  end; // if NOT DwmCompositionEnabled then begin
  PreviewDisable;
  FPreviewEnabled := Succeeded(DwmRegisterThumbnail(ADest, ASource, @FTumbnail));
  if FPreviewEnabled then begin
    LThumpProp.dwFlags := DWM_TNP_SOURCECLIENTAREAONLY or DWM_TNP_VISIBLE or
      DWM_TNP_OPACITY or DWM_TNP_RECTDESTINATION;
    LThumpProp.fSourceClientAreaOnly := False;
    LThumpProp.fVisible := True;
    LThumpProp.opacity := 200;
    LThumpProp.rcDestination := ARect;
    LResult := DwmUpdateThumbnailProperties(FTumbnail, LThumpProp);
    FPreviewEnabled := (LResult = S_OK);
  end else
    MessageDlg('Cannot link to window  ' + IntToStr(ASource), mtError, [mbOK], 0);
end;

end.
&lt;/PRE&gt;&lt;a href="https://sites.google.com/site/delphigeist/downloads/dwm_test1.zip"&gt;or you simply download the demo application&lt;/a&gt;.&lt;br /&gt;
d) have fun!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-929313667260910267?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LxzlQEDu22CEh3JIf7-wMlEk7uU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LxzlQEDu22CEh3JIf7-wMlEk7uU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LxzlQEDu22CEh3JIf7-wMlEk7uU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LxzlQEDu22CEh3JIf7-wMlEk7uU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/-06Apr_G6bw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/929313667260910267/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2011/01/fun-with-dwm.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/929313667260910267?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/929313667260910267?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/-06Apr_G6bw/fun-with-dwm.html" title="Fun with DWM" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.delphigeist.com/2011/01/fun-with-dwm.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEEQHwzeSp7ImA9Wx9WEEU.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-2958444858218594634</id><published>2011-01-15T11:10:00.000+02:00</published><updated>2011-01-15T11:10:01.281+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-15T11:10:01.281+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="utility functions" /><category scheme="http://www.blogger.com/atom/ns#" term="virtual machine" /><title>uDGVMUtils version 1.1 thanks to Chee Meng</title><content type="html">Thanks to Chee Meng I've added a detection scheme for Virtual Box.&lt;br /&gt;
Please let me know of any scenario in which a function fails to return properly so that I can modify the code.&lt;br /&gt;
&lt;PRE&gt;unit uDGVMUtils;

interface

(*******************************************************************************

  uDGVMUtils -- is an attempt to create one of the best virtual machine
    detector methods, feel free to contribute in any way you wish.

  Version 1.1, 2010-01-15

  Copyright© you are free to use it for comercial, private or both purposes

  Contributors:
    Dorin Duminica
    Chee Meng

*******************************************************************************)

type
  TVMWareVersion = (
    vvExpress = 1,
    vvESX,
    vvGSX,
    vvWorkstation,
    vvUnknown,
    vvNative);

const
  VMWARE_VERSION_STRINGS: array [TVMWareVersion] of string = (
    'Express',
    'ESX',
    'GSX',
    'Workstation',
    'Unknown',
    'Native');

type
  TVirtualMachineType = (
    vmNative,
    vmVMWare,
    vmWine,
    vmVirtualPC,
    vmVirtualBox);

const
  VIRTUALMACHINE_STRINGS: array[TVirtualMachineType] of string = (
    'Native',
    'VMWare',
    'Wine',
    'Virtual PC',
    'Virtual Box');

function IsRunningVMWare(var AVMWareVersion: TVMWareVersion): Boolean; overload;
function IsRunningVMWare: Boolean; overload;
function IsRunningWine(var AWineVersion: string): Boolean; overload;
function IsRunningWine: Boolean; overload;
function IsRunningVirtualPC: Boolean;
function IsRunningVBox: Boolean;
function IsRunningVM(var AVMVersion: string): Boolean; overload;
function IsRunningVM: Boolean; overload;

implementation

uses
  SysUtils,
  Windows;

function IsRunningVMWare(var AVMWareVersion: TVMWareVersion): Boolean;
const
  CVMWARE_FLAG = $564D5868;
var
  LFlag: Cardinal;
  LVersion: Cardinal;
begin
  LFlag := 0;
  try
    asm
      push eax
      push ebx
      push ecx
      push edx

      mov eax, 'VMXh'
      mov ecx, 0Ah
      mov dx, 'VX'

      in eax, dx

      mov LFlag, ebx
      mov LVersion, ecx

      pop edx
      pop ecx
      pop ebx
      pop eax
    end;
  except
//  uncomment next two lines if you wish to see exception
//    on E: Exception do
//      ShowMessage(E.message);
  end; // trye
  if LFlag = CVMWARE_FLAG then begin
    Result := True;
    case LVersion of
      1: AVMWareVersion := vvExpress;
      2: AVMWareVersion := vvESX;
      3: AVMWareVersion := vvGSX;
      4: AVMWareVersion := vvWorkstation;
      else
        AVMWareVersion := vvUnknown;
    end
  end else begin
    Result := False;
    AVMWareVersion := vvNative;
  end; // if LFlag = CVMWARE_FLAG then begin
end;

function IsRunningVMWare: Boolean;
var
  LVMWareVersion: TVMWareVersion;
begin
  Result := IsRunningVMWare(LVMWareVersion);
end;

function IsRunningWine(var AWineVersion: string): Boolean;
type
  TWineGetVersion = function: PAnsiChar;{$IFDEF Win32}stdcall;{$ENDIF}
  TWineNTToUnixFileName = procedure (P1: Pointer; P2: Pointer);{$IFDEF Win32}stdcall;{$ENDIF}
var
  LHandle: THandle;
  LWineGetVersion: TWineGetVersion;
  LWineNTToUnixFileName: TWineNTToUnixFileName;
begin
  Result := False;
  AWineVersion := 'Unknown';
  LHandle := LoadLibrary('ntdll.dll');
  if LHandle &gt; 32 then begin
    LWineGetVersion := GetProcAddress(LHandle, 'wine_get_version');
    LWineNTToUnixFileName := GetProcAddress(LHandle, 'wine_nt_to_unix_file_name');
    if Assigned(LWineGetVersion) or Assigned(LWineNTToUnixFileName) then begin
      Result := True;
      if Assigned(LWineGetVersion) then
        AWineVersion := StrPas(LWineGetVersion);
    end; // if Assigned(LWineGetVersion) or ...
    FreeLibrary(LHandle);
  end; // if LHandle &gt; 32 then begin
end;

function IsRunningWine: Boolean;
var
  LWineVersion: string;
begin
  Result := IsRunningWine(LWineVersion);
end;

function IsRunningVirtualPC: Boolean;
asm
  push ebp;
  mov ebp, esp;

  mov ecx, offset @exception_handler;

  push ebx;
  push ecx;

  push dword ptr fs:[0];
  mov dword ptr fs:[0], esp;

  mov ebx, 0; // Flag
  mov eax, 1; // VPC function number

  // call VPC
  db $0F, $3F, $07, $0B

  mov eax, dword ptr ss:[esp];
  mov dword ptr fs:[0], eax;

  add esp, 8;

  test ebx, ebx;

  setz al;

  lea esp, dword ptr ss:[ebp-4];
  mov ebx, dword ptr ss:[esp];
  mov ebp, dword ptr ss:[esp+4];

  add esp, 8;

  jmp @ret1;

  @exception_handler:
  mov ecx, [esp+0Ch];
  mov dword ptr [ecx+0A4h], -1; // EBX = -1 -&gt;; not running, ebx = 0 -&gt; running
  add dword ptr [ecx+0B8h], 4; // -&gt;; skip past the call to VPC
  xor eax, eax; // exception is handled

  @ret1:
end;

function IsRunningVBox: Boolean;

  function Test1: Boolean;
  var
    LHandle: Cardinal;
  begin
    Result := False;
    try
      LHandle := LoadLibrary('VBoxHook.dll');
      Result := (LHandle &lt;&gt; 0);
      if Result then
        FreeLibrary(LHandle);
    except
    end; // trye
  end; // function Test1: Boolean;

  function Test2: Boolean;
  var
    LHandle: Cardinal;
  begin
    Result := False;
    try
      LHandle := CreateFile(
        '\\\\.\\\VBoxMiniRdrDN',
        GENERIC_READ,
        FILE_SHARE_READ,
        NIL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        0);
      Result := (LHandle &lt;&gt; INVALID_HANDLE_VALUE);
      if Result then
        CloseHandle(LHandle);
    except
    end; // trye
  end; // function Test2: Boolean;

begin
  Result := Test1 or Test2;
end;

function IsRunningVM(var AVMVersion: string): Boolean;
begin
  AVMVersion := VIRTUALMACHINE_STRINGS[vmNative];
  Result := True;
  if IsRunningWine then
    AVMVersion := VIRTUALMACHINE_STRINGS[vmWine]
  else
    if IsRunningVMWare then
      AVMVersion := VIRTUALMACHINE_STRINGS[vmVMWare]
    else
      if IsRunningVirtualPC then
        AVMVersion := VIRTUALMACHINE_STRINGS[vmWine]
      else
        if IsRunningVBox then
          AVMVersion := VIRTUALMACHINE_STRINGS[vmVirtualBox]
        else begin
          AVMVersion := VIRTUALMACHINE_STRINGS[vmNative];
          Result := False;
        end;
end;

function IsRunningVM: Boolean;
var
  LVMVersion: string;
begin
  Result := IsRunningVM(LVMVersion);
end;

end.
&lt;/PRE&gt;&lt;FONT SIZE=3&gt;HAVE FUN&lt;/FONT&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-2958444858218594634?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MeG3UieJBhiZ5dEBn3cCkYfFC2c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MeG3UieJBhiZ5dEBn3cCkYfFC2c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MeG3UieJBhiZ5dEBn3cCkYfFC2c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MeG3UieJBhiZ5dEBn3cCkYfFC2c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/L8-rVwYO5sk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/2958444858218594634/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2011/01/udgvmutils-version-11-thanks-to-chee.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/2958444858218594634?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/2958444858218594634?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/L8-rVwYO5sk/udgvmutils-version-11-thanks-to-chee.html" title="uDGVMUtils version 1.1 thanks to Chee Meng" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.delphigeist.com/2011/01/udgvmutils-version-11-thanks-to-chee.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QHQHc4fyp7ImA9Wx9XGEs.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-5783562872659700096</id><published>2011-01-12T15:01:00.001+02:00</published><updated>2011-01-12T22:48:51.937+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-12T22:48:51.937+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="utility functions" /><category scheme="http://www.blogger.com/atom/ns#" term="virtual machine" /><title>Is your app running in a virtual machine?</title><content type="html">Here's an extremely simple unit that will check if your application is running under VMWare, Wine and or Virtual PC:&lt;br /&gt;
&lt;pre&gt;unit uDGVMUtils;

interface

type
  TVMWareVersion = (
    vvExpress = 1,
    vvESX,
    vvGSX,
    vvWorkstation,
    vvUnknown,
    vvNative);

const
  VMWARE_VERSION_STRINGS: array [TVMWareVersion] of string = (
    'Express',
    'ESX',
    'GSX',
    'Workstation',
    'Unknown',
    'Native');

type
  TVirtualMachineType = (
    vmNative,
    vmVMWare,
    vmWine,
    vmVirtualPC);

const
  VIRTUALMACHINE_STRINGS: array[TVirtualMachineType] of string = (
    'Native',
    'VMWare',
    'Wine',
    'Virtual PC');

function IsRunningVMWare(var AVMWareVersion: TVMWareVersion): Boolean; overload;
function IsRunningVMWare: Boolean; overload;
function IsRunningWine(var AWineVersion: string): Boolean; overload;
function IsRunningWine: Boolean; overload;
function IsRunningVirtualPC: Boolean;
function IsRunningVM(var AVMVersion: string): Boolean; overload;
function IsRunningVM: Boolean; overload;

implementation

uses
  SysUtils,
  Windows;

function IsRunningVMWare(var AVMWareVersion: TVMWareVersion): Boolean;
const
  CVMWARE_FLAG = $564D5868;
var
  LFlag: Cardinal;
  LVersion: Cardinal;
begin
  LFlag := 0;
  try
    asm
      push eax
      push ebx
      push ecx
      push edx

      mov eax, 'VMXh'
      mov ecx, 0Ah
      mov dx, 'VX'

      in eax, dx

      mov LFlag, ebx
      mov LVersion, ecx

      pop edx
      pop ecx
      pop ebx
      pop eax
    end;
  except
//  uncomment next two lines if you wish to see exception
//    on E: Exception do
//      ShowMessage(E.message);
  end; // trye
  if LFlag = CVMWARE_FLAG then begin
    Result := True;
    case LVersion of
      1: AVMWareVersion := vvExpress;
      2: AVMWareVersion := vvESX;
      3: AVMWareVersion := vvGSX;
      4: AVMWareVersion := vvWorkstation;
      else
        AVMWareVersion := vvUnknown;
    end
  end else begin
    Result := False;
    AVMWareVersion := vvNative;
  end; // if LFlag = CVMWARE_FLAG then begin
end;

function IsRunningVMWare: Boolean;
var
  LVMWareVersion: TVMWareVersion;
begin
  Result := IsRunningVMWare(LVMWareVersion);
end;

function IsRunningWine(var AWineVersion: string): Boolean;
type
  TWineGetVersion = function: PAnsiChar;{$IFDEF Win32}stdcall;{$ENDIF}
  TWineNTToUnixFileName = procedure (P1: Pointer; P2: Pointer);{$IFDEF Win32}stdcall;{$ENDIF}
var
  LHandle: THandle;
  LWineGetVersion: TWineGetVersion;
  LWineNTToUnixFileName: TWineNTToUnixFileName;
begin
  Result := False;
  AWineVersion := 'Unknown';
  LHandle := LoadLibrary('ntdll.dll');
  if LHandle &gt; 32 then begin
    LWineGetVersion := GetProcAddress(LHandle, 'wine_get_version');
    LWineNTToUnixFileName := GetProcAddress(LHandle, 'wine_nt_to_unix_file_name');
    if Assigned(LWineGetVersion) or Assigned(LWineNTToUnixFileName) then begin
      Result := True;
      if Assigned(LWineGetVersion) then
        AWineVersion := StrPas(LWineGetVersion);
    end; // if Assigned(LWineGetVersion) or ...
    FreeLibrary(LHandle);
  end; // if LHandle &gt; 32 then begin
end;

function IsRunningWine: Boolean;
var
  LWineVersion: string;
begin
  Result := IsRunningWine(LWineVersion);
end;

function IsRunningVirtualPC: Boolean;
asm
  push ebp;
  mov ebp, esp;

  mov ecx, offset @exception_handler;

  push ebx;
  push ecx;

  push dword ptr fs:[0];
  mov dword ptr fs:[0], esp;

  mov ebx, 0; // Flag
  mov eax, 1; // VPC function number

  // call VPC
  db $0F, $3F, $07, $0B

  mov eax, dword ptr ss:[esp];
  mov dword ptr fs:[0], eax;

  add esp, 8;

  test ebx, ebx;

  setz al;

  lea esp, dword ptr ss:[ebp-4];
  mov ebx, dword ptr ss:[esp];
  mov ebp, dword ptr ss:[esp+4];

  add esp, 8;

  jmp @ret1;

  @exception_handler:
  mov ecx, [esp+0Ch];
  mov dword ptr [ecx+0A4h], -1; // EBX = -1 -&gt;; not running, ebx = 0 -&gt; running
  add dword ptr [ecx+0B8h], 4; // -&gt;; skip past the call to VPC
  xor eax, eax; // exception is handled

  @ret1:
end;

function IsRunningVM(var AVMVersion: string): Boolean;
begin
  AVMVersion := VIRTUALMACHINE_STRINGS[vmNative];
  Result := True;
  if IsRunningWine then
    AVMVersion := VIRTUALMACHINE_STRINGS[vmWine]
  else
    if IsRunningVMWare then
      AVMVersion := VIRTUALMACHINE_STRINGS[vmVMWare]
    else
      if IsRunningVirtualPC then
        AVMVersion := VIRTUALMACHINE_STRINGS[vmVirtualPC]
      else begin
        AVMVersion := VIRTUALMACHINE_STRINGS[vmNative];        
        Result := False;
      end;
end;

function IsRunningVM: Boolean;
var
  LVMVersion: string;
begin
  Result := IsRunningVM(LVMVersion);
end;

end.
&lt;/PRE&gt;usage:&lt;br /&gt;
add uDGVMUtils to uses clause and:&lt;br /&gt;
// check if running in a virtual machine&lt;br /&gt;
var&lt;br /&gt;
LVMVersion: string;&lt;br /&gt;
begin&lt;br /&gt;
ShowMessageFmt('%s, VM name: %s', [BoolToStr(IsRunningVM(LVMVersion), True), LVMVersion]);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// check if running in wine&lt;br /&gt;
var&lt;br /&gt;
LWine: Boolean;&lt;br /&gt;
LWineVersion: string;&lt;br /&gt;
begin&lt;br /&gt;
ShowMessageFmt('Wine: %s, Wine ver.: %s', [BoolToStr(IsRunningWine(LWineVersion), True), LWineVersion]);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
you get the picture, have fun!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-5783562872659700096?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Z3opO34q9Muiaf6jtEgwXFJSa9E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Z3opO34q9Muiaf6jtEgwXFJSa9E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Z3opO34q9Muiaf6jtEgwXFJSa9E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Z3opO34q9Muiaf6jtEgwXFJSa9E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/-EvHDgnZOxI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/5783562872659700096/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2011/01/is-your-app-running-in-virtual-machine.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/5783562872659700096?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/5783562872659700096?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/-EvHDgnZOxI/is-your-app-running-in-virtual-machine.html" title="Is your app running in a virtual machine?" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.delphigeist.com/2011/01/is-your-app-running-in-virtual-machine.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cDSXk9eyp7ImA9Wx9XFEQ.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-7584898289578545829</id><published>2011-01-08T15:55:00.002+02:00</published><updated>2011-01-08T15:57:58.763+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-08T15:57:58.763+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="database" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><title>Client activity information in PostgreSQL</title><content type="html">In most of my projects I use &lt;a href="http://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt; as database, I'm sure that if you see what you get for free, most of you will turn to it, anyhu' this post is about getting information from database, such as:&lt;br /&gt;
- databases to which has connections to it;&lt;br /&gt;
- current queries ran on X database and the timestamp when the query was started;&lt;br /&gt;
- ID's of processes;&lt;br /&gt;
- user name of connected clients;&lt;br /&gt;
- port on which each client is connected;&lt;br /&gt;
- client IP address;&lt;br /&gt;
- based upon above information we can get more special info regarding active connections;&lt;br /&gt;
&lt;br /&gt;
In order to see all of the above, run this query on the database:&lt;br /&gt;
&lt;blockquote&gt;SELECT * FROM PG_STAT_ACTIVITY;&lt;br /&gt;
&lt;/BLOCKQUOTE&gt;The reason I was interested in this kind of information is that from time to time the database structure changes, therefore I need to run queries on previous database structures in order to fulfill latest needs, sooo... in order to upgrade the database I require that &lt;b&gt;NO&lt;/B&gt; one else besides my "upgrade" application is connected to the database, therefore I run the following query in order to see to how many connections I have to X database, if the number of connections is greater than 1(if I'm connected to the database, I will be counted as well) then the application will wait until the number of connections to X database reaches 1 and then run the update queries, the query that I'm using is:&lt;br /&gt;
&lt;blockquote&gt;SELECT DATNAME AS "Database", COUNT(*) AS "ConnectionCount" FROM PG_STAT_ACTIVITY GROUP BY "Database";&lt;br /&gt;
&lt;/BLOCKQUOTE&gt;and this will result in showing:&lt;br /&gt;
&lt;table&gt;&lt;tr&gt; &lt;th&gt;Database&lt;/Th&gt; &lt;th&gt;ConnectionCount&lt;/h&gt; &lt;/TR&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;tr&gt; &lt;td&gt;X db&lt;/TD&gt; &lt;td&gt;2&lt;/TD&gt; &lt;/TR&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;tr&gt; &lt;td&gt;Y db&lt;/TD&gt; &lt;td&gt;70&lt;/TD&gt; &lt;/TR&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;tr&gt; &lt;td COLSPAN="2"&gt;etc.&lt;/TD&gt; &lt;/TR&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/TABLE&gt;Well that's about all that I wanted to point out for now, do you have any special queries you run on a PostgreSQL database and want to share? comment bellow and I will put above this final thought like:&lt;br /&gt;
Name:&lt;br /&gt;
SQL QUERY&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-7584898289578545829?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FwWeOo2_W2mBo3tilAl-MX-GCNo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FwWeOo2_W2mBo3tilAl-MX-GCNo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FwWeOo2_W2mBo3tilAl-MX-GCNo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FwWeOo2_W2mBo3tilAl-MX-GCNo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/eaUw01K8HUU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/7584898289578545829/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2011/01/client-activity-information-in.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/7584898289578545829?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/7584898289578545829?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/eaUw01K8HUU/client-activity-information-in.html" title="Client activity information in PostgreSQL" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.delphigeist.com/2011/01/client-activity-information-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YFSHs6fyp7ImA9Wx9QGE4.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-2910726887525960957</id><published>2011-01-01T00:38:00.000+02:00</published><updated>2011-01-01T00:38:39.517+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-01T00:38:39.517+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="new year" /><title>Happy new year!!</title><content type="html">I wish you all a happy new year!!&lt;br /&gt;
Saale Nao Mubbarak&lt;br /&gt;
Gelukkige nuwe jaar&lt;br /&gt;
Gezuar Vitin e Ri&lt;br /&gt;
Snorhavor Nor Tari&lt;br /&gt;
Kul 'am wa antum bikhair&lt;br /&gt;
Sheta Brikhta&lt;br /&gt;
Yeni Iliniz Mubarek!&lt;br /&gt;
Noki saal mubarrak bibi&lt;br /&gt;
Shuvo Nabo Barsho&lt;br /&gt;
Bloavezh Mat&lt;br /&gt;
×åñòèòà Íîâà Ãîäèíà&lt;br /&gt;
Soursdey Chhnam Tmei&lt;br /&gt;
FELIÇ ANY NOU&lt;br /&gt;
Nuo bazzor bekkunore&lt;br /&gt;
Xin Nian Kuai Le&lt;br /&gt;
Pace e Salute&lt;br /&gt;
Sretna Nova godina!&lt;br /&gt;
Blwyddyn Newydd Dda&lt;br /&gt;
Šťastný Nový rok&lt;br /&gt;
Godt Nytår&lt;br /&gt;
Ufaaveri Aa Aharakah Edhen&lt;br /&gt;
GELUKKIG NIEUWJAAR!&lt;br /&gt;
Kiortame pivdluaritlo&lt;br /&gt;
Felican Novan Jaron&lt;br /&gt;
Head uut aastat!&lt;br /&gt;
MELKAM ADDIS AMET YIHUNELIWO!&lt;br /&gt;
RUHUS HADUSH AMET&lt;br /&gt;
Onnellista Uutta Vuotta&lt;br /&gt;
Bonne Annee&lt;br /&gt;
Bliadhna mhath ur&lt;br /&gt;
Bo Nadal e Feliz Aninovo&lt;br /&gt;
Prosit Neujahr&lt;br /&gt;
GILOTSAVT AKHAL TSELS!&lt;br /&gt;
Kenourios Chronos&lt;br /&gt;
Nutan Varshbhinandan&lt;br /&gt;
Hauoli Makahiki Hou&lt;br /&gt;
L'Shannah Tovah&lt;br /&gt;
Naye Varsha Ki Shubhkamanyen&lt;br /&gt;
Sun Leen Fai Lok&lt;br /&gt;
Boldog Új Évet Kivánok&lt;br /&gt;
Selamat Tahun Baru&lt;br /&gt;
Sal -e- no mobarak&lt;br /&gt;
Sanah Jadidah&lt;br /&gt;
Bliain nua fe mhaise dhuit&lt;br /&gt;
Felice anno nuovo&lt;br /&gt;
Akimashite Omedetto Gozaimasu&lt;br /&gt;
Asegwas Amegaz&lt;br /&gt;
Hosa Varushadha Shubhashayagalu&lt;br /&gt;
SOMWAKA OMOYIA OMUYA&lt;br /&gt;
Snem Thymmai Basuk Iaphi&lt;br /&gt;
Sua Sdei tfnam tmei&lt;br /&gt;
Saehae Bock Mani ba deu sei yo!&lt;br /&gt;
NEWROZ PIROZBE&lt;br /&gt;
Laimīgo Jauno Gadu!&lt;br /&gt;
Laimingu Naujuju Metu&lt;br /&gt;
Sabai dee pee mai&lt;br /&gt;
Srekjna Nova Godina&lt;br /&gt;
Tratry  ny  taona&lt;br /&gt;
Selamat Tahun Baru&lt;br /&gt;
Nveen Varshachy Shubhechcha&lt;br /&gt;
Puthuvatsara Aashamsakal&lt;br /&gt;
Kum Thar Chibai&lt;br /&gt;
Is-Sena t-Tajba&lt;br /&gt;
Nawa Barsha ko Shuvakamana&lt;br /&gt;
Godt Nyttår&lt;br /&gt;
Nua Barshara Subhechha&lt;br /&gt;
Nupela yia i go long yu&lt;br /&gt;
Masaganang Bayung Banua&lt;br /&gt;
Nawai Kall Mo Mubarak Shah&lt;br /&gt;
Sal -e- no mobarak&lt;br /&gt;
Manigong Bagong Taon!&lt;br /&gt;
Szczesliwego Nowego Roku&lt;br /&gt;
Feliz Ano Novo&lt;br /&gt;
Nave sal di mubarak&lt;br /&gt;
AN NOU FERICIT&lt;br /&gt;
S Novim Godom&lt;br /&gt;
Manuia le Tausaga Fou&lt;br /&gt;
Sretna nova godina&lt;br /&gt;
Nayou Saal Mubbarak Hoje&lt;br /&gt;
Subha Aluth Awrudhak Vewa&lt;br /&gt;
Nawan Saal Shala Mubarak Theevay&lt;br /&gt;
Stastny Novy rok&lt;br /&gt;
sreèno novo leto&lt;br /&gt;
Iyo Sanad Cusub Oo Fiican!&lt;br /&gt;
Feliz Ano ~Nuevo&lt;br /&gt;
Heri Za Mwaka Mpyaº&lt;br /&gt;
GOTT NYTT ÅR!&lt;br /&gt;
Warsa Enggal&lt;br /&gt;
Eniya Puthandu Nalvazhthukkal&lt;br /&gt;
Losar Tashi Delek&lt;br /&gt;
Noothana samvatsara shubhakankshalu&lt;br /&gt;
Sawadee Pee Mai&lt;br /&gt;
Yeni Yiliniz Kutlu Olsun&lt;br /&gt;
Shchastlyvoho Novoho Roku&lt;br /&gt;
Naya Saal Mubbarak Ho&lt;br /&gt;
Yangi Yil Bilan&lt;br /&gt;
Chuc Mung Tan Nien&lt;br /&gt;
Blwyddyn Newydd Dda!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-2910726887525960957?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0AXVqLAG-5rG4ZnJlLmSz4ArmnY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0AXVqLAG-5rG4ZnJlLmSz4ArmnY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0AXVqLAG-5rG4ZnJlLmSz4ArmnY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0AXVqLAG-5rG4ZnJlLmSz4ArmnY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/GRzQQllVPAM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/2910726887525960957/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2011/01/happy-new-year.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/2910726887525960957?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/2910726887525960957?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/GRzQQllVPAM/happy-new-year.html" title="Happy new year!!" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.delphigeist.com/2011/01/happy-new-year.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUFRHk9cSp7ImA9Wx9QEUs.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-264133632758081789</id><published>2010-12-24T05:10:00.000+02:00</published><updated>2010-12-24T05:10:15.769+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-24T05:10:15.769+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="management" /><title>You gotta grow bigger ballz</title><content type="html">I had a few interesting conversations with a few very smart people the past few days and it came to me that I've never posted about an very interesting thing -- some people are afraid to ask some questions because they don't want to be categorized as &lt;B&gt;stupid people&lt;/B&gt; or &lt;B&gt;dumb as f**k&lt;/B&gt;, etc. -- now I'm pretty sure that some of you out there fall into this category, don't be shy we all been there.&lt;br /&gt;
&lt;br /&gt;
Let's analyze a simple scenario: you are(or someone is) assigned to a new project(either in a company or as a independent contractor) there's a big chance that some parts of the project are harder to understand at first, however some people prefer &lt;B&gt;not&lt;/B&gt; to ask 2, 3 or more times if they didn't get it the first time -- &lt;B&gt;HUGE MISTAKE!!&lt;/B&gt; why is that a huge mistake?! well there is also a fat chance that you will waste time trying to figure some parts out and you might as well fail to deliver on time(happened to almost any person out there or will happen), however if you had ask the manager/client(s) for more details or simply say "I don't understand this and/or that" you could have win a lot of time and also gain trust(there are quite a few people that do appreciate when others admit that they've lost track of the conversation or something isn't clear -- why? because they can see on the spot that you are truly interested in doing a good job!) -- we all know that time is our biggest enemy(for example a day in my life should have at least 30 hours -- same for my clients, cheers!!).&lt;br /&gt;
&lt;br /&gt;
The above example can be applied anywhere, from factory work to software development to rocket science, you name it...&lt;br /&gt;
&lt;br /&gt;
Now I can see some managers going: some of my people always say "I got this", "I understand", "no need for more details", etc. but they actually don't... well yes, some people needs to be pushed from behind a bit, others can grow some balls over time and say "I haven't been concentrating enough to understand" or "sorry I've lost you at X point in the conversation, can you repeat the last part?" -- but these people are few, I won't make up bullshit percentage, I'm just talking from my past and present experience with people, however I can tell you that the number of people who are afraid to ask or simply don't give a damn is pretty big, maybe too big, but as one of my closest friend and client says&lt;br /&gt;
&lt;BLOCKQUOTE&gt;It is what it is, we just got to deal with it...&lt;br /&gt;
&lt;/BLOCKQUOTE&gt;I would recommend spending some time with this people(coworkers, friends, family) and help them bypass their issues in order to get the best out of them, do NOT under any circumstances call them names just because he/she didn't get something the first, second or even third time, there are a lot of reasons why he/she lost focus:&lt;br /&gt;
- personal problems -- most often&lt;br /&gt;
- was concentrating on a personal project -- rarely&lt;br /&gt;
- something distracted the attention along the conversation -- very often, we are surrounded by a lot of gadgets and blinking LED's that it's pretty easy to lose focus&lt;br /&gt;
- etc. you get the point...&lt;br /&gt;
&lt;br /&gt;
I believe the keywords are: "take responsibility" and "have the guts to ask" try to master these two, only good things can come to you.&lt;br /&gt;
&lt;br /&gt;
I also want to cover in a few words the "my boss/manager is an idiot, asks only dumb questions, etc., I don't get why he/she is a boss/manager and I'm just a employee" -- well, I can tell you that they grew some balls over time and as a friend of mine says "they grew thicker skin", if you want to succeed, you really must take everything as it is and step by step get to the end goal.&lt;br /&gt;
&lt;br /&gt;
If you're reading this before January 1st 2011 you really need to get a break, spend some time with your family!!&lt;br /&gt;
&lt;br /&gt;
Merry Christmas and a happy new year to all you coders out there!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-264133632758081789?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ze-gqywy7VyxOVcVpNltZIAL-8w/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ze-gqywy7VyxOVcVpNltZIAL-8w/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ze-gqywy7VyxOVcVpNltZIAL-8w/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ze-gqywy7VyxOVcVpNltZIAL-8w/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/4hSXZPwsUB4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/264133632758081789/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/12/you-gotta-grow-bigger-ballz.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/264133632758081789?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/264133632758081789?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/4hSXZPwsUB4/you-gotta-grow-bigger-ballz.html" title="You gotta grow bigger ballz" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/12/you-gotta-grow-bigger-ballz.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk4AQ3g8fSp7ImA9Wx9QEE4.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-6089014009812407377</id><published>2010-12-22T18:22:00.000+02:00</published><updated>2010-12-22T18:22:22.675+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-22T18:22:22.675+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Indy" /><category scheme="http://www.blogger.com/atom/ns#" term="DWScript" /><title>Dynamic web pages with DWScript and IdHTTPServer</title><content type="html">I've finally found some time in my busy schedule to write a new post, this post is about generating dynamic web pages using DWScript(&lt;a href="http://www.delphitools.info"&gt;http://www.delphitools.info&lt;/a&gt; -- if you find DWScript useful please do not hesitate to donate to Eric, he is doing a wonderful job with DWScript) as script interpreter and IdHTTPServer as HTTP server.&lt;br /&gt;
But first let's understand the difference between static and dynamic web pages:&lt;br /&gt;
1. Static web pages:&lt;br /&gt;
- static web pages are just plain HTML files which will be manually updated by the developer or website owner whenever he wants;&lt;br /&gt;
Here's a drawing of the process that takes place in the case of static web pages&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://sites.google.com/site/delphigeist/downloads/blogimg/static_webpage.png"&gt;&lt;img SRC="https://sites.google.com/site/delphigeist/downloads/blogimg/static_webpage.png" WIDTH="470" HEIGHT="300"&gt;&lt;/IMG&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
2. Dynamic web pages:&lt;br /&gt;
- dynamic web pages are similar to static HTML files, however this HTML files also contain script which is interpreted by a script interpreter which can be almost any script interpreter out there, i.e. perl, php, python, ruby, etc. for this example I've used DWScript;&lt;br /&gt;
Here's a drawing of the process that takes place in the case of dynamic web pages&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://sites.google.com/site/delphigeist/downloads/blogimg/dynamic_webpage.png"&gt;&lt;img SRC="https://sites.google.com/site/delphigeist/downloads/blogimg/dynamic_webpage.png" WIDTH="470" HEIGHT="300"&gt;&lt;/IMG&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
as you can see the noticeable difference between static and dynamic web pages is the script interpreter which comes into play just before serving the HTML to the client.&lt;br /&gt;
&lt;br /&gt;
In this post I won't cover the benefits of using dynamic web pages and the possible exploits.&lt;br /&gt;
&lt;br /&gt;
For this post I've modified the HTTP server which I've created for a &lt;a href="http://www.delphigeist.com/2010/11/dgtv-idhttpserver.html"&gt;video tutorial&lt;/a&gt;, so here's the updated source of the uClientContext.pas file:&lt;br /&gt;
&lt;pre&gt;unit uClientContext;

interface

uses
  SysUtils,
  Classes,
  IdBaseComponent,
  IdComponent,
  IdCustomTCPServer,
  IdCustomHTTPServer,
  IdHTTPServer,
  IdContext,
  dwsComp,
  dwsCompiler,
  dwsExprs,
  dwsClassesLibModule,
  dwsMathFunctions,
  dwsStringFunctions,
  dwsStringResult,
  dwsTimeFunctions,
  dwsVariantFunctions,
  dwsHtmlFilter;

type
  TClientContext = class(TIdServerContext)
  private
    FLogStrings: TStrings;
    procedure Log(const s: string);
  public
    procedure HandleRequest(ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);
    procedure ServeHTMLFile(const AFileName: string;
      ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);
  public
    property LogStrings: TStrings read FLogStrings write FLogStrings;
  end;

implementation

var
  WebDir: string;

{ TClientContext }

procedure TClientContext.HandleRequest(ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);
const
  SERROR_404 = 'Error 404 page not found "%s"';
var
  LLocation: string;
begin
  try
    LLocation := ARequestInfo.Document;
    if LLocation &lt;&gt; EmptyStr then begin
      if (LLocation = '/') or (LLocation = '/*') or SameText(LLocation, '/index.html') then
        ServeHTMLFile(WebDir + 'index.html', ARequestInfo, AResponseInfo)
      else begin
        LLocation := WebDir + Copy(LLocation, 2, MaxInt);
        if NOT SameText(ExtractFileExt(LLocation), '.html') then
          LLocation := LLocation + '.html';
        if FileExists(LLocation) then
          ServeHTMLFile(LLocation, ARequestInfo, AResponseInfo)
        else
          AResponseInfo.ContentText := Format(SERROR_404, [LLocation]);
      end;
    end else
      AResponseInfo.ContentText := Format(SERROR_404, [LLocation]);
  except
    on E: Exception do
      Log('Exception occured from IP ' + Connection.Socket.Binding.PeerIP +
        sLineBreak + E.Message);
  end; // trye
end;

procedure TClientContext.ServeHTMLFile(const AFileName: string;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  LHTMLFile: TStringList;
  LScript: TDelphiWebScript;
  LHTMLFilter: TdwsHtmlFilter;
  LClasses: TdwsClassesLib;
  LProgram: TdwsProgram;
begin
  LScript := TDelphiWebScript.Create(NIL);
  LScript.Config.ScriptPaths.Add(WebDir);
  LClasses := TdwsClassesLib.Create(NIL);
  LHTMLFilter := TdwsHtmlFilter.Create(NIL);
  LScript.Config.Filter := LHTMLFilter;
  LScript.AddUnit(TdwsHtmlUnit.Create(LScript));
  LScript.AddUnit(Tdws2StringsUnit.Create(LScript));
  LHTMLFile := TStringList.Create;
  try
    LClasses.Script := LScript;
    LHTMLFile.LoadFromFile(AFileName);
    LProgram := LScript.Compile(LHTMLFile.Text);
    try
      if NOT LProgram.Msgs.HasErrors then begin
        LProgram.Execute;
        AResponseInfo.ContentText := (LProgram.Result as TdwsDefaultResult).Text;
      end else
        AResponseInfo.ContentText := LProgram.Msgs.AsInfo
    finally
      FreeAndNil(LProgram);
    end; // tryf
  finally
    FreeAndNil(LHTMLFile);
    FreeAndNil(LClasses);
    FreeAndNil(LScript);
    FreeAndNil(LHTMLFilter);
  end; // tryf
end;

procedure TClientContext.Log(const s: string);
begin
  if Assigned(FLogStrings) then
    FLogStrings.Add(s);
end;

initialization
  WebDir := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)) + 'www');

end.
&lt;/PRE&gt;as you can see the source code is pretty similar to the initial code, just that I've added a new method called &lt;b&gt;ServeHTMLFile&lt;/B&gt; -- this method is called only if the requested HTML file is found in the www directory.&lt;br /&gt;
&lt;b&gt;Technique&lt;/B&gt;: we don't create the interpreter instance unless the requested file is found in the www directory -- the reason is pretty obvious, we try to avoid memory allocation if it's not necessary, we could also improve the efficiency by caching the files in memory in order to serve them faster(RAM IO is faster than disk IO therefore this will give a significant speed improvement when server has thousands requests per second) however this will be covered in a future post hopefully.&lt;br /&gt;
In order to provide a proof of concept I've created a fairly simple "website" which has 3 buttons, each button redirects the client to a new web page:&lt;br /&gt;
index.html file&lt;br /&gt;
&lt;pre&gt;&amp;lt;HTML&amp;gt;
  &amp;lt;BODY&amp;gt;
    Hello world!!&amp;lt;BR&amp;gt;
    &amp;lt;BUTTON ONCLICK="window.location.href='/primes100.html'"&amp;gt;show me primes up to 100&amp;lt;/BUTTON&amp;gt; &amp;lt;BR&amp;gt;
    &amp;lt;BUTTON ONCLICK="window.location.href='/primes200.html'"&amp;gt;show me primes up to 200&amp;lt;/BUTTON&amp;gt; &amp;lt;BR&amp;gt;
    &amp;lt;BUTTON ONCLICK="window.location.href='/primes300.html'"&amp;gt;show me primes up to 300&amp;lt;/BUTTON&amp;gt; &amp;lt;BR&amp;gt;            
  &amp;lt;/BODY&amp;gt;
&amp;lt;/HTML&amp;gt;
&lt;/PRE&gt;very simple, right?&lt;br /&gt;
we also have a utils.inc file in which we have a method which checks if a number is prime, this file is also located in www directory&lt;br /&gt;
&lt;pre&gt;function IsPrime(Value: integer): boolean;
var
  Index: Integer;
begin
  Result := False;
  if Value &lt;= 0 then
    Exit;
  for Index := 2 to Round(Sqrt(Value)) do
    if (Value mod Index) = 0 then
      Exit;
  Result := True;
end;
&lt;/PRE&gt;
here are the other 3 HTML files
primes100.html
&lt;pre&gt;&amp;lt;HTML&amp;gt;
  &amp;lt;BODY&amp;gt;
    &amp;lt;%
      {$I 'utils.inc'}
      var
        Index: Integer;
      for Index := 1 to 100 do
        if IsPrime(Index) then
          Send('&amp;lt;BR&amp;gt;' + IntToStr(Index)); 
    %&amp;gt;
  &amp;lt;/BODY&amp;gt;  
&amp;lt;/HTML&amp;gt;
&lt;/PRE&gt;primes200.html
&lt;pre&gt;&amp;lt;HTML&amp;gt;
  &amp;lt;BODY&amp;gt;
    &amp;lt;%
      {$I 'utils.inc'}
      var
        Index: Integer;
      for Index := 1 to 200 do
        if IsPrime(Index) then
          Send('&amp;lt;BR&amp;gt;' + IntToStr(Index)); 
    %&amp;gt;
  &amp;lt;/BODY&amp;gt;  
&amp;lt;/HTML&amp;gt;
&lt;/PRE&gt;primes300.html
&lt;pre&gt;&amp;lt;HTML&amp;gt;
  &amp;lt;BODY&amp;gt;
    &amp;lt;%
      {$I 'utils.inc'}
      var
        Index: Integer;
      for Index := 1 to 300 do
        if IsPrime(Index) then
          Send('&amp;lt;BR&amp;gt;' + IntToStr(Index)); 
    %&amp;gt;
  &amp;lt;/BODY&amp;gt;  
&amp;lt;/HTML&amp;gt;
&lt;/PRE&gt;Now, this is an extremely simple example, but as you can see it can be used as a template for a real hardcore web server.
Unfortunately I don't have enough time these days for more in depth details, but you can download &lt;a href="https://sites.google.com/site/delphigeist/downloads/binsrcDWScriptAndHTTPServer.zip"&gt;binary + source code&lt;/a&gt; or &lt;a href="https://sites.google.com/site/delphigeist/downloads/srcDWScriptAndHTTPServer.zip"&gt;just the source code&lt;/a&gt; and enjoy the power and simplicity of DWScript.&lt;br /&gt;
The application is created in Delphi 2010.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-6089014009812407377?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/J8uAdmgLNqb5aqezJ4617XtcwpY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/J8uAdmgLNqb5aqezJ4617XtcwpY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/J8uAdmgLNqb5aqezJ4617XtcwpY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/J8uAdmgLNqb5aqezJ4617XtcwpY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/zc83OomUAXg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/6089014009812407377/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/12/dynamic-web-pages-with-dwscript-and.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/6089014009812407377?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/6089014009812407377?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/zc83OomUAXg/dynamic-web-pages-with-dwscript-and.html" title="Dynamic web pages with DWScript and IdHTTPServer" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/12/dynamic-web-pages-with-dwscript-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYHQXo6cCp7ImA9Wx9REk4.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-3229518007593845585</id><published>2010-12-13T12:45:00.000+02:00</published><updated>2010-12-13T12:45:30.418+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-13T12:45:30.418+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="uncategorized" /><title>Politics is anything but random</title><content type="html">I admit that I'm having trouble understanding politics, however I try my best to understand it and I'm really interested in how things go around the world because I live in it and to some extent it can/will affect me or my life style, having that said let's see what this post is all about:&lt;br /&gt;
&lt;br /&gt;
In a previous post I've expressed my opinion regarding Wikileaks as being a hoax -- it is my opinion and even if I'm right or wrong I stand by it until someone can prove me wrong -- a reader commented "You're incoherent. Stick to writing about Delphi.", I agree to the second part however, the first part it might also be true.&lt;br /&gt;
The reason I'm against Wikileaks is very obvious... or at least I hope it is...&lt;br /&gt;
We all(or at least a pretty big number of us) know that the mainstream media is corrupted and it's anything but "for the people", they make money out of advertising(it's not a secret) however sometimes it comes down to one or more of the following situations:&lt;br /&gt;
- someone(or the government) does not want something to be published -- this leads into one or all of the following situations:&lt;br /&gt;
a) "someone" has power over the owner of the newspaper, news channel, etc.;&lt;br /&gt;
b) "someone" has enough money to make the newspaper, news channel, etc. turn the head in another direction;&lt;br /&gt;
&lt;br /&gt;
- the media is paid(or forced by "someone") to spread disinformation;&lt;br /&gt;
&lt;br /&gt;
- the media spreads disinformation in order to gain more audience -- this results in higher rate for advertising which leads to more cash;&lt;br /&gt;
&lt;br /&gt;
- the journalist has a pretty good salary however if "someone" threatens his/her family the "subject" vanishes into thin air or if "someone" pays him/her a year(or more) worth of salary to shut up he/she will most likely do it, of course both situations can come as one(pay $ X and threaten family to shut up), most common is the pay;&lt;br /&gt;
&lt;br /&gt;
The Internet is part of our lives these days and it helps us share information with outstanding speed -- this means that any information(especially if it's important) can reach millions of people in very short period of time -- he who controls the Internet has power over people's information(&lt;B&gt;personal as well!!&lt;/B&gt;).&lt;br /&gt;
Take the social networks for instance, they hold so much personal information(which we give for free) that one can know almost anything about Mr./Mrs. X, &lt;B&gt;WHAT IF&lt;/B&gt; "someone" would control the Internet or these companies?! yes... &lt;B&gt;he/they&lt;/B&gt; would know where you are, where you live, what you've done the past X time, who you know, with who are you in a relationship, what you've talked to, who did you talked to, where ware you when you've wrote something, etc. -- can you see how much information we reveal about our selfs on the Internet?!&lt;br /&gt;
Deleting posts or images or changing information on the social networks won't do you any good, why?! because the data doesn't get deleted, there's a field that says "deleted" or "isdeleted" in tables so that information is not shown, however... it's there and can be accessed from server side or with some API's to which only few people have access.&lt;br /&gt;
&lt;br /&gt;
OK, OK, enough BS, where do I want to get with all this?! well... the equation is simple, what if Wikileaks is just disinformation(from what I know until now, there's no real sensitive information released...) which will raise(I'm pretty sure already did) the question in a lot of governments around the world: "What if our sensitive information gets leaked?!" -- now we all know that a lot of dirty things happen(and happened and will still happen in the future) in politics since the beginning of it, do they want you(the guy who is working like a slave everyday in order to have a roof above your head and have something to eat, &lt;B&gt;YOU&lt;/B&gt; pay his salary) to know what exactly is the government doing with the money it gets from you?! of course &lt;B&gt;NOT&lt;/B&gt;...&lt;br /&gt;
Take China(and not only) as example, the government monitors the data that the people are accessing and spreading, WHY?! it's simple, they don't want anything to be leaked, riots or &lt;B&gt;revolutions&lt;/B&gt;.&lt;br /&gt;
NOW, what IF the governments around the world starts controlling the data that floats on the Internet?! we get to the above situation in which we won't have privacy at all.&lt;br /&gt;
How can this happen?! simple, take Wikileaks as a "threat"(which until now isn't a threat at all...) and tell the people that we need to take actions so that we protect sensitive information from the hands of the "terrorists" -- &lt;B&gt;it's a threat to national security, we must act immediately!!&lt;/B&gt; -- do you see a pattern?!&lt;br /&gt;
&lt;br /&gt;
Let's take the word "terrorist", what does it mean?! according to Wikipedia:&lt;br /&gt;
&lt;BLOCKQUOTE&gt;Terrorism is the systematic use of terror especially as a means of coercion.[1] No universally agreed, legally binding, criminal law definition of terrorism currently exists. Common definitions of terrorism refer only to those violent acts which are intended to create fear (terror), are perpetrated for a religious, political or ideological goal, deliberately target or disregard the safety of non-combatants (civilians), and are committed by non-government agencies.&lt;br /&gt;
&lt;/BLOCKQUOTE&gt;OK, OK... now do me a favor, think of yourself as a terrorist(it's hard, but please try), can you throw yourself sky high with a bomb because you don't agree with a government or something?!! I would not think so... I mean some of you have kids, family, friends, etc. can you leave them just to make a point?!&lt;br /&gt;
"But terrorists don't have friends, family, etc." -- possibly true, BUT still... just thinking that you will give your life should give you chills...&lt;br /&gt;
&lt;br /&gt;
"You're paranoid, a total fu** up", "not another conspiracy crap", etc. -- I agree, it's possible that I'm wrong as hell, but still... what if I'm not?!&lt;br /&gt;
Take the time before 9/11 for example, would you allow the police to come into your house without a warrent?! NO!! could they vote this law?! NO!! why?! because it's illegal and immoral by all means!! still they wanted this, what happened?! well... the 9/11 incident in which a lot of people died and got injured -- &lt;B&gt;now that's not right!!&lt;/B&gt;&lt;br /&gt;
How many towers got hit by a plane?! 1?! yea... sooo... why ware there 3(three) towers that collapsed?!! there are few people that know how many towers did actually collapsed on that day -- check that again, don't leave this "unfortunate incident" pass by because it was anything but an "incident".&lt;br /&gt;
Ohhh... yea... after that police got more aggressive, people can't really speak their mind if there's any injustice done to them, why?! because police can arrest you using BS's as excuses, can keep you locked up for as long as they please, etc.&lt;br /&gt;
&lt;br /&gt;
By the way, I've saw a documentary on Discovery channel about "America's doomsday", it's a program started way back in the '50's by the president of USA, the program involved keeping the president and as many people from the government alive in case of a soviet nuclear attack. That's sweet and cool, EXCEPT that they've built a lot of bunkers which where absolute before it was finished because the soviets ware always improving their weapons, they knew that... YET they continued constructing bunkers using the people's money!!&lt;br /&gt;
Where do I want to get with this?! well.. what's the scope of a government?! in my opinion it is a group of people who leads the people and takes necessary actions to protect them against outside threats or against their own people, also the government must improve the life of each and every citizen as much as possible, YET the people are doing very bad, the people have NO defence against a war attack, YET the people is paying a lot of money for weapons, bunkers and all kind of BS's that "we need" in order to insure our safety, YET the people are struggling everyday to have a job or to have something to eat, while to governments around the world starts austerity programs because they "needed" to bailout banks(with the people's money of course) that got us in this situation(the economic crisis that is...) in the first place -- YET few people are revolting on this, WHY?! I'm not saying that we need to start revolutions around the world, NO!! that's not the solution, we need to change governments more often(1, 2 years max.!! if you can't keep our life style in that period, you can't improve it, so why do we need you?!), we need to put government people that took stupid actions with people's money in jail for a few years so that others will be more careful of how they spend money and what actions they take.&lt;br /&gt;
&lt;br /&gt;
I want you to send this message to all your friends that work in the army, police or any type of armed force:&lt;br /&gt;
&lt;BLOCKQUOTE&gt;Don't forget that we're all people and you should protect the people NOT THE GOVERNMENT, any action taken against the people who try to express their problems or needs to the government(which has the job to improve the life of citizens) should be considered a &lt;B&gt;THREAT TO THE PEOPLE, ANY THREAT TO THE PEOPLE SHOULD BE REMOVED IMMEDIATELY BY ALL MEANS NECESSARY!!&lt;/B&gt;&lt;br /&gt;
&lt;/BLOCKQUOTE&gt;&lt;br /&gt;
In the end I would like you to express your opinions about what I've wrote above(&lt;B&gt;note that I might also be wrong&lt;/B&gt;) and also I would like you to verify everything that I wrote above, &lt;U&gt;DO NOT TAKE ANYTHING FOR GRANTED, QUESTION MORE!!&lt;/U&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-3229518007593845585?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_grhKJpFHucjos5QDgPLBGMrQqE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_grhKJpFHucjos5QDgPLBGMrQqE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_grhKJpFHucjos5QDgPLBGMrQqE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_grhKJpFHucjos5QDgPLBGMrQqE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/ThdaLpBvjug" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/3229518007593845585/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/12/politics-is-anything-but-random.html#comment-form" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/3229518007593845585?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/3229518007593845585?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/ThdaLpBvjug/politics-is-anything-but-random.html" title="Politics is anything but random" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>6</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/12/politics-is-anything-but-random.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYNRHc9fSp7ImA9Wx9REEo.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-7271796638706130288</id><published>2010-12-11T15:13:00.000+02:00</published><updated>2010-12-11T15:13:15.965+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-11T15:13:15.965+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="uncategorized" /><title>Religion: who, what, where, why?!!!</title><content type="html">Skip this post if you're not open to impartial when it comes to religion.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;NOTE: that I respect each person's belief regarding religion, we are entitled to our own opinions.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Today I received a e-mail from one of the readers regarding my previous post in which I've mentioned about Vatican's wealth, I will keep the person's name anonymous. the question was:&lt;br /&gt;
"what is your problem with the Vatican?"&lt;br /&gt;
Note: the person was polite and I have no issue whatsoever with his question, therefore I don't want to be misunderstood.&lt;br /&gt;
&lt;br /&gt;
My "issues" with Vatican(and not only) are:&lt;br /&gt;
- why do they need a bank?&lt;br /&gt;
- why do they have their own laws?&lt;br /&gt;
- why do they ask for money(for tickets) in order to see the pope?!&lt;br /&gt;
- why can't ordinary people go in the Vatican library and see at least some(if not all) ancient documents?! -- as a believer you should be entitled to see(under surveillance or whatever, it doesn't matter) -- do they have something to hide?!?!&lt;br /&gt;
- the "why" list goes on...&lt;br /&gt;
&lt;br /&gt;
I am what you call a "atheist" -- I wasn't raised like this, but in time I started to question a lot of things regarding religion(and not only) and I came to the conclusion that people tend to believe in "stuperstitial" stuff before science(NOTE: that NOT ONCE but a lot of times, religions have tried to ban early science because they hate questions to which they have to answer with proof -- why?! simply because you cannot explain religion...).&lt;br /&gt;
&lt;br /&gt;
Let's NOT forget the deaths with the crusades "in the name of god" -- really now, do we have to kill people because they don't believe in our god or because they don't believe in anything?! my answer is NO(what's your answer?!), each individual has the right to own opinions.&lt;br /&gt;
&lt;br /&gt;
I believe that the religions where started because people needs to believe in something in order to go over the hard life, however, from ancient times until now the religion was used as a control tool with each occasion, remember the history classes in which you've learned about how priests where selling "places in heaven"?! Ohhh... yea the same people who are preaching the "word of god" and the same people which added text in the "holly bible".&lt;br /&gt;
&lt;br /&gt;
My main issue is with the influence of the pope(and priests), I mean we're teached in school about god and all that stuff in stead of being educated on how to behave in society and how to be hard worker and a honest person.&lt;br /&gt;
&lt;br /&gt;
When I was young I've read a lot of holly books and the more I read the more I've found out how it contradicts itself and that is very, very hard on taking actions against non-belivers -- again, can you see a pattern?! YES, either you're with us or against us!!&lt;br /&gt;
&lt;br /&gt;
The main issue with people is that a huge percent of them are like sheeps, they refuse to think or to have own opinions, the biggest problem is that they almost never question what's happening around them, they take for granted what others tell them(why should I bother to think?! I already have the answer... -- oh-ho-ho, but DO YOU?) -- this leads to mass manipulation.&lt;br /&gt;
&lt;br /&gt;
I know most of the people don't like history, however, try to read a bit when you have time but don't forget that &lt;b&gt;history is written by the victor&lt;/b&gt; -- never forget that!! -- you will see a lot of dirty things regarding religion and not only, manipulation schemes and other!&lt;br /&gt;
&lt;br /&gt;
I'm pretty sure that a lot of you out there won't agree with what I've written above and very few will.., I'm waiting for your comments, however please be polite, we are humans(we're supposed to be polite with each other) after all...&lt;br /&gt;
&lt;br /&gt;
Question more, don't stop at first answers, don't be afraid to ask "dumb" questions, silence is NOT the answer!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-7271796638706130288?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ldsPfy_RBmwf0aLjjdu5RKBEr_o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ldsPfy_RBmwf0aLjjdu5RKBEr_o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ldsPfy_RBmwf0aLjjdu5RKBEr_o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ldsPfy_RBmwf0aLjjdu5RKBEr_o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/SQd2NeNxsL8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/7271796638706130288/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/12/religion-who-what-where-why.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/7271796638706130288?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/7271796638706130288?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/SQd2NeNxsL8/religion-who-what-where-why.html" title="Religion: who, what, where, why?!!!" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/12/religion-who-what-where-why.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIAR3g-fCp7ImA9Wx9REEw.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-7123909887963031543</id><published>2010-12-10T22:39:00.000+02:00</published><updated>2010-12-10T22:39:06.654+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-10T22:39:06.654+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="uninteresting" /><category scheme="http://www.blogger.com/atom/ns#" term="Huge BS" /><category scheme="http://www.blogger.com/atom/ns#" term="uncategorized" /><title>OK, I can't help myself regarding Wikileaks...</title><content type="html">My blood pressure is sky high each time I hear, read and/or see something regarding the Wikileaks so called "leaks", I'm f**kin' fed up with all this nonsense... I have yet to hear, read and/or see SENSITIVE INFORMATION released by Wikileaks, really now, can someone tell or point me to the right direction?! I only see the scandals on mainstream media regarding the so called "hacks" on Amazon, Visa, Mastercard and PayPal and regarding the illegal detention of J.A. with which I don't agree however law is law and is for everyone(well at least us..., the &lt;b&gt;small&lt;/b&gt; people...).&lt;br /&gt;
&lt;br /&gt;
Now regarding the "hackers" which "attacked" the Amazon(huge fail — LOL!! what the hell?! it's like trying to flood Google servers -- which are millions...), Visa(they don't really give a damn), Mastercard(they laughed their ass off on this...) and PayPal(I'm happy about this attack, they really have big fees!!) websites, c'mon people, that's NOT hacking... and I really hate the freakin' media which is trying to amplify this like it's a major attack on government server... blahhh... major attacks have happen in the past and we didn't hear about and still are happening and still will long after we're gone.&lt;br /&gt;
&lt;br /&gt;
Wanna protect your server for this kind of "hacks"?! simply add another system(near the server) to which the server sends the logs via UDP or whatever... and then if the server is down because of this kind of attack(s), just follow the looong list of IP's which where making requests to the server and resulted in server crash, hello?! someone will have to pay huge amounts of money to da' court.&lt;br /&gt;
&lt;br /&gt;
Bottom line, anyone can and SHOULD think if this is subject is really interesting, I mean, come on people, a lot of shit is happening in the world and no one is lifting a finger to do something, now all of the sudden someone(J.A.) came with some "leaks" which doesn't seem sensitive to me(again, I might be wrong, however please point to the "real" stuff) and we and the media are making a big case out of nothing, it seems to me like something else is happening behind the curtain, but it might be that I'm paranoid...&lt;br /&gt;
Take Vatican for instance, they got so much money that they could literally save tens(if NOT more) of millions of people around the whole freakin' World from starvation and diseases, but do they do it?! NO!! does the media care?! NO!! do &lt;B&gt;WE&lt;/B&gt; care?! HUGE NO!! but still they say they are the voice of God and other BS'es...&lt;br /&gt;
&lt;br /&gt;
&lt;FONT SIZE=10&gt;STOP THE MEDIA FROM MANIPULATING YOU!!&lt;/FONT&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-7123909887963031543?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZFISmbOKP4urgoOBkiJ-uU1vOww/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZFISmbOKP4urgoOBkiJ-uU1vOww/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZFISmbOKP4urgoOBkiJ-uU1vOww/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZFISmbOKP4urgoOBkiJ-uU1vOww/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/_JXxwomIWGo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/7123909887963031543/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/12/ok-i-cant-help-myself-regarding.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/7123909887963031543?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/7123909887963031543?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/_JXxwomIWGo/ok-i-cant-help-myself-regarding.html" title="OK, I can't help myself regarding Wikileaks..." /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/12/ok-i-cant-help-myself-regarding.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4CRnc7cCp7ImA9Wx9SEUw.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-1531932118491058220</id><published>2010-11-30T13:36:00.000+02:00</published><updated>2010-11-30T13:36:07.908+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-30T13:36:07.908+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Interpreter" /><category scheme="http://www.blogger.com/atom/ns#" term="zombie computers" /><category scheme="http://www.blogger.com/atom/ns#" term="skype" /><category scheme="http://www.blogger.com/atom/ns#" term="network" /><category scheme="http://www.blogger.com/atom/ns#" term="Internet" /><title>Computing power: how much is enough?!</title><content type="html">I see almost every day someone showing off with their new hardcore computer with lots of Gigahertz and lots of RAM, etc. but is that system fast enough to find the first 100 mil. or 1 billion prime numbers in under 10 minutes?! well... it depends on the algorithms and the system configuration.&lt;br /&gt;
Time showed us that there's never enough computing power(I'm &lt;B&gt;NOT&lt;/B&gt; talking about browsing the Internet or writing a text file here...), but what can we do in order to achieve our goals using computers as fast as possible?! there are a few options(off the top of my head):&lt;br /&gt;
&lt;br /&gt;
1. buy better computers&lt;br /&gt;
2. use any computer you can get you're hands on&lt;br /&gt;
&lt;br /&gt;
&lt;font size="10"&gt;&lt;B&gt;1.&lt;/B&gt;&lt;/font&gt; We always buy better computers in order to do stuff faster but there are a lot of limitations:&lt;br /&gt;
&lt;B&gt;a.&lt;/B&gt; &lt;U&gt;budget&lt;/U&gt;: we can buy STA(state of the art) computers with 4, 6, etc. cores that will make our life easier, but is this really a good idea?! the answer is &lt;B&gt;NO&lt;/B&gt;, buying a i7 at 3 GHz with 4 cores it's about $ 3-400 depending in which country you live, now 3 Ghz with 4 cores is not the fastest you can get, Intel has way better CPU's than that -- extreme series, they also try to get as many cores as they can into a CPU but let's just stop at the extreme series which costs about $ 1.000/CPU(of course it worths the price, but it depends on your &lt;B&gt;needs&lt;/B&gt;) -- now this is a lot just for a processor but depending on you're budget you can buy or skip.&lt;br /&gt;
&lt;br /&gt;
&lt;B&gt;b.&lt;/B&gt; &lt;U&gt;operating system&lt;/U&gt;: some OS's are better than others -- depending on your needs of course -- let's take Windows for example, it is a very good OS for entertainment and office, but when you need to do some tasks that takes hours/days/weeks to complete is it good?! I honestly can't give a definitive answer on this because for tasks that needs a lot of time to complete I turn to my geek friend &lt;B&gt;&lt;U&gt;Linux&lt;/U&gt;&lt;/B&gt; -- it is very stable, it manages resources very well and if you don't need GUI(graphical user interface) it's pretty much rock-solid.&lt;br /&gt;
&lt;br /&gt;
&lt;font size="10"&gt;&lt;B&gt;2.&lt;/B&gt;&lt;/font&gt; What do I mean by "use any computer you can get you're hands on"?!&lt;br /&gt;
It's not a secret that a lot of companies connect a bunch of computers together through a communication protocol and use each computer as a thread -- WAIT!! how does this work?!!&lt;br /&gt;
Basically it depends on the developers... you can have a system that is the &lt;B&gt;Master&lt;/B&gt; on which you execute &lt;B&gt;special programs&lt;/B&gt; and sends task execute request to 2 or more &lt;B&gt;Slaves&lt;/B&gt;, when a slave completed it's task, it sends back the result to the master and waits for another request from the master -- pretty simple ey?! in essence yes, in practice &lt;B&gt;NOT&lt;/B&gt;!!&lt;br /&gt;
Here is the basic idea:&lt;br /&gt;
step 1. Master =&gt; send request =&gt; slave(s)(1..N computers) -- usually at least 2!!&lt;br /&gt;
step 2. Master waits for all slaves to complete the tasks&lt;br /&gt;
step 3. when a slave completes the task it sends result back to the Master&lt;br /&gt;
step 4. Master processes result(s)&lt;br /&gt;
Fairly simplistic right?! but why do I say "at least 2 computers"?!&lt;br /&gt;
Over time we have been Witness hardware failure(I'm proud that I haven't had too many -- yet!!) let's say we got a highly intensive task that we believe that it will take "forever" to complete a matter of days, &lt;B&gt;WHAT IF&lt;/B&gt; in this time one of the slaves has a hardware failure?! you've lost shit-load of time and we all know the equation:&lt;br /&gt;
&lt;B&gt;time = money -&gt; lose time =&gt; lose money&lt;/B&gt; another way to see this is: the less time you spend on doing something, the more money you earn.&lt;br /&gt;
Sooo... let's review what is one of the best approaches you can take when you need huge computing power:&lt;br /&gt;
1. get as many systems as you can -- no matter how powerful the CPU is or how much RAM the system has&lt;br /&gt;
2. implement the logic and the communication protocol(avoid using hard disks as much as possible &lt;-- slowest part in the computer)
3. start using you're new hardcore computer network
&lt;B&gt;4...N. always improve the idea!!&lt;/B&gt;&lt;br /&gt;
&lt;br /&gt;
Now, let's try to throw some ideas of a possible implementation:&lt;br /&gt;
- create a flexible communication protocol(I prefer using TCP/IP because you can have GB's of data transfered in second(s)) maybe use XML?!&lt;br /&gt;
- choose the cleanest Linux distribution you can think of -- avoid using GUI for better performance(on slave side)&lt;br /&gt;
- implement integer(huge integers -- that can grow up to trillion digits long), string(huge strings that can be concated from 2 or more slaves), object(which has it's own methods which will be transfered along with it from master-slave, slave-master, slave-slave), etc.&lt;br /&gt;
- use some kind of ping mechanism so that the Master is automatically "knows" when a slave is dead and take appropriate actions(send task to another slave, e-mail tech department, etc.)&lt;br /&gt;
- Master CAN NOT execute task -- it needs only to assign tasks to slaves and communicate with them&lt;br /&gt;
- if you try hard enough you can also make the slaves "know" when the Master has a failure and another "free of task" slave can take it's place&lt;br /&gt;
- you will have to use a very fast interpreter&lt;br /&gt;
&lt;br /&gt;
What do we get out of this?! well some of you know that you can buy good old Pentium 4 computers at 2.x-3 Ghz with 512 mb or 1 GB RAM for ~$ 100) -- WAIT!! so I can have 10 cores at $ 1.000?!?! yup...&lt;br /&gt;
You can also use implement this in such a away that you can use virtually any OS -- YES you can have 2 slaves on Windows 2000, 5 slaves on Windows XP, 20 slaves on Linux, 8 slaves on OSX, etc.&lt;br /&gt;
Sooo... the "hardcore" system can have a lot of slaves, running on multiple platforms AND you can always ADD more slaves on the network, OK but where's the drawback, I know there must be at least one -- yes there are plenty, but it basically depends on the developer(s):&lt;br /&gt;
- the system can take anywhere between a few seconds to a few minutes(depending on the initialization implementation -- needs to be ran at the beginning of the program execution) -- this can be tunned!!&lt;br /&gt;
- you will have to take care of the synchronization -- it's normal in a multithreaded environment&lt;br /&gt;
- if master dies the whole program progress can be lost -- this depends entirely on the implementation of the "main executor" or &lt;B&gt;Mr. X&lt;/B&gt; ;-)&lt;br /&gt;
- you also need to take into consideration each system's configuration -- depending on this you can execute small tasks on Pentium 3 systems and others on P4 or i3/5/7's&lt;br /&gt;
&lt;br /&gt;
As you can see the most important piece of the puzzle is the &lt;B&gt;developer's skills&lt;/B&gt;.&lt;br /&gt;
&lt;br /&gt;
But sometimes you need tens of thousands of computers -- WHAT can you do then?!&lt;br /&gt;
We all know that there are hundreds of millions of computers out there that are used only for Internet browsing, multimedia download, how can we use that to our advantage?! well a lot of hackers and companies uses/d &lt;a href="http://en.wikipedia.org/wiki/Zombie_computer"&gt;zombie computers&lt;/a&gt; by uploading torrent clients and or multimedia programs for users to freely download and use, but while a lot of computers spend hours a day just downloading, the CPU and a lot of memory is available to be freely used legally or illegally depending on the &lt;a href="http://en.wikipedia.org/wiki/Software_license_agreement"&gt;EULA&lt;/a&gt; they provided with the software.&lt;br /&gt;
Take &lt;a href="http://www.skype.com/intl/en/home"&gt;Skype&lt;/a&gt; for example, it uses your &lt;B&gt;CPU&lt;/B&gt; and &lt;B&gt;bandwidth&lt;/B&gt; in order to provide you with "free" service:&lt;br /&gt;
&lt;BLOCKQUOTE&gt;4.1 Permission to utilize Your computer. In order to receive the benefits provided by the Skype Software, You hereby grant permission for the Skype Software to utilize the processor and bandwidth of Your computer for the limited purpose of facilitating the communication between Skype Software users.&lt;br /&gt;
&lt;br /&gt;
4.2 Protection of Your computer (resources). You understand that the Skype Software will use its commercially reasonable efforts to protect the privacy and integrity of Your computer resources and Your communication, however, You acknowledge and agree that Skype &lt;font size="10"&gt;&lt;B&gt;cannot&lt;/B&gt;&lt;/font&gt; give any warranties in this respect. &lt;br /&gt;
&lt;br /&gt;
&lt;B&gt;You hereby grant permission for the Skype Software to utilize the processor and bandwidth of Your computer for the limited purpose of facilitating the communication between Skype Software users.&lt;/B&gt;&lt;br /&gt;
&lt;/BLOCKQUOTE&gt;This is a &lt;I&gt;legal&lt;/I&gt; way of using your system, however others are JUST using your system because you got some illegal software from a torrent or warez website and you can't really complain about this in court, if you know what I mean -- it's your full &lt;B&gt;responsibility&lt;/B&gt;.&lt;br /&gt;
&lt;br /&gt;
As a Delphi/Pascal developer, what can you use in order to target as many platforms as you can and implement this? &lt;B&gt;HELLO?!?!&lt;/B&gt; &lt;a href="http://www.freepascal.org/"&gt;Freepascal&lt;/a&gt; and &lt;a href="http://www.lazarus.freepascal.org/"&gt;Lazarus&lt;/a&gt; is a good starting point and DO NOT forget that as a developer you should NOT be limited to a single programming language, you can also use C++ and/or Java as well if you implement your protocol flexible enough!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-1531932118491058220?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6Jy68dz6A3s_1Ao7dmL4NyJk_ZI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6Jy68dz6A3s_1Ao7dmL4NyJk_ZI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6Jy68dz6A3s_1Ao7dmL4NyJk_ZI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6Jy68dz6A3s_1Ao7dmL4NyJk_ZI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/yDV50K362eE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/1531932118491058220/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/11/computing-power-how-much-is-enough.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/1531932118491058220?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/1531932118491058220?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/yDV50K362eE/computing-power-how-much-is-enough.html" title="Computing power: how much is enough?!" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/11/computing-power-how-much-is-enough.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIBRHk_fSp7ImA9Wx9TE0g.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-5035499469853845552</id><published>2010-11-18T10:11:00.002+02:00</published><updated>2010-11-21T18:22:35.745+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-21T18:22:35.745+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Delphi XE Distiller" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Distiller" /><title>Delphi XE Distiller</title><content type="html">&lt;a href="http://www.torry.net/tools/project/projects/XEDistiller1.0.0.9.zip"&gt;Sooo... there's another Delphi Distiller available for those of you who wishes to download click this text(version 1.0.0.9).&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-5035499469853845552?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_TR1q0PvDig4bqtXUWG0Dxr5fhw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_TR1q0PvDig4bqtXUWG0Dxr5fhw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_TR1q0PvDig4bqtXUWG0Dxr5fhw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_TR1q0PvDig4bqtXUWG0Dxr5fhw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/jCZw7NJstdQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/5035499469853845552/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/11/delphi-xe-distiller.html#comment-form" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/5035499469853845552?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/5035499469853845552?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/jCZw7NJstdQ/delphi-xe-distiller.html" title="Delphi XE Distiller" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>9</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/11/delphi-xe-distiller.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQBQ3w-fyp7ImA9Wx5bGUw.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-3952409198164084517</id><published>2010-11-05T00:23:00.003+02:00</published><updated>2010-11-05T01:45:52.257+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-05T01:45:52.257+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Indy" /><category scheme="http://www.blogger.com/atom/ns#" term="DGTV" /><title>DGTV: IdHTTPServer</title><content type="html">A new video tutorial is available, in this tutorial I'm explaining how to create a very basic HTTP server application, please watch it in HD for best experience, any comments are welcomed.&lt;br /&gt;
Part 1&lt;br /&gt;
&lt;object width="960" height="745"&gt;&lt;param name="movie" value="http://www.youtube.com/v/WrKQGRhs4CQ?fs=1&amp;amp;hl=en_US&amp;amp;hd=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/WrKQGRhs4CQ?fs=1&amp;amp;hl=en_US&amp;amp;hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="960" height="745"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;br /&gt;
Part 2&lt;br /&gt;
&lt;object width="960" height="745"&gt;&lt;param name="movie" value="http://www.youtube.com/v/kRivbiKyMBk?fs=1&amp;amp;hl=en_US&amp;amp;hd=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/kRivbiKyMBk?fs=1&amp;amp;hl=en_US&amp;amp;hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="960" height="745"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-3952409198164084517?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/RtYFPupnyNlqEx7tOpBUDFsBu_Y/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RtYFPupnyNlqEx7tOpBUDFsBu_Y/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/RtYFPupnyNlqEx7tOpBUDFsBu_Y/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RtYFPupnyNlqEx7tOpBUDFsBu_Y/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/J_2DfZ6Hj1o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/3952409198164084517/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/11/dgtv-idhttpserver.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/3952409198164084517?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/3952409198164084517?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/J_2DfZ6Hj1o/dgtv-idhttpserver.html" title="DGTV: IdHTTPServer" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/11/dgtv-idhttpserver.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YMQ3g6fip7ImA9Wx5bGU0.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-8008178617055357874</id><published>2010-11-03T01:14:00.002+02:00</published><updated>2010-11-05T00:19:42.616+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-05T00:19:42.616+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="DGTV" /><category scheme="http://www.blogger.com/atom/ns#" term="VirtualTreeview" /><title>DGTV: VirtualStringTree</title><content type="html">I've created my first Delphi video tutorial which covers the basic use of VirtualStringTree component, please see it @ 720p for best experience.&lt;br /&gt;
Leave comments of what subject should I cover in a future video.&lt;br /&gt;
&lt;object width="960" height="745"&gt;&lt;param name="movie" value="http://www.youtube.com/v/o6FpUJhEeoY?fs=1&amp;amp;hl=en_US&amp;amp;hd=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/o6FpUJhEeoY?fs=1&amp;amp;hl=en_US&amp;amp;hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="960" height="745"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-8008178617055357874?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/isRVkzA1bDuJcYu-n4it59A6SZM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/isRVkzA1bDuJcYu-n4it59A6SZM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/isRVkzA1bDuJcYu-n4it59A6SZM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/isRVkzA1bDuJcYu-n4it59A6SZM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/o5frJzSYpy8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/8008178617055357874/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/11/virtualstringtree-video-tutorial.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/8008178617055357874?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/8008178617055357874?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/o5frJzSYpy8/virtualstringtree-video-tutorial.html" title="DGTV: VirtualStringTree" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/11/virtualstringtree-video-tutorial.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IGQH86fyp7ImA9Wx5bF00.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-2753661461069850850</id><published>2010-11-02T15:44:00.001+02:00</published><updated>2010-11-02T15:45:21.117+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-02T15:45:21.117+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="business" /><title>Delphi 2010 or XE?!</title><content type="html">OK, so we had a Delphi 2010 release and a couple of months later a Delphi XE(cool name huh?) release, your confused, what's the logic behind that? no cross platform, no 64 bit compiler nothing new actually besides the XE suffix, some IDE fixes and some light versions of third party tools.&lt;br /&gt;
All this still doesn't make sense... let's try a different approach: we know that the end goal of a company is to maximize their profits right?! if they have released Delphi 2010 without the IDE glitches it would have taken them a few months more to release Delphi 2010, that means that they would have "lost" money, what they(management) choose to do is release a Delphi 2010(I really hate this kind of names with suffix "year of release" sounds really gay!!) and after the IDE fixes a new version would be released(in this case XE) — sweet, the only problem is that people who have already purchased 2010 version have spent some money on a product which is NOT, I REPEAT NOT really good for big projects which involves thousands and thousands of lines of code — takes way too many freaking minutes or tens of minutes to build in order to test.&lt;br /&gt;
Does now make sense?! of course it does, but if your a customer, you're not "so" happy about this approach, Visual Studio has better releases as I've seen the last couple of years — this really bugs me!!&lt;br /&gt;
When I've tested XE(for a couple of minutes), I've seen faster IDE, less glitches, overall XE is a bit better than 2010, the only issue is that you have to spend more freaking money, what was my response to this?! invested $ 1.000 in a i7, memory and a good mother board — why?! well.. instead of giving them a couple of hundred Euros for something they should have giving in the 2010 release, I've upgraded my system which is a 2 years investment at least and give them s**t. Delphi 2010 runs smoothly now, I got a faster system, Intel, ASUS and Kingston got some money from me, problem solved!&lt;br /&gt;
---&lt;br /&gt;
&lt;b&gt;Now I know what some of you might say&lt;/B&gt;: if you're a developer who makes money out of this, why NOT buy the latest releases since it's just a few hundred Euros/Dollars?! well the response is simple, while a company tries to maximize their profits, you as a developer(in this case customer) need to minimize your expenses — learn from your clients!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-2753661461069850850?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/QviwSTkdvGDOrgmNyO0xnVAvdnc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QviwSTkdvGDOrgmNyO0xnVAvdnc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/QviwSTkdvGDOrgmNyO0xnVAvdnc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QviwSTkdvGDOrgmNyO0xnVAvdnc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/zUKsUSXvTNM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/2753661461069850850/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/11/delphi-2010-or-xe.html#comment-form" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/2753661461069850850?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/2753661461069850850?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/zUKsUSXvTNM/delphi-2010-or-xe.html" title="Delphi 2010 or XE?!" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>8</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/11/delphi-2010-or-xe.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IMRXg4fyp7ImA9Wx5UF0k.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-735105527609530567</id><published>2010-10-22T12:58:00.001+03:00</published><updated>2010-10-22T12:59:44.637+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-22T12:59:44.637+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="uncategorized" /><title>Sooo you got your first milion, now what?!</title><content type="html">Let's just say that you just won € 1.7 mil. in lottery(tax free). What would you do with that much money in the current economy state?!&lt;br /&gt;
There are lots of things you can do with it, but the million euro question is: &lt;b&gt;&lt;u&gt;What's the best thing you can do with it&lt;/U&gt;&lt;/B&gt;, for you and MAYBE for others as well.&lt;br /&gt;
&lt;u&gt;Let's just list a few possibilities&lt;/U&gt;:&lt;br /&gt;
- quit the job and waste the money;&lt;br /&gt;
- give the money to homeless people and help them start a fresh new life;&lt;br /&gt;
- give it to charity;&lt;br /&gt;
- start your own company(what kind of company, most of you that read this blog are developers, would you start a software company or do you think you can squeeze more money in other fields?!);&lt;br /&gt;
- buy the company in which you currently work(I'm sure it applies to many of you out there);&lt;br /&gt;
- buy a bigger house, bigger car, lots of bling-blings and biaches(I'm sure some of you want that -smile-);&lt;br /&gt;
- hold on to the money since there's no certain future coming;&lt;br /&gt;
- keep the money until pension, waste it then;&lt;br /&gt;
The above list is just off the top of my head — I disagree with at least half of the list — &lt;b&gt;BUT&lt;/B&gt; I'm curious what other people would do with that much money.&lt;br /&gt;
&lt;hr&gt;No matter what you would do, consider this: money come and go, you're current job(if applies) is most likely pretty steady, you should take a deep breath before starting to think about how would you spend it and on what.&lt;br /&gt;
P.S. Don't forget, you also lose money(inflation which is a pretty big percent, let's say about 2%/year in Germany's or USA's case) by keeping it „safe¯ with each year.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-735105527609530567?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/jew0pVJHci2Ro3T9vBLrqFLrgys/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jew0pVJHci2Ro3T9vBLrqFLrgys/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/jew0pVJHci2Ro3T9vBLrqFLrgys/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jew0pVJHci2Ro3T9vBLrqFLrgys/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/km0PvRm8THg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/735105527609530567/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/10/sooo-you-got-your-first-milion-now-what.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/735105527609530567?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/735105527609530567?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/km0PvRm8THg/sooo-you-got-your-first-milion-now-what.html" title="Sooo you got your first milion, now what?!" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/10/sooo-you-got-your-first-milion-now-what.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08BQng5eSp7ImA9Wx5UEEU.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-1170127228775118857</id><published>2010-10-14T21:44:00.000+03:00</published><updated>2010-10-14T21:44:13.621+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T21:44:13.621+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="utility functions" /><title>Message dialogs: you're doing it wrong...</title><content type="html">No matter what you say or think, end-users are beasts, they will always find a way to make their life more complicated instead of reading messages or instructions...&lt;br /&gt;
I'm pretty sure AT least once in your life you pressed the wrong button on a message dialog, because you „thought¯ you know what it will ask you OR because you was in a hurry...&lt;br /&gt;
The main problem with the end-user is that (s)he will do this most of the times, let's suppose that you're asking the user if (s)he is sure to wipe a file or discard changes that are very important to him/her, even if the user should be blamed because (s)he didn't read the message, you're still the one that will be sweared.&lt;br /&gt;
So what can we do to overcome such a situation?! well not much without stressing the user &lt;B&gt;BUT&lt;/B&gt; we can use a timed message dialog with which the user cannot interact for a amount of time — this will probably force the user to read the freaking message!&lt;br /&gt;
So here's my implementation of a timed message dialog:&lt;br /&gt;
&lt;PRE&gt;unit uTimedMessageDlg;

interface

uses
  SysUtils,
  Windows,
  Classes,
  Forms,
  Dialogs,
  Controls,
  ExtCtrls;

const
  CDEFAULT_WAIT_SEC = 10;
  CSECOND = 1000;
  CTIMED_MESSAGE = '%s (%d seconds)';

type
  TTimedMessageDlg = class(TObject)
  private
    FTimer: TTimer;
    FSeconds: Cardinal;
    FMessageForm: TForm;
    FCountDown: Integer;
    FCaption: string;
    procedure OnTimer(Sender: TObject);
    procedure OnDialogShow(Sender: TObject);
  public
    constructor Create;
    destructor Destroy; override;
  public
    function DisplayDialog(const Msg: string; const Args: array of const;
      DlgType: TMsgDlgType; Buttons: TMsgDlgButtons;
      const SecondsToWait: Cardinal = 10): Integer;
  public
    property Seconds: Cardinal
      read FSeconds write FSeconds;
  end;
  
function TimedMessageDlg(const Msg: string; const Args: array of const ;
  DlgType: TMsgDlgType; Buttons: TMsgDlgButtons;
  const SecondsToWait: Cardinal): Integer;

implementation

{ TTimedMessageDlg }

constructor TTimedMessageDlg.Create;
begin
  FTimer := TTimer.Create(NIL);
  FTimer.Enabled := False;
  FTimer.Interval := 1000;
  FTimer.OnTimer := OnTimer;
  FSeconds := 10;
end;

function TTimedMessageDlg.DisplayDialog(const Msg: string;
  const Args: array of const;
  DlgType: TMsgDlgType; Buttons: TMsgDlgButtons;
  const SecondsToWait: Cardinal = 10): Integer;
begin
  FMessageForm := CreateMessageDialog(Format(Msg, Args), DlgType, Buttons);
  FMessageForm.OnShow := OnDialogShow;
  FCountDown := SecondsToWait -1;
  FCaption := FMessageForm.Caption;
  FMessageForm.Caption := Format(CTIMED_MESSAGE, [FCaption, FCountDown]);
  FTimer.Interval := 1000;
  FTimer.Enabled := True;
  Result := FMessageForm.ShowModal;
  FreeAndNil(FMessageForm);
end;

destructor TTimedMessageDlg.Destroy;
begin
  FreeAndNil(FTimer);
  inherited;
end;

procedure TTimedMessageDlg.OnTimer(Sender: TObject);
begin
  Dec(FCountDown);
  FMessageForm.Caption := Format(CTIMED_MESSAGE, [FCaption, FCountDown]);
  if FCountDown &lt;= 0 then begin
    FMessageForm.Caption := FCaption;
    FTimer.Enabled := False;
    FMessageForm.Enabled := True;
  end; // if FCountDown &lt;= 0 then begin
end;

procedure TTimedMessageDlg.OnDialogShow(Sender: TObject);
begin
  FMessageForm.Enabled := False;
end;

function TimedMessageDlg(const Msg: string; const Args: array of const ;
  DlgType: TMsgDlgType; Buttons: TMsgDlgButtons;
  const SecondsToWait: Cardinal): Integer;
var
  TimedMessage: TTimedMessageDlg;
begin
  TimedMessage := TTimedMessageDlg.Create;
  Result := TimedMessage.DisplayDialog(Msg, Args, DlgType, Buttons,
    SecondsToWait);
  FreeAndNil(TimedMessage);
end;

end.
&lt;/PRE&gt;
Sooo... what's the difference between normal and this custom message dialog?! nothing much, just that it can also format your message if you wish to &lt;B&gt;AND&lt;/B&gt; the user &lt;B&gt;&lt;U&gt;cannot&lt;/U&gt;&lt;/B&gt; close or press any button on the message for the specified amount of time — I suggest to keep the time-out value somewhere between 3 to 7 seconds max.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-1170127228775118857?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/NuGcZa5SIjYamsxEXDzxWa_fk8I/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NuGcZa5SIjYamsxEXDzxWa_fk8I/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/NuGcZa5SIjYamsxEXDzxWa_fk8I/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NuGcZa5SIjYamsxEXDzxWa_fk8I/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/CNgkjnJRphk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/1170127228775118857/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/10/message-dialogs-youre-doing-it-wrong.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/1170127228775118857?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/1170127228775118857?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/CNgkjnJRphk/message-dialogs-youre-doing-it-wrong.html" title="Message dialogs: you're doing it wrong..." /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/10/message-dialogs-youre-doing-it-wrong.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAHSXc8fCp7ImA9Wx5VGEk.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-2801648164793299527</id><published>2010-10-12T04:58:00.000+03:00</published><updated>2010-10-12T04:58:58.974+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-12T04:58:58.974+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tips" /><category scheme="http://www.blogger.com/atom/ns#" term="Callbacks" /><title>Fun with callbacks and progress form</title><content type="html">Some time ago I needed to display a progress form in order to give feedback to the user on current state of the task, therefore the „challenge¯ is pretty simple: a secondary form that will have a label — to display some info on current task — and two progress bars — for visual feedback — 1 progress bar for the „overall progress¯ and the other one for „current progress¯, this means that we have a task which is composed of few steps and each step has it's own progress.&lt;br /&gt;
Sooo... the MAIN idea is that the progress form needs to be displayed as modal while also calling a method(procedure) from another unit — this is where callbacks come into play.&lt;br /&gt;
What are callbacks?!&lt;br /&gt;
&lt;blockquote&gt;&lt;b&gt;&lt;br /&gt;
A callback is a reference to executable code, or a piece of executable code, that is passed as an argument to other code. This allows a lower-level software layer to call a subroutine (or function) defined in a higher-level layer.&lt;br /&gt;
&lt;/B&gt;&lt;/BLOCKQUOTE&gt;&lt;a href="https://sites.google.com/site/delphigeist/downloads/dgProgressCallback.zip"&gt;For a better understanding of this article click this text to download the source code.&lt;/a&gt;&lt;br /&gt;
Let's achieve the same thing in a new project:&lt;br /&gt;
- add a button to this form&lt;br /&gt;
- add a new form to this application, remove it from auto-create forms(Project-&gt;Options-&gt;Forms)&lt;br /&gt;
- add two labels and two progress bars to the second form&lt;br /&gt;
- set the caption of one label to „Overall progress¯ and to the other label „Current progress¯&lt;br /&gt;
- name one progress bar „pbOverall¯ and the other „pbCurrent¯&lt;br /&gt;
Now let's write some code, first define the callback method as&lt;br /&gt;
&lt;pre&gt;&lt;b&gt;type&lt;/B&gt;
  TProgressCallback = &lt;b&gt;procedure&lt;/B&gt; (InProgressOverall, InProgressCurrent: TProgressBar) &lt;b&gt;of Object&lt;/B&gt;;
&lt;/PRE&gt;we will pass „pbOverall¯ and „pbCurrent¯ as parameters in the callback method.&lt;br /&gt;
It's time to define a generic method that will create a new instance of our progress form in order to display a modal progress&lt;br /&gt;
&lt;pre&gt;&lt;b&gt;procedure&lt;/B&gt; ShowProgress(InCallback: TProgressCallback);
&lt;b&gt;var&lt;/B&gt;
  LWindowList: TTaskWindowList;
  LSaveFocusState: TFocusState;
  LProgressForm: TfrmProgressForm;
&lt;b&gt;begin&lt;/B&gt;
  // create the instance
  LProgressForm := TfrmProgressForm.Create(&lt;b&gt;NIL&lt;/B&gt;);
  &lt;b&gt;try&lt;/B&gt;
    // save the focus state
    LSaveFocusState := SaveFocusState;
    // save the focused form
    Screen.SaveFocusedList.Insert(0, Screen.FocusedForm);
    // notify that a form will be displayed as modal
    Application.ModalStarted;
    // disable all other forms
    LWindowList := DisableTaskWindows(0);
    // set the progress form instance as the screen focused form 
    Screen.FocusedForm := LProgressForm;
    // send a active message
    SendMessage(LProgressForm.Handle, CM_ACTIVATE, 0, 0);
    // show the form
    LProgressForm.Show;
    // InCallback is our callback method to which we pass pbOverall and pbCurrent
    // as parameters so we can play with them later
    InCallback(LProgressForm.pbOverall, LProgressForm.pbCurrent);
    // after the callback is executed enable windows
    EnableTaskWindows(LWindowList);
    // restore focus state
    RestoreFocusState(LSaveFocusState);
  &lt;b&gt;finally&lt;/B&gt;
    // notify that we're leaving a modal state
    Application.ModalFinished;
    // free and nil the progress form instance
    FreeAndNil(LProgressForm);
  &lt;b&gt;end&lt;/B&gt;;
&lt;b&gt;end&lt;/B&gt;;
&lt;/PRE&gt;all we have left to do now is to define a (private or public)method in main form with same parameters as the callback method like so:&lt;br /&gt;
&lt;pre&gt;&lt;b&gt;type&lt;/B&gt;
  TForm1 = &lt;b&gt;class&lt;/B&gt;(TForm)
    Button1: TButton;
    &lt;b&gt;procedure&lt;/B&gt; Button1Click(Sender: TObject);
  &lt;b&gt;private&lt;/B&gt;
    // this is our callback method
    &lt;b&gt;procedure&lt;/B&gt; ProgressCallback(InProgressOverall, InProgressCurrent: TProgressBar);
  &lt;b&gt;public&lt;/B&gt;
    { Public declarations }
  &lt;b&gt;end&lt;/B&gt;;
&lt;/PRE&gt;in the implementation section copy-paste this code&lt;br /&gt;
&lt;pre&gt;&lt;b&gt;procedure&lt;/B&gt; TForm1.ProgressCallback(InProgressOverall,
  InProgressCurrent: TProgressBar);
&lt;b&gt;var&lt;/B&gt;
  Index: Integer;
  kIndex: Integer;
&lt;b&gt;begin&lt;/B&gt;
  MessageDlg('Press OK to start a long task...', mtInformation, [mbOK], 0);
  // 10 steps
  InProgressOverall.Max := 10;
  // 3000 updates per step
  InProgressCurrent.Max := 3000;
  &lt;b&gt;for&lt;/B&gt; Index := 1 &lt;b&gt;to&lt;/B&gt; InProgressOverall.Max &lt;b&gt;do begin
    for&lt;/B&gt; kIndex := 1 &lt;b&gt;to&lt;/B&gt; InProgressCurrent.Max &lt;b&gt;do begin&lt;/B&gt;
      InProgressCurrent.Position := kIndex;
      // force application to process messages
      Application.ProcessMessages;
    &lt;b&gt;end&lt;/B&gt;; // for kIndex := 1 to InProgressCurrent.Max do begin
    InProgressOverall.Position := Index;
    // force application to process messages
    Application.ProcessMessages;
  &lt;b&gt;end&lt;/B&gt;; // for Index := 1 to InProgressOverall.Max do begin
  MessageDlg('Task completed!', mtInformation, [mbOK], 0);
&lt;b&gt;end&lt;/B&gt;;
&lt;/PRE&gt;on the main form you have a button, in it's OnClick event add the following code:&lt;br /&gt;
&lt;pre&gt;ShowProgress(Self.ProgressCallback);
&lt;/PRE&gt;Any ideas on how to achieve the same effect in less code or more elegant?! please leave comment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-2801648164793299527?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GflMDwc-Su7Spk5ZmzLI3ihbyXs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GflMDwc-Su7Spk5ZmzLI3ihbyXs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GflMDwc-Su7Spk5ZmzLI3ihbyXs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GflMDwc-Su7Spk5ZmzLI3ihbyXs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/wF8vnYQ8yo8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/2801648164793299527/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/10/fun-with-callbacks-and-progress-form.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/2801648164793299527?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/2801648164793299527?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/wF8vnYQ8yo8/fun-with-callbacks-and-progress-form.html" title="Fun with callbacks and progress form" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/10/fun-with-callbacks-and-progress-form.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEYERXc9fSp7ImA9Wx5WFk4.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-58809915379366030</id><published>2010-09-28T04:08:00.000+03:00</published><updated>2010-09-28T04:08:24.965+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-28T04:08:24.965+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Reports" /><category scheme="http://www.blogger.com/atom/ns#" term="Streams" /><title>How to save a report as PDF to a stream with FastReport</title><content type="html">Recently I needed to save a report to a stream as PDF, I'm using &lt;a href="http://fast-report.com/en/"&gt;FastReport&lt;/a&gt; for my reports.&lt;br /&gt;
I've searched a lot for a way to do this, but unfortunately I only found comments like „you can't export a report to a stream in PDF format with FastReport¯ and similar comments... so I started browsing the source code of the PDF exporter and 2 minutes later I saw that the exporter checks if property „Stream¯ is assigned, otherwise it will create a TFileStream instance using the report's „FileName¯ property — therefore assigning a TStream descendant to PDFExporter.Stream will make the exporter write the PDF data to THAT stream in stead of the file, without further chit-chat, let's see some code:&lt;br /&gt;
I took „PrintStringList¯ example from the Demo folder and modified it to show you how it's done, I've added a new button on the form and a save dialog, in the OnClick event of the button I've added the following code:&lt;br /&gt;
&lt;pre&gt;procedure TForm1.Button2Click(Sender: TObject);
var
  // we use a file stream for example, but you can replace this
  // with a memory stream or any type of stream which is a
  // descendant of abstract class TStream
  LFileStream: TFileStream;
begin
  // allow the user to choose a file name
  if SaveDialog1.Execute then begin
    // create the file stream object
    LFileStream := TFileStream.Create(SaveDialog1.FileName, fmCreate or fmShareDenyNone);
    try
      // set the range properties
      StringDS.RangeEnd := reCount;
      StringDS.RangeEndCount := sl.Count;
      // THIS IS THE MAGIC
      // assign the stream for the TfrxPDFExport component
      frxPDFExport1.Stream := LFileStream;
      // prepare the report
      frxReport1.PrepareReport(True);
      // export calls the PDFExport component in this case
      frxReport1.Export(frxPDFExport1);
    finally
      // free the file stream object
      FreeAndNil(LFileStream);
      // NIL reference to the stream
      frxPDFExport1.Stream := NIL;
    end; // tryf
  end; // if SaveDialog1.Execute then begin
end;
&lt;/pre&gt;&lt;b&gt;NOTE: you need FastReport installed!!&lt;/b&gt;&lt;br /&gt;
&lt;a href="https://sites.google.com/site/delphigeist/downloads/PrintStringList_modified.zip"&gt;You can download the entire project source code by clicking on this text.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-58809915379366030?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/eouiBaNiqkpMZTuNUIbDWfNb-GM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eouiBaNiqkpMZTuNUIbDWfNb-GM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/eouiBaNiqkpMZTuNUIbDWfNb-GM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eouiBaNiqkpMZTuNUIbDWfNb-GM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/FDu4dEzOyOE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/58809915379366030/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/09/how-to-save-report-as-pdf-to-stream.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/58809915379366030?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/58809915379366030?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/FDu4dEzOyOE/how-to-save-report-as-pdf-to-stream.html" title="How to save a report as PDF to a stream with FastReport" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/09/how-to-save-report-as-pdf-to-stream.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04DQnY-eip7ImA9Wx5XGEk.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-5047791801719164342</id><published>2010-09-19T01:46:00.000+03:00</published><updated>2010-09-19T01:46:13.852+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-19T01:46:13.852+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="zlib" /><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><category scheme="http://www.blogger.com/atom/ns#" term="Encryption" /><category scheme="http://www.blogger.com/atom/ns#" term="compression" /><title>File/Stream compression/decompression class</title><content type="html">Tired of searching for zip libraries just to compress/decompress a file/stream?!&lt;br /&gt;
Why not use zlib shipped with Delphi?! it's lightweight, super fast, very good compression and above all it's very easy to use!!&lt;br /&gt;
( uDGCompressor.pas )&lt;br /&gt;
&lt;pre&gt;unit uDGCompressor;

interface

//  Author: Dorin Duminica
//
//  Scope: file/stream compression/decompression and encryption/decryption
//
//  License: free for commercial or private use

uses
  SysUtils,
  Windows,
  Classes,
  zlib;

const
  CKILO_BYTE = 1024;
  //  default buffer //
  CBUFFER_SIZE = 35 * CKILO_BYTE;

//  cipher base class //
//  the child classes will HAVE to implement the Encrypt/Decrypt  //
//  methods based on the parameters defined bellow  //
type
  TDGCipherBase = class(TObject)
  public
    procedure EncryptData(const InData: Pointer; const InSize: Integer;
      out OutData: Pointer; out OutSize: Integer); virtual; abstract;
    procedure DecryptData(const InData: Pointer; const InSize: Integer;
      out OutData: Pointer; out OutSize: Integer); virtual; abstract;
  end;

//  before each compressed block the following structure will be written  //
type
  TDGBlockDesc = record
    //  initial size of the block, before compresstion  //
    InitialSize: Integer;
    //  size of the compressed block in stream  //
    Size: Integer;
  end; // TDGBlockDesc = record

const
  szDGBlockDesc = SizeOf(TDGBlockDesc);

type
  //  each time a block of data is processed  //
  TDGProgressEvent = procedure (const Progress, ProgressMax: Integer) of Object;

  //  before/after compress/decompress events //
  TDGCompressorEvent = procedure (const InFileName, OutFileName: string;
    const InSize, OutSize: Int64) of Object;

  //  when a block's decompressed size is different than initial size //
  //  this type of event will be fired if assigned  //
  TDGDecompressFailEvent = procedure (const BlockDesc: TDGBlockDesc;
    const InBuffer, OutBuffer: Pointer; const InSize, OutSize: Integer) of Object;

//  the compress/decompress class //s
type
  TDGCompressor = class(TObject)
  private
    FInStreamSize: Int64;
    FOutStreamSize: Int64;
    FBufferSize: Integer;
    FCipher: TDGCipherBase;
    FOnProgress: TDGProgressEvent;
    FOnAfterCompress: TDGCompressorEvent;
    FOnBeforeCompress: TDGCompressorEvent;
    FOnAfterDecompress: TDGCompressorEvent;
    FOnBeforeDecompress: TDGCompressorEvent;
    FOnDecompressFail: TDGDecompressFailEvent;
  public
    constructor Create;
  public
    procedure CompressFile(const InFileName, OutFileName: string);
    procedure DecompressFile(const InFileName, OutFileName: string);
    procedure CompressStream(const InStream, OutStream: TStream);
    procedure DecompressStream(const InStream, OutStream: TStream);
  published
    //  properties  //
    property BufferSize: Integer read FBufferSize write FBufferSize;
    property Cipher: TDGCipherBase read FCipher write FCipher;
    property InStreamSize: Int64 read FInStreamSize;
    property OutStreamSize: Int64 read FOutStreamSize;
    //  events  //
    property OnAfterCompress: TDGCompressorEvent read FOnAfterCompress write FOnAfterCompress;
    property OnBeforeCompress: TDGCompressorEvent read FOnBeforeCompress write FOnBeforeCompress;
    property OnAfterDecompress: TDGCompressorEvent read FOnAfterDecompress write FOnAfterDecompress;
    property OnBeforeDecompresss: TDGCompressorEvent read FOnBeforeDecompress write FOnBeforeDecompress;
    property OnDecompressFail: TDGDecompressFailEvent read FOnDecompressFail write FOnDecompressFail;
    property OnProgress: TDGProgressEvent read FOnProgress write FOnProgress;
  end;

implementation

{ TDGCompressor }

procedure TDGCompressor.CompressFile(const InFileName, OutFileName: string);
var
  LInFileStream: TFileStream;
  LOutFileStream: TFileStream;
begin
  //  create TFileStream instances  //
  LInFileStream := TFileStream.Create(InFileName, fmOpenRead or fmShareDenyNone);
  LOutFileStream := TFileStream.Create(OutFileName, fmCreate or fmShareDenyNone);
  //  set the position of LInFileStream to the begining
  LInFileStream.Position := 0;
  //  call OnBeforeCompress event if assigned //
  if Assigned(FOnBeforeCompress) then
    FOnBeforeCompress(InFileName, OutFileName, LInFileStream.Size, LOutFileStream.Size);
  try
    //  attempt to compress stream  //
    CompressStream(LInFileStream, LOutFileStream);
  finally
    //  free objects  //
    FreeAndNil(LInFileStream);
    FreeAndNil(LOutFileStream);
  end; // tryf
  //  call OnAfterCompress event if assigned  //
  if Assigned(FOnAfterCompress) then
    FOnAfterCompress(InFileName, OutFileName, LInFileStream.Size, LOutFileStream.Size);
end;

procedure TDGCompressor.CompressStream(const InStream, OutStream: TStream);

    function ThereAreBytes: Boolean;
    begin
      Result := (InStream.Position &lt; InStream.Size) and
        ((InStream.Size - InStream.Position) &gt; 0);
    end; // function ThereAreBytes: Boolean;

var
  LInBuffer: Pointer;
  LOutBuffer: Pointer;
  LWriteBuffer: Pointer;
  LBlockDesc: TDGBlockDesc;
  LProgress: Integer;
  LWriteSize: Integer;
  LReadBytes: Integer;
  LProgressMax: Integer;
  LCompressedSize: Integer;
begin
  //  store the size of the InStream
  FInStreamSize := InStream.Size;
  //  allocate memory for the read buffer //
  LInBuffer := AllocMem(BufferSize);
  //  initalize progress  //
  LProgress := 0;
  //  set the max progress  //
  LProgressMax := InStream.Size;
  //  while we have bytes in InStream that are not compressed //
  while ThereAreBytes do begin
    //  attempt to read the BufferSize number of bytes from InStream  //
    LReadBytes := InStream.Read(LInBuffer^, BufferSize);
    //  compress the read bytes based on LReadBytes variable which holds
    //  the actual number of read bytes from InStream
    ZCompress(LInBuffer, LReadBytes, LOutBuffer, LCompressedSize);
    //  if we don't have a cipher assigned
    if NOT Assigned(FCipher) then begin
      //  set the reference to LOutBuffer
      LWriteBuffer := LOutBuffer;
      //  copy the size of the buffer
      LWriteSize := LCompressedSize;
    end else
      //  we have a cipher assigned, this means that we need to
      //  call the default EncryptData method which will encrypt our
      //  compressed data
      FCipher.EncryptData(LOutBuffer, LCompressedSize, LWriteBuffer, LWriteSize);
    //  set the inital size of the block, we check it on decompress
    LBlockDesc.InitialSize := LReadBytes;
    //  set the number of bytes that we have compressed and/or encrypted
    LBlockDesc.Size := LWriteSize;
    //  write the block descriptor
    OutStream.WriteBuffer(LBlockDesc, szDGBlockDesc);
    //  write the block data
    OutStream.WriteBuffer(LWriteBuffer^, LWriteSize);
    //  free memory from LOutBuffer
    FreeMem(LOutBuffer);
    //  free memory from LWriteBuffer only if a cipher is assigned
    if Assigned(FCipher) then
      FreeMem(LWriteBuffer);
    //  increment the progress by the number of read bytes
    Inc(LProgress, LReadBytes);
    // update the size of the OutStream
    FOutStreamSize := OutStream.Size;
    //  if the OnProgress event is assigned then call it by passing
    //  the current progress and the maximum progress
    if Assigned(FOnProgress) then
      FOnProgress(LProgress, LProgressMax);
  end; // while ThereAreBytes do begin
  //  free memory from LInBuffer
  FreeMem(LInBuffer, BufferSize);
end;

constructor TDGCompressor.Create;
begin
  //  initialize default values //
  FBufferSize := CBUFFER_SIZE;
  FInStreamSize := 0;
  FOutStreamSize := 0;
end;

procedure TDGCompressor.DecompressFile(const InFileName, OutFileName: string);
var
  LInFileStream: TFileStream;
  LOutFileStream: TFileStream;
begin
  //  create TFileStream instances  //
  LInFileStream := TFileStream.Create(InFileName, fmOpenRead or fmShareDenyNone);
  LOutFileStream := TFileStream.Create(OutFileName, fmCreate or fmShareDenyNone);
  //  call OnBeforeDecompress event if assigned //
  if Assigned(FOnBeforeDecompress) then
    FOnBeforeDecompress(InFileName, OutFileName, LInFileStream.Size, LOutFileStream.Size);
  //  attempt to decompress stream  //
  try
    DecompressStream(LInFileStream, LOutFileStream);
  finally
    //  free objects  //
    FreeAndNil(LInFileStream);
    FreeAndNil(LOutFileStream);
  end; // tryf
  //  call OnAfterDecompress event if assigned  //
  if Assigned(FOnAfterDecompress) then
    FOnAfterDecompress(InFileName, OutFileName, LInFileStream.Size, LOutFileStream.Size);
end;

procedure TDGCompressor.DecompressStream(const InStream, OutStream: TStream);

    function ThereAreBytes: Boolean;
    begin
      Result := (InStream.Position &lt; InStream.Size) and
        ((InStream.Size - InStream.Position) &gt; 0);
    end; // function ThereAreBytes: Boolean;

var
  LInBuffer: Pointer;
  LOutBuffer: Pointer;
  LWriteBuffer: Pointer;
  LBlockDesc: TDGBlockDesc;
  LProgress: Integer;
  LWriteSize: Integer;
  LReadBytes: Integer;
  LProgressMax: Integer;
  LDecompressedSize: Integer;
begin
  //  store the size of the InStream
  FInStreamSize := InStream.Size;
  //  allocate memory for the read buffer //
  LInBuffer := AllocMem(BufferSize);
  //  initalize progress  //
  LProgress := 0;
  //  set the max progress  //
  LProgressMax := InStream.Size;
  //  while we have bytes in InStream ... //
  while ThereAreBytes do begin
    //  read the block descriptor from stream
    InStream.ReadBuffer(LBlockDesc, szDGBlockDesc);
    //  attempt to read the number of bytes in the block descriptor
    LReadBytes := InStream.Read(LInBuffer^, LBlockDesc.Size);
    //  if we don't have a cipher assigned  ///
    if NOT Assigned(FCipher) then begin
      //  decompress the buffer //
      ZDecompress(LInBuffer, LReadBytes, LOutBuffer, LDecompressedSize);
      //  set reference to LOutBuffer //
      LWriteBuffer := LOutBuffer;
      //  copy the number of bytes  //
      LWriteSize := LDecompressedSize;
    end else begin
      //  we have a cipher assigned, we first decrypt data  //
      FCipher.DecryptData(LInBuffer, LReadBytes, LOutBuffer, LDecompressedSize);
      //  and then decompress it  //
      ZDecompress(LOutBuffer, LDecompressedSize, LWriteBuffer, LWriteSize);
    end; // if NOT Assigned(FCipher) then begin
    //  check if initial size is equal to current (decrypted and) decompressed size //
    if LBlockDesc.InitialSize &lt;&gt; LWriteSize then
      if Assigned(FOnDecompressFail) then
        FOnDecompressFail(LBlockDesc, LInBuffer, LWriteBuffer, LReadBytes, LWriteSize);
    OutStream.WriteBuffer(LWriteBuffer^, LWriteSize);
    FreeMem(LOutBuffer);
    if Assigned(FCipher) then
      FreeMem(LWriteBuffer);
    Inc(LProgress, LReadBytes + szDGBlockDesc);
    //  update the size of the OutStream
    FOutStreamSize := OutStream.Size;
    //  if the OnProgress event is assigned then call it by passing
    //  the current progress and the maximum progress
    if Assigned(FOnProgress) then
      FOnProgress(LProgress, LProgressMax);
  end; // while ThereAreBytes do begin
  //  free memory from LInBuffer
  FreeMem(LInBuffer, BufferSize);
end;

end.
&lt;/pre&gt;&lt;br /&gt;
You can download:&lt;br /&gt;
- &lt;a href="https://sites.google.com/site/delphigeist/downloads/DGCompressor_SRC.zip"&gt;only the source code&lt;/a&gt;&lt;br /&gt;
- &lt;a href="https://sites.google.com/site/delphigeist/downloads/DGCompressor_BIN.zip"&gt;source code + binary&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;B&gt;As always any comments are welcomed.&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-5047791801719164342?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Ap564oSxEqm6dkLs8pMSUrVClq0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ap564oSxEqm6dkLs8pMSUrVClq0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Ap564oSxEqm6dkLs8pMSUrVClq0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ap564oSxEqm6dkLs8pMSUrVClq0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/6Us5J1KvCq4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/5047791801719164342/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/09/filestream-compressiondecompression.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/5047791801719164342?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/5047791801719164342?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/6Us5J1KvCq4/filestream-compressiondecompression.html" title="File/Stream compression/decompression class" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/09/filestream-compressiondecompression.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYBRno7eCp7ImA9Wx5XEE0.&quot;"><id>tag:blogger.com,1999:blog-7691723069373577907.post-1659324288125481802</id><published>2010-09-09T07:39:00.000+03:00</published><updated>2010-09-09T07:39:17.400+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-09T07:39:17.400+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Facebook" /><title>Delphigeist group is available on Facebook</title><content type="html">&lt;a href="http://www.facebook.com/group.php?gid=159341794080763"&gt;I've been thinking of creating Delphigeist group on Facebook so here's the link http://www.facebook.com/group.php?gid=159341794080763&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7691723069373577907-1659324288125481802?l=www.delphigeist.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xQFYkEoljZ8dAZA7eq7P617xD6A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xQFYkEoljZ8dAZA7eq7P617xD6A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xQFYkEoljZ8dAZA7eq7P617xD6A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xQFYkEoljZ8dAZA7eq7P617xD6A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheSpiritOfDelphi/~4/Jt7zcd06uyg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.delphigeist.com/feeds/1659324288125481802/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.delphigeist.com/2010/09/delphigeist-group-is-available-on.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/1659324288125481802?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7691723069373577907/posts/default/1659324288125481802?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheSpiritOfDelphi/~3/Jt7zcd06uyg/delphigeist-group-is-available-on.html" title="Delphigeist group is available on Facebook" /><author><name>Dorin Duminica</name><uri>http://www.blogger.com/profile/02436024025965763054</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_MRKM_3muqTc/TLRmigHfZMI/AAAAAAAAAC0/lChKAVxy24k/S220/avatar.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.delphigeist.com/2010/09/delphigeist-group-is-available-on.html</feedburner:origLink></entry></feed>

