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

<channel>
	<title>Ilya Gorodnyanskiy - IT-Blog &#187; Delphi</title>
	<atom:link href="http://i-gorod.org/itblog/category/delphi/feed/" rel="self" type="application/rss+xml" />
	<link>http://i-gorod.org/itblog</link>
	<description>Personal web site of Ilya Gorodnyanskiy</description>
	<lastBuildDate>Tue, 01 Nov 2011 17:19:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.2</generator>
		<item>
		<title>Open Folder Dialog in Delphi</title>
		<link>http://i-gorod.org/itblog/2011/11/01/open_file_dialog_delphi/</link>
		<comments>http://i-gorod.org/itblog/2011/11/01/open_file_dialog_delphi/#comments</comments>
		<pubDate>Tue, 01 Nov 2011 17:06:48 +0000</pubDate>
		<dc:creator>Ilya G.</dc:creator>
				<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://i-gorod.org/itblog/?p=148</guid>
		<description><![CDATA[The function below uses ShellAPI and implements Open Folder Dialog. This function works fine on Windows XP and Windows7 as well. function GetFolderDialog(const ACaption: string; out ADirectory: string): boolean; const BIF_NEWDIALOGSTYLE = $0040; BIF_NONEWFOLDERBUTTON = $0200; BIF_USENEWUI = BIF_NEWDIALOGSTYLE or BIF_EDITBOX; var pWindowList: Pointer; tbsBrowseInfo: TBrowseInfo; pBuffer: PChar; iOldErrorMode: cardinal; pIemIDList: PItemIDList; pShellMalloc: IMalloc; begin [...]]]></description>
			<content:encoded><![CDATA[<p>The function below uses ShellAPI and implements Open Folder Dialog. This function works fine on Windows XP and Windows7 as well.<br />
<span id="more-148"></span><br />
<code></p>
<pre>
function GetFolderDialog(const ACaption: string;
                      out ADirectory: string): boolean;
const
  BIF_NEWDIALOGSTYLE = $0040;
  BIF_NONEWFOLDERBUTTON = $0200;
  BIF_USENEWUI = BIF_NEWDIALOGSTYLE or BIF_EDITBOX;
var
  pWindowList: Pointer;
  tbsBrowseInfo: TBrowseInfo;
  pBuffer: PChar;
  iOldErrorMode: cardinal;
  pIemIDList: PItemIDList;
  pShellMalloc: IMalloc;
begin
  CoInitialize(nil);
  try
    Result := false;
    ADirectory := '';
    FillChar(tbsBrowseInfo, sizeof(tbsBrowseInfo), 0);
    if (ShGetMalloc(pShellMalloc) = S_OK)
                   and Assigned(pShellMalloc) then begin
      pBuffer := pShellMalloc.Alloc(MAX_PATH);
      try
        with tbsBrowseInfo do begin
          hwndOwner := Application.Handle;
          pidlRoot := nil;
          pszDisplayName := pBuffer;
          lpszTitle := PChar(ACaption);
          ulFlags := BIF_USENEWUI or
                         BIF_RETURNONLYFSDIRS or
                         BIF_NONEWFOLDERBUTTON;
          lParam := 0;
        end;
        pWindowList := DisableTaskWindows(0);
        iOldErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS);
        try
          pIemIDList := ShBrowseForFolder(tbsBrowseInfo);
        finally
          SetErrorMode(iOldErrorMode);
          EnableTaskWindows(pWindowList);
        end;
        Result := Assigned(pIemIDList);
        if Result then begin
          ShGetPathFromIDList(pIemIDList, pBuffer);
          pShellMalloc.Free(pIemIDList);
          ADirectory := pBuffer;
        end;
      finally
        pShellMalloc.Free(pBuffer);
      end;
    end;
  finally
    CoUninitialize;
  end;
end;
</pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://i-gorod.org/itblog/2011/11/01/open_file_dialog_delphi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Copy Data from Grid and paste it into Excel</title>
		<link>http://i-gorod.org/itblog/2011/07/22/grid-copy-data-paste-exce/</link>
		<comments>http://i-gorod.org/itblog/2011/07/22/grid-copy-data-paste-exce/#comments</comments>
		<pubDate>Fri, 22 Jul 2011 10:05:47 +0000</pubDate>
		<dc:creator>Ilya G.</dc:creator>
				<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://i-gorod.org/itblog/?p=145</guid>
		<description><![CDATA[If you want to copy some lines of data from a Grid (Ctrl+C) and paste (Ctrl+V) it into an Excel document, just use following code: procedure MyForm.Button1Click(Sender: TObject); var i, j: integer; lString: string; begin lString := ''; for i := 0 to Grid.RowCount - 1 do begin for j := 0 to Grid.ColCount - [...]]]></description>
			<content:encoded><![CDATA[<p>If you want to copy some lines of data from a Grid (Ctrl+C) and paste (Ctrl+V) it into an Excel document, just use following code:</p>
<pre>
<code>
procedure MyForm.Button1Click(Sender: TObject);
var
  i, j: integer;
  lString: string;
begin
  lString := '';
  for i := 0 to Grid.RowCount - 1 do begin
    for j := 0 to Grid.ColCount - 1 do begin
      lString := lString + Grid.Cells[j, i];
      if j &lt; Grid.ColCount - 1 then
        lString := lString + #9;
    end;
    if i &lt; Grid.RowCount - 1 then
      lString := lString + #13;
  end;
  Clipboard.AsText := lString;
end;
</code>
</pre>
<p>With few modifications this code can be also applied to TDrawGridEx.</p>
]]></content:encoded>
			<wfw:commentRss>http://i-gorod.org/itblog/2011/07/22/grid-copy-data-paste-exce/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xml Alternative for Delphi&#8217;s INI Files.</title>
		<link>http://i-gorod.org/itblog/2011/03/31/xml-delphi-ini-files/</link>
		<comments>http://i-gorod.org/itblog/2011/03/31/xml-delphi-ini-files/#comments</comments>
		<pubDate>Thu, 31 Mar 2011 07:37:46 +0000</pubDate>
		<dc:creator>Ilya G.</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[files]]></category>
		<category><![CDATA[ini]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://i-gorod.org/itblog/?p=140</guid>
		<description><![CDATA[I found on the net the way how to use XML files instead of Delphi ini-files. The advantage of xml uasage is that you could extend the code by methods for iterating through the sections and their entries. unit XMLConfig; interface uses Forms, SysUtils, Windows, XmlIntf, XMLDoc; type TXMLConfig = class private FModified: Boolean; FFileName: [...]]]></description>
			<content:encoded><![CDATA[<p>I found on the net the way how to use XML files instead of Delphi ini-files. The advantage of xml uasage is that you could extend the code by methods for iterating through the sections and their entries.<br />
<span id="more-140"></span></p>
<pre>
<code>

unit XMLConfig;

interface

uses
  Forms, SysUtils, Windows, XmlIntf, XMLDoc;

type
  TXMLConfig = class
  private
    FModified: Boolean;
    FFileName: string;
    FXMLDoc: TXMLDocument;
    FBackup: Boolean;
    function GetVersion: string;
  public
    constructor Create(const FileName: string); overload;
    constructor Create; overload;
    destructor Destroy; override;
    procedure Save;
    function ReadString(const Section, Key,
                               default: string): string;
    procedure WriteString(const Section, Key,
                               Value: string);
    function ReadInteger(const Section, Key: string;
                                 default: Integer): Integer;
    procedure WriteInteger(const Section, Key: string;
                                    Value: Integer);
    function ReadBoolean(const Section, Key: string;
                                default: Boolean): Boolean;
    procedure WriteBoolean(const Section, Key: string;
                                    Value: Boolean);
    property Backup: Boolean read FBackup write FBackup;
    property Version: string read GetVersion;
  end;

implementation

{ TXMLConfig }

constructor TXMLConfig.Create(const FileName: string);
begin
  inherited Create;
  FBackup         := True;
  FFileName       := FileName;
  FXMLDoc         := TXMLDocument.Create(Application);
  FXMLDoc.Options := [doNodeAutoIndent];
  if FileExists(FFileName) then
    FXMLDoc.LoadFromFile(FFileName)
  else
  begin
    FXMLDoc.Active := True;
    FXMLDoc.AddChild('Configuration');
  end;
end;

constructor TXMLConfig.Create;
begin
  Create(ChangeFileExt(Application.Exename, '_cfg.xml'));
end;

destructor TXMLConfig.Destroy;
begin
  Save;
  FXMLDoc.Destroy;
  inherited;
end;

function TXMLConfig.GetVersion: string;
begin
  Result := '1.00';
end;

function TXMLConfig.ReadBoolean(const Section, Key: string; default: Boolean): Boolean;
begin
  Result := Boolean(ReadInteger(Section, Key, Integer(default)));
end;

function TXMLConfig.ReadInteger(const Section, Key: string; default: Integer): Integer;
begin
  Result := StrToInt(ReadString(Section, Key, IntToStr(default)));
end;

function TXMLConfig.ReadString(const Section, Key, default: string): string;
var
  Node: IXMLNode;
begin
  Node := FXMLDoc.DocumentElement.ChildNodes.FindNode(Section);
  if Assigned(Node) and Node.HasAttribute(Key) then
    Result := Node.Attributes[Key]
  else
    Result := default;
end;

procedure TXMLConfig.Save;
begin
  if not FModified then
    Exit;
  if FBackup then

    CopyFile(PChar(FFileName), PChar(FFileName + '.bak'), False);
  FXMLDoc.SaveToFile(FFileName);
  FModified := False;
end;

procedure TXMLConfig.WriteBoolean(const Section, Key: string; Value: Boolean);
begin
  WriteInteger(Section, Key, Integer(Value));
end;

procedure TXMLConfig.WriteInteger(const Section, Key: string; Value: Integer);
begin
  WriteString(Section, Key, IntToStr(Value));
end;

procedure TXMLConfig.WriteString(const Section, Key, Value: string);
var
  lNode: IXMLNode;
begin
  if ReadString(Section, Key, '') = Value then
    Exit;
  lNode := FXMLDoc.DocumentElement.ChildNodes.FindNode(Section);
  if not Assigned(lNode) then
    lNode := FXMLDoc.DocumentElement.AddChild(Section);
  lNode.Attributes[Key] := Value;
  FModified := True;
end;

end.
</code>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://i-gorod.org/itblog/2011/03/31/xml-delphi-ini-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Make Modal Form?</title>
		<link>http://i-gorod.org/itblog/2010/04/26/how-to-make-modal-form/</link>
		<comments>http://i-gorod.org/itblog/2010/04/26/how-to-make-modal-form/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 05:14:59 +0000</pubDate>
		<dc:creator>Ilya G.</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[modal form]]></category>
		<category><![CDATA[modal result]]></category>
		<category><![CDATA[modal window]]></category>

		<guid isPermaLink="false">http://i-gorod.org/itblog/?p=133</guid>
		<description><![CDATA[Just a short notice how to make modal forms in Delphi. Assume, you have two Forms: AForm and BForm. AForm is your main form and you want now to call B as modal form (a modal form is a child form that requires the user to interact with it before it gets possible to return [...]]]></description>
			<content:encoded><![CDATA[<p>Just a short notice how to make modal forms in Delphi. Assume, you have two Forms: AForm and BForm. AForm is your main form and you want now to call B as modal form (a modal form is a child form that requires the user to interact with it before it gets possible to return to the parent form). So inside your AForm you call BForm in the following way:<span id="more-133"></span></p>
<pre>
<code>
procedure AForm.Button1Click(Sender: TObject);
var b : BForm;
begin
  b := BForm.Create(nil);
  try
    if b.ShowModal = mrOk then begin
      // your code if OK Button is clicked
    end
    else begin
      // your code, if cancel is clicked
    end;
  finally
      b.Release;
  end;
end;
</code>
</pre>
<p>On your BForm you need two Buttons. One of them you use for Ok and the other one for Cancel. The only thing you need to do is to chage respectively the ModalResult property of these buttons as shown in the picture bellow:</p>
<p><img src="http://i-gorod.org/itblog/images/delphi/modalButton.gif" alt="Change properties of the buttons for modal result" /></p>
<p>That&#8217;s all. Notice, that the value of the Visible-property of your BForm should be false. </p>
]]></content:encoded>
			<wfw:commentRss>http://i-gorod.org/itblog/2010/04/26/how-to-make-modal-form/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exception Handling in Delphi</title>
		<link>http://i-gorod.org/itblog/2010/04/25/exception-handling-in-delphi/</link>
		<comments>http://i-gorod.org/itblog/2010/04/25/exception-handling-in-delphi/#comments</comments>
		<pubDate>Sun, 25 Apr 2010 13:30:53 +0000</pubDate>
		<dc:creator>Ilya G.</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[catch]]></category>
		<category><![CDATA[except]]></category>
		<category><![CDATA[exception]]></category>
		<category><![CDATA[finally]]></category>
		<category><![CDATA[try]]></category>

		<guid isPermaLink="false">http://i-gorod.org/itblog/?p=135</guid>
		<description><![CDATA[Exceptions are a vital language structure of any modern programming language. This posting shows the usage of Delphi&#8217;s exceptions. To raise an exception: raise Exception.Create('Your exception message'); Excepion is general exception class. Of course you can define your own Exception classes. To catch exceptions you have several options: try // your code except // exception [...]]]></description>
			<content:encoded><![CDATA[<p>Exceptions  are a vital language structure of any modern programming language. This posting shows the usage of Delphi&#8217;s exceptions.<span id="more-135"></span></p>
<p>To raise an exception:</p>
<pre>
<code>
raise Exception.Create('Your exception message');
</code>
</pre>
<p>Excepion is general exception class. Of course you can define your own Exception classes.</p>
<p>To catch exceptions you have several options: </p>
<pre>
<code>
try
  // your code
except
  // exception handling
end;
</code>
</pre>
<pre>
<code>
try
  // your code
except on e:Exception do
  // exception handling, for example :
  showmessage(E.Message);
end;
</code>
</pre>
<p>The combination of except and finally sections looks like this:</p>
<pre>
<code>
try
    try
       // your code
    except on e:exception do begin
       // exception handling
    end;
finally
    // finally section
end;
</code>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://i-gorod.org/itblog/2010/04/25/exception-handling-in-delphi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Problem with Synchronize-calls in DLLs</title>
		<link>http://i-gorod.org/itblog/2010/03/24/problem-with-synchronize-calls-in-dlls/</link>
		<comments>http://i-gorod.org/itblog/2010/03/24/problem-with-synchronize-calls-in-dlls/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 16:03:50 +0000</pubDate>
		<dc:creator>Ilya G.</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[dll]]></category>
		<category><![CDATA[synchronize]]></category>

		<guid isPermaLink="false">http://i-gorod.org/itblog/?p=128</guid>
		<description><![CDATA[If you use Synchronize() method for the synchronization of your thread with GUI, be ready to wonder, if this method does not work in DLLs. It&#8217;s a buggy feature of Delphi 2006. Peter Below offers a fix for this issue. The fix is to be found here. It is just one file that you add [...]]]></description>
			<content:encoded><![CDATA[<p>If you use Synchronize() method for the synchronization of your thread with GUI, be ready to wonder, if this method does not work in DLLs. It&#8217;s a buggy feature of Delphi 2006. Peter Below offers a fix for this issue. The fix is to be found <a href="http://cc.embarcadero.com/Item.aspx?id=21148">here</a>. It is just one file that you add to your DLL. Afterwards Synchronize() works as expected.</p>
]]></content:encoded>
			<wfw:commentRss>http://i-gorod.org/itblog/2010/03/24/problem-with-synchronize-calls-in-dlls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TNotifyEvent. OnClick Example for Delphi.</title>
		<link>http://i-gorod.org/itblog/2010/02/17/tnotifyevent-onclick-example-delphi/</link>
		<comments>http://i-gorod.org/itblog/2010/02/17/tnotifyevent-onclick-example-delphi/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 04:59:29 +0000</pubDate>
		<dc:creator>Ilya G.</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Example]]></category>
		<category><![CDATA[OnClick]]></category>
		<category><![CDATA[TNotifyEvent]]></category>

		<guid isPermaLink="false">http://i-gorod.org/itblog/?p=110</guid>
		<description><![CDATA[Listening to events in Delphi is pretty easy. In following I&#8217;d like to introduce two ways to list to events. Consider following example: type TForm1 = class(TForm) MyButton1: TButton; procedure FormCreate(Sender: TObject); private { Private-Deklarationen } procedure MyBtnClick(Sender: TObject); public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.MyButtonClick(Sender: TObject); begin ShowMessage('Button [...]]]></description>
			<content:encoded><![CDATA[<p>Listening to events in Delphi is pretty easy. In following I&#8217;d like to introduce two ways to list to events. Consider following example:<span id="more-110"></span></p>
<pre>
<code>
type
  TForm1 = class(TForm)
    MyButton1: TButton;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure MyBtnClick(Sender: TObject);
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.MyButtonClick(Sender: TObject);
begin
  ShowMessage('Button is clicked!');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  MyButton1 := TButton.Create(Form1);
  MyButton1.Parent := Form1;
  MyButton1.OnClick := MyButtonClick;
end;
</code>
</pre>
<p>In this simple case MyButtonClick is a class method. The way it&#8217;s used in the example above is quite usual. But what to do if you need to use some method to handle  OnClick event, which is defined outside the class(external function)? In this situation you have to wrap up your method by a record:</p>
<pre>
<code>
type
  TMethodPointer = packed record
    pMethod: Pointer;
    pObject: TObject;
end;
</code>
</pre>
<p>After this you can add your event handler, using casting to <strong>TNotifyEvent</strong> like this:</p>
<pre>
<code>
methodPointer.pMethod := @MyOnClickMethod;
methodPointer.pObject := nil;
MyButton1.OnClick :=  TNotifyEvent(methodPointer);
</code>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://i-gorod.org/itblog/2010/02/17/tnotifyevent-onclick-example-delphi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

