Wednesday, May 22, 2013 Register  Login

This site uses DNS Made Easy. Use it for reliable and professional DNS services.

RSS Feeds
Categories
  
Blog Archives
  
Blog

Entries for October 2010

Oct
09
 2353 Views ::  15 Comments RSS comment feed

I'm involved in creating a COM interface from a C# 4.0 library. This took a lot of hair-pulling and banging-head-against-the-wall moments. This skillset appears to be quickly disappearing; sad, but quite understandable. I wanted to store how this is done, because I found many little slivers across the Intertubes, but nowhere did I find the slivers put into a coherent picture.

I'm going to use a simple class that I'm calling ComDog. Here is the definition:

using System;

using System.Runtime.InteropServices;

namespace ComDog

{

    [ComVisible(false)]

    public delegatevoid DogEventHandler();

    [ComVisible(true)]

    [Guid("2406DD50-A3CE-43A6-9F20-112B621CB784")]

    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]

    public interfaceIDogEvents

   {

        [DispId(1)]

        void Bark(); 

        [DispId(2)]

        void Howl(); 

        [DispId(3)]

        void Eat();

    }

    [ComVisible(true)]

    [Guid("8C6DAD17-0612-4166-AD35-3A55DDEAF62E")]

    [ClassInterface(ClassInterfaceType.AutoDual)]

    [ComSourceInterfaces(typeof(IDogEvents))]

    public class Dog : MarshalByRefObject

   {

        public event DogEventHandler Bark;

        public event DogEventHandler Howl;

        public event DogEventHandler Eat;

 

        public void MakeDogBark()

       {

            if (Bark != null)

           {

               Bark();

           }

       }

 

        public void MakeDogHowl()

       {

            if (Howl != null)

           {

               Howl();

           }

       }

 

        public void MakeDogEat()

       {

            if (Eat != null)

           {

               Eat();

           }

       }

   }

Now let's get this compiled and registered. To get this registered with COM, well need to issue this command, in an elevated command prompt:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm comdog.dll /tlb:ComDog.tlb

Now on to Delphi 7...

Copy both the ComDog.dll and ComDog.tlb to the same folder as your Delphi project. I'm doing this, because I don't want to mess with the GAC.

In the Delphi IDE, select Project --> Import Type Library. It will look like this:

This in turn, should show the Import Type Library dialog, that looks like this:

If you registered the assembly (dll in .NET parlance), you should see an entry for ComDog, like the selected one in the dialog above. Click on the "Create Unit" button. This will add a "ComDog_TLB.pas" file to your Delphi project.

One important section that I want to direct your attention to:

// *********************************************************************//
// OLE Server Proxy class declaration
// Server Object    : TDog
// Help String      :
// Default Interface: _Dog
// Def. Intf. DISP? : No
// Event   Interface: IDogEvents
// TypeFlags        : (2) CanCreate
// *********************************************************************//
{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
  TDogProperties= class;
{$ENDIF}
  TDog = class(TOleServer)
  private
    FOnBark: TNotifyEvent;
    FOnHowl: TNotifyEvent;
    FOnEat: TNotifyEvent;
    FIntf:        _Dog;

The events are of type TNotifyEvent, because they do not have parameters. This comes from the IDogEvents. Delphi will ALWAYS use the definition in your event interface, instead of the events listed in the main class. Make absolutely sure that the signature in the event interface match the signature of the events in your main C# class.

Here is what the definition of the events will look like in your Delphi main form/unit:

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ActiveX, ComObj, ComDog_TLB, StdCtrls, OleServer;

type
  TForm1 = class(TForm)
    btnBark: TButton;
    btnHowl: TButton;
    btnEat: TButton;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure btnBarkClick(Sender: TObject);
    procedure btnHowlClick(Sender: TObject);
    procedure btnEatClick(Sender: TObject);
  private
    { Private declarations }
  protected
    procedure Barked(Sender: TObject);
    procedure Howled(Sender: TObject);
    procedure Ate(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  TestDog: TDog;

The proctected section above defines the events. This you will have to type manually. Make sure that your _TLB file is listed in the uses section above.

Now to actually have the events handled, you will have to create a procedure that matches the signature of event. Like so:

procedure TForm1.Barked(Sender: TObject);
begin
  Memo1.Lines.Add('Dog Barked');
end;

procedure TForm1.Howled(Sender: TObject);
begin
  Memo1.Lines.Add('Dog Howled');
end;

procedure TForm1.Ate(Sender: TObject);
begin
  Memo1.Lines.Add('Dog ate something');
end;

This is how you wire up C# COM events up to a Delphi COM client app.

The next question is how to deal with events that have parameters. It's basically the same thing. You'll just have to make sure that the signatures for event definitions and event handlers in Delphi, match what's in the _TLB file.

I did a lot of hair-pulling in order to get this working. I wanted to post this in my blog, for the next time I'm doing this. Please feel free to comment here, if you need more help.

posted @ Saturday, October 09, 2010 6:34 AM by Hector Sosa, Jr

Actions:Tweet This Share on Facebook Share on LinkedIn Emakl Permalink del.icio.us
Oct
06

I now have time to update various apps on my website. I have some bug fixes and some additions to PainlessSVN. I will add the ability to add users to groups when your repository is using authorization rules, better known as path based authorization. I will release version 1.1.1, once I get this done.

As a technology solution, PainlessSVN has been a success. It helps me manage all my repositories painlessly. As a commercial product, it has been an abject failure. This being the case, I will put it in the back burner, and update it when I need specific funtionality. It won't disappear from this website, I just can't justify spending that much time on it, when it is not producing revenue.

posted @ Wednesday, October 06, 2010 12:47 AM by Hector Sosa, Jr

Posted in: PainlessSVN

Actions:Tweet This Share on Facebook Share on LinkedIn Emakl Permalink del.icio.us
Oct
06
 1272 Views ::  2 Comments RSS comment feed

I was doing a code spike to see if I could get .NET 4 to work with MMC 3.0. All my attempts failed. I googled a bit, and it looks like I'm not the only one.

In a nutshell, you might get lucky, but for the most part it doesn't work.

Here's a post on StackOverflow:

MMC .Net Runtime Version

Here's the official response from Microsoft:

Can not use .Net 4.0 to create MMC SnapIn

Stuff like this is what makes it very hard to trust Microsoft as a developer.

posted @ Wednesday, October 06, 2010 12:40 AM by Hector Sosa, Jr

Actions:Tweet This Share on Facebook Share on LinkedIn Emakl Permalink del.icio.us
Oct
02

I've spent the last few months fighting hackers, heat, and the recession. I got laid off from my daytime job in March of this year. I was fortunate enough to find a new job in April. I had to take a paycut. I'm thankful that I have a job to pay for bills.

We bought our new house, in September 2009, without central cooling. My layoff put a crimp in our finances, so we were not able to put central cooling until about a week ago (September 2010). My new home office has been extremely hot, and haven't been able to spend much time in it, until the central cooling was installed.

Now comes my fight with hackers. There was a break in at Google. Some Russian hackers got a hold of many Gmail account login details. The hackers got this website's FTP credentails when they broke into my Gmail personal account. This was one massive attack, where they put Javascript malware on a bunch of websites worldwide. I'm surprise that there hasn't been more of an uproar from the media outlets that deal with technical stuff.

It took me close to two and a half months to get this website back up and working correctly. I had restored this website from a backup, and that cleared it from malware the first time.

The second time, they used a FTP account that I had forgotten about. I deleted this account as soon as I found it. Next, I used NetDrive to map the FTP site to a local drive, and used Multi-Edit to do a file search and replace. I got rid of all the bad Javascript, and this site is clean again.

I lost several blog posts, but I have the one about C# COM and Delphi saved up in Surfulater. I want to put this one back up, because there's hardly any information on how to get this done out on the Internet.

It's been a frustrating year so far. I'll just keep plucking along. As life keeps knocking you down, you just need to keep getting up.

posted @ Saturday, October 02, 2010 11:51 PM by Hector Sosa, Jr

Posted in: Personal

Actions:Tweet This Share on Facebook Share on LinkedIn Emakl Permalink del.icio.us
Terms Of Use | Privacy Statement | SystemWidgets
Copyright 2002-2013 by SystemWidgets
Google Analytics Alternative