Powered by discountASP.NET
referal ID: sdtref
Why recommend discountASP.NET?

Archives
Steve Trefethen Steve's RSS Feed Subscribe or via email
What's this?
Contact me Send mail to the author(s)
About Me
View my LinkedIn profile

Add to Google
Subscribe with Bloglines
MCP Microsoft Certified Professional

Falafel Software
ActiveFocus Project Management Solution by Falafel Software
Online or OnSite TestComplete Training
Blogroll
Recent Comments
My Online Tools
Stats
Total Posts: 441
This Year: 46
This Month: 2
This Week: 0
Comments: 1526
Tags
Disclaimer
The posts on this weblog are provided �AS IS� with no warranties, and confer no rights. The opinions expressed herein are my own personal opinions and do not represent my employer�s view in any way.
 Tuesday, April 15, 2008

C# Source Code Formatting Preferences

Posted @ 1:37AM by Steve Trefethen

Categories: .NET | Opinion | Programming

Tags:  |  | 

I just tried checking in some C# code and ran into a merge error so I fired up Araxis Merge and noticed hundreds of unexpected changes all to whitespace! That was a bummer because I just wanted to check in and call it a night but alas, it’ll have to wait a day. Now, I know code formatting can be a religious issue but...

Here are a few examples, the actual code of which is unimportant for the purposes of this discussion:

1 public void foo(string locator) { 2 try { 3 if (selenium.IsElementPresent(locator)) 4 break; 5 } catch (Exception) { 6 } 7 }
and
1 public void foo(string locator) 2 { 3 try 4 { 5 if (selenium.IsElementPresent(locator)) 6 break; 7 } 8 catch (Exception) 9 { } 10 }

I’d call the latter more "mainstream" as the majority of Open Source projects I’ve looks at (including dasBlog, FileHelpers, RssToolkit, SubSonic, CCNET and SubText) all seem to align the braces with a few exceptions like the empty catch block or a single statement block. I haven’t downloaded the .NET sources yet but I’d be interested to know what Microsoft uses.

Chuck Jazdzewski, a well known 'softie publishes a good deal of C# code on his blog formatted using the top style. A few colleagues, John Waters, Falafel's CTO and Adam Andersen have both blogged using the latter style, here and here respectively.

Which do you prefer? Do you consider either more "mainstream" than the other?

[Update: April 15, 2008] Added a list of OS projects I've looked at.
 Thursday, November 01, 2007

Processing CSV files in C# using Open Source FileHelpers Library

Posted @ 1:39AM by Steve Trefethen

Categories: .NET | howto | Open Source | Programming

Tags:  |  |  | 

Scott Hanselman recently posted about parsing CSV files from PowerShell and while I found it interesting I didn’t find the solution to be intuitive though perhaps that’s just me. I’ve recently purchased PowerShell in Action by Bruce Payette and I like the idea of PowerShell though I find myself bailing back to a plain old Command Prompt quite frequently. Anyway, a few days ago I blogged about using the Open Source FileHelpers library for parsing fixed and delimited length files. I thought it might be fun to tackle Scotts problem and see just how difficult it would be to duplicate his solution in C#. Here is what he was parsing (at least a snippet of it anyway):

"File","Hits","Bandwidth"
"/hanselminutes_0026_lo.wma","78173","163625808"
"/hanselminutes_0076_robert_pickering.wma","24626","-1789110063"
"/hanselminutes_0077.wma","17204","1959963618"
"/hanselminutes_0076_robert_pickering.mp3","15796","-55874279"
"/hanselminutes_0078.wma","14832","-1241370004"
"/hanselminutes_0075.mp3","13685","-1840937989"
"/hanselminutes_0075.wma","12129","1276597408"
"/hanselminutes_0078.mp3","11058","-1186433073"

With FileHelpers the first thing to do is define a class that maps the data in your file which for Scott’s data would look something like this:

    [DelimitedRecord(",")]

    class Show

    {

        public string Filename;

        [FieldConverter(typeof(IntConverter))]

        public Int32 downloads;

        [FieldConverter(typeof(IntConverter))]

        public Int32 bandwidth;

    }

Notice the class attribute indicates the separator used. Also notice the member attributes that provide string conversion for the integer values read from the file. Since the integers, unfortunately, have quotes the stock FileHelpers converter won’t work though that’s easily solved by writing a new IntConverted like this:

    public class IntConverter : ConverterBase

    {

        public override object StringToField(string from)

        {

            if (from != "" || from != "\"\"")

                return Convert.ToInt32(from.Substring(1, from.Length - 2));

            else

                return string.Empty;

        }

    }

For parsing the file we use FileHelpers DelimitedFileEngine like this:

     DelimitedFileEngine e = new DelimitedFileEngine(typeof(Show));

     e.Options.IgnoreFirstLines = 1;

     object[] shows = e.ReadFile("c:\\shows.txt");

This creates an instance of the engine passing our Show class type with an option to ignore the first line of the file (the one with column headings). Calling ReadFile parses it into and array of Show objects populated with the data. Next, we’ll change the filename to the episode number using Scott’s regex and sort the data both using anonymous delegates:

    Regex regex = new Regex("\\d{2}(?=[_.])");

    Array.ForEach((Show[])shows, delegate(Show one)

        { one.Filename = regex.Match(one.Filename).ToString(); }

    );

    Array.Sort((Show[])shows, delegate(Show one, Show two)

        { return one.Filename.CompareTo(two.Filename); }

    );

Finally, we sum the downloads and print the data. Note this for loop modifies the array using the first instance of an episode to aggregate the total downloads, perhaps not optimal but gets the job done:

    Show sh = (Show)shows[0];

    for (int i = 1; i < shows.Length; i++)

    {

        if (((Show)shows[i]).Filename.CompareTo(sh.Filename) == 0)

            sh.downloads += ((Show)shows[i]).downloads;

        else

        {

            Console.WriteLine("{0,-4} {1,-6}", sh.Filename, sh.downloads);

            sh = ((Show)shows[i]);

        }

    }

    Console.WriteLine("{0,-4} {1,-6}", sh.Filename, sh.downloads);


So, what’s the point? Well, at the end of Scott’s post he wrote:

It took less time than it would take to write a C# program and it’s easily modified ad-hoc.

Armed with FileHelpers this took no time at all, the bulk of the code is spent working with the data not importing into a usable form. Another point is, IMO the C# code is considerably easier to read. I’m finding that getting my head around PowerShell commands to be a bit awkward. For me PowerShell is tantilizingly powerful but I feel requires a different enough mind set to perhaps thwart rapid adoption. I can empathize with all those people who have "been meaning to try..." Of course, I suppose if we all had the chance to sit down with Lee Holmes things might be different.
 Wednesday, June 13, 2007

Calling Windows Client code from Javascript hosted inside the WebBrowser control

Posted @ 6:02PM by Steve Trefethen

Categories: Programming

Tags:

Well, Allen pretty much stole the thunder on this one so I'll post this article I wrote a few days ago and try to get the code cleaned up and posted ASAP. Though I suppose now I should look to incorporate his code rather than duplicating that effort. Anyhoo...

In a previous post, I talked about using Google maps from within a Windows Client application (in this case a Delphi VCL application). I demonstrated how it's possible to call into the Javascript loaded in a hosted WebBrowser control using IHTMLWindow2::execScript method. Through this technique it's possible to manipulate a things like Google maps rendered in the browser control.

Closing the Loop
In this post, I'll discuss a technique that allows Javascript, on a page rendered in the WebBrowser control, to execute VCL application code using IDocHostUIHandler::GetExternal. If you happened to read this post from Hallvard Vassbotn, a little over a year ago, then you're already aware of the unit which is the secret behind getting this technique to work. The unit is ObjComAuto.pas. It introduces TObjectDispatch which implements IDispatch and provides the plumbing necessary to script VCL objects compiled with the directive {$METHODINFO ON} which  is used to generate extended RTTI for public and published methods.

Up's and Down's
Now, if you're familiar with the VCL you know it's not compiled with METHODINFO ON since the additional RTTI (Runtime Type Information) would dramatically increase the size of the resulting executables. As a result, we need a mechanism to map an instance of a VCL object that does not have this additional RTTI to one that does, using wrapper classes and a class map. The up-side is that we're able to control the amount of additional RTTI that's generated by providing implementations for only those things we really want. The downside of course, is that everything we want to script has to be exposed manually though as you'll see it's not that bad. Another issue is that the code for any classes added to the class map will be pulled into our application regardless of whether or there instantiated.

Base Wrapper Class
The first step is to create a base class with METHODINFO ON that's will be bound to a VCL object and implements a few key methods to get the ball rolling:

1 { TObjectWrapper } 2 3 {$METHODINFO ON} 4 TObjectWrapper = class(TObject) 5 private 6 function GetClassName: string; 7 function GetParentClass: string; 8 protected 9 FObject: TObject; 10 public 11 constructor Connect(AObject: TObject); virtual; 12 function InheritsFrom(const ClassName: string): Boolean; 13 published 14 property ParentClass: string read GetParentClass; 15 {$WARNINGS OFF} 16 property ClassName: string read GetClassName; 17 {$WARNINGS ON} 18 end; 19

From this we'll construct additional classes which mirror VCL classes like TComponentWrapper, TControlWrapper and TWinControlWrapper that expose various key properties and methods we need to build a VCL scripting framework.

A Mapper Class
Next, we construct a list that will allow us to map VCL classes to these wrapper classes which we can do with a TObjectList:

1 TObjectWrapperClass = class of TObjectWrapper; 2 3 TClassMap = class(TObjectList) 4 public 5 procedure AddClass(AClass: TClass; AObjWrapper: TObjectWrapperClass); 6 procedure RemoveClass(AClass: TClass; AObjWrapper: TObjectWrapperClass); 7 function FindObjectWrapper(AClass: TClass): TObjectWrapperClass; 8 end; 9

Using the Class Map
Then we implement a descendant of TObjectDispatch and override GetObjectDispatch, GetMethodInfo and GetPropInfo to create instances of our wrapper classes from the class map for use with automation:

1 TAutoObjectDispatch = class(TObjectDispatch) 2 protected 3 function GetObjectDispatch(Obj: TObject): TObjectDispatch; override; 4 function GetMethodInfo(const AName: ShortString; 5 var AInstance: TObject): PMethodInfoHeader; override; 6 function GetPropInfo(const AName: string; var AInstance: TObject; 7 var CompIndex: Integer): PPropInfo; override; 8 end; 9

Connecting with Javascript
Then we implement IDocHostUIHandler::GetExternal and use TAutoObjectDispatch class to create objects that can be used from Javascript:

1 function TWebBrowser.GetExternal(out ppDispatch: IDispatch): HResult; 2 var 3 W: TAppObjectWrapper; 4 begin 5 W := TAppObjectWrapper.Connect(Forms.Application); 6 ppDispatch := TAutoObjectDispatch.Create(W) as IDispatch; 7 Result := S_OK; 8 end;

Putting it all together
Once we have these pieces in place it's possible to build VCL applications that host the WebBrowser control and allow for rich interactions between the web page and the application itself. Of course, this same technique can be utilized in other ways as well though like Hallvard I'll leave that as an exercise for the reader.

 Wednesday, June 06, 2007

Using Google Maps from a Windows Client application

Posted @ 4:16PM by Steve Trefethen

Categories: Programming

Tags:

The other day I blogged about mashing up Google Maps and VCL in a Delphi Win32 application with support for bi-directional VCL-> JavaScript and JavaScript-> VCL allowing for rich interaction with the map. The first part of this "conversation" is actually very easy to accomplish. Here is what you need to do if you want to give it a try. I'll talk about this from the Delphi perspective though the same logic will work from C# or any other language that can host the Microsoft WebBrowser control.
  1. Start a new VCL application
  2. Drop a TWebBrowser control
  3. Create a Form1.OnCreate event handler
  4. Add the following line of code:
    WebBrowser1.Navigate(
      'http://www.stevetrefethen.com/files/googlemap.htm');
  5. Add a TButton to the form and an OnClick event handler and add the following code:
procedure TForm1.Button1Click(Sender: TObject); var Doc2: IHTMLDocument2; begin with WebBrowser1.Document as IHTMLDocument2 do with parentWindow do execScript('createMapMarker("31.05173494", "-122.03160858", "test")', 'JavaScript'); end;

This will create a new marker on the map in Scotts Valley, CA. In fact, you can execute any method of the Google Map object by replacing the first parameter in execScript (above) with something like this:

map.panTo(new GLatLng(37.05173492, -122.031608568));

Hopefully, you can see the possibilities this creates. To get it working on your own domain you'll need to do the following:

  1. Get yourself GMail account if you don't already have one
  2. Get a Google Maps API key you'll need a domain where you can upload files to
  3. Right click and save this file to disk
  4. Edit the file you just download and change the API to use your key (mine won't work on your domain)
  5. Change the .Navigate call to use your URL

That's it, you can now interact with Google maps from a Windows client application (VCL in this case). As you can see mashups aren't strictly the domain of web only applications. In a subsequent post I'll talk about how to interact with the hosting application from the JavaScript on the page for true two way interaction.

[UPDATE: April 2, 2008] Related posts:

||| |
 Monday, May 07, 2007

Is Microsoft expanding the API war?

Posted @ 11:46PM by Steve Trefethen

Categories: Development | Programming | Vista

Tags:  |  | 

Of course, that title is a play on Joel's api war post a few years ago but it seems fitting. Last week was a veritable bonanza of Microsoft beta's, alpha's and futures with all the "news" coming out of MIX07. To be honest, I'm not so sure what to make of all this stuff, heck in many ways I'm still back here. It seems Redmond has one-upped Google by putting out alpha software and beta software with "Go Live" licenses. How long will it be before we see alpha software with a "Go Live" license? Are we to believe businesses today are betting their future on all of this pre-release code?

Will there ever be some sort of stabilization period where apps can mature and the technology settles into a known state where developers are comfortable about the foundation from which their working? I suppose that's the Win32 system referred to in the following quote from the article on MSDN titled "Top Ten UI Development Breakthroughs In Windows Presentation Foundation":

"The current Win32-based Windows UI graphics subsystem, found in Windows® XP, has been around for nearly 20 years. It's aging and limited, and as a result, user interface development has been somewhat, well, constrained at best."
- MSDN Magazine January 2006

Is that implying that the new Office 11 Ribbon UI is "constrained? Ah, but it's  not .NET so it must be constrained. And what about Vista's fancy new albeit unmanaged UI surely that must be constrained right? Btw, where is Microsoft's developer support for the new Vista UI? That's not due to arrive until Orcas ships. Didn't the MFC guys know when Vista was going to ship? Or was it that it just didn't matter until recently?

It's almost as though the Microsoft factory is stuck on hyperdrive. They're competing with Linux, Apache, PHP, Flash, Eclipse, Java, Oracle/MySQL/DB2/etc, Google, Mozilla, Open Office, MySpace, Yahoo and over the past 12 months have released betas in nearly all of these areas.

But what does this mean? That seems like some technology for the "real world" where the abandoned VB6 developers are struggling to move their applications to .NET enough so that perhaps "one form at a time" might be a bit better pace. I almost feel bad for the VB6 guys since it has to be difficult deciding which direction to go when faced with rewriting your apps. Staying with Microsoft tools will undoubtedly mean moving to .NET and seemingly lots of change in the coming years which I'm sure has been causing some headaches. It makes me wonder how many of these guys know that there are tools that value compatibility while still moving forward.

Does anyone know what will really happen to WinForms with WPF being touted as the new UI for Windows? Will there be an Interop WPF toolkit available to move your WinForms apps one form at a time to XAML/WPF?

And checkout this smorgasbord of pre-release/beta/CTP software you'll need just to get you started with SilverLight (formerly WPF/E). If you've ever gone down the path of installing CTP's I'm sure you know the hassle that can be.

Oh, I almost forgot, what about those 7000 new API's in Windows Vista?

The sad thing is that I'm actually interested in several of these technologies but the field is increasingly looking like the slide from Stephen Colbert's The New AT&T (see about 50 seconds into the video). I've been trying to keep up though it seems a lost cause with each passing day I'm falling further behind.

What about you, how are you dealing with all of this? Or are you dealing with it?

 Friday, April 06, 2007

A generic Windows application written in Object Pascal

Posted @ 2:03PM by Steve Trefethen

Categories: Delphi | Programming

Tags:  | 

This is a bit of a throw back to Delphi 1.0 days. Recently, we were wanting to see exactly what messages Windows sent when maxmimizing/minimizing/restoring an application without the impact of any sort of framework like the VCL. Thus we resurrected Generic.pas from Delphi 1.0 and below is a copy that  compiles/executes with Delphi 2007. This code can also be useful for playing around with code snippets Raymond Chen posts on his blog. Here's a post where he explains why he uses code like this in the first place.

You can download the .DPR along with the .RC/.RES files here.
1 {************************************************} 2 { } 3 { Demo program } 4 { Copyright (c) 1991, 2007 by CodeGear } 5 { } 6 {************************************************} 7 8 { "Generic" Windows application written in Turbo Pascal } 9 10 program Generic; 11 12 {$R GENERIC.RES} 13 {$WARN SYMBOL_PLATFORM OFF} 14 15 uses Messages, Windows; 16 17 const 18 SAppName = 'Generic'; 19 SAboutBox = 'AboutBox'; 20 SWindowName = 'Turbo Pascal Generic'; 21 22 const 23 idm_About = 100; 24 25 function About(Dialog: HWnd; Message, WParam: Longint; 26 LParam: Longint): Bool; stdcall; 27 begin 28 About := True; 29 case Message of 30 wm_InitDialog: 31 Exit; 32 wm_Command: 33 if (WParam = id_Ok) or (WParam = id_Cancel) then 34 begin 35 EndDialog(Dialog, 1); 36 Exit; 37 end; 38 end; 39 About := False; 40 end; 41 42 function WindowProc(Window: HWnd; Message, WParam: Longint; 43 LParam: Longint): Longint; stdcall; 44 begin 45 Result := 0; 46 case Message of 47 wm_Command: 48 if WParam = idm_About then 49 begin 50 DialogBox(HInstance, SAboutBox, Window, @About); 51 Exit; 52 end; 53 wm_Destroy: 54 begin 55 PostQuitMessage(0); 56 Exit; 57 end; 58 end; 59 Result := DefWindowProc(Window, Message, WParam, LParam); 60 end; 61 62 var 63 WindowClass: TWndClass = ( 64 style: 0; 65 lpfnWndProc: @WindowProc; 66 cbClsExtra: 0; 67 cbWndExtra: 0; 68 hInstance: 0; 69 hIcon: 0; 70 hCursor: 0; 71 hbrBackground: COLOR_WINDOW; 72 lpszMenuName: SAppName; 73 lpszClassName: SAppName); 74 75 procedure WinMain; 76 var 77 Window: HWnd; 78 Message: TMsg; 79 begin 80 { Register the window class } 81 WindowClass.hInstance := HInstance; 82 WindowClass.hIcon := LoadIcon(0, idi_Application); 83 WindowClass.hCursor := LoadCursor(0, idc_Arrow); 84 if Windows.RegisterClass(WindowClass) = 0 then 85 Halt(1); 86 { Create and show the window } 87 Window := CreateWindow(SAppName, SWindowName, ws_OverlappedWindow, 88 Integer(cw_UseDefault), Integer(cw_UseDefault), 320, 240, 89 0, 0, HInstance, nil); 90 ShowWindow(Window, CmdShow); 91 UpdateWindow(Window); 92 { and crank up a message loop } 93 while GetMessage(Message, 0, 0, 0) do 94 begin 95 TranslateMessage(Message); 96 DispatchMessage(Message); 97 end; 98 Halt(Message.wParam); 99 end; 100 101 begin 102 WinMain; 103 end.
 Sunday, February 04, 2007

Using the WS_EX_COMPOSITE window style to eliminate flicker on Windows XP

Posted @ 10:38PM by Steve Trefethen

Categories: Delphi | Performance | Programming | VCL

Tags:  |  |  | 

As I continue to work through the various flicker issues on individual controls in the VCL I thought it worth mentioning a bit more "global" way to tackle the "flicker" problem. If you're running Windows XP there is a window style called WS_EX_COMPOSITED which you'll find documented on MSDN under CreateWindowEx here. This style bit instructs the OS to apply double buffered painting for you. Here is how you would add this to a Delphi VCL form:
1 type 2 TMyForm = class(TForm) 3 protected 4 procedure CreateParams(var Params: TCreateParams); override; 5 end; 6 7 ... 8 9 procedure TMyForm.CreateParams(var Params: TCreateParams); 10 begin 11 inherited; 12 // This only works on Windows XP and above 13 if CheckWin32Version(5, 1) then 14 Params.ExStyle := Params.ExStyle or WS_EX_COMPOSITED; 15 end; 16

You should be able to use this on any 32-bit version of Delphi as long as your app is running on Windows XP.

The downside is that depending on your application this change could have rather serious performance implications during a window resize particularly with aligned controls. The upside of course is that it's flicker free! :-)

I've read that there may be some issues related to using this window style with GDI+ so be sure to look for that if it affects you.

There is no comment on the MSDN as to how this works under Windows Vista but I'd guess there may be some differences.

 Thursday, February 01, 2007

A KillTask routine to terminate a process from a Delphi application

Posted @ 9:29AM by Steve Trefethen

Categories: Delphi | Programming

Tags:  | 

One thing that's great about having my own blog is that I get to see all of the searches that led people to find my blog. I've noticed numerous searches for a routine that would kill a Windows process written in Delphi. Here is just such a routine written by Misha Moellner.
 Friday, November 24, 2006

Development using Agile

Posted @ 2:55PM by Steve Trefethen

Categories: Agile | Programming | Quality

Tags:  |  | 

Since the beginning of the Highlander (vNext BDS) development cycle the team has been using Agile and at this point, it's safe to say I'm still on the fence about it. The decision to use Agile wasn't quick nor was it made on the first day of the project, rather it came after numerous discussions and actual training sessions with an Agile instructor/consultant. Now, I'm not blaming the consultant and in fact, if anything the instruction was useful for us to improve our development process for reasons unrelated to learning Agile. I believe there are projects which would/could benefit from a strictly Agile approach however, given our team size, the disparate skill sets our staff has, the size and complexity of the IDE I think we're likely to have to reexamine and adapt our use of Agile which isn't a surprise and I'm sure at least some people in the Agile community would say that that's what Agile is all about.

Prior to this year I'd say our development process was a modified version of waterfall which has seen it's ups and downs. One point I'd make though is that when there are changes in the engineering staff, the technology, the market, the business and the management is it fair to blame the process when things go wrong? I'll be the first to admit our process can and needs further improvement and we're committed to and actively working on those improvements today. In fact, I've blogged a lot about our development process much of which has evolved even since last year and not just because of our use of Agile.

Like most engineers my team has lots of ideas about how things could be improved and in many cases those ideas are acted upon independently and our process incrementally improves. Perhaps one of the best things to come from all the focus on Agile and XP is simply the fact it has gotten engineers actively interested in thinking about the development process. Of course, it hasn't hurt that the discussion has been accompanied by lots of tools for things like unit testing and continuous integration which I believe really helps drive engineering interest.

It's interesting, I think most of the process improvements our team has enjoyed this past year occurred organically driven, not by management, but by individual engineers with a desire to utilize the maturing set of tools that are available today. I believe one critical turning point was our single minded focus on quality for the BDS 2006 release. I believe the release itself was high quality but since November of last year we've released at least seven updates more than triple what we normally ship. It's this same desire to ship quality code that has fueled much of the process changes we've put in place in the past 12 months.

I haven't really talked about why I'm on the fence about Agile and at some point I'll fill in the blanks but one thing is clear, IMO the BDS development team is actively moving in the right direction.

If you're new to reading my blog check out my Zombie posts regarding our automated testing efforts and have a look at the video I posted of our R&D smoke test for BDS.

 Wednesday, November 01, 2006

Using Microsoft's Windows RSS Platform from IE7 in Delphi (Win32)

Posted @ 1:29AM by Steve Trefethen

Categories: Delphi | Programming | RSS

Tags:  |  | 

Recently, Microsoft introduced the Windows RSS Platform which allows you to programmatically manipulate RSS feeds for use in your own applications. I'm a big fan of RSS and thus this new platform interested me. Thankfully a Microsoft blogger named Walter vonKoch was kind enough to post the RSS Platform MiniSDK including the type library msfeeds.tlb that we can easily import into Delphi. Big thanks to Walter for posting this!

In the interest of completeness I used the tlibimp utility that ships with BDS to import the type library using the following command line:

tlibimp -Hr- -Hs- -Fe- msfeeds.tlb

Here is a Delphi Win32 project I wrote which is likely the quickest/dirtiest RSS reader you may ever run into but it illustrates my point which is to use the new Microsoft Windows RSS Platform from Delphi nicely. Disclaimer: I quickly hacked together this application with the sole interest of using as little of my time as possible leaving the details as an exercise for the reader. A few important points:

  • The imported type library unit is included in the download
  • The unit was imported using the tlibimp from Highlander so please let me know if you run into any issues compiling it with earlier versions of BDS
  • To run this demo you must have IE7 installed

Lastly, should you write something really cool using this platform please let me know I'd love to hear about it.

Reference:
 Saturday, October 28, 2006

Calculating process CPU usage

Posted @ 2:31PM by Steve Trefethen

Categories: Programming

Tags:

Recently, I needed a routine to calculate CPU usage so that I could detect when a process went idle. As usual a quick search on Google Groups turned up the answer in this post. The routine calls GetProcessTimes then sleeps for a brief period, calls it again and calculates the average over that interval. The only change I made was to take into account the number of CPU's on the system by calling GetSystemInfo and divide accordingly.