国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

Ole控件的事件輔助類

發布時間:2011-3-29 20:24    發布者:1770309616
關鍵詞: Ole控件 , 事件輔助類
概述
       Delphi對Ole控件作了很好的封裝,使用起來要比C++的方便地多,比如想用IE控件,只需要將TWebBrowser拖到窗體上,設置相關屬性,處理相關事件,一切和其他控件沒有什么區別。
       但是使用過程中,我們會發現一個問題,拿TWebBrowser來說,它沒有OnNavigateError事件,如果我們想在連接錯誤的時候做一些事情,比如要用一個更漂亮的網頁來代替IE預定義的錯誤頁面,那么似乎是沒有辦法的了。
       出現這個問題的原因是IE控件的版本,越高版本功能越多,比如錯誤事件是在IE 6才有的,而TWebBrowser顯然是用更低版本的IE類型庫生成的。解決辦法之一是通過更新的類型庫生成更新的控件,但這仍然不大方便,如果下一版本的IE提供了更多的事件,你就必須重新生成控件了。
我這里提供了一個更好的辦法,無需要生成類型庫就可以接收所有的事件。下面就是代碼:
代碼
(**
* OLE控件的事件輔助類
*
* by linzhenqun 2008-12-6
*)
unit OleCtrlEventHelper;
{
  用法:
  1、開始時:創建TOleCtrlEventHelper,建立連接點,添加想處理的事件:
     FOleCtrlEventHelper := TOleCtrlEventHelper.Create(DIID_DWebBrowserEvents2);
     FOleCtrlEventHelper.EventConnect(Webbrowser.DefaultInterface);
     FOleCtrlEventHelper.AddEvent($10F, Method(Self, @TMyClass.OnNavigateError));
  2、結束時:斷開連接點,消毀TOleCtrlEventHelper
     FOleCtrlEventHelper.EventDisconnect(Webbrowser.DefaultInterface);
     FOleCtrlEventHelper.Free;
                                                        --- linzhenqun
}
interface
uses
  SysUtils, ActiveX, Classes;
type
  PEventRec = ^TEventRec;
  TEventRec = record
    DispID: TDispID;
    Method: TMethod;
  end;
  TOleCtrlEventHelper = class(TObject, IUnknown, IDispatch)
  private
    FEventIID: TGUID;
    FEventList: TList;
    FEventsConnection: LongInt;
  private
    procedure ClearEvent;
    procedure InvokeEvent(DispID: TDispID; var Params: TDispParams);
  protected
    { IUnknown }
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
    { IDispatch }
    function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
    function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
    function GetIDsOfNames(const IID: TGUID; Names: Pointer;
      NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
    function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
      Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
  public
    constructor Create(const EventIID: TGUID);
    destructor Destroy; override;
    function AddEvent(DispID: TDispID; const Method: TMethod): Boolean;
    function RemoveEvent(DispID: TDispID): Boolean;
    function GetEvent(DispID: TDispID; var Method: TMethod): Boolean;
    procedure EventConnect(Source: IInterface);
    procedure EventDisconnect(Source: IInterface);
  end;
function Method(Data, Code: Pointer): TMethod;
implementation
uses
  ComObj;
function Method(Data, Code: Pointer): TMethod;
begin
  Result.Code := Code;
  Result.Data := Data;
end;
{ TOleCtrlEventHelper }
function TOleCtrlEventHelper.AddEvent(DispID: TDispID; const Method: TMethod): Boolean;
var
  M: TMethod;
  EventRec: PEventRec;
begin
  Result := False;
  if not GetEvent(DispID, M) then
  begin
    New(EventRec);
    EventRec^.DispID := DispID;
    EventRec^.Method := Method;
    FEventList.Add(EventRec);
    Result := True;
  end;  
end;
procedure TOleCtrlEventHelper.ClearEvent;
var
  i: Integer;
begin
  for i := 0 to FEventList.Count - 1 do
    Dispose(FEventList.Items);
  FEventList.Clear;
end;
constructor TOleCtrlEventHelper.Create(const EventIID: TGUID);
begin
  FEventIID := EventIID;
  FEventList := TList.Create;
end;
destructor TOleCtrlEventHelper.Destroy;
begin
  ClearEvent;
  FEventList.Free;
  inherited;
end;
procedure TOleCtrlEventHelper.EventConnect(Source: IInterface);
begin
  InterfaceConnect(Source, FEventIID, Self, FEventsConnection);
end;
procedure TOleCtrlEventHelper.EventDisconnect(Source: IInterface);
begin
  InterfaceDisconnect(Source, FEventIID, FEventsConnection);
end;
function TOleCtrlEventHelper.GetEvent(DispID: TDispID; var Method: TMethod): Boolean;
var
  i: Integer;
  EventRec: PEventRec;
begin
  Result := False;
  for i := FEventList.Count - 1 downto 0 do
  begin
    EventRec := PEventRec(FEventList);
    if EventRec^.DispID = DispID then
    begin
      Method := EventRec^.Method;
      Result := True;
      Break;
    end;
  end;
end;
function TOleCtrlEventHelper.GetIDsOfNames(const IID: TGUID; Names: Pointer;
  NameCount, LocaleID: Integer; DispIDs: Pointer): HResult;
begin
  Result := E_NOTIMPL;
end;
function TOleCtrlEventHelper.GetTypeInfo(Index, LocaleID: Integer;
  out TypeInfo): HResult;
begin
  Pointer(TypeInfo) := nil;
  Result := E_NOTIMPL;
end;
function TOleCtrlEventHelper.GetTypeInfoCount(out Count: Integer): HResult;
begin
  Count := 0;
  Result := S_OK;
end;
function TOleCtrlEventHelper.Invoke(DispID: Integer; const IID: TGUID;
  LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo,
  ArgErr: Pointer): HResult;
begin
  if not ((DispID >= DISPID_MOUSEUP) and (DispID <= DISPID_CLICK)) then
    InvokeEvent(DispID, TDispParams(Params));
  Result := S_OK;
end;
procedure TOleCtrlEventHelper.InvokeEvent(DispID: TDispID;
  var Params: TDispParams);
var
  EventMethod: TMethod;
begin
  if not GetEvent(DispID, EventMethod) or
    (Integer(EventMethod.Code) < $10000) then Exit;
  // copy from olectrls.pas: TOleControl.InvokeEvent
  try
    asm
              PUSH    EBX
              PUSH    ESI
              MOV     ESI, Params
              MOV     EBX, [ESI].TDispParams.cArgs
              TEST    EBX, EBX
              JZ      @@7
              MOV     ESI, [ESI].TDispParams.rgvarg
              MOV     EAX, EBX
              SHL     EAX, 4                         // count * sizeof(TVarArg)
              XOR     EDX, EDX
              ADD     ESI, EAX                       // EDI = Params.rgvarg^[ArgCount]
      @@1:    SUB     ESI, 16                        // Sizeof(TVarArg)
              MOV     EAX, dword ptr [ESI]
              CMP     AX, varSingle                  // 4 bytes to push
              JA      @@3
              JE      @@5
      @@2:    TEST    DL,DL
              JNE     @@2a
              MOV     ECX, ESI
              INC     DL
              TEST    EAX, varArray
              JNZ     @@6
              MOV     ECX, dword ptr [ESI+8]
              JMP     @@6
      @@2a:   TEST    EAX, varArray
              JZ      @@5
              PUSH    ESI
              JMP     @@6
      @@3:    CMP     AX, varDate                    // 8 bytes to push
              JA      @@2
      @@4:    PUSH    dword ptr [ESI+12]
      @@5:    PUSH    dword ptr [ESI+8]
      @@6:    DEC     EBX
              JNE     @@1
      @@7:    MOV     EDX, Self
              MOV     EAX, EventMethod.Data
              CALL    EventMethod.Code
              POP     ESI
              POP     EBX
    end;
  except
  end;
end;
function TOleCtrlEventHelper.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
  if GetInterface(IID, Obj) then
  begin
    Result := S_OK;
    Exit;
  end;
  if IsEqualIID(IID, FEventIID) then
  begin
    GetInterface(IDispatch, Obj);
    Result := S_OK;
    Exit;
  end;
  Result := E_NOINTERFACE;
end;
function TOleCtrlEventHelper.RemoveEvent(DispID: TDispID): Boolean;
var
  i: Integer;
  EventRec: PEventRec;
begin
  Result := False;
  for i := FEventList.Count - 1 downto 0 do
  begin
    EventRec := PEventRec(FEventList);
    if EventRec^.DispID = DispID then
    begin
      FEventList.Remove(EventRec);
      Dispose(EventRec);
      Result := True;
      Break;
    end;
  end;
end;
function TOleCtrlEventHelper._AddRef: Integer;
begin
  Result := -1;
end;
function TOleCtrlEventHelper._Release: Integer;
begin
  Result := -1;
end;
end.

用法
       使用方法非常簡單,我寫了一個Demo傳上來,可以從下面連接下載:
http://download.csdn.net/source/843895
       TOleCtrlEventHelper是一個比較輕量級的類,使用時需要手工創建和消毀,如果要更方便一點,可以寫成一個組件,這樣就不必關心它的生命周期了,當然代價就是多了一些體積。
本文地址:http://www.qingdxww.cn/thread-60398-1-1.html     【打印本頁】

本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
您需要登錄后才可以發表評論 登錄 | 立即注冊

廠商推薦

  • Microchip視頻專區
  • 想要避免發生災難,就用MPLAB SiC電源仿真器!
  • 利用模擬開發工具生態系統進行安全電路設計
  • 你仿真過嗎?使用免費的MPLAB Mindi模擬仿真器降低設計風險
  • 我們是Microchip
  • 貿澤電子(Mouser)專區
關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
快速回復 返回頂部 返回列表
主站蜘蛛池模板: 五月婷婷在线观看 | 深入敌后免费高清完整版在线观看 | 黄页免费在线看 | 国产综合久久久久影院 | 亚洲国产欧美在线人网站 | 一区二区高清在线 | 日韩免费一级片 | 三区在线观看 | 国内自拍视频在线观看 | 黄色片视频免费看 | 日韩成人动漫在线观看 | 欧美xxxx新一区二区三区 | 四虎国产一区 | 91麻豆精品国产91久久久久 | 黄色免费网站视频 | 香蕉女郎在线观看 | 久久精品久久久久 | 成人国产精品免费视频 | 亚洲欧洲国产成人精品 | 色999| 美国在线视频 | 四虎影视884aa·com | 亚洲高清在线观看视频 | 国产精品精品国产 | 中国欧美日韩一区二区三区 | 日韩毛片在线看 | 97精品免费视频 | 视频在线观看一区二区 | 国产三级自拍 | 91日韩在线 | 国产午夜精品免费一二区 | 国产成人香蕉久久久久 | 日韩视频免费看 | 失乐园电视剧日本第6集 | 欧美一级日韩在线观看 | 一级做性色a爱片久久片 | 四虎免费在线观看 | 青青青视频蜜桃一区二区 | 日本一区二区三区久久久 | 亚洲第一区第二区 | 午夜在线播放免费人成无 |