<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7205444</id><updated>2011-12-14T19:03:13.879-08:00</updated><title type='text'>Shenoy At Work</title><subtitle type='html'>A Blog About Delphi, Win32 and .NET Programming. By Deepak Shenoy.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>77</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7205444.post-116374586642385720</id><published>2006-11-16T22:37:00.000-08:00</published><updated>2006-11-17T10:21:44.233-08:00</updated><title type='text'>Setting timeouts in Delphi SOAP</title><content type='html'>If you want to timeout your webservice call - either connecting, sending or receiving, you may be tempted to use the HttpRio.HttpWebNode properties: ConnectTimeout, SendTimeout and ReceiveTimeout. You will then face this error:&lt;br /&gt;&lt;br /&gt;"The data area passed to a system call is too small. - URL:{some url here} - SOAPAction:{some other text here}"&lt;br /&gt;&lt;br /&gt;The problem here is that calls made to &lt;span style="font-weight: bold;"&gt;InternetSetOption&lt;/span&gt; (in &lt;span style="font-weight: bold;"&gt;SOAPHTTPTrans.pas&lt;/span&gt; in the &lt;span style="font-weight: bold;"&gt;THTTPReqResp.Send&lt;/span&gt; procedure) is throwing an error. This is weird because although it returns an error code it does exactly what you want! There are calls to check the return code in the above file, and those checks fail.&lt;br /&gt;&lt;br /&gt;Well, I'm not going to ask you to change the Borland source code this time. There's a way around it.&lt;br /&gt;&lt;br /&gt;The way for you to do this is:&lt;br /&gt;1) Do not set the ReceiveTimeout or the ConnectTimeout or other timeout properties of HTTPRio.HTTPWebNode.&lt;br /&gt;&lt;br /&gt;2) Handle HTTPRio.HttpWebNode.BeforePost event and do this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;procedure TForm2.HTTPRIO1HTTPWebNode1BeforePost(&lt;br /&gt;const HTTPReqResp: THTTPReqResp; Data: Pointer);&lt;br /&gt;var TimeOut : integer;&lt;br /&gt;begin&lt;br /&gt; TimeOut := 2000; // in milleseconds.&lt;br /&gt; InternetSetOption(Data,&lt;br /&gt;      INTERNET_OPTION_RECEIVE_TIMEOUT,&lt;br /&gt;      Pointer(@TimeOut),&lt;br /&gt;      SizeOf(TimeOut));&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(Do not check the return code of InternetSetOption above. It returns an error although everything's fine)&lt;br /&gt;&lt;br /&gt;Note: This only works for INTERNET_OPTION_RECEIVE_TIMEOUT. The connect timeout (INTERNET_OPTION_CONNECT_TIMEOUT) and Send Timeout (INTERNET_OPTION_SEND_TIMEOUT) are broken with WinInet in synchronous mode (as HTTPRio uses) - check this &lt;a href="http://support.microsoft.com/kb/176420/en-us"&gt;Microsoft Support article&lt;/a&gt;. That means if you want to configure Send or Connect timeouts, you must use a different thread or use WinInet asynchronously (which is not at all an easy thing with HttpRio).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-116374586642385720?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/116374586642385720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=116374586642385720' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/116374586642385720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/116374586642385720'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2006/11/setting-timeouts-in-delphi-soap.html' title='Setting timeouts in Delphi SOAP'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-116117980026064657</id><published>2006-10-18T06:37:00.000-07:00</published><updated>2006-10-18T06:57:55.220-07:00</updated><title type='text'>Showing Download Progress with .NET webservice clients</title><content type='html'>Let's say you were interested in displaying a progress bar in your .NET application form while a BIG SOAP message was coming down the line. There's an &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnservice/html/service11052002.asp"&gt;MSDN Article by Matt Powell&lt;/a&gt; explaining how you can do exactly that.&lt;br /&gt;&lt;br /&gt;I managed to finally get it to twist and turn and&lt;br /&gt;actually work with my Delphi (Win32) &lt;a href="http://www.agnisoft.com/white_papers/dlprogress/dlprogress.asp"&gt;"Showing SOAP Download progress" article&lt;/a&gt; code.&lt;br /&gt;&lt;br /&gt;The Microsoft article expects your client application to already know the transfer size, which honestly is not usually available beforehand. You would expect that the size of the content would vary and your progress bar should work for all transfer sizes. &lt;br /&gt;&lt;br /&gt;But then I see why Matt has done that. You don't get any knowledge of the transfer size in your &lt;span style="font-weight:bold;"&gt;SoapExtension&lt;/span&gt; class (which gets you a non-seekable stream meaning you can't get &lt;span style="font-weight:bold;"&gt;Stream.Length&lt;/span&gt; from it)&lt;br /&gt;&lt;br /&gt;So how do you get to the length then? &lt;span style="font-weight:bold;"&gt;Response.ContentLength&lt;/span&gt; is your&lt;br /&gt;answer; since the data you are deserializing is the entire Response stream. But where can you see the &lt;span style="font-weight:bold;"&gt;Response&lt;/span&gt; that is actually received? &lt;br /&gt;&lt;br /&gt;Answer: NOWHERE. &lt;br /&gt;&lt;br /&gt;I had to use &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;Reflector&lt;/a&gt; to back up the call stack a little bit and find a reasonable place, and that's another overridden method in the original article. Heck, let me not bore you with all of this. Here's the entire Extension code in one class:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;namespace DotNetProgress&lt;br /&gt;{&lt;br /&gt;  internal class ProgressClient :&lt;br /&gt;DotNetProgress.localhost.IIDownloaderservice&lt;br /&gt;  {&lt;br /&gt;    public ProgressBar Progress;&lt;br /&gt;    public int TransferSize;&lt;br /&gt;    public Form1.UpdateDelegate ProgressDelegate;&lt;br /&gt;    public WebResponse _Response = null;&lt;br /&gt;&lt;br /&gt;    protected override WebResponse GetWebResponse(WebRequest&lt;br /&gt;      request)&lt;br /&gt;    {&lt;br /&gt;        _Response = base.GetWebResponse(request);&lt;br /&gt;        return _Response;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class ProgressExtension : SoapExtension&lt;br /&gt;{&lt;br /&gt;    // Holds the original stream&lt;br /&gt;    private Stream m_oldStream;&lt;br /&gt;    // The new stream&lt;br /&gt;    private Stream m_newStream;&lt;br /&gt;    // The buffer for reading from the old stream&lt;br /&gt;    // and writing to the new stream&lt;br /&gt;    private byte[] m_bufferIn;&lt;br /&gt;    // The progress bar we will be incrementing&lt;br /&gt;    private ProgressBar m_Progress;&lt;br /&gt;    // The size of each read&lt;br /&gt;    private int m_readSize;&lt;br /&gt;    private int m_totalSize;&lt;br /&gt;    // The delegate we will invoke for updating the&lt;br /&gt;    // progress bar.&lt;br /&gt;    private Form1.UpdateDelegate m_progressDelegate;&lt;br /&gt;    // Used to keep track of which stream we are trying&lt;br /&gt;    // to chain into&lt;br /&gt;    private bool m_isAfterSerialization;&lt;br /&gt;    public override void ProcessMessage(SoapMessage message)&lt;br /&gt;    {&lt;br /&gt;      switch (message.Stage)&lt;br /&gt;      {&lt;br /&gt;        case SoapMessageStage.AfterSerialize:&lt;br /&gt;          // To let us know that the next ChainStream call&lt;br /&gt;          // will let us hook in where we want.&lt;br /&gt;          m_isAfterSerialization = true;&lt;br /&gt;          break;&lt;br /&gt;        case SoapMessageStage.BeforeDeserialize:&lt;br /&gt;          // This is where we stream through the data&lt;br /&gt;          SoapClientMessage clientMessage&lt;br /&gt;              = (SoapClientMessage)message;&lt;br /&gt;          if (clientMessage.Client is ProgressClient)&lt;br /&gt;          {&lt;br /&gt;            ProgressClient proxy&lt;br /&gt;                      = (ProgressClient)clientMessage.Client;&lt;br /&gt;            m_Progress = proxy.Progress;&lt;br /&gt;            // Read 1/100th of the request at a time.&lt;br /&gt;            // This will give the progress bar 100&lt;br /&gt;            // notifications.&lt;br /&gt;            //m_readSize = proxy.TransferSize / 100;&lt;br /&gt;            m_readSize = 8192;&lt;br /&gt;            m_totalSize = ((int)&lt;br /&gt;                proxy._Response.ContentLength) / 100;&lt;br /&gt;            m_progressDelegate = proxy.ProgressDelegate;&lt;br /&gt;          }&lt;br /&gt;          int CurRead = 0;&lt;br /&gt;          while (true)&lt;br /&gt;          {&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;              int bytesRead&lt;br /&gt;                  = m_oldStream.Read(m_bufferIn,&lt;br /&gt;                  0,&lt;br /&gt;                  m_readSize);&lt;br /&gt;              if (bytesRead == 0)&lt;br /&gt;              {&lt;br /&gt;                  // end of message...rewind the&lt;br /&gt;                  // memory stream so it is ready&lt;br /&gt;                  // to be read during deserial.&lt;br /&gt;                  m_newStream.Seek(0,&lt;br /&gt;                      System.IO.SeekOrigin.Begin);&lt;br /&gt;                  return;&lt;br /&gt;              }&lt;br /&gt;&lt;br /&gt;              m_newStream.Write(m_bufferIn,&lt;br /&gt;                  0,&lt;br /&gt;                  bytesRead);&lt;br /&gt;&lt;br /&gt;              // Update the progress bar&lt;br /&gt;              CurRead += bytesRead;&lt;br /&gt;              m_Progress.Invoke(m_progressDelegate, new&lt;br /&gt;                object[] { CurRead, m_totalSize });&lt;br /&gt;            }&lt;br /&gt;            catch&lt;br /&gt;            {&lt;br /&gt;                // rewind the memory stream&lt;br /&gt;                m_newStream.Seek(0,&lt;br /&gt;                    System.IO.SeekOrigin.Begin);&lt;br /&gt;                return;&lt;br /&gt;            }&lt;br /&gt;          }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public override Stream ChainStream(Stream stream)&lt;br /&gt;    {&lt;br /&gt;      if (m_isAfterSerialization)&lt;br /&gt;      {&lt;br /&gt;          m_oldStream = stream;&lt;br /&gt;          m_newStream = new MemoryStream();&lt;br /&gt;          m_bufferIn = new Byte[8192];&lt;br /&gt;          return m_newStream;&lt;br /&gt;      }&lt;br /&gt;      return stream;&lt;br /&gt;    }&lt;br /&gt;    // We don't have an initializer to be shared across streams&lt;br /&gt;    public override object GetInitializer(Type serviceType)&lt;br /&gt;    {&lt;br /&gt;      return null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public override object GetInitializer(&lt;br /&gt;        LogicalMethodInfo methodInfo,&lt;br /&gt;        SoapExtensionAttribute attribute)&lt;br /&gt;    {&lt;br /&gt;      return null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public override void Initialize(object initializer)&lt;br /&gt;    { m_isAfterSerialization = false; }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and in the Main Form, where I have a button and progress bar: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;private void btnDownload_Click(&lt;br /&gt;         object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;  ProgressClient srv = new ProgressClient();&lt;br /&gt;  srv.Progress = this.progressBar1;&lt;br /&gt;  srv.TransferSize = 8192 * 100;&lt;br /&gt;  srv.ProgressDelegate = new&lt;br /&gt;    UpdateDelegate(ProgressBarUpdate);&lt;br /&gt;  srv.DownloadFile(edtFileName.Text);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public delegate void UpdateDelegate(&lt;br /&gt;     int CurRead, int TotalSize);&lt;br /&gt;&lt;br /&gt;private void ProgressBarUpdate(&lt;br /&gt;   int CurRead, int TotalSize)&lt;br /&gt;{&lt;br /&gt;  progressBar1.Value = CurRead / TotalSize;&lt;br /&gt;  Application.DoEvents();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That works for responses of all sizes, and works with the Delphi Win32 server I'd created in the earlier mentioned article.&lt;br /&gt;&lt;br /&gt;Note: If you're using the Delphi server code, you'll have to comment out the Delphi TSoapAttachment based code, because MIME attachments aren't supported by .NET. Commenting it out in the interface should work just fine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-116117980026064657?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/116117980026064657/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=116117980026064657' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/116117980026064657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/116117980026064657'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2006/10/showing-download-progress-with-net.html' title='Showing Download Progress with .NET webservice clients'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-115891941913298054</id><published>2006-09-22T03:01:00.000-07:00</published><updated>2006-09-22T03:05:01.186-07:00</updated><title type='text'>SQL Server: How to get the server's IP Address using T-SQL</title><content type='html'>Someone asked this on a newsgroup, and my answer: If you have admin rights on the server, you can use &lt;span style="font-weight: bold;"&gt;xp_cmdshell&lt;/span&gt; to run a command line application, grab the results and parse them.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;CREATE TABLE #temp1&lt;br /&gt;(t varchar(3000))&lt;br /&gt;&lt;br /&gt;insert into #temp1&lt;br /&gt;exec xp_cmdshell 'ipconfig'&lt;br /&gt;DECLARE @t1 varchar(300)&lt;br /&gt;&lt;br /&gt;-- subject to localisation&lt;br /&gt;SET @t1 = (SELECT top 1 t from #temp1&lt;br /&gt;     where t like '%IP Address%' order by t DESC)&lt;br /&gt;&lt;br /&gt;declare @len int&lt;br /&gt;set @Len = CHARINDEX(':', @t1)&lt;br /&gt;&lt;br /&gt;SELECT TOP 1 LTRIM(RTRIM(SUBSTRING(@t1, @Len+1, LEN(@T1)))) as T&lt;br /&gt;&lt;br /&gt;drop table #temp1&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-115891941913298054?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/115891941913298054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=115891941913298054' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/115891941913298054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/115891941913298054'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2006/09/sql-server-how-to-get-servers-ip.html' title='SQL Server: How to get the server&apos;s IP Address using T-SQL'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-115616621296804458</id><published>2006-08-21T05:29:00.000-07:00</published><updated>2006-08-21T06:16:53.090-07:00</updated><title type='text'>Keep a "Non Modal" window active when a modal window is being shown</title><content type='html'>Recently, I was exploring writing an ADO SQL logging tool (sorta like BDE monitor) - more details on that later - which would show SQL statements on the screen as they ran. All was well until I figured I needed to be able to see my SQL logging form  even when a Modal window was being displayed. TForm.ShowModal() disables all other windows in the current thread, so my SQL logging form is there in the background - but that's not much use because I don't want to close my modal form to get to the SQL log.&lt;br /&gt;&lt;br /&gt;So is there a way to have another active while a Modal form is being displayed?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;The answer is yes.&lt;/span&gt; Going through the Delphi source code in Forms.pas, in TForm.ShowModal() a call to "DisableThreadWindows" is made to ensure that all non modal forms are inactive, and when the modal form is closed "EnableThreadWindows" is called. What these do is simply disable all other windows and then re-enable them.&lt;br /&gt;&lt;br /&gt;What you can do is:&lt;br /&gt;1) Handle the &lt;span style="font-weight: bold;"&gt;WM_ENABLE&lt;/span&gt; message that is sent to your form to set the enabled state.&lt;br /&gt;2) Use "PostMessage" to post a custom message (say WM_REENABLE) back to your form.&lt;br /&gt;3) Handle the WM_REENABLE custom message and in the handler, Enable your window.&lt;br /&gt;&lt;br /&gt;So in your Delphi form create a form like so:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;type&lt;br /&gt; TForm2 = class(TForm)&lt;br /&gt;...&lt;br /&gt;   procedure WMEnable(var Message: TWMEnable); message WM_ENABLE;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;procedure TForm2.WMEnable(var Message: TWMEnable);&lt;br /&gt;begin&lt;br /&gt; if not Message.Enabled then&lt;br /&gt; begin&lt;br /&gt;   PostMessage(Self.Handle, WM_REENABLE, 1, 0);&lt;br /&gt; end;&lt;br /&gt;end;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;where WM_REENABLE is defined earlier as:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;const&lt;br /&gt; WM_REENABLE = WM_USER + $100;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then add a WM_REENABLE handler like this:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;type&lt;br /&gt; TForm2 = class( TForm )&lt;br /&gt;...&lt;br /&gt;   procedure WMReenable(var Message: TMessage); message WM_REENABLE;&lt;br /&gt;...&lt;br /&gt;procedure TForm2.WMReenable(var Message: TMessage);&lt;br /&gt;begin&lt;br /&gt; EnableWindow(Self.Handle, True);&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Now your form will be active even if a modal window is shown.&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;Note: I have tried the following and they do not work:&lt;br /&gt;1) Calling EnableWindow() in the WM_ENABLE handler.&lt;br /&gt;2) Posting a WM_ENABLE message in the WM_ENABLE handler.&lt;br /&gt;3) Trying to change Window styles of my window to Stay on Top.&lt;br /&gt;&lt;br /&gt;Note#2: Do not call "SendMessage" instead of PostMessage, it will not work consistently.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-115616621296804458?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/115616621296804458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=115616621296804458' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/115616621296804458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/115616621296804458'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2006/08/keep-non-modal-window-active-when.html' title='Keep a &quot;Non Modal&quot; window active when a modal window is being shown'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-114949688944568454</id><published>2006-06-05T01:29:00.000-07:00</published><updated>2006-06-05T01:41:31.013-07:00</updated><title type='text'>Converting dd/MM/yyyy strings to Datetimes in .NET</title><content type='html'>It's not easy to find documentation on "How to parse a string into a DateTime variable in .NET?". I had to create an application that parsed a date entered as dd/MM/yyyy, and I had to ensure the code would run on any system, including U.S. based computers which would have the culture info set to MM/dd/yyyy.&lt;br /&gt;&lt;br /&gt;All documentation points to the &lt;span style="font-weight: bold;"&gt;DateTime.Parse()&lt;/span&gt; method. Now this method is of no real use, because it always uses the culture information, which according to me is a no-entry zone because heck, all I want to do is parse a date, not change a whole culture.&lt;br /&gt;&lt;br /&gt;Now there's this other function named &lt;span style="font-weight: bold;"&gt;DateTime.ParseExact( string s, string Format, IFormatProvider provider)&lt;/span&gt;. This is EXACTLY what I needed, except I didn't know what to do with the &lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;provider&lt;/span&gt;&lt;/span&gt; parameter. All the documentation says is "An &lt;a href="T_System_IFormatProvider.htm"&gt;IFormatProvider&lt;/a&gt; that supplies  culture-specific format information about &lt;span class="parameter"&gt;s&lt;/span&gt;."&lt;br /&gt;&lt;br /&gt;Another mention of the dreaded "culture". I tried to understand what this IFormatProvider was, and got to some custom class that converts strings to radixes (whatever they are). I don't know any culture that has radixes but I might have been living in a shell somewhere and all of this just happened.&lt;br /&gt;&lt;br /&gt;Completely flummoxed, I thought, "to heck with this culture and IFormatProvider business" and passed "null" instead, and I got exactly what I wanted.&lt;br /&gt;&lt;br /&gt;All you have to do is call:&lt;br /&gt;&lt;br /&gt;   DateTime d = DateTime.ParseExact( s, "dd/MM/yyyy", null);&lt;br /&gt;&lt;br /&gt;and the string s will get converted to a DateTime, if it's in the dd/MM/yyyy format.&lt;br /&gt;&lt;br /&gt;I wish they'd mentioned "optional" in the documentation for the provider parameter.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-114949688944568454?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/114949688944568454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=114949688944568454' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/114949688944568454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/114949688944568454'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2006/06/converting-ddmmyyyy-strings-to.html' title='Converting dd/MM/yyyy strings to Datetimes in .NET'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-114769701965845514</id><published>2006-05-15T05:35:00.000-07:00</published><updated>2006-05-15T05:43:39.673-07:00</updated><title type='text'>.NET Soap: Capturing Request and Response streams</title><content type='html'>There's just no simple way to capture the Raw Request and Response  inside a SOAP server application in .NET. Of course you do have the &lt;span style="font-weight: bold;"&gt;Context.Request&lt;/span&gt; reference, which I thought was logically where the request would be. Boy, was I wrong.&lt;br /&gt;&lt;br /&gt;It turns out that if you write code to access &lt;span style="font-weight: bold;"&gt;Context.Request.InputStream&lt;/span&gt; or use &lt;span style="font-weight: bold;"&gt;Context.Request.BinaryRead&lt;/span&gt; (which uses InputStream, as I decoded from &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;Reflector&lt;/a&gt;) you will always get nothing. Zilch. Nada.&lt;br /&gt;&lt;br /&gt;All sorts of google searches resulted in dead ends. In the end I found out about &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwebservicesprotocolssoapextensionclasstopic.asp"&gt;Soap Extensions on MSDN&lt;/a&gt;. This article shows you how you can add an attribute called &lt;span style="font-weight: bold;"&gt;TraceAttribute&lt;/span&gt; on your method like so:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt; &lt;code&gt;&lt;br /&gt;[WebMethod]&lt;br /&gt;   [SoapInclude(typeof(ArrayList))]&lt;br /&gt;   [TraceExtension(Filename = @"C:\soaplog.txt")]&lt;br /&gt;   public ArrayList GetMyData()&lt;br /&gt;   ....&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and you will get a log of your request and response in the file mentioned.&lt;br /&gt;&lt;br /&gt;I need to extend this to only log requests or responses, and to use TraceListeners if necessary. Also, this should be available as a stream rather than saving to a file only.&lt;br /&gt;&lt;br /&gt;But I hope this helps people who need to see their request/response in a .NET SOAP WebService.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-114769701965845514?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/114769701965845514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=114769701965845514' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/114769701965845514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/114769701965845514'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2006/05/net-soap-capturing-request-and.html' title='.NET Soap: Capturing Request and Response streams'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-113955840260677061</id><published>2006-02-09T20:51:00.000-08:00</published><updated>2006-02-10T00:00:02.660-08:00</updated><title type='text'>Borland says goodbye to IDEs, and Delphi collects $200</title><content type='html'>Borland is &lt;a href="http://bdn.borland.com/article/0,1410,33439,00.html"&gt;selling off its IDEs&lt;/a&gt;. That means Delphi, C++ Builder, JBuilder and other IDE tools are being sold to another company or investor. (who hasn't yet been identified, so will the real buyer-of-IDE please stand up.)&lt;br /&gt;&lt;br /&gt;There's tons of messages everywhere in the Borland Blogosphere. Marco Cantu has collated a &lt;a href="http://blog.marcocantu.com/blog/borlandsellingmore.html"&gt;list  of Borlander messages&lt;/a&gt;, and Nick Hodges has some &lt;a href="http://www.lemanix.com/nickblog/PermaLink,guid,cf2db958-f6ef-4fe7-ba0e-248eaa09d66b.aspx"&gt;interesting viewpoints&lt;/a&gt; too.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Shenoy Take&lt;br /&gt;&lt;/span&gt;Shenoy is ambivalent. These are exciting times, not because the deal is mindblowingly fantastic. But because the options that are on the table make everything a lot more dynamic. And Shenoy's has a nine year investment in this technology. So is it going down the toilet, or will we see the next developer tool giant?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;[We will now stop referring to ourselves in the third person. Instead we will refer to us in the plural.]&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Start with the facts&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;Let's take some base facts:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Borland is &lt;a href="http://biz.yahoo.com/ap/060208/earns_borland.html?.v=1"&gt;still losing money&lt;/a&gt;. A company that's losing money has to focus on what it needs to do to earn money. Borland has thus decided it's the ALM route to take, not the IDE route.&lt;/li&gt;&lt;li&gt;Borland has done a lousy job for marketing IDEs. &lt;a href="http://www.lemanix.com/nickblog/PermaLink,guid,c0ee055c-5c2e-44b4-ba7f-116f40d9d13b.aspx"&gt;Nick has argued&lt;/a&gt;, and in quite a convincing manner, that the Borland Sales Force tends to focus on Enterprise sales rather than channel sales (where Delphi comes in). Plus they don't advertise much, and their channel doesn't either.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The IDE tools haven't really gotten investment. I'm not talking about building new versions, which Borland has done, but about a larger strategy in the developer world. Giving more power and resources to Evangelism. Buying or fostering third party add ons. Venturing into tech areas that have long term potential.&lt;/li&gt;&lt;/ul&gt;So what are the &lt;span style="font-weight: bold;"&gt;Good Things &lt;/span&gt;about the deal?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Good Thing #1: IDE Marketing improvement&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The IDE tools are out of Borland's vice-like grip. Borland has been tying their hands behind their back all this time, and now the IDE tools will be able to strategize better. They can, for instance:&lt;br /&gt;- Build &lt;span style="font-weight: bold;"&gt;SKUs at lower prices&lt;/span&gt; to address competition&lt;br /&gt;- Advertise, Advertise, &lt;span style="font-weight: bold;"&gt;Advertise&lt;/span&gt;.&lt;br /&gt;- Build BDN content into much much more, including online marketplaces for third party products, eBay links for Product sales, Blog aggregators, etc.&lt;br /&gt;- Increase channel sales.&lt;br /&gt;- Partner with web hosting companies to include Borland DLLs in their shared hosting packages.&lt;br /&gt;- &lt;span style="font-weight: bold;"&gt;Training: &lt;/span&gt;Get more training companies affiliated, and build more certification levels.&lt;br /&gt;- Revive the &lt;span style="font-weight: bold;"&gt;"Publishing" &lt;/span&gt;unit and promote authors for books/technology, even build online PDF sales of book content, chapter by chapter! Sell CDs of "Best of BDN" etc. or  bundle it with  IDE products. Stupid, you think? It was, earlier. Now is the time to start it again.&lt;br /&gt;- Additional focus on the neglected &lt;span style="font-weight: bold;"&gt;Asian/European market&lt;/span&gt;, where a lot of development seems to be happening with Borland products.&lt;br /&gt;- Put more money into &lt;span style="font-weight: bold;"&gt;Evangelism&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;These are all possible only with an IDE spin off. Borland will just not allow them to do any of this without showing a multi million revenue potential in immediate quarters.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Good Thing #2: The Poor Man's ALM&lt;/span&gt;&lt;br /&gt;Borland gets to focus on ALM: Application Lifecycle management. And tie in with Microsoft and other offerings, rather than be stuck with its own toolkit. So they become an integrator, with products like Caliber for Requirements Management, StarTeam for Configuration Management, Segue for Quality, Legadero for Project Managment/Time Tracking/Bug Tracking etc.&lt;br /&gt;&lt;br /&gt;Each of the above "ALM" tools cost a LOT of money. I would guess that a 10 to 20 person company will have to invest more than $10,000 for &lt;span style="font-weight: bold;"&gt;each&lt;/span&gt; of these tools, and in addition to buying these tools, a company has to buy Professional Services from Borland which I'm guess is going to be a significant expense.&lt;br /&gt;&lt;br /&gt;Note also that they don't mention cost of any of these products, or sell them online.That's because it's expensive. That's because they're difficult to sell off the shelf, because using them needs training, consulting and deployment and that can only be sold face to face.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;So what I'm suggesting is the New Company ("NewCo") can build or buy such tools for a lot lesser cost. I mean:&lt;br /&gt;- &lt;span style="font-weight: bold;"&gt;Lower cost bug tracking &lt;/span&gt;tools. You get 'em for $100 a piece.&lt;br /&gt;&lt;br /&gt;- Simpler &lt;span style="font-weight: bold;"&gt;web based project management&lt;/span&gt; tools, integrating with the IDE.&lt;br /&gt;&lt;br /&gt;- Version control: link with &lt;span style="font-weight: bold;"&gt;Subversion or CVS&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;- Add: &lt;span style="font-weight: bold;"&gt;build and deployment tools &lt;/span&gt;like BuildStudio or FinalBuilder&lt;br /&gt;&lt;br /&gt;- Add: Sell the IDE as a &lt;span style="font-weight: bold;"&gt;prototyping tool&lt;/span&gt; as well (or build a CUT down designer version to prototype)&lt;br /&gt;&lt;br /&gt;- Add: Use of &lt;span style="font-weight: bold; font-style: italic;"&gt;"agile" programming techniques &lt;/span&gt;in the IDE. For instance, &lt;span style="font-weight: bold;"&gt;Pair programming using VNC technology&lt;/span&gt; to "repeat" actions in multiple computers.  This also helps in team code reviews over an intranet (or even, over the internet!)&lt;br /&gt;&lt;br /&gt;- Add: &lt;span style="font-weight: bold;"&gt;Chat, Voice and Video Integration&lt;/span&gt; WITHIN the IDE. Why? Today development can be done on the same project by people in multiple locations. Building IDE level interaction will make many things possible over long distances, such as code discussions, refactoring. etc. And perhaps as importantly, this is a &lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;great training tool.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Technology wise, all the above are simple to integrate for a company like Borland. With its presence it can easily partner with such vendors of such tools, or integrate open source tools like VNC and Subversion. The business benefit is only visible in the long term: if Borland pulls this off, they will be the most flexible IDE in the market for small to mid size companies: a market Visual Studio is slowly moving away from.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Good Thing #3&lt;/span&gt;: &lt;span style="font-weight: bold;"&gt;Team Retention&lt;/span&gt;&lt;br /&gt;It's scary for us when people at Borland leave.&lt;br /&gt;&lt;br /&gt;Why? Because we fear their going means loss of an irreplacable resource at Borland. That these people have been been masters of their domain and the knowledge is not spread across many others, because hiring has been low.&lt;br /&gt;&lt;br /&gt;Why has Hiring been low? Because Borland's strategy was to focus on buying ALM companies, not augmenting current team strengths. Because they wanted to keep head counts low for idiotic-stock-market-appeasing purposes. Because they wouldn't release budgets for building bigger high quality development teams.&lt;br /&gt;&lt;br /&gt;The deal may change all that. With an increased focus on IDE products, the best way ahead is to&lt;br /&gt;- innovate in the products, meaning a bigger better team&lt;br /&gt;- increase evangelism resources meaning more people on DevRel&lt;br /&gt;&lt;br /&gt;A bigger team means less fear of people leaving, and of course lesser fear that one person leaving will trigger other exits as well.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What about Bad Things?&lt;br /&gt;&lt;/span&gt;Of course there are bad things. Every deal has nightmare speculators jumping in, and I'll put a few important (to me) Bad Things.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Bad Thing #1: The IDEs will Die.&lt;br /&gt;&lt;/span&gt;You might think a Microsoft or Oracle will gobble up this company and kill the IDE products. Small change for some of these companies, actually.&lt;br /&gt;&lt;br /&gt;You might think the buyer won't put in additional funding for a real strategy. That is no different from Borland, and will kill the IDE company.&lt;br /&gt;&lt;br /&gt;Both could be true, but Borlanders don't seem to think so, with David I, John Kaster and Anders Ohlsson repeatedly saying in the newsgroups that the "NewCo" will have a strategic investor who will take the business forward.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Bad Thing #2: They will open source Delphi&lt;/span&gt;.&lt;br /&gt;I don't think this is a good idea. I, for one, hate it, but there is a a feeling that if they don't get a buyer they will try something like open sourcing Delphi.&lt;br /&gt;&lt;br /&gt;I like open source, but frankly, open sourcing Delphi gives no revenue for Borland, and very little promotional possibility for the IDE ecosystem. So I'm saying this will be a bad thing.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Bad Thing #3: The loss of the Borland Name&lt;/span&gt;&lt;br /&gt;This is a definite bad thing, in the sense that the Borland name will no longer be available to market. Like in the IBM Thinkpad/Lenovo scene, I believe the brand name has a lot to say in a sale.&lt;br /&gt;&lt;br /&gt;But having said that, I believe the product names - Delphi, Interbase etc. - have a good brand standing on their own. So this may not hit NewCo too much, unless we're talking "Enterprise" sales, which obviously will go to the Borland stable, not to NewCo.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;This is the longest post I've ever made on this blog. I have to add a conclusion so that you know I'll finally shut up sometime.&lt;br /&gt;&lt;br /&gt;This is a great step for Delphi (and other IDE products). The team seems extremely excited in a happy sort of way, and seems to be waiting to throw away the shackles that hold them back. The message is universal, and clear: The IDE people at Borland want this, and want this now. It's time for us, the community, to watch them weave their magic.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Who does Shenoy Think it is?&lt;/span&gt;&lt;br /&gt;Shenoy thinks it's the big search engine giant. Shenoy may be an idiot. A fool. Shenoy's head may be full of little wooden pieces that he doesn't remember the technical name for, because his brain is full of little wooden pieces. You just can't say, though.&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-113955840260677061?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/113955840260677061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=113955840260677061' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/113955840260677061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/113955840260677061'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2006/02/borland-says-goodbye-to-ides-and.html' title='Borland says goodbye to IDEs, and Delphi collects $200'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-113907996896441473</id><published>2006-02-04T11:00:00.000-08:00</published><updated>2006-02-04T11:06:08.980-08:00</updated><title type='text'>Soap Download Progress</title><content type='html'>I had written an article about how to provide feedback during a SOAP call using a progress bar in Delphi. That article seems to be offline, temporarily. You can now also access this article at:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.teamb.com/deepakshenoy/articles/SoapDownloadProgress.aspx"&gt;http://blogs.teamb.com/deepakshenoy/articles/SoapDownloadProgress.aspx&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-113907996896441473?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/113907996896441473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=113907996896441473' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/113907996896441473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/113907996896441473'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2006/02/soap-download-progress.html' title='Soap Download Progress'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-113846464953026019</id><published>2006-01-28T05:02:00.000-08:00</published><updated>2006-01-28T08:45:23.263-08:00</updated><title type='text'>The PInvoke Live Template</title><content type='html'>Live Templates in Delphi 2006 are a pretty cool feature. The idea is that you can extend the Code Template mechanism (Ctrl+J since, well, a long time) - by including your snippets of code, and even add functionality to the IDE beyond simple code replacements. For instance, typing in "if" and hitting the space bar immediately brings up a series of things in the IDE that look like this:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/7240/160/1600/livetemplates.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer;" src="http://photos1.blogger.com/blogger/7240/160/320/livetemplates.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;You can type in a condition and hit [tab] : the cursor will move to the next line for you to continue. Awesome stuff, and more importantly, it's all extensible! Check out the set of files in your &lt;span style="font-weight: bold;"&gt;ObjRepos &lt;/span&gt;directory, by default at &lt;span style="font-family:courier new;"&gt;C:\Program Files\Borland\BDS\4.0\Objrepos\code_templates\delphi&lt;/span&gt;.&lt;br /&gt;&lt;tab&gt;&lt;br /&gt;The XML files are a little complicated, but you will find Deborah Pate's &lt;a href="http://blogs.teamb.com/deborahpate/articles/22331.aspx"&gt;detailed explanation&lt;/a&gt; of these files very helpful to start. Also you can refer to the &lt;a href="http://delphi.wikicities.com/wiki/Live_Templates_Technical_Info"&gt;Wiki for Live Templates&lt;/a&gt;, containing more helpful information.&lt;br /&gt;&lt;br /&gt;From the XML file, you can call "script" functions that will make Delphi automatically declare a variable, or Invoke Code Completion or call some other functions. But, and this is very interesting, you can &lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;extend this script. &lt;/span&gt;&lt;/span&gt;What this means is, a live template can call YOUR custom function when a user invokes it. For instance, a template could brings up a message saying "How disgusting." when a user types "GOTO", and then proceed to erase the GOTO.&lt;br /&gt;&lt;br /&gt;Sparky's blog post tells you &lt;a href="http://blogs.borland.com/adammarkowitz/archive/2006/01/20/22839.aspx"&gt;how to extend this script schema&lt;/a&gt;. The extension involves writing a package with a new "script engine" and then calling that script engine from the live template XML file. The post contains a very good example of how to paste clipboard text wrapped around a try/finally block, by just typing &lt;span style="font-weight: bold; font-style: italic;"&gt;clippy&lt;/span&gt; in the code and hitting TAB.&lt;br /&gt;&lt;br /&gt;This got me thinking. Can we call &lt;span style="font-style: italic;"&gt;external&lt;/span&gt; applications using live templates? "Of course you can.", is the right answer. And I'm not the first one to get there or blog about it - Daniel Wischnewski has written an &lt;a href="http://delphi-notes.blogspot.com/2005/12/creating-script-template-engine-for.html"&gt;article about a web search live template script&lt;/a&gt; that invokes your browser from the IDE.&lt;br /&gt;&lt;br /&gt;I wrote something too. It's called a "PInvoke extension" for Delphi and C#. You need to do the following:&lt;br /&gt;&lt;br /&gt;1) Download the source code from &lt;a href="http://cc.borland.com/item.aspx?id=23915"&gt;http://cc.borland.com/item.aspx?id=23915&lt;/a&gt;.&lt;br /&gt;2) compile/install the package in the IDE.&lt;br /&gt;3) Copy the .xml files over to your ObjRepos folder (appropriate sub folder) or to the User Folder (by default: &lt;span style="font-family:courier new;"&gt;c:\Documents and Settings\[USERNAME]\Local Settings\Application Data\Borland\BDS\4.0\code_templates&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;Then in a new &lt;span style="font-weight: bold;"&gt;Delphi &lt;/span&gt;unit type: &lt;span style="font-weight: bold;"&gt;pinvd&lt;/span&gt; and you'll see this:&lt;br /&gt;&lt;/tab&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/7240/160/1600/pinvd1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/7240/160/320/pinvd1.png" alt="" border="0" /&gt;&lt;/a&gt;I typed in &lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;PeekMessage&lt;/span&gt;&lt;/span&gt; and I got:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/7240/160/1600/pinvd2.0.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/7240/160/320/pinvd2.0.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;(Click to enlarge)&lt;br /&gt;&lt;br /&gt;You can use  &lt;span style="font-weight: bold;"&gt;pinvc&lt;/span&gt; in a C# file as well, and the result is the C# code for the Win32 call. I've used both Adam Nathan's &lt;a href="http://www.pinvoke.net"&gt;pinvoke.net site&lt;/a&gt; and &lt;a href="http://dotnet.borland.com/babelcode/"&gt;John Kaster's BabelCode C# to Delphi for .NET converter&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;(&lt;span style="font-style: italic;"&gt;The pinvoke.net site only gave me C# definitions. I used that and sent it over to BabelCode for the Delphi translation of the same C# code.)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What? No Stock Quotes?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;And in the spirit of a true web service programmer, you will also need to get Stock Quotes when you are in the IDE. Which means you can type &lt;span style="font-weight: bold;"&gt;squote&lt;/span&gt; and hit TAB, and you'll get:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/7240/160/1600/squote1.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: none; cursor: pointer;" src="http://photos1.blogger.com/blogger/7240/160/320/squote1.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;and if you type BORL and [enter] you get:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/7240/160/1600/squote2.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: none; cursor: pointer;" src="http://photos1.blogger.com/blogger/7240/160/320/squote2.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Can't live without it.&lt;br /&gt;&lt;br /&gt;Anyhow, all source is available, so feel free to dig in, and tell me what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-113846464953026019?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/113846464953026019/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=113846464953026019' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/113846464953026019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/113846464953026019'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2006/01/pinvoke-live-template.html' title='The PInvoke Live Template'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-113220216442288433</id><published>2005-11-16T20:18:00.000-08:00</published><updated>2005-11-16T20:36:04.456-08:00</updated><title type='text'>Stress testing Web Services</title><content type='html'>If you need to test your Web Service for performance, you can use the&lt;a href="http://www.microsoft.com/technet/archive/itsolutions/intranet/downloads/webstres.mspx"&gt; Web Application Stress Test&lt;/a&gt; (WAST) tool. It's a microsoft tool, free of cost.&lt;br /&gt;&lt;br /&gt;You can learn more about how to use it in my paper on &lt;a href="http://www.agnisoft.com/white_papers/optimizingwebapps/default.asp"&gt;optimizing web applications&lt;/a&gt;. But that paper only talks about using WAST for web apps, i.e. browser based applications. What about web services?&lt;br /&gt;&lt;br /&gt;Let's see how WAST works. When you hit "record", WAST opens a new browser window, where you must access your web page, click links, enter data etc. When you're done, you close the browser, and WAST will then allow you to simulate the same steps with lots more users, bandwidth etc. and gets the results to see how your web app responds to stress.&lt;br /&gt;&lt;br /&gt;What WAST does is it acts like a proxy server, and records your requests. It will then "play back" the requests through multiple threads to simulate multiple users. &lt;br /&gt;&lt;br /&gt;Web services can be stress tested the same way. &lt;br /&gt;&lt;br /&gt;First, ensure you're using WinInet in &lt;br /&gt;your Delphi SOAP and not Indy (WinInet is the default so if you don't know what this is, don't bother) This step is not necessary for .NET based web services of course.&lt;br /&gt;&lt;br /&gt;Run WAST, and hit "Record". A browser window will come up. Ignore it, but do NOT close it.&lt;br /&gt;&lt;br /&gt;Run your Web Service Client (something that accesses all functions of your web service) in the same machine as your server. &lt;br /&gt;&lt;br /&gt;Go through a simulated use case on the client - eg. logon, get something, save something etc.&lt;br /&gt;&lt;br /&gt;Close that (ignored) browser window when done.&lt;br /&gt;&lt;br /&gt;You'll notice that WAST has done all the recording of XML sent etc. This can then be simulated for lots more users.&lt;br /&gt;&lt;br /&gt;Note that WAST will only report on bad web results (Server errors returned as HTTP result codes etc.) You might need a different approach if you need to figure out SOAP Faults as well (maybe a temporary try/catch handler in the server that returns a different HTTP code if there's an exception)&lt;br /&gt;&lt;br /&gt;Also if you want to see web requests in general, check out &lt;a href="http://www.fiddlertool.com"&gt;Fiddler&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-113220216442288433?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/113220216442288433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=113220216442288433' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/113220216442288433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/113220216442288433'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/11/stress-testing-web-services.html' title='Stress testing Web Services'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-112788616895759624</id><published>2005-09-27T22:42:00.000-07:00</published><updated>2005-09-27T22:49:12.920-07:00</updated><title type='text'>Yes, a Delphi Roadmap.</title><content type='html'>It's here, finally. From &lt;a href="http://blogs.borland.com/dcc/archive/2005/09/27/21361.aspx" target="_blank"&gt;Danny's post on Borland's Delphi Roadmap&lt;/a&gt;, the whole "strategy" thing is a lot clearer. So we have a future, for both the Win32 and .NET side of things.&lt;br /&gt;&lt;br /&gt;What we have is:&lt;br /&gt;&lt;b&gt;Dexter in 2005&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Language improvents: &lt;i&gt;(e.g. operator overloading)&lt;/i&gt; &lt;/li&gt;&lt;li&gt;Speed: IDE Startup and runtime speed improvements (with stuff from &lt;a href="http://www.fastcode.dk/fastcodeproject/index.htm" target="_blank"&gt;the Fastcode Project&lt;/a&gt;) &lt;/li&gt;&lt;li&gt;C++ support (Win32) including support for the VCL &lt;li&gt;Command line CF compiler &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;b&gt;Highlander in 2006&lt;/b&gt; &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Another dumb project name ("Highlander"???) &lt;li&gt;.NET 2.0 support (if .NET 2.0 is actually out by then) &lt;li&gt;We're talking generics, partial classes, and nullable types. &lt;li&gt;The CF "IDE" with VCL.NET support&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Overall this shows that Borland has a vision for a product that's always been good, but has lost a lot of its former shine. Now, what we need is for Borland Management to not backtrack. Let there be more &lt;a href="http://blogs.borland.com/abauer/archive/2005/09/14/21158.aspx" target="_blank"&gt;such informal fixes&lt;/a&gt; and more informal previews of upcoming products.&lt;br /&gt;&lt;br /&gt;Oh yes, there's even talk of a &lt;a href="http://delphi-notes.blogspot.com/2005/09/jason-vokes-does-his-product.html" target="_blank"&gt;Delphi Win64 compiler in 2007&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-112788616895759624?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/112788616895759624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=112788616895759624' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112788616895759624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112788616895759624'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/09/yes-delphi-roadmap.html' title='Yes, a Delphi Roadmap.'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-112672817498007943</id><published>2005-09-14T13:02:00.000-07:00</published><updated>2005-09-14T21:25:35.590-07:00</updated><title type='text'>"Beginning to Offshore"?????</title><content type='html'>Why do people write like &lt;a href="http://www.a1technology.com/blog/2005/09/beginning-to-offshore-clichs-outlook.htm" target="_blank"&gt;this&lt;/a&gt;? Choice phrases:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;"clichés, outlook and a realistic suggestions"&lt;/i&gt; &lt;li&gt;&lt;i&gt;But, flourishing outsourced development engages more than defining a product spec.&lt;/i&gt; &lt;li&gt;&lt;i&gt;"remember: the more an outsourcer comprehends the milieu, the better prepared it will be..."&lt;/i&gt; &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;Overall the entire article is as clear as mud. But there's more! It's a ripoff from &lt;a href="http://www.dmreview.com/editorial/newsletter_article.cfm?nl=dmdirect&amp;articleId=1004186&amp;amp;issue=20027%20%20" target="_blank"&gt;Bharat Khatau's original article&lt;/a&gt;, which is a magnitude better in content and grammar. The rip off is terrible - it's just run through a thesaurus, methinks. Every single sentence has been rephrased...no, has been gramatically assaulted - to produce something that might pass a copyright test, but fails on the ground that it's utter nonsense.&lt;br /&gt;&lt;br /&gt;The original article has this for instance:&lt;br /&gt;&lt;b&gt;&lt;i&gt;"Success requires careful definition of how your company and the outsourcer will interact - and the right spirit governing those interactions."&lt;/i&gt;&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;The rip-off says :&lt;br /&gt;&lt;b&gt;&lt;i&gt;"Success necessitates fastidious description of the way your company and the outsourcer will interrelate"&lt;/i&gt;&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Also, &lt;b&gt;&lt;i&gt;Good projects for successful pilots involve minimal risks to the business strategy or core product&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;becomes &lt;b&gt;&lt;i&gt;&lt;b&gt;First-rate projects for triumphant pilots rivet least risks to the business strategy or core product.&lt;/b&gt;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;("rivet least risks"???? What are they smoking?)&lt;br /&gt;&lt;br /&gt;The rip-off has, very helpfully, placed a link to the original article. Which kinda sums it up, I think: it's not a malicious act, they're just stupid.&lt;br /&gt;&lt;br /&gt;Let me not take away from the entertainment value, of course. You need such articles so you can tell people - "I may be bad at documentation, but I ain't *this* bad".&lt;br /&gt;&lt;br /&gt;(If you like using one-and-a-half-foot words, you'll love &lt;a href="http://mead.cc/pedantry.html" target="_blank"&gt;sesqupedal pedantry&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-112672817498007943?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/112672817498007943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=112672817498007943' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112672817498007943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112672817498007943'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/09/beginning-to-offshore.html' title='&quot;Beginning to Offshore&quot;?????'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-112564650095368018</id><published>2005-09-02T00:35:00.000-07:00</published><updated>2005-09-02T00:35:01.006-07:00</updated><title type='text'>A TeamB'er wrote Dr. Watson!</title><content type='html'>Just went through &lt;a href="http://blogs.msdn.com/matt_pietrek/archive/2005/08/10/450005.aspx" target="_blank"&gt;a Matt Pietrek post&lt;/a&gt; about &lt;b&gt;Dr. Watson&lt;/b&gt;.The original author, Don Corbitt, was a member of &lt;a href="http://www.teamb.com" target="_blank"&gt;TeamB&lt;/a&gt; before he joined Microsoft! (Very sadly, Don died in a private plane crash) &lt;br /&gt;&lt;br /&gt;Also Matt was a Borlander, and he wrote a "Dr. Frank" to overcome the limitations - named after, I guess, &lt;a href="http://bdn.borland.com/article/0,1410,20283,00.html" target="_blank"&gt;Frank Borland&lt;/a&gt;. Speaking of debugging tools, I just found some free hex editors and disassemblers &lt;a href="http://www.thefreecountry.com/programming/disassemblers.shtml" target="_blank"&gt;here&lt;/a&gt;. Amazing how much stuff is available out there, for free. &lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-112564650095368018?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/112564650095368018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=112564650095368018' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112564650095368018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112564650095368018'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/09/teamber-wrote-dr-watson.html' title='A TeamB&apos;er wrote Dr. Watson!'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-112557270116117255</id><published>2005-09-01T04:05:00.000-07:00</published><updated>2005-09-01T04:06:48.933-07:00</updated><title type='text'>Microsoft Research</title><content type='html'>I just visited &lt;a href="http://distribucon.com/blog/" target="_blank"&gt;Dan Miser's Blog&lt;/a&gt; and found a link to &lt;a href="http://research.microsoft.com/research/downloads/" target="_blank"&gt;Microsoft Research Downloads&lt;/a&gt;. I knew they did some research out there, but this stuff is just awesome! They have &lt;a href="http://research.microsoft.com/research/allegiance" target="_blank"&gt;Allegiance&lt;/a&gt;-  a multiplayer space-combat game, source code to attach to &lt;a href="http://research.microsoft.com/netres/" target="_blank"&gt;WiFi Networks using a single WiFi card&lt;/a&gt;, and even a &lt;a href="http://research.microsoft.com/vault/" target="_blank"&gt;safe versoin of C&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I haven't yet experiemented with &lt;a href="http://www.learningwebservices.com/community/default.aspx" target="_blank"&gt;ConferenceXP&lt;/a&gt; - another one of the research projects. Essentially it's software that allows video conferences to be "multi-cast" across a network - currently it needs a good/fast link, multi cast support and a really high end dedicated server for such stuff, but I think in the near future that will not be a big issue. This is a killer app, especially for multi location offices like ours. What I like about this is the ability to "archive" sessions - so that people who couldn't attend a session can view it at a later date. I've always wanted such things for conference calls - i.e. record a call to mp3 and then run it back for a transcript. (If anyone knows such a tool...)&lt;br /&gt;&lt;br /&gt;Also, we've started to use &lt;a href="http://www.skype.com" target="_blank"&gt;Skype&lt;/a&gt; for office communication. It's amazing in terms of quality and also has an &lt;a href="http://www.freewebs.com/skypeansweringmachine/index.htm" target="_blank"&gt;answering machine&lt;/a&gt;. Not that I hate regular phones - but I think they're too darn expensive when you're calling between India and the UK. &lt;br /&gt;&lt;br /&gt;Yeah, no code in this post either. I have not compiled anything for weeks now...but I have found time to play squash. Maybe  they're mutually exclusive.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-112557270116117255?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/112557270116117255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=112557270116117255' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112557270116117255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112557270116117255'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/09/microsoft-research.html' title='Microsoft Research'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-112075499046994791</id><published>2005-07-07T09:27:00.000-07:00</published><updated>2005-07-07T09:55:15.150-07:00</updated><title type='text'>New Job!</title><content type='html'>It's time for a new job! I'm now at &lt;a href="http://www.flovate.com" target="_blank"&gt;Flovate Technologies&lt;/a&gt;, as Chief Executive Officer, India. That's a fancy title all right. But wait till you hear about my computer! (This is geeky)&lt;br /&gt;&lt;br /&gt;I get a Dual Xeon 3 Ghz monster, with a 22" main and a 15" secondary monitor. There's 1 GB ram and SCSI RAID disks totalling 140 Gigs of Bytes. And a 128 MB ATI Card, and three mice running around in wheels. Awesome stuff. I just get lost in the incredible real estate on the screen. My 15.4" Dell latitude is like a crowded alley in comparison.&lt;br /&gt;&lt;br /&gt;I get to manage the team in India and co-ordinate with the folks in the UK, where I must say there are some incredibly talented developers! I just went through a couple of frameworks and man, this stuff is really impressive. I can't reveal the juicy details, but let me just say that if there's a Workflow map in the future, we're going to be on it.&lt;br /&gt;&lt;br /&gt;Non geeky stuff: I'm learning the ropes on a different kind of management. It's so tempting to get into code, but it's simply better not to touch it until you really understand the situation. I used to think the code was king, that you could figure out anything just looking at the source code : Yes, at this point I can probably identify a ton of patterns by looking deep enough. But does that really matter? What you really need to understand, right off the top, is what the product or project is about. What kind of users use it, what the business proposition is. Imagine you're the customer, and ask stupid questions (the former sometimes implies the latter). Only then get into the code!&lt;br /&gt;&lt;br /&gt;I also need to understand that every developer will take short cuts, even the best of 'em. To refactor is one thing. To identify and create an environment that will support and encourage refactoring is quite another. And then there's the whole scheduling, project management etc. issue - I think I'm going to become a PHB. &lt;br /&gt;&lt;br /&gt;Anyhow, what's important is this: I can have THREE rows of icons on the status bar and still have enough on the screen to eat dinner out of. Ha! &lt;br /&gt;&lt;br /&gt;No seriously, this is going to be one helluva challenge. I'm quite looking forward to it! My next few posts might involve lesser technology. Or more. I don't know. Interesting times, indeed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-112075499046994791?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/112075499046994791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=112075499046994791' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112075499046994791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112075499046994791'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/07/new-job.html' title='New Job!'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-112021699742044143</id><published>2005-07-01T04:23:00.000-07:00</published><updated>2005-07-01T04:25:46.290-07:00</updated><title type='text'>Delphi problem with uploading compressed streams</title><content type='html'>In my &lt;a href="http://www.agnisoft.com/white_papers/advancedws/default.asp" target="_blank"&gt;Advanced Web Services article&lt;/a&gt;, I had demonstrated how you could do &lt;b&gt;Datapacket compression&lt;/b&gt; by compressing the ENTIRE packet before it was sent from the server, and decompressing it at the client end. (Applies to encryption also)&lt;br /&gt;&lt;br /&gt;Now I'd said you could do this the other way around too : compressing packets before sending on the client end, and expanding them at the server, using the &lt;b&gt;BeforeRequest&lt;/b&gt; event of THTTPRio. This doesn't work: Firstly there is a bug in D7 SOAP, that ignores the var parameter in the &lt;b&gt;BeforeRequest&lt;/b&gt; handler. &lt;a href="http://groups.google.co.in/group/borland.public.delphi.webservices.soap/browse_thread/thread/876db802f78970b5/7f994153c194dca2?q=deepak+shenoy+tstringstream+req&amp;rnum=1&amp;hl=en#7f994153c194dca2" target="_blank"&gt;Look here for a fix I've mentioned.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A bigger problem is this: The &lt;b&gt;BeforeExecute&lt;/b&gt; event is declared like this:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  TBeforeExecuteEvent = &lt;br /&gt;           procedure( const MethodName: string; &lt;br /&gt;                           var SOAPRequest: InvString) of object;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now if you do some kind of compression or encryption, you might not like to deal with the &lt;i&gt;WideString&lt;/i&gt; parameter. The process might introduce some NULL (0) characters in the character array, which will then be truncated by Delphi (which assumes a string ends on a NULL character). &lt;br /&gt;&lt;br /&gt;Fortunately, the source is king. Here's a few steps:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt; Write a descendant component from THttpRio (call it THTTPRioEnh)&lt;br /&gt;&lt;br /&gt;&lt;li&gt; Declare a type like so:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;TBeforeExecuteStreamEvent = &lt;br /&gt;     procedure(const MethodName: string; &lt;br /&gt;                       Request: TStream) of object;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt; In the THTTPRioEnh class, declare a published variable of type:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;property OnBeforeExecuteStream: TBeforeExecuteStreamEvent &lt;br /&gt;       read FOnBeforeExecuteStream &lt;br /&gt;       write FOnBeforeExecuteStream;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Hit Ctrl+Shift+C. The private variable should get declared&lt;br /&gt;automatically.&lt;br /&gt;&lt;br /&gt;&lt;li&gt; override the DoBeforeExecute procedure and in it put:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;procedure DoBeforeExecute(const MethodName: string; &lt;br /&gt;              Request: TStream); &lt;br /&gt;begin&lt;br /&gt;  inherited DoBeforeExecute(MethodName, Request); &lt;br /&gt;&lt;br /&gt;  if Assigned( FOnBeforeExecuteStream ) then&lt;br /&gt;    FOnBeforeExecuteStream( MethodName, Request );&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Then register the component using a &lt;b&gt;Register&lt;/b&gt; procedure, put it in a package, compile and install.&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;You can then drop a &lt;b&gt;THTTPRioEnh&lt;/b&gt; component on your form, and assign a handler to &lt;b&gt;OnBeforeExecuteStream&lt;/b&gt; of this component.&lt;br /&gt;&lt;br /&gt;I am lazy, so I did all this in Rio.Pas and instead of creating a handler in the IDE I set this up in code instead, something like:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;HTTPRio1.OnBeforeExecuteStream := BeforeExecuteStream;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Where I do the modifications to the request stream.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-112021699742044143?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/112021699742044143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=112021699742044143' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112021699742044143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112021699742044143'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/07/delphi-problem-with-uploading.html' title='Delphi problem with uploading compressed streams'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-112014234752052920</id><published>2005-06-30T07:39:00.000-07:00</published><updated>2005-06-30T07:39:07.526-07:00</updated><title type='text'>Last Day at Agni</title><content type='html'>It's my last day at &lt;a href="http://www.agnisoft.com" target="_blank"&gt;Agni Software&lt;/a&gt;. It's been a remarkable 7 years here, and I've had a lot of fun and learning at Agni. I was a tinhorn when I started, and I'm a little less of one now - I don't file notches on my guns, but I haven't learnt to shoot any better. (They keep moving the targets!)&lt;br /&gt;&lt;br /&gt;Arun and Chirag, my co-founders, will continue to grow Agni, and I wish them and everyone at Agni the very best for the brightest possible future. We're all very good friends, and I'm sure there's going to be a lot of getting together for coffee.  (they're teetotallers, so beer is out) (No, that's not why I'm leaving! :) )&lt;br /&gt;&lt;br /&gt;I'll be around on the blog scene, and I'll tell you all about my new job. Tomorrow.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-112014234752052920?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/112014234752052920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=112014234752052920' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112014234752052920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112014234752052920'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/06/last-day-at-agni.html' title='Last Day at Agni'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-112014185353912876</id><published>2005-06-30T07:30:00.000-07:00</published><updated>2005-06-30T07:30:53.600-07:00</updated><title type='text'>Skype - and how to use it in Delphi</title><content type='html'>&lt;a href="http://www.skype.com" target="_blank"&gt;Skype&lt;/a&gt; has a public API, and it's almost impossible to find. Actually there's no specific file for the API - Skype itself responds to calls using WM_COPYDATA. It'll also send you notifications - stuff that you must handle in your form's Message Handler.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Ok, this isn't that simple to explain. Check out a sample Skype Tracer that I've developed, and it's available at:&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a href="http://www.agnisoft.com/downloads/SkypeTracerDelphi.zip" target="_blank"&gt;http://www.agnisoft.com/downloads/SkypeTracerDelphi.zip&lt;/a&gt;. Let me know what you think...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-112014185353912876?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/112014185353912876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=112014185353912876' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112014185353912876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/112014185353912876'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/06/skype-and-how-to-use-it-in-delphi.html' title='Skype - and how to use it in Delphi'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-111977610486481966</id><published>2005-06-26T01:55:00.000-07:00</published><updated>2005-06-27T00:51:58.493-07:00</updated><title type='text'>.Text Comment Spam</title><content type='html'>I got hit recently with a lot of Comment Spam on &lt;a href="http://blogs.teamb.com/deepakshenoy"&gt;my TeamB blog&lt;/a&gt;. It was incredibly boring to sit and delete all of the spam comments - which, because of what I would only call laziness, had grown to around 500 in number - since .Text only allows you to delete one comment at a time! And each time it would bring up a confirmation web page from the server, and then, when you select "Yes, I know what I'm doing, just delete the darn message"  it throws up &lt;b&gt;another&lt;/b&gt; page with "Message Deleted" or something like that. You have to then click once more to get back to the message list. Note: I don't have access to the database.&lt;br /&gt;&lt;br /&gt;Obviously this could be rectified by changing some code. The .Text source is available - so maybe it could be modified.&lt;br /&gt;&lt;br /&gt;I &lt;a href="http://www.gotdotnet.com/workspaces/releases/viewuploads.aspx?id=e99fccb3-1a8c-42b5-90ee-348f6b77c407"&gt;downloaded the .Text source&lt;/a&gt; and then managed to actually get it compiled and running on my laptop. What I started to do was to check how the code worked - and it turns out there's a way to enter "comments" by creating a "trackback" to your page. I'm not going to reveal how - but the source code of the page reveals all.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Solution:&lt;/b&gt; Simply remove trackbacks from your page. Let people actually enter the trackback in, as a comment. And introduce a CAPTCHA in the comment entry page. &lt;br /&gt;&lt;br /&gt;The CAPTCHA solution is fairly well documented. You can download&lt;a href="http://blogs.clearscreen.com/migs/archive/2005/04/05/1270.aspx" target="_blank"&gt;The Clearscreen CAPTCHA control for .Text by Miguel Jiminez&lt;/a&gt; and install/run it. &lt;br /&gt;&lt;br /&gt;For removing trackbacks: Go to your web.config on your .Text site and remove the lines starting with &lt;b&gt;&amp;lt;HttpHandler&lt;/b&gt; and that contain the text &lt;b&gt;pingback&lt;/b&gt; or &lt;b&gt;trackback&lt;/b&gt;. Or set &lt;b&gt;enableTrackBacks="false" and enablePingBacks="false"&lt;/b&gt; in the &lt;b&gt;&amp;lt;Tracking  &lt;/b&gt; element.&lt;br /&gt;&lt;br /&gt;No trackbacks then? Maybe the comment api can be modified to allow it as a different field - I don't think I'll have time to do this, but if anyone has, please let me know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-111977610486481966?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/111977610486481966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=111977610486481966' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111977610486481966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111977610486481966'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/06/text-comment-spam.html' title='.Text Comment Spam'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-111899766832399534</id><published>2005-06-17T01:41:00.000-07:00</published><updated>2005-06-20T02:01:40.553-07:00</updated><title type='text'>Setting Focus with MessageDlg</title><content type='html'>One of the things I've had to do manually many times is to have dialog boxes pop up, but logically "OK" should not be the focussed button. (Like "Do you want to format this disk?")&lt;br /&gt;&lt;p&gt;&lt;br /&gt;In Delphi, you'd usually call &lt;b&gt;MessageDlg&lt;/b&gt; for a dialog that had a Yes/No/Cancel or an Ok/Cancel input only - but that doesn't give you a way to change the focus or default button. So here's how you would do it - call &lt;b&gt;MessageDlgFocus&lt;/b&gt; instead:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;var&lt;br /&gt;  ButtonNames: array[TMsgDlgBtn] of string = (&lt;br /&gt;    'Yes', 'No', 'OK', 'Cancel', 'Abort', 'Retry', 'Ignore', &lt;br /&gt;   'All', 'NoToAll', 'YesToAll', 'Help');&lt;br /&gt;&lt;br /&gt;function MessageDlgWithFocus(const Msg: string; &lt;br /&gt;  DlgType: TMsgDlgType;&lt;br /&gt;  Buttons: TMsgDlgButtons; &lt;br /&gt;  FocusBtn: TMsgDlgBtn; &lt;br /&gt;  HelpCtx: Longint): Integer;&lt;br /&gt;var Btn: TComponent;&lt;br /&gt;begin&lt;br /&gt;  with CreateMessageDialog(Msg, DlgType, Buttons) do&lt;br /&gt;    try&lt;br /&gt;      HelpContext := HelpCtx;&lt;br /&gt;      Position := poScreenCenter;&lt;br /&gt;&lt;br /&gt;      Btn := FindComponent( ButtonNames[FocusBtn] );&lt;br /&gt;      if (Btn &lt;&gt; nil) and (Btn is TWinControl) then&lt;br /&gt;	      ActiveControl := Btn as TWinControl;&lt;br /&gt;&lt;br /&gt;      Result := ShowModal;&lt;br /&gt;    finally&lt;br /&gt;      Free;&lt;br /&gt;    end;&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Call it with:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt; MessageDlgWithFocus('test', mtCOnfirmation, &lt;br /&gt;                           [mbOk, mbCancel], mbCancel, 0);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This code will bring up a dialog with &lt;i&gt;OK&lt;/i&gt; and &lt;i&gt;Cancel&lt;/i&gt; buttons, and the &lt;i&gt;&lt;b&gt;Cancel&lt;/b&gt;&lt;/i&gt; button is focussed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-111899766832399534?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/111899766832399534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=111899766832399534' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111899766832399534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111899766832399534'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/06/setting-focus-with-messagedlg.html' title='Setting Focus with MessageDlg'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-111469612748290062</id><published>2005-04-28T06:48:00.000-07:00</published><updated>2005-04-28T06:48:47.483-07:00</updated><title type='text'>Really stupid web site tricks?</title><content type='html'>What I refer to, is &lt;a href="http://www.boyet.com/Articles/StupidWebSiteTricks.html" target="_blank"&gt;Julian Bucknall's post&lt;/a&gt; on Stupid Web Site Tricks - about how nutty it is when good links are usually orphaned during a site re-org. &lt;br /&gt;&lt;br /&gt;Turns out Microsoft is one of 'em. I had, in my &lt;a href="http://www.agnisoft.com/white_papers/optimizingwebapps/default.asp" target="_blank"&gt;Optimizing Web Applications&lt;/a&gt; article, linked to the Microsoft Web Application Stress Tool which has been moved from &lt;a href="http://www.microsoft.com/technet/itsolutions/intranet/downloads/webstres.asp" target="_blank"&gt;here&lt;/a&gt; to &lt;a href="http://www.microsoft.com/technet/archive/itsolutions/intranet/downloads/webstres.mspx" target="_blank"&gt;here&lt;/a&gt;. Grrr. &lt;br /&gt;&lt;br /&gt;Maybe they don't want us to find it, and buy some of their non free tools instead. Well, they should hide it where no one can find it, instead of playing hide-and-seek with the links.&lt;br /&gt;&lt;br /&gt;Btw, I've reorg-ed my site a few times, and I'm guilty of not really maintaining any links either - but all of MY past has some &lt;a href="http://www.randomexcuse.com/" target="_blank"&gt;excuse&lt;/a&gt; for it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-111469612748290062?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/111469612748290062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=111469612748290062' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111469612748290062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111469612748290062'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/04/really-stupid-web-site-tricks.html' title='Really stupid web site tricks?'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-111467980268243770</id><published>2005-04-28T02:16:00.000-07:00</published><updated>2005-04-28T02:16:42.683-07:00</updated><title type='text'>Optimizing web applications - white paper</title><content type='html'>After reading &lt;a href="http://distribucon.com/blog/archive/2005/04/22/531.aspx#Feedback" target="_blank"&gt;Dan Miser's post&lt;/a&gt; about the ISAPIThreadPool unit, I dug up an article I'd written long back...and managed to reformat it so I could make it public. Well, here it is at &lt;a href="http://www.agnisoft.com/white_papers/optimizingwebapps/default.asp" target="_blank"&gt;http://www.agnisoft.com/white_papers/optimizingwebapps/&lt;/a&gt;. Cheers, have fun, and let me know what you think!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-111467980268243770?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/111467980268243770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=111467980268243770' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111467980268243770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111467980268243770'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/04/optimizing-web-applications-white.html' title='Optimizing web applications - white paper'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-111451415752753030</id><published>2005-04-26T04:15:00.000-07:00</published><updated>2005-04-26T04:15:57.526-07:00</updated><title type='text'>Multiple windows in Delphi</title><content type='html'>From a &lt;a href="http://groups.google.co.in/groups?hl=en&amp;lr=&amp;threadm=426dcb9f%40newsgroups.borland.com&amp;rnum=1&amp;prev=/groups%3Fq%3Ddeepak%2Bshenoy%2Bgroup:borland.public.delphi.nativeapi.*%26hl%3Den%26lr%3D%26scoring%3Dd%26selm%3D426dcb9f%2540newsgroups.borland.com%26rnum%3" target="_blank"&gt;recent thread&lt;/a&gt; in borland.public.delphi.nativeapi.win32: &lt;br /&gt;&lt;br /&gt;There's a problem in the way Delphi handles multiple open forms. Delphi applications can have multiple forms, and you will notice that each form does not appear on the task bar. Delphi forms do not have the WS_EX_APPWINDOW style set - this style is required if a window needs to appear in the task bar. But there is one icon, isn't there? That's the icon of the Delphi "Application" - and clicking on it in the task bar simply focusses the main window (or any other modal window above it)&lt;br /&gt;&lt;br /&gt;If you need your "other" windows to appear in the task bar, then you can do this: Override the CreateParams procedure in your other forms, and write this code in there:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;procedure CreateParams(var Params: TCreateParams); override;&lt;br /&gt;...&lt;br /&gt;procedure TForm1.CreateParams(var Params: TCreateParams);&lt;br /&gt;begin&lt;br /&gt;  inherited;&lt;br /&gt;  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;&lt;br /&gt;  Params.WndParent := GetDesktopWindow;&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, if you're doing this, you probably are writing applications where ndividual windows behave independently of the "main" form. You might notice that suddenly, the main form comes up in FRONT of the other top level form, like when showing hints or displaying dialog boxes from them. Reason: Delphi's Application variable is the culprit - it handles a lot of things including hint display, Dialog box messages etc. When it gets these messages, the main form gets activated, for some reason.&lt;br /&gt;&lt;br /&gt;Fix: Don't just make your "other" forms with WS_EX_APPWINDOW. Make ALL your top level forms have that style, including your main form. (Use the same logic for the main form). Then, REMOVE the WS_EX_APPWINDOW style from the "Application" - using this code:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  SetWindowLong(Application.Handle, GWL_EXSTYLE,&lt;br /&gt;    GetWindowLong(Application.Handle,GWL_EXSTYLE) &lt;br /&gt;        and not WS_EX_APPWINDOW&lt;br /&gt;        or WS_EX_TOOLWINDOW);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You'll have a lot less trouble then.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-111451415752753030?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/111451415752753030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=111451415752753030' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111451415752753030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111451415752753030'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/04/multiple-windows-in-delphi.html' title='Multiple windows in Delphi'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-111416222550196253</id><published>2005-04-22T02:30:00.000-07:00</published><updated>2005-04-22T02:30:25.500-07:00</updated><title type='text'>Jedi again - JvDesktopAlert</title><content type='html'>Yet another lesser known &lt;a href="http://jvcl.sourceforge.net" target="_blank"&gt;JVCL component&lt;/a&gt; - &lt;b&gt;TJvDesktopAlert&lt;/b&gt;. You know those little popups that Outlook 2003 brings up from the System Tray? Well, here's how you can do it too. Just drop the TJvDesktopAlter component on your form and you're done. Here's the demo app:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.agnisoft.com/deepak/blog/DesktopAlertForm.gif"&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;br /&gt;And here's how it looks:&lt;br /&gt;&lt;img src="http://www.agnisoft.com/deepak/blog/DesktopAlert.jpg"&gt;&lt;br /&gt;&lt;br /&gt;Pretty nifty, I thought. Another one of them hidden gems....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-111416222550196253?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/111416222550196253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=111416222550196253' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111416222550196253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111416222550196253'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/04/jedi-again-jvdesktopalert.html' title='Jedi again - JvDesktopAlert'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-111408853807776063</id><published>2005-04-21T06:02:00.000-07:00</published><updated>2005-04-21T06:30:11.473-07:00</updated><title type='text'>Object Picker dialog in Delphi</title><content type='html'>I was going through &lt;a href="http://www.thecodeproject.com" target="_blank"&gt;thecodeproject.com&lt;/a&gt;, and came across an article: &lt;a href="http://www.thecodeproject.com/w2k/BfObjectSelection2.asp" target="_blank"&gt;Using the Windows 2000/XP Object Selection Dialog&lt;/a&gt;. Basically, this is the dialog in Windows XP/2000 that allows you to choose users,groups and/or computers to grant (or deny) access to resources, such as files, folders, etc. &lt;br /&gt;&lt;br /&gt;If you want to show this in your application, you can, using the &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ad/ad/idsobjectpicker_invokedialog.asp" target="_blank"&gt;IDsObjetPicker.InvokeDialog&lt;/a&gt;. If this looks like greek to you, simply &lt;a href="http://jvcl.sourceforge.net" target="_blank"&gt;download the JVCL&lt;/a&gt; and use the TJvObjectPickerDialog.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://homepages.borland.com/jedi/jedihelp/item.php?Id=61012" target="_blank"&gt;JEDI online help&lt;/a&gt; for this function is sketchy. Actually it's near non-existant, but the CodeProject and MSDN references give you enough to work with. &lt;br /&gt;&lt;br /&gt;But if you just want to see it in action, here are the steps:&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Drop a TJvObjectPickerDialog instance on your form.&lt;br /&gt;&lt;li&gt;Double click the &lt;b&gt;Scopes&lt;/b&gt; property and add a Scope. &lt;br /&gt;&lt;li&gt;For this scope, set &lt;b&gt;ScopeTypes.stTargetComputer&lt;/b&gt; to &lt;b&gt;True&lt;/b&gt;, and &lt;b&gt;DownLevelFiler.dlUsers&lt;/b&gt; to &lt;b&gt;True&lt;/b&gt;.&lt;br /&gt;&lt;li&gt;Right click on the &lt;b&gt;TJvObjectPickerDialog&lt;/b&gt; and click &lt;b&gt;Preview&lt;/b&gt;.&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.agnisoft.com/deepak/blog/selectuser.jpg"&gt;&lt;br /&gt;&lt;br /&gt;That should do it. JVCL is just AWESOME - there's so much in there that you can use but it's a little difficult to find. In my next few blog posts I hope to demonstrate the use of some of these components.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-111408853807776063?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/111408853807776063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=111408853807776063' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111408853807776063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111408853807776063'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/04/object-picker-dialog-in-delphi.html' title='Object Picker dialog in Delphi'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-111340206194339890</id><published>2005-04-13T07:21:00.000-07:00</published><updated>2005-04-13T07:21:39.746-07:00</updated><title type='text'>Search agnisoft.com!</title><content type='html'>I finally got down to doing this. &lt;br /&gt;&lt;br /&gt;You can now &lt;a href="http://www.agnisoft.com/search" target="_blank"&gt;Search agnisoft.com&lt;/a&gt;. Whoopee!&lt;br /&gt;&lt;br /&gt;(Applause)&lt;br /&gt;&lt;br /&gt;(Bow)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-111340206194339890?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/111340206194339890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=111340206194339890' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111340206194339890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111340206194339890'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/04/search-agnisoftcom.html' title='Search agnisoft.com!'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-111339692546204937</id><published>2005-04-13T05:55:00.000-07:00</published><updated>2005-04-13T05:55:25.463-07:00</updated><title type='text'>Google avatars and their platforms</title><content type='html'>Did you know you could actually go to &lt;a href="http://www.google.com/microsoft" target="_blank"&gt;http://www.google.com/microsoft&lt;/a&gt; and &lt;a href="http://www.google.com/linux" target="_blank"&gt;http://www.google.com/linux&lt;/a&gt;? What this does is searches for whatever keyword you type in, plus "microsoft" or "linux". Not that earth-shattering, but when I first saw it, what came my mind was a google search dedicated to....&lt;br /&gt;&lt;br /&gt;Anyhow, I figured it out today after I found my &lt;a href="http://www.agnisoft.com" target="_blank"&gt;company web page&lt;/a&gt; had been visited from the microsoft link. Right now, I'm researching  &lt;a href="http://code.google.com/" target="_blank"&gt;google code&lt;/a&gt;, which looks interesting. Stay tuned....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-111339692546204937?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/111339692546204937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=111339692546204937' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111339692546204937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111339692546204937'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/04/google-avatars-and-their-platforms.html' title='Google avatars and their platforms'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-111330608086468834</id><published>2005-04-12T04:41:00.000-07:00</published><updated>2005-04-12T04:41:20.863-07:00</updated><title type='text'>An Online Share Trading Game?</title><content type='html'>ICICI Direct has an &lt;a href="http://equitiesi.rediff.com/html/idirect/game.htm"&gt;Online Share Trading Game&lt;/a&gt; which, in my humble opinion, sucks. That's not a share trading game, that's a bloody advertisement! I guess we're in the age of NOT providing value, and this is just part of the ball game. Jeez. &lt;br /&gt;&lt;br /&gt;I have a friend who had created a web site that was entirely focussed on the blogging for the Indian cellphone user - and there are a few million of such users now. The idea wasn't all that unique - a "moblog" so to speak. But one of the biggest Indian Cellphone companies backed off the sponsorship because they wanted the site to be restricted to only their users - i.e. you couldn't post your "moblog" if you weren't their subscriber. And this, apart from the fact that they would get ad space everywhere for their money, and would be featured on the whole offline launch. What they wanted it to be was a massive ad-campaign for them. &lt;br /&gt;&lt;br /&gt;I think that's a little short sighted, but when have big companies known to be visionaries in their field?&lt;br /&gt;&lt;br /&gt;When they were small, that's when. Maybe becoming big gives you cataract. Or blurred vision, at least.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-111330608086468834?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/111330608086468834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=111330608086468834' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111330608086468834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111330608086468834'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/04/online-share-trading-game.html' title='An Online Share Trading Game?'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-111104381303733807</id><published>2005-03-16T23:16:00.000-08:00</published><updated>2005-03-16T23:16:53.036-08:00</updated><title type='text'>SOAP bug fix: changes to request don't get recorded.</title><content type='html'>Delphi 7 and 2005 have an issue in the SOAP client area - if you change the XML in the OnBeforeExecute Event of THTTPRio, the change doesn't get recorded (i.e. the original XML gets sent no matter what you do) That's not intended, since the event gives you a "var" parameter. &lt;br /&gt;&lt;br /&gt;A fix for this is to add this in RIO.Pas,  in the DoBeforeExecute procedure, AFTER the following line: &lt;br /&gt; &lt;br /&gt;{ NOTE: We ignore the var WideString passed in... ???? } &lt;br /&gt; &lt;br /&gt;add: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt; &lt;br /&gt; // DEEPAK &lt;br /&gt; Req := ReqW; &lt;br /&gt;&lt;br /&gt; StrStrm := TStringStream.Create(Req); &lt;br /&gt; try &lt;br /&gt;    StrStrm.Position := 0; &lt;br /&gt;    Request.CopyFrom( StrStrm, 0 ); &lt;br /&gt; finally &lt;br /&gt;    StrStrm.Free; &lt;br /&gt; end; &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;{note: Declare Req:string and StrStrm: TStringStream; as local &lt;br /&gt;variables} &lt;br /&gt;&lt;br /&gt;Ah, yes, and I'm a married man now. Sunila and I tied the knot a couple weeks back, and I'll post a link to the photos soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-111104381303733807?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/111104381303733807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=111104381303733807' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111104381303733807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/111104381303733807'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/03/soap-bug-fix-changes-to-request-dont.html' title='SOAP bug fix: changes to request don&apos;t get recorded.'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110907731657388180</id><published>2005-02-22T05:01:00.000-08:00</published><updated>2005-02-22T05:04:33.396-08:00</updated><title type='text'>IThumbnailCapture and Delphi</title><content type='html'>From a request in borland.public.delphi.nativeapi.win32 , I found that the IThumbnailCapture interface wasn't very well documented - or rather, what wasn't was how to create an instance that supported such an interface. So I spent some time making a demo, modifying the &lt;b&gt;CoolStuf&lt;/b&gt; demo that comes with Delphi. (In the Demos\CoolStuf folder).&lt;br /&gt;&lt;br /&gt;The actual translation of the interface is :&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;const&lt;br /&gt;  IID_IThumbnailCapture : TGUID = (&lt;br /&gt;    D1:$4ea39266; D2:$7211; D3:$409f; &lt;br /&gt;    D4:($b6,$22,$f6,$3d,$bd,$16,$c5,$33));&lt;br /&gt;type&lt;br /&gt;  SIZE = record&lt;br /&gt;    cx, cy : LongInt;&lt;br /&gt;  end;&lt;br /&gt;  PSIZE = ^SIZE;&lt;br /&gt;&lt;br /&gt;  IThumbnailCapture = interface( IUnknown )&lt;br /&gt;  ['{4ea39266-7211-409f-b622-f63dbd16c533}']    &lt;br /&gt;    // *** IThumbnailCapture methods ***&lt;br /&gt;    function CaptureThumbnail( pMaxSize : PSIZE;&lt;br /&gt;          pHTMLDoc2 : IUnknown;&lt;br /&gt;          var phbmThumbnail : HBiTMAP ) : HResult; &lt;br /&gt;                      stdcall;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and the way to create an instance is:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  CoCreateInstance(ClassID, nil, &lt;br /&gt;       CLSCTX_INPROC_SERVER or &lt;br /&gt;       CLSCTX_LOCAL_SERVER,&lt;br /&gt;       IThumbnailCapture, Capture);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Hope this helps. &lt;a href="http://www.agnisoft.com/downloads/thumbnaildemo.zip"&gt;Download the code&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110907731657388180?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110907731657388180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110907731657388180' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110907731657388180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110907731657388180'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/02/ithumbnailcapture-and-delphi.html' title='IThumbnailCapture and Delphi'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110811475935608733</id><published>2005-02-11T01:39:00.001-08:00</published><updated>2006-08-31T01:53:05.730-07:00</updated><title type='text'>Getting WSDL using basic authentication</title><content type='html'>Well, this one's tricky. The concept of getting a WSDL that needs authentication to get to - there's one simple way of course, do it yourself, read the WSDL using an Indy component and write it to a local file, and use the local file in Delphi SOAP.&lt;br /&gt;&lt;br /&gt;But a far more complicated method is described in &lt;a href="http://tinyurl.com/4ge83"&gt;my post to the Delphi SOAP newsgroup&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;1) Set up an event called &lt;span style="font-weight: bold;"&gt;OnBeforeGet&lt;/span&gt; in THTTPReqResp (the same way&lt;br /&gt;TOnBeforePost is set up)&lt;br /&gt;a) add a private declaration:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;   // Deepak 11 Feb 2005&lt;br /&gt;   FOnBeforeGet: TBeforePostEvent;&lt;br /&gt;   // End Deepak 11 Feb 2005&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;b) in the public part:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;// Deepak 11 Feb 2005&lt;br /&gt;   { Events }&lt;br /&gt;   property  OnBeforeGet: TBeforePostEvent read FOnBeforeGet write FOnBeforeGet;&lt;br /&gt;// End Deepak 11 Feb 2005&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;2) In the SendGet method of THTTPReqResp, add this line after&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  Check(not Assigned(Request), False);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Add:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;   // Deepak 11 Feb 2005&lt;br /&gt;   if Assigned(FOnBeforeGet) then&lt;br /&gt;     FOnBeforeGet(Self, Request);&lt;br /&gt;   // End Deepak 11 Feb 2005&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Thats part 1. Now, part 2 is quite complicated, because, as it turns&lt;br /&gt;out, the way the WSDL is fetched is totally inaccessible to us. what&lt;br /&gt;you need to do is:&lt;br /&gt;&lt;br /&gt;1) Set up a new event in THTTPRIO - call it TOnGetWSDLItems;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt; // Deepak 11 Feb 2005&lt;br /&gt; TOnGetWSDLItems = Function( Sender : TObject ) : TWSDLItems of object;&lt;br /&gt; // End Deepak 11 Feb 2005&lt;br /&gt;... (setup an event called OnGetWSDLItems)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;2) in the CheckWSDLView procedure, after:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;procedure THTTPRIO.CheckWSDLView;&lt;br /&gt;begin&lt;br /&gt; if not Assigned(FWSDLItems) then&lt;br /&gt; begin&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;add: &lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;   If Assigned( FOnGetWSDLItems) then&lt;br /&gt;     FWSDLItems := FOnGetWSDLItems( Self );&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;3) in your main form you'll have to go to HTTPUtil.pas, copy the entire&lt;br /&gt;definition of TStreamLoader over to your main form.&lt;br /&gt;&lt;br /&gt;4) Now in the main form, add a funciton like this:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;var StreamLoader : TStreamLoader;&lt;br /&gt;begin&lt;br /&gt; StreamLoader := TStreamLoader.Create;&lt;br /&gt; StreamLoader.FUserName := HTTPRIO1.HTTPWebNode.UserName;&lt;br /&gt; StreamLoader.FPassword := HTTPRIO1.HTTPWebNode.Password;&lt;br /&gt; StreamLoader.FHTTPReqResp.GetHTTPReqResp.OnBeforeGet :=&lt;br /&gt;      Self.HTTPRIO1HTTPWebNode1BeforePost;&lt;br /&gt; result := TWSDLItems.Create(nil, StreamLoader);&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;5) Before you do anything, set up your HTTPRIO1 like so:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;HTTPRio1.OnGetWSDLItems := OnGetWsdlItems;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Okay, if you're still here, and you've managed to successfully do this,&lt;br /&gt;let me know. I can't post all the code, because it's mostly Borland&lt;br /&gt;code, but it does work. Let me know here if you need it and i'll send&lt;br /&gt;it to you by email.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110811475935608733?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110811475935608733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110811475935608733' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110811475935608733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110811475935608733'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/02/getting-wsdl-using-basic.html' title='Getting WSDL using basic authentication'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110811474480276659</id><published>2005-02-11T01:39:00.000-08:00</published><updated>2005-02-11T01:39:04.803-08:00</updated><title type='text'>Google, mapped.</title><content type='html'>Yep, everyone's talking about &lt;a href="maps.google.com"&gt;maps.google.com&lt;/a&gt;. Note: this is of absolutely no use to me right now, because they don't map India (yet). Heck, there's a business idea...no, wait. anyhow, that's a LONG story, which I'll leave for another day. Suffice it to say that I'm not going to be looking for chinese restaurants in Mumbai using maps.google.com.&lt;br /&gt;&lt;br /&gt;Anyhow, what I wanted to tell you was that you can now see &lt;a href="http://jgwebber.blogspot.com/2005/02/mapping-google.html"&gt;how it's done&lt;/a&gt;. Google is just awesome.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110811474480276659?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110811474480276659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110811474480276659' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110811474480276659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110811474480276659'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/02/google-mapped.html' title='Google, mapped.'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110793549109238838</id><published>2005-02-08T23:51:00.000-08:00</published><updated>2005-02-08T23:51:31.093-08:00</updated><title type='text'>Soap paper updated</title><content type='html'>It's time I'd done this. My paper on &lt;a href="http://www.agnisoft.com/white_papers/soap1.asp"&gt;Using ADO.NET datasets in Delphi&lt;/a&gt; has been updated. Check it out, let me know what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110793549109238838?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110793549109238838/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110793549109238838' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110793549109238838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110793549109238838'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/02/soap-paper-updated.html' title='Soap paper updated'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110688807843019258</id><published>2005-01-27T20:54:00.000-08:00</published><updated>2005-01-27T20:54:38.430-08:00</updated><title type='text'>Google ads</title><content type='html'>Folks, I've added Google ads to this page. (Not to the TeamB page, however) I'd only read about ad-click revenues till now, and I've never been able to get any real figures on the ad-click business - all I've ever heard about is:&lt;br /&gt;a) How they are so ineffective in today's ad infested world.&lt;br /&gt;b) Why you can't build a business model on ad-based-revenues. &lt;br /&gt;&lt;br /&gt;I think Google's model is good. It's fairly inobtrusive, you can turn off images and Flash, and most importantly, it's got a fairly clean brand image. But, that means nothing if it doesn't translate to money. From my point of view, this is a test - it means that if I make money from "clicks" on the google ads, it'll also make sense for us to buy ad space from Google. Ok, that's far fetched, but I don't really know a better way.&lt;br /&gt;&lt;br /&gt;Oh yes, and if you don't like the ads, let me know. And if you can't see them, let me know too. The ads are in the side bar, waaay below. Maybe I should put them higher up, if it won't tick visitors off.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110688807843019258?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110688807843019258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110688807843019258' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110688807843019258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110688807843019258'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/01/google-ads.html' title='Google ads'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110665405191487348</id><published>2005-01-25T03:54:00.000-08:00</published><updated>2005-01-25T03:54:11.913-08:00</updated><title type='text'>TDBImage and JPEG files</title><content type='html'>It's been a while. Well, I've no time to explain, so here's a tip. If you were looking to support JPEGs in TDBImage, you're out of luck, because it only supports BMPs (or so I think). I found out that TJvDBImage from &lt;a href="http://jvcl.sourceforge.net"&gt;jvcl.sourceforge.net&lt;/a&gt; supports JPEG images...but there's a catch. There are two kinds of JPEG images, JFIF and Exif. (Exifs are usually output by digital cameras)&lt;br /&gt;&lt;br /&gt;Now if you want Exif support, the standard TJpegImage supports it - but TJvDBImage does not. To fix, add the following line in the &lt;b&gt;GraphicSignaturesNeeded&lt;/b&gt; procedure:&lt;br /&gt;&lt;br /&gt;RegisterGraphicSignature('Exif', 6  , TJPEGImage);&lt;br /&gt;&lt;br /&gt;That's about all you need.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110665405191487348?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110665405191487348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110665405191487348' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110665405191487348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110665405191487348'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2005/01/tdbimage-and-jpeg-files.html' title='TDBImage and JPEG files'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110329142784272752</id><published>2004-12-17T05:50:00.000-08:00</published><updated>2004-12-17T05:50:34.316-08:00</updated><title type='text'>F12 brings up CPU debugger window?</title><content type='html'>In Delphi, if you're debugging an app which has F12 as a shortcut key for some command, then you're most likely going to get very ticked off by having Delphi "break" when you hit F12. This is because F12 is the "UserDebuggerKey" on Windows 2000 and above, by default. What this means is that if a program is being debugged, hitting the UserDebuggerKey will break into the debugger - and Delphi shows you a nice little CPU window.&lt;br /&gt;&lt;br /&gt;To get rid of this problem, you can reassign the UserDebuggerKey by changing the registry. There's a &lt;a href="http://www.microsoft.com/resources/documentation/Windows/2000/server/reskit/en-us/Default.asp?url=/resources/documentation/Windows/2000/server/reskit/en-us/regentry/11501.asp"&gt;Microsoft support page&lt;/a&gt; that details the key (HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug) and what values you can use.&lt;br /&gt;&lt;br /&gt;I would think "Pause" would be a better key to use - makes more sense to me, since the only time I've used it ever has been in the boot process and when getting to the System Properties screen (WinKey + Pause). Both of which I'm unlikely to be desperate for when debugging.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110329142784272752?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110329142784272752/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110329142784272752' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110329142784272752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110329142784272752'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/12/f12-brings-up-cpu-debugger-window.html' title='F12 brings up CPU debugger window?'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110303329269747180</id><published>2004-12-14T06:08:00.000-08:00</published><updated>2004-12-14T21:37:21.280-08:00</updated><title type='text'>Firefox beats IE?</title><content type='html'>Seems like &lt;a href="http://www.mozilla.org/products/firefox/"&gt;FireFox&lt;/a&gt; has made some serious headway in the world of "people who read my blog". According to the latest stats, 47.4% of the hits on my site are through FireFox and only 42.1% on IE. Last time I checked was a VERY long time back - it was more like 92% IE then. &lt;br /&gt;&lt;br /&gt;Not that my site is any indicator or trendsetter, of course. But...wow.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110303329269747180?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110303329269747180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110303329269747180' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110303329269747180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110303329269747180'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/12/firefox-beats-ie.html' title='Firefox beats IE?'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110293289966708702</id><published>2004-12-13T02:14:00.000-08:00</published><updated>2004-12-13T02:14:59.666-08:00</updated><title type='text'>Excel users...</title><content type='html'>If you use Excel quite a bit, check out &lt;a href="http://www.exceluser.com/"&gt;http://www.exceluser.com/&lt;/a&gt;. This is an awesome site, with sample dashboards, formula explanations (what's MIRR? I never thought I'd need to know) and  some more. Good stuff.&lt;br /&gt;&lt;br /&gt;Why do I need Excel? Running a small company too requires that we track trends, competition, tasks and so on. Plus the whole financial jungle that comes with being a Director. &lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110293289966708702?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110293289966708702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110293289966708702' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110293289966708702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110293289966708702'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/12/excel-users.html' title='Excel users...'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110277806238140365</id><published>2004-12-11T07:14:00.000-08:00</published><updated>2004-12-11T07:14:22.380-08:00</updated><title type='text'>Suggestions on a web page?</title><content type='html'>Autocomplete's next avatar? Check out &lt;a href="http://www.google.com/webhp?complete=1&amp;hl=en"&gt;Google Suggest&lt;/a&gt;. Amazing concept this - supposedly uses &lt;a href="http://www.sitepoint.com/blog-post-view.php?id=216588"&gt;XmlHttpRequest&lt;/a&gt; and tons of &lt;a href="http://www.google.com/ac.js"&gt;obfuscated Javascript&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;From the &lt;a href="http://slashdot.org/comments.pl?sid=132312&amp;cid=11053245"&gt;slashdot comments&lt;/a&gt;, I've got the link that actually gets you the details: &lt;br /&gt;&lt;a href="http://www.google.com/complete/search?hl=en&amp;js=true&amp;qu=chicken"&gt;http://www.google.com/complete/search?hl=en&amp;js=true&amp;qu=chicken&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Gets one thinking, doesn't it?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110277806238140365?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110277806238140365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110277806238140365' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110277806238140365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110277806238140365'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/12/suggestions-on-web-page.html' title='Suggestions on a web page?'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110208850255439702</id><published>2004-12-03T07:41:00.000-08:00</published><updated>2004-12-03T07:48:45.586-08:00</updated><title type='text'>Bug in Delphi SOAP: arrays of TByteDynarrays don't work well.</title><content type='html'>There's a bug in the Delphi SOAP source code when using parameters like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;type&lt;br /&gt;  MultiArray = array of TByteDynArray;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To fix this, first add $(DELPHI)\Source\Soap to your search path, or copy the file&lt;br /&gt;OPtoSOAPDOMConv.pas to your local directory.&lt;br /&gt;&lt;br /&gt;then modify the file as follows:&lt;br /&gt;&lt;br /&gt;1. Locate the function &lt;b&gt;ConvertSoapToNativeArrayElem&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;2. add the following as a subfunction:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;// DEEPAK changed 3.12.2004 fix for arrays of &lt;br /&gt;//  TByteDynArray&lt;br /&gt;function TestDimDynArray( var Res : Pointer ) : boolean;&lt;br /&gt;var ArrayLen : integer;&lt;br /&gt;  DynP : Pointer;&lt;br /&gt;  TypeURI, TYpeName : InvString;&lt;br /&gt;  S : string;&lt;br /&gt;begin&lt;br /&gt;  result := False;&lt;br /&gt;  GetElementType(Node, TypeURI, TypeName);&lt;br /&gt;  if (Dims = 1) and&lt;br /&gt;     ((ElemInfo.Kind = tkInteger) or&lt;br /&gt;      (ElemInfo.Kind = tkChar)) and&lt;br /&gt;     (GetTypeData(ElemInfo).OrdType = otUByte) and&lt;br /&gt;       { Some SOAP implementations don't &lt;br /&gt;          send the XML Namespace!! }&lt;br /&gt;     (((TypeName ='base64Binary')) or&lt;br /&gt;      ((TypeURI = SSoap11EncodingS5) and &lt;br /&gt;        (TypeName = 'base64')) or&lt;br /&gt;        { Some SOAP implementations don't &lt;br /&gt;                send the type!! }&lt;br /&gt;        (TypeName = '' )) then&lt;br /&gt;    begin&lt;br /&gt;      S := DecodeString(Node.Text);&lt;br /&gt;      ArrayLen := Length(S);&lt;br /&gt;      DynP := Pointer(PInteger(DataP)^);&lt;br /&gt;      DynArraySetLength(DynP, TypeInfo(TByteDynArray), &lt;br /&gt;               1,  @ArrayLen);&lt;br /&gt;      Move(S[1], DynP^, Length(S));&lt;br /&gt;      Res := DynP;&lt;br /&gt;      Result := True;&lt;br /&gt;    end;&lt;br /&gt;  end;&lt;br /&gt;  // end DEEPAK&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;3. in the procedure, after following code:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;end else if Dims = 1 then&lt;br /&gt;begin&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;add:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  // DEEPAK 03.12.2004 line added&lt;br /&gt;&lt;br /&gt;  if not TestDimDynArray(Result) then   &lt;br /&gt;  begin&lt;br /&gt;     [ NOW put everything from &lt;br /&gt;          Size := ntElementChildCount(Node);&lt;br /&gt;      to&lt;br /&gt;          if Size &gt; 0 then&lt;br /&gt;             ReadRow(RootNode, Node, CurElem,  &lt;br /&gt;                                 Size, PElem, ElemInfo);&lt;br /&gt;      in this block]&lt;br /&gt;  end;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;(essentially, byte dynarrays must be handled differently, even when you&lt;br /&gt;have an array of bytearrays)&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110208850255439702?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110208850255439702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110208850255439702' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110208850255439702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110208850255439702'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/12/bug-in-delphi-soap-arrays-of.html' title='Bug in Delphi SOAP: arrays of TByteDynarrays don&apos;t work well.'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110208234330962020</id><published>2004-12-03T05:59:00.000-08:00</published><updated>2004-12-03T05:59:03.310-08:00</updated><title type='text'>Delphi 7: Library path edit dialog too small?</title><content type='html'>It's kinda irritating to have to resize the Delphi library path (Tools|Environment Options|Library tab, first "..." button) edit dialog so small - it's resizable, but it doesn't "remember" the size. There might be other solutions to this, like writing an IDE expert. But I got down to solving it the "brute force" way. &lt;br /&gt;&lt;br /&gt;I downloaded PE Resource Explorer from Colin Wilson's (excellent) Delphi Site, and used it to open coride70.bpl in my Delphi bin folder. I then opened up the RCDATA section, and browsed to the entry named "TORDEREDLISTDLG". On the right, after selecting the Neutral subnode, I found the DFM definition of &lt;b&gt;TOrderedListDlg&lt;/b&gt;, which is the dialog displayed. (How did I find out? Spy++ is my friend.)&lt;br /&gt;&lt;br /&gt;Using complex mathematical techniques such as addition and subtraction (done using excel, of course) I changed the width, height, top and/or bottom of whatever I wanted to change. Essentially I've made the dialog 500x450 now, a much better size to work with. I've uploaded this definition as a text file, so you can &lt;a href="http://www.agnisoft.com/downloads/libpathdlg.txt"&gt;download it here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Note: You'll have to use PE explorer and change this in coride70.bpl, save the changes and run Delphi again to check. Take a backup. Please. Only tried with Delphi 7. If you want different resolutions, do the calculations yourself. Your mileage may vary, and if it does, it isn't my fault.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110208234330962020?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110208234330962020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110208234330962020' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110208234330962020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110208234330962020'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/12/delphi-7-library-path-edit-dialog-too.html' title='Delphi 7: Library path edit dialog too small?'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110188592702916201</id><published>2004-11-30T23:25:00.000-08:00</published><updated>2004-11-30T23:25:27.030-08:00</updated><title type='text'>Keeping out-of-proc automation servers alive</title><content type='html'>I know, out-of-proc automation servers aren't very popular in these days when you have COM+ and .NET. But if you're still a person writing out of proc automation servers, (like Microsoft is with Word, Excel and the whole lot) you might need to consider a small fact. &lt;br /&gt;&lt;br /&gt;Delphi assumes that if your EXE was already running when a COM call was made to an object hosted inside it, then AFTER that call finishes, Delphi keeps your application running. (Obviously, I guess) But if your EXE isn't already running, then a COM call will *instantiate* your EXE, and create the COM object. Fine. But after the COM object is released, your EXE shuts down!!!!&lt;br /&gt;&lt;br /&gt;This is because of some code in ComServ.pas that's specific to automation - it actually checks if your EXE was launched through Automation (i.e. with a /AUTOMATION or /EMBEDDING parameter) and if so, when your object is released, it clears a reference to the factory. The Windows COM subsystem maintains references to the object factory in your application...and when that count reaches zero, COM assumes your factory has bid it goodbye, and in subsequent calls, will create a NEW instance of your application. &lt;br /&gt;&lt;br /&gt;So if you want to be able to say "I don't care how my EXE is launched but once it's launched I want the same EXE to handle all subsequent calls to the COM objects I host.", then read on. (If you're totally confused by now, stop.) &lt;br /&gt;&lt;br /&gt;What you need to do, is to trick COM into thinking your object factory is still alive. So, in some global create code (maybe in a form create event in an autocreated form, or a constructor of a global object) add this:&lt;br /&gt;&lt;br /&gt;ComObj.CoAddRefServerProcess;&lt;br /&gt;&lt;br /&gt;and in the corresponding destructor or FormDestroy, add:&lt;br /&gt;&lt;br /&gt;ComObj.CoReleaseServerProcess;&lt;br /&gt;&lt;br /&gt;(obviously, use &lt;b&gt;ComObj&lt;/b&gt;.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110188592702916201?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110188592702916201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110188592702916201' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110188592702916201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110188592702916201'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/12/keeping-out-of-proc-automation-servers.html' title='Keeping out-of-proc automation servers alive'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110146395262673409</id><published>2004-11-26T02:12:00.000-08:00</published><updated>2004-11-26T02:12:32.626-08:00</updated><title type='text'>Like Firefox? Want it INSIDE your Delphi app?</title><content type='html'>If you like &lt;a href="http://www.mozilla.org/products/firefox/"&gt;Firefox 1.0&lt;/a&gt;, you're probably using it as your default browser, copying your favourites and all that stuff. Well, if you want to migrate your Delphi applications to use it instead of TWebBrowser, you're in Luck!&lt;br /&gt;&lt;br /&gt;Check out &lt;a href="http://www.iol.ie/%7Elocka/mozilla/mozilla.htm"&gt;The Mozilla ActiveX Control&lt;/a&gt; and &lt;a href="http://www.paranoia.clara.net/articles/taming_the_lizard_with_delphi.html"&gt;Dave Murray's article&lt;/a&gt; on how to use it in Delphi. Will save you some (or all) of the trouble you have with SP2 going berserk - like &lt;a href="http://blogs.borland.com/abauer/archive/2004/10/29/1698.aspx"&gt;Allen Bauer seemed to have had&lt;/a&gt;. (If you're curious, that problem &lt;a href="http://blogs.borland.com/abauer/archive/2004/11/04.aspx"&gt; has been solved&lt;/a&gt;.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110146395262673409?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110146395262673409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110146395262673409' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110146395262673409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110146395262673409'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/11/like-firefox-want-it-inside-your.html' title='Like Firefox? Want it INSIDE your Delphi app?'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110139800051193047</id><published>2004-11-25T07:53:00.000-08:00</published><updated>2004-11-25T07:53:20.510-08:00</updated><title type='text'>Delphi 2005: Use only the Win32 part?</title><content type='html'>Well, if you want to do this, you CAN. And &lt;a href="http://delphi2005.cjb.net/"&gt;this page&lt;/a&gt; gives you step by step instructions....so if you're anti .NET, go for it.&lt;br /&gt;&lt;br /&gt;More useful, in my opinion is to use that in conjunction with &lt;a href="http://blogs.borland.com/corbindunn/archive/2004/09/29.aspx"&gt;Corbin Dunn's article&lt;/a&gt; on how to use the /r command line option in Delphi. Try it - you can set up a completely different IDE if you like, and one for Win32, and one for .NET. Btw, all of that works with Delphi 7 too, as I recently found out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110139800051193047?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110139800051193047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110139800051193047' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110139800051193047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110139800051193047'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/11/delphi-2005-use-only-win32-part.html' title='Delphi 2005: Use only the Win32 part?'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-110046711409221939</id><published>2004-11-14T13:18:00.000-08:00</published><updated>2004-11-14T13:21:14.820-08:00</updated><title type='text'>Deleting a SOAP attachment file</title><content type='html'>If you're creating a SOAP attachment on the server, and creating a temporary file for the purpose, you probably need to delete the file after you're done. You can't do this in &lt;b&gt;ANY&lt;/b&gt; of the events provided - the attachment stream is not freed before any event occurs. So, what you must do is that instead of using &lt;b&gt;TSOAPAttachment.SetSourceFile&lt;/b&gt;, you must use &lt;b&gt;TSOAPAttachment.SetSourceStream&lt;/b&gt; instead, but with your own stream like so:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;type&lt;br /&gt;  TMyStream = class( TFileStream )&lt;br /&gt;  public&lt;br /&gt;    destructor Destroy; override;&lt;br /&gt;  end;&lt;br /&gt;...&lt;br /&gt;destructor TMyStream.Destroy;&lt;br /&gt;begin&lt;br /&gt;  inherited;&lt;br /&gt;  Deletefile('c:\sql1.txt'); // or whatever has to be deleted&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and in your implementation have something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;var str : TMYStream;&lt;br /&gt;begin&lt;br /&gt;  Result := TSOAPAttachment.Create;&lt;br /&gt;  Str := TMyStream.Create('c:\sql1.txt', fmOPenread);&lt;br /&gt;&lt;br /&gt;  Result.SetSourceStream(Str,soOwned) ;&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-110046711409221939?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/110046711409221939/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=110046711409221939' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110046711409221939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/110046711409221939'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/11/deleting-soap-attachment-file.html' title='Deleting a SOAP attachment file'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-109870590331607989</id><published>2004-10-25T05:05:00.000-07:00</published><updated>2004-10-25T08:38:23.586-07:00</updated><title type='text'>Using TLinkedRio</title><content type='html'>If you need to test your webservices before they're deployed, you needn't build a client. To test your functions, simply create a TLinkedRio, and cast it to your interface. The TLinkedRio will also store the XML passed in files (for debugging)&lt;br /&gt; &lt;br /&gt;For instance, for a procedure named &lt;b&gt;Yawn&lt;/b&gt; in an exposed Interface &lt;b&gt;IICancelWait&lt;/b&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;function TICancelWait.Yawn: string;&lt;br /&gt;begin&lt;br /&gt;  Sleep( 10000 );&lt;br /&gt;&lt;br /&gt;  Result := 'Excuse Me';&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;To test it in the service itself, you can drop a button in the Server form (this is a WAD project) and a label, with the following code in the button's handler:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;procedure TForm1.Button1Click(Sender: TObject);&lt;br /&gt;var MyRio : TLinkedRio;&lt;br /&gt;begin&lt;br /&gt;  // use a TLinkedRIO&lt;br /&gt;&lt;br /&gt;  MyRio := TLinkedRio.Create(nil) ;&lt;br /&gt;  Label1.Caption := (MyRio as IICancelWait).Yawn;&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Notice that you don't need to free MyRio. A TLinkedRio will automatically get freed when it goes out of scope, if the Owner is null. &lt;br /&gt;&lt;br /&gt;All you have to do is include the SoapLinked unit and the interface units in your server project.&lt;br /&gt;&lt;br /&gt;You can even store the Request and Response in XML files to check the XML formatting or for other validations. Instead of Create, call CreateFile. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  MyRio := TLinkedRio.CreateFile(nil,&lt;br /&gt;             ExtractFilePath(Application.ExeName)+'Req.xml', &lt;br /&gt;             ExtractFilePath(Application.ExeName)+'Resp.xml');&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;i&gt;Note: &lt;b&gt;Application.ExeName&lt;/b&gt; will only work for WAD executables. You need to use &lt;b&gt;GetModuleFileName&lt;/b&gt; for ISAPI dlls, instead of Application.ExeName.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-109870590331607989?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/109870590331607989/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=109870590331607989' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109870590331607989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109870590331607989'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/10/using-tlinkedrio.html' title='Using TLinkedRio'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-109826313713723595</id><published>2004-10-20T02:05:00.000-07:00</published><updated>2004-10-20T02:05:37.136-07:00</updated><title type='text'>Advanced Web Services</title><content type='html'>I presented a paper at Borcon 2003, on Advanced web services. You can now see it online at &lt;a href="http://www.agnisoft.com/white_papers/advancedws"&gt;http://www.agnisoft.com/white_papers/advancedws&lt;/a&gt;. Tell me what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-109826313713723595?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/109826313713723595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=109826313713723595' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109826313713723595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109826313713723595'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/10/advanced-web-services.html' title='Advanced Web Services'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-109808408771531633</id><published>2004-10-18T00:21:00.000-07:00</published><updated>2004-10-18T00:21:27.716-07:00</updated><title type='text'>Optimize your ISAPI Dlls - Increase MaxConnections!</title><content type='html'>When your web application is called (as an ISAPI, NSAPI or Apache module), the Application spawns a new thread for a request. Within the context of this thread, your main web module is create.&lt;br /&gt;&lt;br /&gt;When the request is handled and response is sent, the created instance is then: &lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Freed, if you set Application.CacheConnections=False. (It's true by default) &lt;br /&gt;&lt;li&gt;If Cache Connections is true, then the webmodule is cached in an internal array for reuse at the next request.&lt;br /&gt;&lt;/ul&gt; &lt;br /&gt;Setting CacheConnections to false will create a webmodule for each request - something we don't want, unless there's a real reason for doing so. So let's keep CacheConnections on. But, what if you have one request being handled when another request comes in? The application will look inside the cache - if a webmodule is available, it is used. Otherwise a new thread is created, with a new instance of a the webmodule is created to handle the request. This happens until the number of currently active connections reaches the value in Application.MaxConnections, after which an exception is raised which says "Too many active connections". This shows up as an Internal Server Error on the browser. &lt;br /&gt;&lt;br /&gt;Now the default for Application.MaxConnections is 32 - so if you have any more than 32 connections active at any time, you will see internal server errors. 32 is woefully inadequate for anything that's in production, so you must increase this number - but do remember to test the "before" and "after" because at some point your memory usage will trade off against performance.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Note: All you have to do is set &lt;b&gt;Application.MaxConnections&lt;/b&gt; in your .dpr file.&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-109808408771531633?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/109808408771531633/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=109808408771531633' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109808408771531633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109808408771531633'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/10/optimize-your-isapi-dlls-increase.html' title='Optimize your ISAPI Dlls - Increase MaxConnections!'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-109767200635693110</id><published>2004-10-13T05:53:00.000-07:00</published><updated>2004-10-18T00:11:37.176-07:00</updated><title type='text'>SOAP Basic Authentication - D7</title><content type='html'>Back after a break. It's been quite a while since I wrote, so I'll cut to the chase. Question on newsgroups: How do I set username/password for Basic Authentication on SOAP. &lt;br /&gt;&lt;br /&gt;Issues: The HTTPRio.HTTPWebNode.UserName and .Password properties are used only in situations where theres a proxy. But let's assume you wanted to use these for basic authentication. You're going to have to set an event handler for &lt;b&gt;HttpRio.HttpWebNode.OnBeforePost&lt;/b&gt;. You get a &lt;b&gt;Data&lt;/b&gt; parameter here, and this is the HRequest used for sending the data.&lt;br /&gt;&lt;br /&gt;All you now have to do is write something like this in the event handler:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  if not InternetSetOption(Data, &lt;br /&gt;               INTERNET_OPTION_USERNAME, &lt;br /&gt;               PChar(HTTPRIO1.HTTPWebNode.UserName), &lt;br /&gt;               Length(HTTPRIO1.HTTPWebNode.UserName)) then&lt;br /&gt;     ShowMessage(SysErrorMessage(GetLastError));&lt;br /&gt;&lt;br /&gt;  if not InternetSetOption(Data, &lt;br /&gt;               INTERNET_OPTION_PASSWORD, &lt;br /&gt;               PChar(HTTPRIO1.HTTPWebNode.Password), &lt;br /&gt;               Length (HTTPRIO1.HTTPWebNode.Password)) then&lt;br /&gt;     ShowMessage(SysErrorMessage(GetLastError));&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can of course set any other password you want. &lt;i&gt;Note:&lt;/i&gt; You need to add &lt;b&gt;WinInet&lt;/b&gt; and &lt;b&gt;SOAPHttpTrans&lt;/b&gt; to your uses clause.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-109767200635693110?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/109767200635693110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=109767200635693110' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109767200635693110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109767200635693110'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/10/back-after-break.html' title='SOAP Basic Authentication - D7'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-109172638925294483</id><published>2004-08-05T10:19:00.000-07:00</published><updated>2004-08-05T10:19:49.256-07:00</updated><title type='text'>A Custom Places Bar</title><content type='html'>Another Open Dialog Customization: I found out from &lt;a href="http://msdn.microsoft.com/msdnmag/issues/03/03/CuttingEdge/default.aspx"&gt;Dino's Article on MSDN&lt;/a&gt; that you can customize the links on your File Open Dialog boxes, even on a &lt;i&gt;Per Process Basis&lt;/i&gt;. I naturally had to see that in Delphi, and it wasn't too difficult. I'm not going to explain a heck of a lot here, because it's way too late to do that. &lt;a href="http://www.agnisoft.com/downloads/customplacesbar.zip"&gt;Download the code here.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-109172638925294483?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/109172638925294483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=109172638925294483' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109172638925294483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109172638925294483'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/08/custom-places-bar.html' title='A Custom Places Bar'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-109155132829564512</id><published>2004-08-03T09:42:00.000-07:00</published><updated>2004-08-03T09:44:21.546-07:00</updated><title type='text'>Changing the default view in TAgOpenDialog</title><content type='html'>I got a mail today asking if &lt;a href="http://www.agnisoft.com/downloads/downloads.asp"&gt;AgOpenDialog&lt;/a&gt;, a dialog I'd written for D5 a few years ago, would support &lt;i&gt;defining a default view&lt;/i&gt; - i.e. when the dialog opens, it should be configurable to display the list view in, for instance, the &lt;b&gt;thumbnails&lt;/b&gt; view.&lt;br /&gt;&lt;br /&gt;A little bit of help from a &lt;a href="http://www.mvps.org/vbvision/grouped_demos.htm#Common_Dialogs"&gt;Visual Basic site&lt;/a&gt; (The "Save and Open File Dialog Demo" link) gave me a clue. Define this first:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;const&lt;br /&gt;  FCIDM_SHVIEW_LARGEICON = $7029;   // 28713&lt;br /&gt;  FCIDM_SHVIEW_SMALLICON = $702A;   // 28714&lt;br /&gt;  FCIDM_SHVIEW_LIST = $702B;        // 28715&lt;br /&gt;  FCIDM_SHVIEW_REPORT = $702C;      // 28716&lt;br /&gt;  FCIDM_SHVIEW_THUMBNAIL = $702D;   // 28717&lt;br /&gt;  FCIDM_SHVIEW_TILE = $702E;        // 28718&lt;br /&gt;type&lt;br /&gt;  TAgOpenDialogView = (ovLargeIcon, ovSmallIcon, &lt;br /&gt;            ovList, ovReport, &lt;br /&gt;            ovThumbnails, ovTile);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and a published property:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;property DefaultView : TAgOpenDialogView &lt;br /&gt;     read FDefaultView &lt;br /&gt;     write FDefaultView default ovLargeIcon;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, override the &lt;b&gt;WndProc&lt;/b&gt; and set it up:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;procedure TAgOpenDialog.WndProc(var Message: TMessage);&lt;br /&gt;const&lt;br /&gt;  ViewConsts : array[TAgOpenDialogView] of integer = &lt;br /&gt;(  FCIDM_SHVIEW_LARGEICON, FCIDM_SHVIEW_SMALLICON,&lt;br /&gt;   FCIDM_SHVIEW_LIST,  FCIDM_SHVIEW_REPORT,  &lt;br /&gt;   FCIDM_SHVIEW_THUMBNAIL,  FCIDM_SHVIEW_TILE);&lt;br /&gt;var hList : THandle;&lt;br /&gt;begin&lt;br /&gt;  inherited;&lt;br /&gt;  if (Message.Msg = WM_NOTIFY) then&lt;br /&gt;    case (POFNotify(Message.LParam)^.hdr.code) of&lt;br /&gt;    CDN_FOLDERCHANGE:&lt;br /&gt;      begin&lt;br /&gt;        if not FDefaultViewChanged then&lt;br /&gt;        begin&lt;br /&gt;          hList := FindWindowEx( GetParent(handle), 0, &lt;br /&gt;                'SHELLDLL_DefView', '');&lt;br /&gt;          if hList &lt;&gt; 0 then&lt;br /&gt;          begin&lt;br /&gt;            SendMessage(hList, WM_COMMAND, &lt;br /&gt;                ViewConsts[FDefaultView], 0);&lt;br /&gt;            FDefaultViewChanged := True;&lt;br /&gt;          end;&lt;br /&gt;        end;&lt;br /&gt;      end;&lt;br /&gt;    end;&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The &lt;b&gt;FDefaultViewChanged&lt;/b&gt; is a boolean member initialized to &lt;b&gt;False&lt;/b&gt; in the overridden Execute procedure. You can &lt;a href="http://www.agnisoft.com/downloads/agopendialog.zip"&gt;download the component and source code here.&lt;/a&gt; (Test project included).&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-109155132829564512?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/109155132829564512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=109155132829564512' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109155132829564512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109155132829564512'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/08/changing-default-view-in-tagopendialog.html' title='Changing the default view in TAgOpenDialog'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-109084720903346680</id><published>2004-07-26T06:06:00.000-07:00</published><updated>2004-07-26T06:06:49.040-07:00</updated><title type='text'>Open Source Myths</title><content type='html'>A post in our &lt;a href="http://www.linux-bangalore.org"&gt;local Linux user group&lt;/a&gt; pointed me to an article about &lt;a href="http://www.neilgunton.com/open_source_myths/"&gt;Common Open Source Myths&lt;/a&gt;. I especially like the &lt;i&gt;All Software should be Free&lt;/i&gt; paragraph; Software should never be treated as something that &lt;b&gt;must&lt;/b&gt; be free. Even as in beer. Because at a very macro level, the small company is going to have problems - imagine a garage company that makes and sells something. If they need accounting software, it's free (GREAT!) but now if they have a problem, they have choices of:&lt;br /&gt;&lt;br /&gt;a) Contact a programmer who wrote the software, which is open source, so he's funded by his full time job in organization X that makes microprocessor chips. So he doesn't have time to fix or address the problem immediately, or&lt;br /&gt;&lt;br /&gt;b) Find a "support" company that will support this famous open source software, but they're either too expensive or don't have any good programmers who can fix the software using the source code. Because the best programmers are at company X at makes microprocessor chips. &lt;br /&gt;&lt;br /&gt;My point: The best programmers will leave the industry if there's not enough money to be made writing software. &lt;br /&gt;&lt;br /&gt;Extrapolate further: as support becomes the only money making opportunity, countries like India and China, who have vast resources of programmers, will be able to provide support at much cheaper rates. (No, I don't believe providing "support" is a wonderful thing to do, even if it provides revenue for my country. We'll always stay at the bottom of the value chain) And if the entire business model depends on support - why would anyone ever want to fully document software? Or even fix things that they see as potential problems, but aren't noticed by customers yet? (Hey, we can bill them for it when they find out :) )&lt;br /&gt;&lt;br /&gt;I like open source software - I use many tools that are open source. Our internal company rule disallows the use of GPL based components in any of the work we do, but we do use MPL and other free licence based components. But I think closed and open source software should co-exist, as competition. &lt;br /&gt;&lt;br /&gt;There's tons of free source code dished out in newsgroups, source code (even from Microsoft) and websites such as &lt;a href="http://www.codeproject.com"&gt;CodeProject&lt;/a&gt;. Anyone can use this source code today: I just hope such code doesn't become inaccessbile to us closed source application authors!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-109084720903346680?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/109084720903346680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=109084720903346680' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109084720903346680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109084720903346680'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/07/open-source-myths.html' title='Open Source Myths'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-109051713333578913</id><published>2004-07-22T10:25:00.000-07:00</published><updated>2004-07-22T10:25:33.340-07:00</updated><title type='text'>India Delphi User Group (INDUG)</title><content type='html'>We started &lt;a href="http://groups.yahoo.com/group/indug"&gt;INDUG&lt;/a&gt; a few years back, and boy has it grown! 776 members and counting...what's surprising is that in the last few days the activity has started to heat up. Turns out there were 48 members in the last two months! &lt;br /&gt;&lt;br /&gt;Delphi is growing up, at least in India. I don't know what the reason is, but it seems like a lot of companies have started to look at Delphi seriously - I just heard of an appliance company that's using Delphi! And the ads in the Employment sections seem to have a lot more Delphi-count nowadays. I don't know if this is absolutely correct, but it looks like for Win32 folks that aren't into C++, Delphi's simply the best option in the market. Microsoft's hardselling .NET but everyone knows that Win32 isn't going anywhere soon - and .NET isn't going to be ubiquitous anytime soon either.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-109051713333578913?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/109051713333578913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=109051713333578913' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109051713333578913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109051713333578913'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/07/india-delphi-user-group-indug.html' title='India Delphi User Group (INDUG)'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-109031444706457048</id><published>2004-07-20T02:07:00.000-07:00</published><updated>2004-07-20T02:07:27.070-07:00</updated><title type='text'>MSBuild - the build tool of the future?</title><content type='html'>I just found out that Microsoft is planning to ship MSBuild as part of the CLR. Now I can't find the link to MSBuild itself - anyone know? - but I found &lt;a href="http://blogs.msdn.com/MSBuildExplorers/"&gt;the blog of the MSBuild dev team&lt;/a&gt;. You can also &lt;a href="http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=2CB20E79-D706-4706-9EA0-26188257EE7D"&gt;download the bits&lt;/a&gt; that will work with version 1.2 and 2.0.&lt;br /&gt;&lt;br /&gt;Very interesting tool, this. You can schedule your builds, co-ordinate check outs/check ins, zip/unzip files, deploy to remote directories etc., all using a single XML. Something like &lt;a href="http://www.finalbuilder.com"&gt;FinalBuilder&lt;/a&gt;, except this is now going to be part of the CLR. And I have no clue what the GUI will look like, but I do like FinalBuilder's GUI. &lt;br /&gt;&lt;br /&gt;If I find the time, I'm going to write a Delphi compile action for MSBuild. If someone beats me to it, let me know :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-109031444706457048?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/109031444706457048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=109031444706457048' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109031444706457048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/109031444706457048'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/07/msbuild-build-tool-of-future.html' title='MSBuild - the build tool of the future?'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108997659561251350</id><published>2004-07-16T04:16:00.000-07:00</published><updated>2004-07-16T04:16:35.616-07:00</updated><title type='text'>Set Next Statement in Delphi?</title><content type='html'>I am a huge fan of &lt;a href="http://blogs.msdn.com/matt_pietrek/"&gt;Matt Pietrek&lt;/a&gt;. I also just found &lt;a href="http://www.wheaty.net/"&gt;his home page&lt;/a&gt;. And guess what, he even worked for &lt;a href="http://www.borland.com"&gt;Borland&lt;/a&gt;!!! Oh and you should read his material - Under the Hood on MSDN, the Windows Internals, System Programming Secrets and Undocumented Windows books, and &lt;a href="http://www.wheaty.net/images/timesheet.jpg"&gt;this&lt;/a&gt; (the last one isnt his, but hey it deserves a mention).&lt;br /&gt;&lt;br /&gt;Okay, so in his &lt;a href="http://blogs.msdn.com/matt_pietrek/"&gt;Blog&lt;/a&gt;, Matt mentions a "Set Next Statement" - something in VS that allows you to actually move the next instruction executed to a new position. This isn't exclusive to VS, you can do it in Delphi too, it's just not documented well enough. Here's how you do this:&lt;br /&gt;&lt;br /&gt;Let's say you have this kick-ass piece of code:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;procedure TForm1.Button1Click(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;  DoSomethingStupid;&lt;br /&gt;&lt;br /&gt;  ShowMessage('Done');&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TForm1.DoSomethingStupid;&lt;br /&gt;begin&lt;br /&gt;&lt;b&gt;  while true do ;&lt;/b&gt;&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You should never be able to debug this down to the "ShowMessage('Done');" statement, because of the wonderful "while true do ; " code. Now I've faced this problem many-a-times; I just want to get out the &lt;b&gt;DoSomethingStupid&lt;/b&gt; function, and move on to the next piece of code which I've got to test. (Recompiling is easy in Delphi, you say. Ha.  Not if relaunching of the app involves a login, navigation, entering some specific data and then debugging.)&lt;br /&gt;&lt;br /&gt;Set a breakpoint in the "while true do;" line. When the program breaks there, hit Ctrl+Alt+C (or View|Debug Windows|CPU). The windows looks like this:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.agnisoft.com/deepak/blog/CPUFirst.jpg"&gt;&lt;br /&gt;&lt;br /&gt;Right click on the next line (with the &lt;b&gt;ret&lt;/b&gt; instruction) and select &lt;b&gt;New EIP&lt;/b&gt;. &lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.agnisoft.com/deepak/blog/CPUSecond.jpg"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;EIP is the (Extended) Instruction Pointer, which is what makes you a pointy haired boss (PHB). No, that's something else.  Anyways. &lt;br /&gt;&lt;br /&gt;What happens next is that your ShowMessage call runs! so you're out of the infinite loop, without having to recompile. This is very helpful when you've made an obvious blunder (like in saving a file, you've given an invalid path) but that blunder doesn't affect anything else like parameters, stack etc. (And don't try doing this to get out of a try/except/finally statement - won't work most of the time)&lt;br /&gt;&lt;br /&gt;The CPU window is your friend. There are tons more tricks you can use - &lt;a href="http://homepages.borland.com/dthorpe/blog/delphi/"&gt;Danny&lt;/a&gt; had an amazing session ("Reading Tea Leaves") in a BorCon long back that led me on to this, but there's not much else I've remembered...&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108997659561251350?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108997659561251350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108997659561251350' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108997659561251350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108997659561251350'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/07/set-next-statement-in-delphi.html' title='Set Next Statement in Delphi?'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108971407942207078</id><published>2004-07-13T03:21:00.000-07:00</published><updated>2004-07-13T03:21:19.426-07:00</updated><title type='text'>WFML : A DFM equivalent for .NET?</title><content type='html'>Check out &lt;a href="http://windowsforms.net/articles/wfml.aspx"&gt;http://windowsforms.net/articles/wfml.aspx&lt;/a&gt;.  This is a component that can use XML markup to "design" forms - so you can have your form design separate from your code! Very much like Delphi DFMs - and the event model also expects handlers inside of the .CS class. No designer for it, of course - and probably no support in Longhorn either - XAML does this in Longhorn anyhow.&lt;br /&gt;&lt;br /&gt;But you know what, this does one thing that I've always wanted in Delphi - allows me to put comment in the form design code - i.e. comment out a component easily. Even in the .NET IDEs, you can't really muck about with the "InitializeComponent()" code - they don't like it too much, for reasons I can't understand. (If you're parsing, parse it right, dammit. So what if I chose to comment something out?)&lt;br /&gt;&lt;br /&gt;But the app is *slow*. No, this isn't just .NET - XML parsing in general is slow, and then all the stuff like dynamically creating stuff is slower.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108971407942207078?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108971407942207078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108971407942207078' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108971407942207078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108971407942207078'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/07/wfml-dfm-equivalent-for-net.html' title='WFML : A DFM equivalent for .NET?'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108961461763097735</id><published>2004-07-11T23:43:00.000-07:00</published><updated>2004-07-11T23:43:37.636-07:00</updated><title type='text'>PInvoke - Win32 declarations again</title><content type='html'>I found a &lt;a href="http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=f1dd70e4-c212-4a6f-bff7-c82e34c8836f"&gt;GotDotNet Sample&lt;/a&gt; that looks like it has some of the Windows.H declarations. No #defines converted, though. &lt;br /&gt;&lt;br /&gt;So why am I harping about all this PInvoke stuff? i just don't believe that .NET's going to be the only platform for years to come, and there's tons of things in Win32 that are plain ignored in the FCL. So, we'll need PInvoke for a while - and it's better to have a ready set of translations so you can use what you're going to need.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108961461763097735?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108961461763097735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108961461763097735' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108961461763097735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108961461763097735'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/07/pinvoke-win32-declarations-again.html' title='PInvoke - Win32 declarations again'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108930491072585229</id><published>2004-07-08T09:41:00.001-07:00</published><updated>2004-07-08T09:41:50.730-07:00</updated><title type='text'>ListView - Groups?</title><content type='html'>I was wondering how the groups and "tiles" worked in XP. For groups we have &lt;a href="http://www.swissdelphicenter.ch/en/showcode.php?id=1782"&gt;some code here&lt;/a&gt;. Useful, definitely - still need to figure out the "tile" thing.  &lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108930491072585229?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108930491072585229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108930491072585229' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108930491072585229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108930491072585229'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/07/listview-groups.html' title='ListView - Groups?'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108929220195705476</id><published>2004-07-08T06:10:00.000-07:00</published><updated>2004-07-08T08:08:38.383-07:00</updated><title type='text'>Tracker. Free.</title><content type='html'>I've always been a fan of bug tracking apps - have at least 10 of them on my machine! But this one just plain blew me away. Check out Tracker at:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://windowsforms.net/articles/writingntierapps.aspx"&gt;http://windowsforms.net/articles/writingntierapps.aspx&lt;/a&gt;&lt;br /&gt;&lt;a href="http://devcenter.infragistics.com/RefApps/Tracker/DownloadTracker.Aspx"&gt;Download Tracker Here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pretty nifty, or at least the screen shots say so. I took some time off, installed it - and found it does NOT like MSDE...(not a named instance anyhow). So after figuring that out, I uploaded it to a SQL server base instance here, and then created the database, and voila! I had a winner. This app is just COOL. I haven't used it much but it makes me want to - I'll see how it goes and post a progress message next week or so.&lt;br /&gt;&lt;br /&gt;And this is free. With Source. Non GPL'ed. Isn't that something? &lt;br /&gt;&lt;br /&gt;Also, check out the ASP.NET starter kits at &lt;a href="http://www.asp.net/Default.aspx?tabindex=9&amp;tabid=47&lt;br /&gt;"&gt;http://www.asp.net/Default.aspx?tabindex=9&amp;tabid=47&lt;/a&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108929220195705476?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108929220195705476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108929220195705476' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108929220195705476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108929220195705476'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/07/tracker-free.html' title='Tracker. Free.'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108927097550646903</id><published>2004-07-08T00:16:00.000-07:00</published><updated>2004-07-08T00:29:18.426-07:00</updated><title type='text'>Unloading an ISAPI dll from IIS</title><content type='html'>I got this snippet from the borland.public.delphi.internet.isapi-webbroker newsgroup - a simple way to unload an ISAPI dll programmatically:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;var&lt;br /&gt;  WSite, WServer, WRoot: Variant;&lt;br /&gt;begin&lt;br /&gt;  WSite := CreateOleObject('IISNamespace');&lt;br /&gt;  WSite := WSite.GetObject('IIsWebService', &lt;br /&gt;                'localhost/w3svc');&lt;br /&gt;  WServer := WSite.GetObject('IIsWebServer', '1');&lt;br /&gt;  WRoot := WServer.GetObject('IIsWebVirtualDir', &lt;br /&gt;                'Root');&lt;br /&gt;  wserver.stop;&lt;br /&gt;  wroot.appunload;&lt;br /&gt;  wserver.start;&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This works on XP - I didn't even know you could create an OLE object with "IISNamespace". But you can. Anyhow, in the WSite.GetObject call you see a "1" - if you're wondering what that is, it's the number given to a web site by IIS. You can get the numbers of all your websites through Adsi - import the Ads type library and use the code from &lt;a href="http://www.agnisoft.com/white_papers/active_directory.asp"&gt;my ADSI paper&lt;/a&gt; like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;var serv : IADSContainer;&lt;br /&gt;    e : IEnumVARIANT;&lt;br /&gt;    varArr : OleVariant;&lt;br /&gt;    lNumElements : ULong;&lt;br /&gt;    obj : IADs;&lt;br /&gt;    hr : integer;&lt;br /&gt;begin&lt;br /&gt;  // list web sites&lt;br /&gt;  AdsGetObject('IIS://localhost/w3svc',IAdsContainer, serv) ;&lt;br /&gt;&lt;br /&gt;  hr := ADsBuildEnumerator(serv,e);&lt;br /&gt;  while(Succeeded(Hr)) do&lt;br /&gt;  begin&lt;br /&gt;    hr := ADsEnumerateNext(e,1,&lt;br /&gt;                    varArr ,lNumElements);&lt;br /&gt;&lt;br /&gt;    if (lNumElements=0) then&lt;br /&gt;      break;&lt;br /&gt;&lt;br /&gt;    IDispatch(varArr).QueryInterface(IADs, obj);&lt;br /&gt;    if obj&lt;&gt;nil then&lt;br /&gt;    begin&lt;br /&gt;      if obj.Class_ = 'IIsWebServer' then&lt;br /&gt;          &lt;b&gt;// obj.Name contains the "number" you need.&lt;/b&gt;&lt;br /&gt;    end;&lt;br /&gt;    obj := nil;&lt;br /&gt;    varArr := NULL;&lt;br /&gt; end;&lt;br /&gt; //don't call ADsFreeEnumerator(e); &lt;br /&gt;//since e will be released by Delphi&lt;br /&gt;...&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can use ADSI to do a ton of things. I've been planning to finish up a set of ADSI components for Delphi - never had the time though. I don't even know if there'll be enough people who need it - but I do get something like 10-20 mails a month on my paper. If the market's big enough, I'd like to make it commercial - which gives me time to work on it. Otherwise it goes as "free" stuff, but no time allocated to finish it. Tough call.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108927097550646903?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108927097550646903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108927097550646903' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108927097550646903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108927097550646903'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/07/unloading-isapi-dll-from-iis.html' title='Unloading an ISAPI dll from IIS'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108858962046830939</id><published>2004-06-30T03:00:00.000-07:00</published><updated>2004-06-30T03:00:20.473-07:00</updated><title type='text'>Cancelling a SOAP function call</title><content type='html'>A newsgroup user asked "Is it possible to cancel waiting for the webservice to return the result of a function?" To be extremely brief: Yes. &lt;br /&gt;&lt;br /&gt;Less succinctly, the answer lies in the ingenious use of threads. Firstly, if you're going to have a single threaded application, you can't stop a function call while it's running. It's like you're reading the paper in your car, stopped at a traffic light, alone; and the light's just turned green. You have no idea because well, there's no one around to tell you. (for the record, I've never done this) &lt;br /&gt;&lt;br /&gt;So in order to cancel a function call, you need to put that function call in a separate thread, and in the main UI thread (where your form is) - implement a cancel button that will somehow terminate the function call. How does one do that? The SOAP call that you make actually waits for the Internet call to return - and you have no way to tell this code to stop gracefully. &lt;br /&gt;&lt;br /&gt;Now, a HTTPRio uses WinInet by default, and you get the handle to the Request in the &lt;b&gt;HttpWebNode.OnBeforePost&lt;/b&gt; event. You can call &lt;b&gt;InternetCloseHandle&lt;/b&gt; with this handle anytime - this will raise an exception in the thread - with a &lt;i&gt;"The operation has been canceled...."&lt;/i&gt; message. The thread will terminate, and your function call get cancelled. &lt;br /&gt;&lt;br /&gt;Note: the server call will continue to run on the server till termination. To actually terminate whatever's happening at the server you'll need to use some other logic (like a server thread that can be terminated from another SOAP call or some kind of constant check on the request validity).&lt;br /&gt;&lt;br /&gt;I've got a test application here that demonstrates what I'm talking about. Download it at &lt;a href="http://www.agnisoft.com/downloads/SoapCancelWait.zip"&gt;http://www.agnisoft.com/downloads/SoapCancelWait.zip&lt;/a&gt;. And as usual, tell me what you think!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108858962046830939?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108858962046830939/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108858962046830939' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108858962046830939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108858962046830939'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/cancelling-soap-function-call.html' title='Cancelling a SOAP function call'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108806390404871576</id><published>2004-06-24T00:58:00.000-07:00</published><updated>2004-06-24T00:58:24.053-07:00</updated><title type='text'>Launched from a shortcut?</title><content type='html'>If you would EVER need a way to check if your application was launched from a shortcut, rather than accessing the EXE itself, &lt;a href="http://www.catch22.org.uk/tuts/undoc01.asp"&gt;this article&lt;/a&gt; should help. &lt;br /&gt;&lt;br /&gt;Now why you would want to do this is, frankly, beyond my imagination. The only thing I can think of is that on XP/2000, you can choose to run a program with different credentials through a shortcut. Even here you can't specify the credentials - the user gets to choose them (and enter a username/password) And the user can actually choose the *same* credentials as the logged on user, even with this flag set.&lt;br /&gt;&lt;br /&gt;This is the programming equivalent of saying "There may be someone else on the computer right now, or maybe not.". Which might not be the lifesaver we're all looking for. (And no, we don't get them in India. The famous mints here are "polo" and "minto", if you're curious. Which you probably aren't, but I'm bored to death of the programming stuff)  If anyone knows what scenerio such code might be useful in, I'd really appreciate a hint...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108806390404871576?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108806390404871576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108806390404871576' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108806390404871576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108806390404871576'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/launched-from-shortcut.html' title='Launched from a shortcut?'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108797267974336815</id><published>2004-06-22T23:37:00.000-07:00</published><updated>2004-06-22T23:37:59.750-07:00</updated><title type='text'>The FileZilla FTP Client</title><content type='html'>There are tons of FTP clients out there, I know. But if you will, check out &lt;a href="http://sourceforge.net/projects/filezilla"&gt;FileZilla&lt;/a&gt;. Awesome client...I used it to do a ton of uploads/downloads - very impressive in terms of speed and features.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108797267974336815?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108797267974336815/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108797267974336815' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108797267974336815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108797267974336815'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/filezilla-ftp-client.html' title='The FileZilla FTP Client'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108797239438393133</id><published>2004-06-22T23:33:00.000-07:00</published><updated>2004-06-22T23:33:14.390-07:00</updated><title type='text'>They're all blogging!</title><content type='html'>&lt;a href="http://blogs.teamb.com"&gt;TeamB&lt;/a&gt; and &lt;a href="http://blogs.borland.com"&gt;Borland&lt;/a&gt; have joined the blogging fray. (This is old hat, I know). Oh btw, you can check my &lt;a href="http://blogs.teamb.com/deepakshenoy"&gt;blog on the TeamB blog server&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108797239438393133?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108797239438393133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108797239438393133' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108797239438393133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108797239438393133'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/theyre-all-blogging.html' title='They&apos;re all blogging!'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108793035273361440</id><published>2004-06-22T11:52:00.000-07:00</published><updated>2004-07-21T01:41:27.856-07:00</updated><title type='text'>Introducing "AltInvoke"</title><content type='html'>I've started getting all sorts of ideas now with this Microsoft page giving you &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/win32map.asp"&gt;alternatives to common PInvoke calls&lt;/a&gt;. My first set: Include it in my PBroker tool - now you have a "Get Alternatives" button that gives you...well, alternatives for your PInvoke calls. The first screen shot: (Click for a larger pic)&lt;br&gt;&lt;br /&gt;&lt;a href="http://www.agnisoft.com/images/pbroker.jpg"&gt;&lt;img src="http://www.agnisoft.com/images/pbrokersmall.jpg"&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;And you can &lt;a href="http://www.agnisoft.com/downloads/pbroker.zip"&gt;download PBroker here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108793035273361440?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108793035273361440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108793035273361440' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108793035273361440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108793035273361440'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/introducing-altinvoke.html' title='Introducing &quot;AltInvoke&quot;'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108747401496890122</id><published>2004-06-17T04:58:00.000-07:00</published><updated>2004-07-21T01:40:31.803-07:00</updated><title type='text'>.NET equivalents of Unmanaged calls</title><content type='html'>You have to check this site if you're even thinking of using PInvoke. Read: &lt;br /&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/win32map.asp"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/win32map.asp&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;It contains the equivalents of a number of Win32 functions. Now that gets me thinking....&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108747401496890122?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108747401496890122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108747401496890122' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108747401496890122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108747401496890122'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/net-equivalents-of-unmanaged-calls.html' title='.NET equivalents of Unmanaged calls'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108737812453435681</id><published>2004-06-16T01:52:00.000-07:00</published><updated>2004-06-16T02:28:44.533-07:00</updated><title type='text'>Shenoy In BusinessWorld</title><content type='html'>Seems I made it into a &lt;a href="http://www.businessworldindia.com/sep2903/invogue.asp"&gt;news article on Business World (India)&lt;/a&gt;. But the &lt;a href="http://www.nokia.com/nokia/0,,137,00.html"&gt;Nokia 7650&lt;/a&gt; was my old phone. My new phone is a &lt;a href="http://www.sonyericsson.com/p900/main.aspx?regionCode=in"&gt;Sony Ericsson P900&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;And the Sony even runs .NET apps, through something called &lt;a href="http://www.appforge.com/products/enterprise/crossfire/index.html"&gt;Crossfire&lt;/a&gt;. Haven't tried it yet, but this definitely looks interesting. Of course, the phone is Symbian OS based and supports MIDP and J2ME apps too. Gadgets rule!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108737812453435681?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108737812453435681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108737812453435681' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108737812453435681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108737812453435681'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/shenoy-in-businessworld.html' title='Shenoy In BusinessWorld'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108730152889139401</id><published>2004-06-15T05:08:00.001-07:00</published><updated>2004-06-15T05:14:47.996-07:00</updated><title type='text'>Web App Debugger problem</title><content type='html'>Lachlan was wondering if I had a workaround for: &lt;br /&gt;&lt;a href="http://qc.borland.com/wc/wc.exe/details?ReportID=7738"&gt;http://qc.borland.com/wc/wc.exe/details?ReportID=7738&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ok, that problem really sucks. The problem is that a lot of the Delphi code actually depends on the prog id being part of the path info. Here's the fix:&lt;br /&gt;&lt;br /&gt;Copy "SockHTTP" from the Delphi Source\Internet folder into your project folder, and most importantly, &lt;b&gt;Add it to your project&lt;/b&gt;. Then, change the TSockWebRequest.GetStringVariable to:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;function TSockWebRequest.GetStringVariable(&lt;br /&gt;           Index: Integer): string;&lt;br /&gt;var iPos : integer;&lt;br /&gt;begin&lt;br /&gt;  Result := FIntf.GetStringVariable(Index);&lt;br /&gt;  if Index=4 then // pathinfo&lt;br /&gt;  begin&lt;br /&gt;    result := Copy(Result, 2, Length(Result));&lt;br /&gt;    iPos := Pos('/', Result);&lt;br /&gt;    if iPos&gt;0 then&lt;br /&gt;      Result := Copy(Result, iPos, &lt;br /&gt;                     Length(Result))&lt;br /&gt;    else&lt;br /&gt;      Result := '/';&lt;br /&gt;  end;&lt;br /&gt;end;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Also change TSockWebRequest.GetInternalPathInfo to: (You'll need to comment out a few lines)&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;function &lt;br /&gt;  TSockWebRequest.GetInternalPathInfo: string;&lt;br /&gt;var&lt;br /&gt;  P: Integer;&lt;br /&gt;begin&lt;br /&gt;  if UsingStub then&lt;br /&gt;  begin&lt;br /&gt;    Result := PathInfo;&lt;br /&gt;    Assert(Length(Result) &gt; 0, 'Unexpected length');&lt;br /&gt;&lt;i&gt;&lt;br /&gt;    (* COMMENTED BY DEEPAK&lt;br /&gt;&lt;br /&gt;    Assert(Result[1] = '/', 'Unexpected value');&lt;br /&gt;    Delete(Result, 1, 1);&lt;br /&gt;    // Remove first section of path.  This is a reference&lt;br /&gt;    // to the progid.&lt;br /&gt;    P := Pos('/', Result);   {do not localize}&lt;br /&gt;    if P &gt; 0 then&lt;br /&gt;      Delete(Result, 1, P-1)&lt;br /&gt;    else&lt;br /&gt;      Result := '/';&lt;br /&gt;&lt;br /&gt;    END COMMENTED BY DEEPAK *)&lt;/i&gt;&lt;br /&gt;  end&lt;br /&gt;  else&lt;br /&gt;    Result := inherited GetInternalPathInfo;&lt;br /&gt;end;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Remember, &lt;b&gt;Copy&lt;/b&gt; the SockHTTP.pas to your project folder, don't edit it in the Borland source folder!&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108730152889139401?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108730152889139401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108730152889139401' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108730152889139401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108730152889139401'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/web-app-debugger-problem.html' title='Web App Debugger problem'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108729562328720739</id><published>2004-06-15T02:18:00.000-07:00</published><updated>2004-06-15T03:33:43.286-07:00</updated><title type='text'>Singletons and more...</title><content type='html'>I just read &lt;a href="http://www.lemanix.com/nick/"&gt;Nick's&lt;/a&gt; excellent &lt;a href="http://www.lemanix.com/nick/archive/2004/06/11/694.aspx"&gt;post on Singleton datamodules&lt;/a&gt; explaining how he accessed a datamodule using a global function.&lt;br /&gt;&lt;br /&gt;Which got me thinking, a fairly rare occurance these days. What went through my mind was: What if someone, ignorantly or maliciously, did a &lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;var MyModule : TMyDatamodule;&lt;br /&gt;begin&lt;br /&gt;  MyModule := TMyDataModule.Create(nil);&lt;br /&gt;end;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I know what you're thinking. "You're &lt;b&gt;supposed&lt;/b&gt; to use the global function!!!!". Er...this is a big team, someone forgot to document that, I was trying to figure out what would happen, I don't really like you...tons of excuses! And you'll only figure out something was wrong when you did a code review, or a synchronization or resource conflict occured...and probably have ZERO control over it if you were writing a library (like Borland is with the "Printer" variable). &lt;br /&gt;&lt;br /&gt;Now, what could be better than to allow users to use the ".Create" convention, but return them a singleton instance on subsequent calls? It &lt;b&gt;is&lt;/b&gt; possible. And no hacks.&lt;br /&gt;&lt;br /&gt;Here's the scoop: Override the &lt;b&gt;NewInstance&lt;/b&gt; function. This is a class (&lt;b&gt;static&lt;/b&gt; for you C++ folks) function that gets called during object construction. Here's an example. I've used a form, with a label on it. Each unique instance gets a "Number" - so we can track what's going where. In this class, TForm2, (laziness written all over the name, of course):&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;var UseSingleTon : boolean = False;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  iNUM : integer = 1;&lt;br /&gt;  Form2: TForm2 = nil;&lt;br /&gt;&lt;br /&gt;class function TForm2.NewInstance: TObject;&lt;br /&gt;begin&lt;br /&gt;  // don't call inherited if we already have an instance&lt;br /&gt;  if UseSingleTon then&lt;br /&gt;    if Assigned(Form2) then&lt;br /&gt;    begin&lt;br /&gt;      Result := Form2;&lt;br /&gt;      Exit;&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;  Result := inherited NewInstance;&lt;br /&gt;end;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UseSingleton&lt;/b&gt; is a global variable that's in there only for demonstration. You can change it or set it to true forever. &lt;br /&gt;&lt;br /&gt;You calling code is:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;procedure TForm1.Button1Click(Sender: TObject);&lt;br /&gt;var frm : Tform2;&lt;br /&gt;begin&lt;br /&gt;  frm := Tform2.Create( self );&lt;br /&gt;  frm.Show;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Will this work? Actually, No. It's more than just that. There are two things you want to avoid:&lt;br /&gt;&lt;br /&gt;a) Having the base class constructor (&lt;b&gt;TForm.Create&lt;/b&gt;) run on every subsequent call to TForm2.Create. It should run just once!&lt;br /&gt;b) Even the FormCreate call should run only once. &lt;br /&gt;&lt;br /&gt;This isn't very difficult, just needs a little more searching. Here's what I did:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;procedure TForm2.AfterConstruction;&lt;br /&gt;begin&lt;br /&gt;  if UseSingleTon and Assigned(Form2) then Exit;&lt;br /&gt;  inherited;&lt;br /&gt;  Form2 := Self;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;constructor TForm2.Create(AOwner: TComponent);&lt;br /&gt;begin&lt;br /&gt;  if UseSingleTon and  Assigned(Form2) then Exit;&lt;br /&gt;  inherited;&lt;br /&gt;end;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Simply put, I'm avoiding calling the base constructors or construction based functions if the object is alive.&lt;br /&gt;&lt;br /&gt;Next, we have to ensure that destruction is all right too - since we're going to use .Create to create the instance, we'll expect to use .Free to free it. A singleton should only be freed when the program shuts down, probably in a .Free that you have set up in a &lt;b&gt;finalization&lt;/b&gt; section. For this I have included some "reference counting" in the code. But I'm way too lazy to type it all. So, &lt;a href="http://www.agnisoft.com/downloads/singleton.zip"&gt;download the code&lt;/a&gt; and check it out. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108729562328720739?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108729562328720739/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108729562328720739' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108729562328720739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108729562328720739'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/singletons-and-more.html' title='Singletons and more...'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108728984966271342</id><published>2004-06-15T01:52:00.000-07:00</published><updated>2004-06-15T01:57:29.663-07:00</updated><title type='text'>Web App Debugger</title><content type='html'>A paper I'd written for Borcon 2002 is finally ready on &lt;a href="http://www.agnisoft.com"&gt;my company's web site&lt;/a&gt;. It's about how to use the Web App Debugger in Delphi. Read more at &lt;a href="http://www.agnisoft.com/white_papers/wad/default.asp"&gt;http://www.agnisoft.com/white_papers/wad/default.asp&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;(And I finally updated the phone numbers on the Contact page)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108728984966271342?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108728984966271342/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108728984966271342' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108728984966271342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108728984966271342'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/web-app-debugger.html' title='Web App Debugger'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108687078258864984</id><published>2004-06-10T05:28:00.000-07:00</published><updated>2004-06-10T05:34:02.950-07:00</updated><title type='text'>Search for Delphi files in Windows Explorer</title><content type='html'>I just read &lt;a href="http://homepages.borland.com/strefethen/"&gt;Steve Trefethen's&lt;/a&gt; page. Awesome site - Steve has some really cool stuff here! Check out his &lt;a href="http://homepages.borland.com/strefethen/index.php?pagename=Main.TipsPage"&gt;Tips and Tricks&lt;/a&gt; section where he tells you how you can use Windows Explorer to search .PAS files. And .DFM files, I guess. Thanks for that, Steve!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108687078258864984?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108687078258864984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108687078258864984' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108687078258864984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108687078258864984'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/search-for-delphi-files-in-windows.html' title='Search for Delphi files in Windows Explorer'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108687030580636682</id><published>2004-06-10T04:52:00.000-07:00</published><updated>2004-06-10T05:25:27.636-07:00</updated><title type='text'>PInvoke and Delphi</title><content type='html'>&lt;a href="http://blogs.msdn.com/adam_nathan/"&gt;Adam Nathan&lt;/a&gt; has written a &lt;a href="http://www.pinvoke.net"&gt;PInvoke.Net Webservice&lt;/a&gt; - a webservice that gives you C# and VB PInvoke definitions for Win32 functions. Actually, for any DLL function that you used to access in Win32. Obviously "Header conversion" is a painful job, and we've all seen that in Delphi. &lt;br /&gt;&lt;br /&gt;I think this is a wonderful idea. A community maintained Wiki that contains definitions of the functions you might need, and you can add your own. I just hope no one abuses this system.&lt;br /&gt;&lt;br /&gt;There's still one tiny little problem. Since C# is so ubiquitous in the .NET world, there were way too many functions with just C# definitions, not even VB. And ZERO in Delphi, though the site is fairly language agnostic. Now this gets me thinking: &lt;a href="http://bdn.borland.com/soapbox/behindthescreen/"&gt;John Kaster&lt;/a&gt; has written the &lt;a href="http://dotnet.borland.com/babelcode/"&gt;BabelCode&lt;/a&gt; webservice using &lt;a href="http://homepages.borland.com/cdunn/blog/"&gt;Corbin's&lt;/a&gt; CodeDOM engine (I guess :) ). This converts C# code to Delphi (for .NET). And it's also a webservice serving SOAP requests.&lt;br /&gt;&lt;br /&gt;My next thought was: make an application that calls the PInvoke.net webservice, takes the C# code from there, calls the BabelCode webservice and voila, we have the equivalent Delphi PInvoke declaration. (Note: Do not try this at home) Being me, I couldn't resist this - and being me, I had to write it in Delphi 7. It's all done and all that - available at &lt;a href="http://www.agnisoft.com/downloads/pbroker.zip"&gt;http://www.agnisoft.com/downloads/pbroker.zip&lt;/a&gt;. Check it out, tell me what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108687030580636682?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108687030580636682/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108687030580636682' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108687030580636682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108687030580636682'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/pinvoke-and-delphi.html' title='PInvoke and Delphi'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108680355371568250</id><published>2004-06-09T10:44:00.000-07:00</published><updated>2004-06-09T10:52:33.716-07:00</updated><title type='text'>Virtual PC and Windows ME</title><content type='html'>I tried to install Windows ME on VPC 2004 today - Virtual PC, btw, is an awesome tool by Microsoft, giving you a virtual machine on which you can install other operating systems. So, on Windows XP, You can set up multiple VMs running other versions of Windows. Being short of test systems, I tried installing WinME from my MSDN CD, on my XP pro. The CD wasn't bootable! &lt;br /&gt;&lt;br /&gt;So the only way out was to try and find a DOS boot disk somehow and let Virtual PC boot into DOS, and then install WinME. But how the heck do I get a boot disk? I haven't used a floppy disk for ages! I found out that VPC allows you to "capture" a floppy disk image from a VFD file, and even boot from it. Good. Now a quick google search gave me &lt;a href="http://roudybob.net/category/21.aspx"&gt;this amazing blog&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;You can download the &lt;a href="http://www.roudybob.net/downloads/winmeboot.zip"&gt;Windows ME boot disk directly&lt;/a&gt;. Or, choose the boot disks for &lt;a href="http://www.roudybob.net/downloads/windowsxppro.zip"&gt;Windows XP Professional&lt;/a&gt;, &lt;a href="http://www.roudybob.net/downloads/win98seboot.zip"&gt;Windows 98 SE&lt;/a&gt;, or any of the others mentioned. &lt;br /&gt;&lt;br /&gt;&lt;i&gt;I'm just putting this in my blog for reference...&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108680355371568250?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108680355371568250/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108680355371568250' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108680355371568250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108680355371568250'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/virtual-pc-and-windows-me.html' title='Virtual PC and Windows ME'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108669520697570034</id><published>2004-06-08T04:38:00.000-07:00</published><updated>2004-06-08T05:05:13.053-07:00</updated><title type='text'>Instances and Interfaces</title><content type='html'>I found &lt;a href="http://groups.google.co.in/groups?hl=en&amp;lr=&amp;ie=UTF-8&amp;threadm=3c878959_1%40dnews&amp;rnum=1&amp;prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DUTF-8%26selm%3D3c878959_1%2540dnews"&gt;this thread&lt;/a&gt; - and therefore a very interesting piece of code. It gets you the "implementing object" from an interface pointer. Here's the function (all credit to &lt;a href="http://hallvards.blogspot.com/"&gt;Hallvard&lt;/a&gt; here):&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;function GetImplementingObject(const I: IInterface): TObject;&lt;br /&gt;const&lt;br /&gt;  AddByte = $04244483; // opcode : ADD DWORD PTR [ESP+4], &lt;br /&gt;                       //          Shortint&lt;br /&gt;  AddLong = $04244481; // opcode : ADD DWORD PTR [ESP+4], &lt;br /&gt;                       //          Longint&lt;br /&gt;type&lt;br /&gt;  PAdjustSelfThunk = ^TAdjustSelfThunk;&lt;br /&gt;  TAdjustSelfThunk = packed record&lt;br /&gt;    case AddInstruction: longint of&lt;br /&gt;      AddByte : (AdjustmentByte: shortint);&lt;br /&gt;      AddLong : (AdjustmentLong: longint);&lt;br /&gt;  end;&lt;br /&gt;  PInterfaceMT = ^TInterfaceMT;&lt;br /&gt;  TInterfaceMT = packed record&lt;br /&gt;    QueryInterfaceThunk: PAdjustSelfThunk;&lt;br /&gt;  end;&lt;br /&gt;  TInterfaceRef = ^PInterfaceMT;&lt;br /&gt;var&lt;br /&gt;  QueryInterfaceThunk: PAdjustSelfThunk;&lt;br /&gt;begin&lt;br /&gt;  Result := Pointer(I);&lt;br /&gt;  if Assigned(Result) then&lt;br /&gt;    try&lt;br /&gt;      QueryInterfaceThunk := &lt;br /&gt;           TInterfaceRef(I)^.QueryInterfaceThunk;&lt;br /&gt;      case QueryInterfaceThunk.AddInstruction of&lt;br /&gt;        AddByte: Inc(PChar(Result), &lt;br /&gt;                    QueryInterfaceThunk.AdjustmentByte);&lt;br /&gt;        AddLong: Inc(PChar(Result), &lt;br /&gt;                    QueryInterfaceThunk.AdjustmentLong);&lt;br /&gt;        else     Result := nil;&lt;br /&gt;      end;&lt;br /&gt;    except&lt;br /&gt;      Result := nil;&lt;br /&gt;    end;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The idea here is that if you have code like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt; &lt;pre&gt;&lt;br /&gt;  IMyInterface = interface&lt;br /&gt;  [SOMEGUID]&lt;br /&gt;    procedure DoSomething;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TMyClass = class( TInterfacedObject, IMyInterface)&lt;br /&gt;  protected&lt;br /&gt;    procedure DoSomething;&lt;br /&gt;  public    &lt;br /&gt;    //note: This proc is not in interface&lt;br /&gt;    procedure DoSomethingElse; &lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;var &lt;br /&gt;  MyInterface: IMyInterface;&lt;br /&gt;  MyClass : TMyClass;&lt;br /&gt;begin&lt;br /&gt;  MyInterface := TMyClass.Create;&lt;br /&gt;  MyInterface.DoSomething;&lt;br /&gt;&lt;br /&gt;  &lt;b&gt;// This will not work&lt;/b&gt;&lt;br /&gt;  TMyClass(MyInterface).DoSomethingElse; // crash boom bang!&lt;br /&gt;&lt;br /&gt;  &lt;b&gt;// This is slightly better&lt;/b&gt;&lt;br /&gt;  MyClass := TMyClass(GetImplementingObject(MyInterface));&lt;br /&gt;  MyClass.DoSomethingElse;&lt;br /&gt;end;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now this may or may not work in future versions of Delphi, but this is the only option if you can't modify the code of the interface or the implementation. If you can, here's a better option:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;br /&gt;  IMyInterface = interface&lt;br /&gt;  [SOMEGUID]&lt;br /&gt;    procedure DoSomething;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TMyClass = class;&lt;br /&gt;&lt;br /&gt;  IMyClassAccess = interface&lt;br /&gt;  [SOMEGUID2]&lt;br /&gt;    function GetMyClass : TMyClass;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TMyClass = class( TInterfacedObject, IMyInterface, &lt;br /&gt;                    IMyClassAccess)&lt;br /&gt;  protected&lt;br /&gt;    procedure DoSomething;&lt;br /&gt;    function GetMyClass : TMyClass ; // Result := Self;&lt;br /&gt;  public    &lt;br /&gt;    // note: This proc is not in interface&lt;br /&gt;    procedure DoSomethingElse; &lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;var &lt;br /&gt;  MyInterface: IMyInterface;&lt;br /&gt;  MyClass : TMyClass;&lt;br /&gt;  obj : IMyClassAccess;&lt;br /&gt;begin&lt;br /&gt;  MyInterface := TMyClass.Create;&lt;br /&gt;  MyInterface.DoSomething;&lt;br /&gt;&lt;br /&gt;  &lt;b&gt;// This is slightly better&lt;/b&gt;&lt;br /&gt;  MyInterface.QueryInterface( SOMEGUID2, Obj);&lt;br /&gt;  MyClass := Obj.GetMyClass;&lt;br /&gt;  MyClass.DoSomethingElse;&lt;br /&gt;end;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Better option, but requires you to modify the implementation class. All thanks to Hallvard...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108669520697570034?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108669520697570034/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108669520697570034' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108669520697570034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108669520697570034'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/instances-and-interfaces.html' title='Instances and Interfaces'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108668610500463141</id><published>2004-06-08T02:14:00.000-07:00</published><updated>2004-06-08T02:15:05.006-07:00</updated><title type='text'>No longer an unknown blog</title><content type='html'>&lt;a href="http://homepages.borland.com/aohlsson/blog_beta/"&gt;Anders&lt;/a&gt; found me! :) (Thanks Anders!)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108668610500463141?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108668610500463141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108668610500463141' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108668610500463141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108668610500463141'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/no-longer-unknown-blog.html' title='No longer an unknown blog'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108661136655734150</id><published>2004-06-07T01:03:00.000-07:00</published><updated>2004-06-07T22:36:31.080-07:00</updated><title type='text'>Delegation, Active Directory and WMI</title><content type='html'>&lt;i&gt;Note: Do not start "researching" anything on Friday afternoon. &lt;/i&gt; &lt;br /&gt;&lt;br /&gt;I can explain. I have this project where I'm on Computer A, and I need to run an executable on Computer B. (This executable is one of them command line utilities with no UI) The problem really is that this little executable is on Computer C...and A, B and C are all on my little network here. &lt;br /&gt;&lt;br /&gt;Since everyone was running Windows 2000, I assumed we could use WMI to connect from A to B as an Administrative user. Then, I could run this executable from C by creating a "Win32_process" on B (with &lt;b&gt;\\C\something.exe&lt;/b&gt; as the executable filename) Not that simple, it turned out.&lt;br /&gt;&lt;br /&gt;The problem is that when you run code on Computer A which connects to Computer B using WMI, you need to pass a set of credentials, usually a domain admin username/password. When you request B to access a third computer (C),   the code runs in the context of the "LocalSystem" user in B, &lt;b&gt;NOT&lt;/b&gt; the username/password you supplied! And LocalSystem, by default, does not get access to network resources. &lt;br /&gt;&lt;br /&gt;So what do you do? One of two things:&lt;br /&gt;1) &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/connecting_to_a_3rd_computer-delegation.asp"&gt;This URL&lt;/a&gt; explains the architecture of &lt;b&gt;Delegation&lt;/b&gt;. Basically you allow Computer B, a domain computer, access to all network resources. The caveats? Computer B needs to be in the same domain, and needs to be registered in Active Directory. Also, your friendly neighbourhood Network Administrator is going to kill you.&lt;br /&gt;&lt;br /&gt;2) You can "copy" the executable file to the remote computer and then execute it. (the LocalSystem has access to Local System resources. "Duh" - Ed.) I found &lt;a href="http://support.microsoft.com/?id=827227"&gt;another URL&lt;/a&gt; at Microsoft that shows you how to do all of this. Concept? Map a drive, z:,  on to the remote computer (B) with the domain admin username/password, and then use the &lt;b&gt;CopyFile&lt;/b&gt; function to copy from "\\C\somefolder\myexe.exe" to "z:\temp\myexe.exe", for example. You might wonder, what if nothing's shared on the remote computer - well, there's always an "ADMIN$" share or "C$" share that you can use. Or so I think.&lt;br /&gt;&lt;br /&gt;Coming back to the note above. I had to stay late figuring all of this out, because I hate coming in on Saturdays. So, once again, DO NOT start something new, at work, on Friday afternoon.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108661136655734150?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108661136655734150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108661136655734150' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108661136655734150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108661136655734150'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/delegation-active-directory-and-wmi.html' title='Delegation, Active Directory and WMI'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7205444.post-108633312117310630</id><published>2004-06-04T00:09:00.000-07:00</published><updated>2004-06-04T01:07:58.406-07:00</updated><title type='text'>The SOAP Insanity: "expecting text/xml, received text/html"</title><content type='html'>Welcome to my new blog! Here's where I'll write about my experiences with Programming.&lt;br /&gt;&lt;br /&gt;First, the most often asked question about Delphi SOAP: What's the "expecting text/xml, received text/html" error?&lt;br /&gt;&lt;br /&gt;The Delphi Web Service wizard, when generating the code for an ISAPI application, generates this code in the .dpr file:&lt;br /&gt;&lt;br /&gt;&lt;font face="courier new"&gt;uses&lt;br /&gt;  ActiveX,&lt;br /&gt;  ComObj,&lt;br /&gt;  WebBroker,&lt;br /&gt;  ISAPIThreadPool,&lt;br /&gt;  ISAPIApp,&lt;br /&gt;  Unit1 in 'Unit1.pas' {WebModule1: TWebModule};&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;You need to &lt;b&gt;Interchange&lt;/b&gt; the positions of &lt;b&gt;ISAPIThreadPool&lt;/b&gt; and &lt;b&gt;ISAPIApp&lt;/b&gt; in the .dpr file. The reason is that the initialization section of the ISAPIThreadPool unit needs to run &lt;b&gt;after&lt;/b&gt; the ISAPIApp unit's initialization section, so the thread pool is initialized properly. &lt;br /&gt;&lt;br /&gt;You &lt;b&gt;don't&lt;/b&gt; need to do anything for CGI, Apache DSO or Web App Debugger executables. This fix is specific to Delphi 7 generated ISAPI SOAP applications.&lt;br /&gt;&lt;br /&gt;Note: The Delphi 6 Thread Pool unit does nothing. Throw it away.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7205444-108633312117310630?l=shenoyatwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenoyatwork.blogspot.com/feeds/108633312117310630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7205444&amp;postID=108633312117310630' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108633312117310630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7205444/posts/default/108633312117310630'/><link rel='alternate' type='text/html' href='http://shenoyatwork.blogspot.com/2004/06/soap-insanity-expecting-textxml.html' title='The SOAP Insanity: &quot;expecting text/xml, received text/html&quot;'/><author><name>Deepak Shenoy</name><uri>http://www.blogger.com/profile/04209677935830502120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.deepakshenoy.com/gallery/albums/chik/normal_DSC01465.JPG'/></author><thr:total>1</thr:total></entry></feed>
