DELPHI 包装.NET COM组件

       Delphi 可以很容易的将.NET COM组件包装成简单的ActiveX控件,任意调用,但是有一些由于DELPHI不包含.NET 属性可能造成ACTIVEX控件会报错,通常是颜色等。详细的属性详见Winapi.ActiveX.pas核心代码。

  修改方法1:直接修改源代码再编译。

{ Standard dispatch ID constants }
<pre name="code" class="delphi">procedure TOleControl.CreateControl;
var
  Stream: IStream;
  CS: IOleClientSite;
  X: Integer;
begin
  if FOleControl = nil then
    try
      try  // work around ATL bug
        X := FOleObject.GetClientSite(CS);
      except
        X := -1;
      end;
      if (X <> 0) or (CS = nil) then
        OleCheck(FOleObject.SetClientSite(Self));
      if FObjectData = 0 then OleCheck(FPersistStream.InitNew) else
      begin
        OleCheck(CreateStreamOnHGlobal(FObjectData, False, Stream));
        OleCheck(FPersistStream.Load(Stream));
        DestroyStorage;
      end;
      OleCheck(FOleObject.QueryInterface(IOleControl, FOleControl));
      OleCheck(FOleObject.QueryInterface(IDispatch, FControlDispatch));
      FOleObject.QueryInterface(IPerPropertyBrowsing, FPropBrowsing);
      InterfaceConnect(FOleObject, IPropertyNotifySink,
        Self, FPropConnection);
      InterfaceConnect(FOleObject, FControlData^.EventIID,
        FEventDispatch, FEventsConnection);
      //
//      if FControlData^.Flags and cfBackColor <> 0 then
//        OnChanged(DISPID_BACKCOLOR);

      if FControlData^.Flags and cfEnabled <> 0 then
        OnChanged(DISPID_ENABLED);
      if FControlData^.Flags and cfFont <> 0 then
        OnChanged(DISPID_FONT);
      if FControlData^.Flags and cfForeColor <> 0 then
        OnChanged(DISPID_FORECOLOR);
      FOleControl.OnAmbientPropertyChange(DISPID_UNKNOWN);
      RequestNewObjectLayout;
    except
      DestroyControl;
      raise;
    end;
end;

{$EXTERNALSYM DISPID_AUTOSIZE} DISPID_AUTOSIZE = -500; {$EXTERNALSYM DISPID_BACKCOLOR} <span style="color:#ff0000;"> DISPID_BACKCOLOR = -501; {$EXTERNALSYM DISPID_BACKSTYLE}</span> DISPID_BACKSTYLE = -502; {$EXTERNALSYM DISPID_BORDERCOLOR} DISPID_BORDERCOLOR = -503; {$EXTERNALSYM DISPID_BORDERSTYLE} DISPID_BORDERSTYLE = -504; {$EXTERNALSYM DISPID_BORDERWIDTH} DISPID_BORDERWIDTH = -505; {$EXTERNALSYM DISPID_DRAWMODE} DISPID_DRAWMODE = -507; {$EXTERNALSYM DISPID_DRAWSTYLE} DISPID_DRAWSTYLE = -508; {$EXTERNALSYM DISPID_DRAWWIDTH} DISPID_DRAWWIDTH = -509; {$EXTERNALSYM DISPID_FILLCOLOR} DISPID_FILLCOLOR = -510; {$EXTERNALSYM DISPID_FILLSTYLE} DISPID_FILLSTYLE = -511; {$EXTERNALSYM DISPID_FONT} DISPID_FONT = -512; {$EXTERNALSYM DISPID_FORECOLOR} DISPID_FORECOLOR = -513;<span style="color:#ff0000;"> {$EXTERNALSYM DISPID_ENABLED} DISPID_ENABLED = -514;</span> {$EXTERNALSYM DISPID_HWND} DISPID_HWND = -515; {$EXTERNALSYM DISPID_TABSTOP} DISPID_TABSTOP = -516; {$EXTERNALSYM DISPID_TEXT} DISPID_TEXT = -517; {$EXTERNALSYM DISPID_CAPTION} DISPID_CAPTION = -518; {$EXTERNALSYM DISPID_BORDERVISIBLE} DISPID_BORDERVISIBLE = -519; {$EXTERNALSYM DISPID_APPEARANCE} DISPID_APPEARANCE = -520; {$EXTERNALSYM DISPID_MOUSEPOINTER} DISPID_MOUSEPOINTER = -521; {$EXTERNALSYM DISPID_MOUSEICON} DISPID_MOUSEICON = -522; {$EXTERNALSYM DISPID_PICTURE} DISPID_PICTURE = -523; {$EXTERNALSYM DISPID_VALID} DISPID_VALID = -524; {$EXTERNALSYM DISPID_READYSTATE} DISPID_READYSTATE = -525; {$EXTERNALSYM DISPID_REFRESH} DISPID_REFRESH = -550; {$EXTERNALSYM DISPID_DOCLICK} DISPID_DOCLICK = -551; {$EXTERNALSYM DISPID_ABOUTBOX} DISPID_ABOUTBOX = -552;
 

红色表示是不支持,不知道如何转换成DELPHI对象。暂时不知道,不过暂时不需要知道。

unit Vcl.OleCtrls;

procedure TOleControl.CreateControl;
var
  Stream: IStream;
  CS: IOleClientSite;
  X: Integer;
begin
  if FOleControl = nil then
    try
      try  // work around ATL bug
        X := FOleObject.GetClientSite(CS);
      except
        X := -1;
      end;
      if (X <> 0) or (CS = nil) then
        OleCheck(FOleObject.SetClientSite(Self));
      if FObjectData = 0 then OleCheck(FPersistStream.InitNew) else
      begin
        OleCheck(CreateStreamOnHGlobal(FObjectData, False, Stream));
        OleCheck(FPersistStream.Load(Stream));
        DestroyStorage;
      end;
      OleCheck(FOleObject.QueryInterface(IOleControl, FOleControl));
      OleCheck(FOleObject.QueryInterface(IDispatch, FControlDispatch));
      FOleObject.QueryInterface(IPerPropertyBrowsing, FPropBrowsing);
      InterfaceConnect(FOleObject, IPropertyNotifySink,
        Self, FPropConnection);
      InterfaceConnect(FOleObject, FControlData^.EventIID,
        FEventDispatch, FEventsConnection);
      //
//      if FControlData^.Flags and cfBackColor <> 0 then
//        OnChanged(DISPID_BACKCOLOR);

      if FControlData^.Flags and cfEnabled <> 0 then
        OnChanged(DISPID_ENABLED);
      if FControlData^.Flags and cfFont <> 0 then
        OnChanged(DISPID_FONT);
      if FControlData^.Flags and cfForeColor <> 0 then
        OnChanged(DISPID_FORECOLOR);
      FOleControl.OnAmbientPropertyChange(DISPID_UNKNOWN);
      RequestNewObjectLayout;
    except
      DestroyControl;
      raise;
    end;
end;
删除如上代码或者,直接覆盖OnChange方法。

修改方法2:在构造方法中,修改传递参数

procedure TExFxCtrl.InitControlData;
const
  CEventDispIDs: array [0..7] of DWORD = (
    $000000C9, $000000CA, $000000CB, $000000CC, $000000CD, $000000CE,
    $000000CF, $000000D0);
  CTFontIDs: array [0..0] of DWORD = (
    $FFFFFE00);
  CControlData: TControlData2 = (
     ClassID:      '{4B9D6684-D466-4C72-8BE1-88FA1E9E0B2F}';
     EventIID:     '{B9DF5E90-AB92-4D7C-84D1-4AC98D0ED682}';
    EventCount:   0;
    EventDispIDs: nil;
    LicenseKey:   nil (*HR:$00000000*);
    <span style="color:#ff0000;">Flags:        $00000000;//修改这里就行了。</span>
    Version:      500;
    FontCount:    1;
    FontIDs:      @CTFontIDs);
begin
  ControlData := @CControlData;
  TControlData2(CControlData).FirstEventOfs := UIntPtr(@@FOnActivate) - UIntPtr(Self);
end;


============================

另外在DELPHI XE原来的简单使用PCHAR要注意,默认的PCHAR是PWideChar,很多WINDOWS API的底层的都是LPCSTR都要修改为PAnsiChar!

procedure WindowExec(AFileName:String;args:String;uCmdShow: UINT);
var
  sDir:String;
  sCmd:String;
begin
  sDir:=ExtractFilePath(AFileName);
  GetWindowsDirectory(PChar(SDir),Sizeof(sDir));
  sCmd:= AFileName+' '+args;
  //--------------------------------------------
  WinExec(PAnsiChar(sCmd),  uCmdShow);
end;


阿斯

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值