Thoughts from Dan Miser RSS 2.0
# Thursday, March 10, 2005
Jeremy North just released version 2 of his Delphi Configuration Manager (DCM). It's a tool that helps you optimize your Delphi IDE by creating profiles that load specific packages. So, if you have one client that uses one set of packages, and another that uses a different set, you can set up 2 different profiles and only load the packages that you need depending on which client you're working on currently. The main feature that I like in this version is that run-time packages are also available to be controlled in a profile. Give it a look. Very well done.
Thursday, March 10, 2005 9:51:00 AM (Central Standard Time, UTC-06:00)  #    Comments [0] -
Delphi
# Tuesday, March 08, 2005
Google Desktop Search has made it's way out of beta and is now a released product. It looks like it has become way more flexible, too. The biggest complaint I had was the lack of file extension support, which was sort of tied to the fact that there was no SDK. They re-architected this area, and now have support for plugins (including, a Trillian plugin) and allow developers to create plugins via the SDK. More information on developing plugins can be found here. They also expanded the default set of files that are indexed to include (among others) MP3 and PDF files. I also really love the DeskBar to gain easy access to searches.

My buddy, Rich Werning, and I were talking about some possible plugins that we may develop after we convert the SDK files to Delphi:

  • ZIP plugin - Scan through ZIP files to find items inside a ZIP
  • Blog/FeedDemon plugin - Search your locally downloaded blog entries, and have it take you to the original author's page when an item is found
  • Database plugin - Not entirely certain on this one, but if you provided a full connection string, maybe you could search a DB schema for fields/tables/etc. Or maybe even search a table for specific text.

I'll certainly blog anything we do on this front.

Tuesday, March 08, 2005 8:48:00 PM (Central Standard Time, UTC-06:00)  #    Comments [0] -
Delphi
Kostas Terzides has started playing with DataSnap recently. He contacted me to add his his DataSnap components to MidEss. I'm hoping his addition to the project will energize it once again. Thanks for volunteering, and welcome!
Tuesday, March 08, 2005 9:44:00 AM (Central Standard Time, UTC-06:00)  #    Comments [0] -
DataSnap
# Monday, March 07, 2005
I needed to create a custom TField class to handle some special processing recently. It was surprisingly easy to get this working:
1. First, create a descendant TField class and put it in a run-time package.

type
  TDrmBCDField = class(TBCDField)
    //override whatever methods you need here
  end;

2. Next, create a registration unit and place that in a design-time package. This unit has nothing more than this:

unit uDrmBCDFieldReg;

interface

procedure Register;

implementation

uses
  uDrmBCDField,
  DB;

procedure Register;
begin
  RegisterFields([TDrmBCDField, TDrmFMTBCDField]);
end;

end.

After compiling these packages, you can now get the new custom TField type to display when selecting "New Field..." in the Dataset designer. However, this doesn't address places where you don't use persistent fields, and it doesn't address the (IMO) more commonly used "Add Fields..." or "Add All Fields" context menu items. In order to always use your new custom class, you need to add code like this to your run-time package. By doing this, both the Delphi IDE and your code at run-time will pick up the proper field class type. I had to use code like this because Delphi 6 doesn't have assignable const permissions in the DB.pas unit.


var
  FieldClass: ^TFieldClass = nil;
initialization
  FieldClass := @DefaultFieldClasses[ftBCD];
  FieldClass^ := TTIPBCDField;
finalization
  if Assigned(FieldClass) then
    FieldClass^ := TBCDField;
end.

Notes:

  • There is a bug in Delphi 6 that causes occasional AVs when rebuilding packages that use RegisterFields. According to this Google post by Vitaliy Lyanchevskiy, you can use RegisterClasses during design and development to get around this problem.
  • Instead of DefaultFieldClasses, you can override TDataset.GetFieldClass if you want specific field types to be used at a TDataset-level.
Monday, March 07, 2005 4:48:00 PM (Central Standard Time, UTC-06:00)  #    Comments [0] -
Delphi
# Saturday, March 05, 2005
I went to the Deeper in .NET training session today. It was a free event put on by the Wisconsin .NET User Group. The lineup of speakers was sensational: Scott Guthrie, Rob Howard, Rocky Lhotka, Jason Beres, and Chris Mayo. No offense to the other speakers, but I went solely to hear Rocky speak. He wrote the book Expert C# Business Objects, and it is a very well-done book. If you're doing .NET, you should definitely pick up a copy and maybe even read it. ;-) (Thanks for the pointer to this book, Mark!)

Rocky did not disappoint the packed crowd, and delivered an exceptional talk about Distributed Application Architecture in .NET. His main focus seemed to stem from one of his more recent blog entries where he advocates sensible (and sparring) use of tiers, but heavy reliance on layers. It was a very entertaining and well-reasoned talk. Ah, but who knows, maybe I just think this because I've been advocating the same idea for many years. :-)

Saturday, March 05, 2005 4:47:00 PM (Central Standard Time, UTC-06:00)  #    Comments [1] -
.NET
# Friday, March 04, 2005
March 5, 2004 was the date of my first blog post. While I'm certainly not even in the same category as the blogosphere bigwigs (like Robert Scoble), I've found this medium to be very effective. I typically blog about things that I'd want to read about, and I tend to stay more technical. I find myself going back to my previous posts on occasion, and I like that I have an easy way to reference topics I've covered when people contact me about those topics. All in all, I think I'll continue this exercise for another year and see what things look like then. :-)

Thanks for reading.

Friday, March 04, 2005 11:27:00 AM (Central Standard Time, UTC-06:00)  #    Comments [0] -

# Thursday, March 03, 2005
For those of you who use ActiveForms, you may have applied my technique to solve the problem when the ActiveX ActiveForm is not activated. Unfortunately, this one line of code gives us a new problem losing focus. For example, say you have focus on a button, and that button calls ShowMessage. If you did a PostMessage(WM_ACTIVATE), then you'll notice that the focus is lost after returning from the ShowMessage call. More precisely, the currently focused control at this point is the Shell DocObject View window used within IE. From this point on, pressing TAB will not take you from control to control within your ActiveForm. You can use the mouse to set focus, but that's sub-optimal.

To solve this, the easiest thing I found was to use the OnFrameWindowActivate and OnDocWindowActivate methods of the IOleInPlaceActiveObject interface. I posted another article about how to use a custom TActiveXControlClass, and that code already uses a method from IOleInPlaceActiveObject. This means that all we need to do is add these 2 methods to that existing class and implement them. The code looks like this:


type
  TTranslateAcceleratorFormControl = class(TActiveFormControl, IOleInPlaceActiveObject)
  private
    FActiveHWND: HWND;
    procedure HandleActiveHWND(Activate: boolean);
  protected
    function TranslateAccelerator(var msg: TMsg): HResult; stdcall;
    function OnFrameWindowActivate(fActivate: BOOL): HResult; stdcall;
    function OnDocWindowActivate(fActivate: BOOL): HResult; stdcall;
  end;


procedure TTranslateAcceleratorFormControl.HandleActiveHWND(Activate: boolean);
begin
  if Activate then
  begin
    if FActiveHWND <> 0 then
      SetFocus(FActiveHWND);
  end
  else
    FActiveHWND := GetFocus;
end;

function TTranslateAcceleratorFormControl.OnDocWindowActivate(fActivate: BOOL): HResult;
begin
  Result := inherited OnDocWindowActivate(fActivate);
  HandleActiveHWND(fActivate);
end;

function TTranslateAcceleratorFormControl.OnFrameWindowActivate(fActivate: BOOL): HResult;
begin
  Result := inherited OnFrameWindowActivate(fActivate);
  HandleActiveHWND(fActivate);
end;

function TTranslateAcceleratorFormControl.TranslateAccelerator(var msg: TMsg): HResult;
begin
  Result := inherited TranslateAccelerator(msg);

  if Result = S_OK then
  begin
    if (msg.message = WM_KEYDOWN) and (GetKeyState(VK_CONTROL) < 0) and (msg.wParam = 67) then
      Result := S_FALSE;
  end;
end;

If you test the ActiveForm at this point, you'll find that things work pretty well. The one remaining problem is that these methods don't fire when getting activated, so I handled that by adding another PostMessage after the PostMessage(WM_ACTIVATE) call. By doing this, we're letting the DAX framework set things up properly, and during that time, InPlaceActivate is called which finishes proper initialization. The code in the ActiveForm class looks similar to this:


type
  TMyActiveForm = class(TActiveForm, IMyActiveForm)
    procedure UMACtivate(var Message: TMessage); message UM_ACTIVATE; // const UM_ACTIVATE = WM_USER + 123;
// Other methods declared here

procedure TMyActiveForm.UMActivate(var Message: TMessage); 
begin
  (ComObject as IOleInPlaceActiveObject).OnFrameWindowActivate(true);
end;

Be sure to call

PostMessage(Handle, UM_ACTIVATE, 0, 0);
after your existing PostMessage call to WM_ACTIVATE.

Let me know if you run into any problems with this approach.

Thursday, March 03, 2005 1:19:00 PM (Central Standard Time, UTC-06:00)  #    Comments [1] -

# Friday, February 25, 2005
We currently use Multilizer in our product. However, we really don't use all of the features. It's use is pretty confined to "dynamically display messages" and "translate captions/labels on forms". Using Delphi 6 with Multilizer 5, things work fairly well.

We are also preparing the switch to Delphi 2005 in the next couple weeks. After contacting Multilizer, it turns out that there is no support for Multilizer 5 with Delphi 2005, and as a result, we would be required to spend many thousands of dollars to upgrade to Multilizer 6. That isn't a very attractive option. As of this writing, Multilizer will be thrown out of here, never to return. I'm investigating using Delphi's built-in Integrated Translation Environment (ITE) at the moment. I remember there were all sorts of problems with ITE early on (like in the Delphi 3/4 days). I'm hoping enough work has been done in this area to make it usable for our fairly simple needs. If not, we're writing our own tools to do this.

I believe component vendors should provide version compatible releases for newer versions of Delphi. Most component vendors actually do this quite well. I also believe that when companies try to force you into spending thousands of dollars, you should look to replace them immediately.

Friday, February 25, 2005 11:28:00 AM (Central Standard Time, UTC-06:00)  #    Comments [8] -
Delphi
Navigation
Archive
<March 2005>
SunMonTueWedThuFriSat
272812345
6789101112
13141516171819
20212223242526
272829303112
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 2013
Dan Miser
Sign In
Statistics
Total Posts: 391
This Year: 2
This Month: 2
This Week: 0
Comments: 674
Themes
Pick a theme:
All Content © 2013, Dan Miser
DasBlog theme 'Business' created by Christoph De Baene (delarou)