Thoughts from Dan Miser RSS 2.0
 Friday, September 24, 2004
I'm a little partial to Borland DB technologies, and especially BDP. ;-) However, I think this demo shows some of the power that BDP has in the upcoming version of Delphi. Check out the BDNtv episode presented by Jason Vokes and see what you think.

I saw many other properties and methods in this demo that weren't touched on. All in all, BDP looks incredibly flexible in Diamondback - especially when either doing multi-tier apps, or using data from heterogenous sources.

Friday, September 24, 2004 8:51:00 AM (Central Standard Time, UTC-06:00)  #    Comments [1] -
Delphi
 Thursday, September 23, 2004
By default, COM Servers register themselves in HKEY_CLASSES_ROOT (HKCR). The actual registry entries will get written to HKEY_LOCAL_MACHINE (HKLM) in most cases. HKCR is an alias to HKEY_LOCAL_MACHINE in older versions of Windows, but starting in Windows 2000 and later, HKCR is a merged view of HKLM and HKEY_CURRENT_USER (HKCU). I needed a way to register my COM server into HKCU so that locked down machines that don't have access to HKLM could still run properly. For some background information on HKCR, check out MSDN.

I came across the function RegOverridePredefKey, and it looked like it would do the job by allowing me to hook into a root HKEY and write to a completely different HKEY. So I started looking in the Delphi source code, and noticed that this function was not imported. The following code snippet shows the procedure that I ended up writing to have anything written to HKCR be written to HKCU instead.


function RegOverridePredefKey(hKey: HKEY; hNewKey: HKEY): Longint; stdcall; 
  external advapi32 name 'RegOverridePredefKey';

procedure OverrideRegistryKey(Register: boolean);
var
  HKCU: HKEY;
  ret: integer;
begin
  if Register then
  begin
    RegOpenKeyEx(HKEY_CURRENT_USER, 'Software\Classes', 0, HEY_ALL_ACCESS, HKCU);
    try
      ret := RegOverridePredefKey(HKEY_CLASSES_ROOT, HKCU);
      if ret <> ERROR_SUCCESS  then
        ShowMessage('Error overriding HKCU:' + #13#10 + SysErrorMessage(ret));
    finally
      RegCloseKey(HKCU);
    end;
  end
  else
    RegOverridePredefKey(HKEY_CLASSES_ROOT, 0);
end;
So that left me with the question "Where do I call this?". My first thought was to hook into the UpdateRegistry method and call my OverrideRegistry procedure there. Unfortunately, by the time UpdateRegistry is called in my Remote DataModule (RDM), several other registration calls have already finished. This left me with some things in HKLM and some in HKCU. Then I remembered that the COM registration occurs when Application.Initialize is called in the dpr file. The following is the code I use in my dpr to write to the right place in the registry.

  OverrideRegistryKey(true);
  try
    Application.Initialize;
  finally
    OverrideRegistryKey(false);
  end;
After doing this, I checked in regedit and verified that everything was registered in HKCU, and it was there. Since HKCR shows the merge of HKLM and HKCU, it was also present in HKCR. This means that COM calls will find the app server. Running a quick test showed me that everything worked as I expected.

In my production code, I'll also put in a quick check to make sure that we're running on Windows 2000 or greater. Since we run both as a Server and a Service, I'll put this code in a conditional define, since there is no concept of HKCU in a service.

Note: I also failed to find the header for RegOpenUserClassesRoot in Delphi. If you find that you need this function, you'll need to import the function yourself.

Thursday, September 23, 2004 3:48:00 PM (Central Standard Time, UTC-06:00)  #    Comments [0] -
Delphi
 Thursday, September 16, 2004
Joe White took some notes on NDataStore. I will be keeping a very, very close eye on this DB. I have used JDataStore in past lives, and it was an extreme pleasure to use it. Steve Shaugnessy really knows how to eek performance out of a DBMS.
Thursday, September 16, 2004 9:30:00 AM (Central Standard Time, UTC-06:00)  #    Comments [3] -
ADO.NET
 Wednesday, September 15, 2004
Take a look at this sneak peek of DiamondBack presented by John Kaster. Major things I noticed just in this 14 minute demo were:
  • Language bundling announement (C#, Delphi, Win32)
  • for..in syntax (similar to C# foreach syntax)
  • A new start page (to replace DelphiDirect, most likely)
  • Refactoring support (available in all languages)
  • Error Insight
  • Help Insight
  • History view (including smart diff engine. Similar to JBuilder's feature of the same name - very nice)
  • Tight StarTeam integration
  • Free floating form designer (a la Delphi 7 and below)
  • Delphi Win32 was enhanced to support many extensions created in Delphi .NET
Wow!! It seems pretty full-featured, and I didn't even see all of the features first-hand at BorCon. I can't wait to get my hands on it. Well done, John and Borland.
Wednesday, September 15, 2004 1:05:00 PM (Central Standard Time, UTC-06:00)  #    Comments [1] -
Delphi
 Tuesday, September 14, 2004
Yup, it's time to talk about ActiveForms again. :-)

If you're using ActiveForms, then you need to know about an ugly little secret. If you use MyDelphiForm.ActiveControl := Edit1, then you will get an exception stating 'Cannot focus a disabled or invisible window'. The reason for this is due to the implementation of TCustomForm.SetActiveControl. This setter method is called when you try to set ActiveControl on a form. The first thing it does is this:


    if not ((Control = nil) or (Control <> Self) and
      (GetParentForm(Control) = Self) and ((csLoading in ComponentState) or
        Control.CanFocus)) then
      raise EInvalidOperation.Create(SCannotFocus);
Note the part where it is trying to assert that the root ParentForm for the Control you are trying to set focus to is the same as the current form. This works fine in regular windows applications, but unfortunately in ActiveForms, the root ParentForm is the actual ActiveForm. Most people use that form as nothing more than a container to then host their forms inside. I wrote about this technique in a previous Delphi Informant, and it has been posted plenty of places on the Internet as well (e.g. Conrad Hermann had the first mention of this that I can remember).

The workaround is to use code like this to set the ActiveControl:


var
  ParentForm: TCustomForm;
begin
  ParentForm := GetParentForm(Self);
  ParentForm.ActiveControl := Edit1;
Tuesday, September 14, 2004 9:37:00 AM (Central Standard Time, UTC-06:00)  #    Comments [1] -
Delphi
 Thursday, September 09, 2004
An ActiveForm will not receive a WM_ACTIVATE message when initializting since WM_ACTIVATE only goes to the top level windows, or in this case, the IE browser window. By sending our own WM_ACTIVATE, we get initial focus set to the ActiveForm, but more importantly, the WMActivate method in TCustomForm calls TCustomForm.SetActive. This in turn, sets the Active property which means that the form has focus. This is important later on, e.g. in TCustomForm.SetActiveControl, the focus will never be set to the ActiveControl.

For example, the code below will do nothing in the default case. It will work fine after you apply the work-around mentioned later on.


var
  ParentForm: TCustomForm;
begin
  ParentForm := GetParentForm(Self);
  ParentForm.ActiveControl := Edit1;
end;

The bad behavior is also apparent when using TPageControl, since TPageControl.ChangeActivePage tries to set the ActiveControl when changing pages.

The simple work-around for this is to call the following in your ActiveForm code: PostMessage(Handle, WM_ACTIVATE, WA_ACTIVE, 0);

Since I use PARAM tags in my OBJECT tag to pass parameters, I am doing this in IPersistPropertyBagLoad method after creating my Delphi form. After doing this, everything is working great.

Thanks to Steve Trefethen for listening to my original vent. :-)

Thursday, September 09, 2004 9:01:00 AM (Central Standard Time, UTC-06:00)  #    Comments [1] -
Delphi
 Tuesday, September 07, 2004
There. I said it. I feel better now. I did some digging on how to remove it from my XP system and came up with a couple of links:
Microsoft's sanctioned approach
Unofficial removal

I used the second method since I recall using it before on my machine (before my latest rebuild).

So what do I use for an IM client? Right now, I use Trillian. I like the fact that it has multi-protocol support. Everyone always thinks their IM client is best. Who am I to argue? I'd rather be neutral and still be able to chat with people without having 4 different IMs installed.

Postscript: I also looked at GAIM a while back. It was OK. Maybe it's gotten better over the past year or so, but I still came back to Trillian.

Tuesday, September 07, 2004 10:35:00 AM (Central Standard Time, UTC-06:00)  #    Comments [6] -

 Friday, August 06, 2004
Whiteboard with Anders Hejlsberg is a must-watch video from an informal presentation he gave at TechEd 2004. The conciseness, clarity and depth of knowledge is impressive. He covers a range of topics and talks about design decisions that were made to help us understand why something is or isn't part of C#. All I can say is I want to be like Anders when I grow up. Hmmm. Probably too late. :)
Friday, August 06, 2004 9:16:00 AM (Central Standard Time, UTC-06:00)  #    Comments [1] -
.NET
Navigation
Archive
<September 2004>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Dan Miser
Sign In
Statistics
Total Posts: 306
This Year: 21
This Month: 0
This Week: 0
Comments: 604
All Content © 2008, Dan Miser
DasBlog theme 'Business' created by Christoph De Baene (delarou)