Delphi - объектно-ориентированный язык программирования, разработанный компанией Borland в 1995 году. Он основан на языке программирования Pascal, но имеет более расширенные возможности и добавлены новые функции.
Delphi является интегрированной средой разработки (IDE), которая позволяет разрабатывать программное обеспечение для различных платформ, включая Windows, macOS, Android и iOS. Delphi достигает многоплатформенности с помощью...
{
This component allows you to intercept Internet Explorer messages such as
"StatusTextChangeEvent", "DocumentCompleteEvent" and so on.
Mit folgende Komponente lassen sich Nachrichten wie
"StatusTextChangeEvent", "DocumentCompleteEvent" usw. von
Internet Explorer Fenstern abfangen.
}
//---- Component Source: Install this component first.
unit IEEvents;
interface
uses
Windows, SysUtils, Classes, Graphics, ComObj, ActiveX, SHDocVW;
type
// Event types exposed from the Internet Explorer interface
TIEStatusTextChangeEvent = procedure
(Sender: TObject; const
Text: WideString) of
object
;
TIEProgressChangeEvent = procedure
(Sender: TObject; Progress: Integer; ProgressMax: Integer) of
object
;
TIECommandStateChangeEvent = procedure
(Sender: TObject; Command: Integer; Enable: WordBool) of
object
;
TIEDownloadBeginEvent = procedure
(Sender: TObject) of
object
;
TIEDownloadCompleteEvent = procedure
(Sender: TObject) of
object
;
TIETitleChangeEvent = procedure
(Sender: TObject; const
Text: WideString) of
object
;
TIEPropertyChangeEvent = procedure
(Sender: TObject; const
szProperty: WideString) of
object
;
TIEBeforeNavigate2Event = procedure
(Sender: TObject; const
pDisp: IDispatch;
var
URL: OleVariant; var
Flags: OleVariant; var
TargetFrameName: OleVariant;
var
PostData: OleVariant; var
Headers: OleVariant; var
Cancel: WordBool) of
object
;
TIENewWindow2Event = procedure
(Sender: TObject; var
ppDisp: IDispatch; var
Cancel: WordBool) of
object
;
TIENavigateComplete2Event = procedure
(Sender: TObject; const
pDisp: IDispatch; var
URL: OleVariant) of
object
;
TIEDocumentCompleteEvent = procedure
(Sender: TObject; const
pDisp: IDispatch; var
URL: OleVariant) of
object
;
TIEOnQuitEvent = procedure
(Sender: TObject) of
object
;
TIEOnVisibleEvent = procedure
(Sender: TObject; Visible: WordBool) of
object
;
TIEOnToolBarEvent = procedure
(Sender: TObject; ToolBar: WordBool) of
object
;
TIEOnMenuBarEvent = procedure
(Sender: TObject; MenuBar: WordBool) of
object
;
TIEOnStatusBarEvent = procedure
(Sender: TObject; StatusBar: WordBool) of
object
;
TIEOnFullScreenEvent = procedure
(Sender: TObject; FullScreen: WordBool) of
object
;
TIEOnTheaterModeEvent = procedure
(Sender: TObject; TheaterMode: WordBool) of
object
;
// Event component for Internet Explorer
TIEEvents = class
(TComponent, IUnknown, IDispatch)
private
// Private declarations
FConnected: Boolean;
FCookie: Integer;
FCP: IConnectionPoint;
FSinkIID: TGuid;
FSource: IWebBrowser2;
FStatusTextChange: TIEStatusTextChangeEvent;
FProgressChange: TIEProgressChangeEvent;
FCommandStateChange: TIECommandStateChangeEvent;
FDownloadBegin: TIEDownloadBeginEvent;
FDownloadComplete: TIEDownloadCompleteEvent;
FTitleChange: TIETitleChangeEvent;
FPropertyChange: TIEPropertyChangeEvent;
FBeforeNavigate2: TIEBeforeNavigate2Event;
FNewWindow2: TIENewWindow2Event;
FNavigateComplete2: TIENavigateComplete2Event;
FDocumentComplete: TIEDocumentCompleteEvent;
FOnQuit: TIEOnQuitEvent;
FOnVisible: TIEOnVisibleEvent;
FOnToolBar: TIEOnToolBarEvent;
FOnMenuBar: TIEOnMenuBarEvent;
FOnStatusBar: TIEOnStatusBarEvent;
FOnFullScreen: TIEOnFullScreenEvent;
FOnTheaterMode: TIEOnTheaterModeEvent;
protected
// Protected declaratios for IUnknown
function
QueryInterface(const
IID: TGUID; out Obj): HResult; override
;
function
_AddRef: Integer; stdcall
;
function
_Release: Integer; stdcall
;
// Protected declaratios for IDispatch
function
GetIDsOfNames(const
IID: TGUID; Names: Pointer; NameCount, LocaleID:
Integer; DispIDs: Pointer): HResult; virtual
; stdcall
;
function
GetTypeInfo(Index
, LocaleID: Integer; out TypeInfo): HResult; virtual
; stdcall
;
function
GetTypeInfoCount(out Count: Integer): HResult; virtual
; stdcall
;
function
Invoke(DispID
: Integer; const
IID: TGUID; LocaleID: Integer;
Flags: Word; var
Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; virtual
; stdcall
;
// Protected declarations
procedure
DoStatusTextChange(const
Text: WideString); safecall;
procedure
DoProgressChange(Progress: Integer; ProgressMax: Integer); safecall;
procedure
DoCommandStateChange(Command: Integer; Enable: WordBool); safecall;
procedure
DoDownloadBegin; safecall;
procedure
DoDownloadComplete; safecall;
procedure
DoTitleChange(const
Text: WideString); safecall;
procedure
DoPropertyChange(const
szProperty: WideString); safecall;
procedure
DoBeforeNavigate2(const
pDisp: IDispatch; var
URL: OleVariant;
var
Flags: OleVariant; var
TargetFrameName: OleVariant; var
PostData: OleVariant;
var
Headers: OleVariant; var
Cancel: WordBool); safecall;
procedure
DoNewWindow2(var
ppDisp: IDispatch; var
Cancel: WordBool); safecall;
procedure
DoNavigateComplete2(const
pDisp: IDispatch; var
URL: OleVariant); safecall;
procedure
DoDocumentComplete(const
pDisp: IDispatch; var
URL: OleVariant); safecall;
procedure
DoOnQuit; safecall;
procedure
DoOnVisible(Visible: WordBool); safecall;
procedure
DoOnToolBar(ToolBar: WordBool); safecall;
procedure
DoOnMenuBar(MenuBar: WordBool); safecall;
procedure
DoOnStatusBar(StatusBar: WordBool); safecall;
procedure
DoOnFullScreen(FullScreen: WordBool); safecall;
procedure
DoOnTheaterMode(TheaterMode: WordBool); safecall;
public
// Public declarations
constructor
Create(AOwner: TComponent); override
;
destructor
Destroy; override
;
procedure
ConnectTo(Source: IWebBrowser2);
procedure
Disconnect;
property
SinkIID: TGuid read
FSinkIID;
property
Source: IWebBrowser2 read
FSource;
published
// Published declarations
property
WebObj: IWebBrowser2 read
FSource;
property
Connected: Boolean read
FConnected;
property
StatusTextChange: TIEStatusTextChangeEvent read
FStatusTextChange write
FStatusTextChange;
property
ProgressChange: TIEProgressChangeEvent read
FProgressChange write
FProgressChange;
property
CommandStateChange: TIECommandStateChangeEvent read
FCommandStateChange write
FCommandStateChange;
property
DownloadBegin: TIEDownloadBeginEvent read
FDownloadBegin write
FDownloadBegin;
property
DownloadComplete: TIEDownloadCompleteEvent read
FDownloadComplete write
FDownloadComplete;
property
TitleChange: TIETitleChangeEvent read
FTitleChange write
FTitleChange;
property
PropertyChange: TIEPropertyChangeEvent read
FPropertyChange write
FPropertyChange;
property
BeforeNavigate2: TIEBeforeNavigate2Event read
FBeforeNavigate2 write
FBeforeNavigate2;
property
NewWindow2: TIENewWindow2Event read
FNewWindow2 write
FNewWindow2;
property
NavigateComplete2: TIENavigateComplete2Event read
FNavigateComplete2 write
FNavigateComplete2;
property
DocumentComplete: TIEDocumentCompleteEvent read
FDocumentComplete write
FDocumentComplete;
property
OnQuit: TIEOnQuitEvent read
FOnQuit write
FOnQuit;
property
OnVisible: TIEOnVisibleEvent read
FOnVisible write
FOnVisible;
property
OnToolBar: TIEOnToolBarEvent read
FOnToolBar write
FOnToolBar;
property
OnMenuBar: TIEOnMenuBarEvent read
FOnMenuBar write
FOnMenuBar;
property
OnStatusBar: TIEOnStatusBarEvent read
FOnStatusBar write
FOnStatusBar;
property
OnFullScreen: TIEOnFullScreenEvent read
FOnFullScreen write
FOnFullScreen;
property
OnTheaterMode: TIEOnTheaterModeEvent read
FOnTheaterMode write
FOnTheaterMode;
end
;
// Register procedure
procedure
Register
;
implementation
function
TIEEvents._AddRef: Integer;
begin
// No more than 2 counts
result := 2;
end
;
function
TIEEvents._Release: Integer;
begin
// Always maintain 1 ref count (component holds the ref count)
result := 1;
end
;
function
TIEEvents.QueryInterface(const
IID: TGUID; out Obj): HResult;
begin
// Clear interface pointer
Pointer(Obj) := nil
;
// Attempt to get the requested interface
if
(GetInterface(IID, Obj)) then
// Success
result := S_OK
// Check to see if the guid requested is for the event
else
if
(IsEqualIID(IID, FSinkIID)) then
begin
// Event is dispatch based, so get dispatch interface (closest we can come)
if
(GetInterface(IDispatch, Obj)) then
// Success
result := S_OK
else
// Failure
result := E_NOINTERFACE;
end
else
// Failure
result := E_NOINTERFACE;
end
;
function
TIEEvents.GetIDsOfNames(const
IID: TGUID; Names: Pointer; NameCount,
LocaleID: Integer; DispIDs: Pointer): HResult;
begin
// Not implemented
result := E_NOTIMPL;
end
;
function
TIEEvents.GetTypeInfo(Index
, LocaleID: Integer; out TypeInfo): HResult;
begin
// Clear the result interface
Pointer(TypeInfo) := nil
;
// No type info for our interface
result := E_NOTIMPL;
end
;
function
TIEEvents.GetTypeInfoCount(out Count: Integer): HResult;
begin
// Zero type info counts
Count := 0;
// Return success
result := S_OK;
end
;
function
TIEEvents.Invoke(DispID
: Integer; const
IID: TGUID; LocaleID: Integer; Flags: Word;
var
Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;
var
pdpParams: PDispParams;
lpDispIDs: array
[0..63] of
TDispID;
dwCount: Integer;
begin
// Get the parameters
pdpParams := @Params;
// Events can only be called with method dispatch, not property get/set
if
((Flags and
DISPATCH_METHOD) > 0) then
begin
// Clear DispID list
ZeroMemory(@lpDispIDs, SizeOf(lpDispIDs));
// Build dispatch ID list to handle named args
if
(pdpParams^.cArgs > 0) then
begin
// Reverse the order of the params because they are backwards
for
dwCount := 0 to
Pred(pdpParams^.cArgs) do
lpDispIDs[dwCount] := Pred(pdpParams^.cArgs) - dwCount;
// Handle named arguments
if
(pdpParams^.cNamedArgs > 0) then
begin
for
dwCount := 0 to
Pred(pdpParams^.cNamedArgs) do
lpDispIDs[pdpParams^.rgdispidNamedArgs^[dwCount]] := dwCount;
end
;
end
;
// Unless the event falls into the "else" clause of the case statement the result is S_OK
result := S_OK;
// Handle the event
case
DispID
of
102: DoStatusTextChange(pdpParams^.rgvarg^[lpDispIds[0]].bstrval);
104: DoDownloadComplete;
105: DoCommandStateChange(pdpParams^.rgvarg^[lpDispIds[0]].lval,
pdpParams^.rgvarg^[lpDispIds[1]].vbool);
106: DoDownloadBegin;
108: DoProgressChange(pdpParams^.rgvarg^[lpDispIds[0]].lval,
pdpParams^.rgvarg^[lpDispIds[1]].lval);
112: DoPropertyChange(pdpParams^.rgvarg^[lpDispIds[0]].bstrval);
113: DoTitleChange(pdpParams^.rgvarg^[lpDispIds[0]].bstrval);
250: DoBeforeNavigate2(IDispatch(pdpParams^.rgvarg^[lpDispIds[0]].dispval),
POleVariant(pdpParams^.rgvarg^[lpDispIds[1]].pvarval)^,
POleVariant(pdpParams^.rgvarg^[lpDispIds[2]].pvarval)^,
POleVariant(pdpParams^.rgvarg^[lpDispIds[3]].pvarval)^,
POleVariant(pdpParams^.rgvarg^[lpDispIds[4]].pvarval)^,
POleVariant(pdpParams^.rgvarg^[lpDispIds[5]].pvarval)^,
pdpParams^.rgvarg^[lpDispIds[6]].pbool^);
251: DoNewWindow2(IDispatch(pdpParams^.rgvarg^[lpDispIds[0]].pdispval^),
pdpParams^.rgvarg^[lpDispIds[1]].pbool^);
252: DoNavigateComplete2(IDispatch(pdpParams^.rgvarg^[lpDispIds[0]].dispval),
POleVariant(pdpParams^.rgvarg^[lpDispIds[1]].pvarval)^);
253:
begin
// Special case handler. When Quit is called, IE is going away so we might
// as well unbind from the interface by calling disconnect.
DoOnQuit;
// Call disconnect
Disconnect;
end
;
254: DoOnVisible(pdpParams^.rgvarg^[lpDispIds[0]].vbool);
255: DoOnToolBar(pdpParams^.rgvarg^[lpDispIds[0]].vbool);
256: DoOnMenuBar(pdpParams^.rgvarg^[lpDispIds[0]].vbool);
257: DoOnStatusBar(pdpParams^.rgvarg^[lpDispIds[0]].vbool);
258: DoOnFullScreen(pdpParams^.rgvarg^[lpDispIds[0]].vbool);
259: DoDocumentComplete(IDispatch(pdpParams^.rgvarg^[lpDispIds[0]].dispval),
POleVariant(pdpParams^.rgvarg^[lpDispIds[1]].pvarval)^);
260: DoOnTheaterMode(pdpParams^.rgvarg^[lpDispIds[0]].vbool);
else
// Have to idea of what event they are calling
result := DISP_E_MEMBERNOTFOUND;
end
;
end
else
// Called with wrong flags
result := DISP_E_MEMBERNOTFOUND;
end
;
constructor
TIEEvents.Create(AOwner: TComponent);
begin
// Perform inherited
inherited
Create(AOwner);
// Set the event sink IID
FSinkIID := DWebBrowserEvents2;
end
;
destructor
TIEEvents.Destroy;
begin
// Disconnect
Disconnect;
// Perform inherited
inherited
Destroy;
end
;
procedure
TIEEvents.ConnectTo(Source: IWebBrowser2);
var
pvCPC: IConnectionPointContainer;
begin
// Disconnect from any currently connected event sink
Disconnect;
// Query for the connection point container and desired connection point.
// On success, sink the connection point
OleCheck(Source.QueryInterface(IConnectionPointContainer, pvCPC));
OleCheck(pvCPC.FindConnectionPoint(FSinkIID, FCP));
OleCheck(FCP.Advise(Self, FCookie));
// Update internal state variables
FSource := Source;
// We are in a connected state
FConnected := True;
// Release the temp interface
pvCPC := nil
;
end
;
procedure
TIEEvents.Disconnect;
begin
// Do we have the IWebBrowser2 interface?
if
Assigned(FSource) then
begin
try
// Unadvise the connection point
OleCheck(FCP.Unadvise(FCookie));
// Release the interfaces
FCP := nil
;
FSource := nil
;
except
Pointer(FCP) := nil
;
Pointer(FSource) := nil
;
end
;
end
;
// Disconnected state
FConnected := False;
end
;
procedure
TIEEvents.DoStatusTextChange(const
Text: WideString);
begin
// Call assigned event
if
Assigned(FStatusTextChange) then
FStatusTextChange(Self, Text);
end
;
procedure
TIEEvents.DoProgressChange(Progress: Integer; ProgressMax: Integer);
begin
// Call assigned event
if
Assigned(FProgressChange) then
FProgressChange(Self, Progress, ProgressMax);
end
;
procedure
TIEEvents.DoCommandStateChange(Command: Integer; Enable: WordBool);
begin
// Call assigned event
if
Assigned(FCommandStateChange) then
FCommandStateChange(Self, Command, Enable);
end
;
procedure
TIEEvents.DoDownloadBegin;
begin
// Call assigned event
if
Assigned(FDownloadBegin) then
FDownloadBegin(Self);
end
;
procedure
TIEEvents.DoDownloadComplete;
begin
// Call assigned event
if
Assigned(FDownloadComplete) then
FDownloadComplete(Self);
end
;
procedure
TIEEvents.DoTitleChange(const
Text: WideString);
begin
// Call assigned event
if
Assigned(FTitleChange) then
FTitleChange(Self, Text);
end
;
procedure
TIEEvents.DoPropertyChange(const
szProperty: WideString);
begin
// Call assigned event
if
Assigned(FPropertyChange) then
FPropertyChange(Self, szProperty);
end
;
procedure
TIEEvents.DoBeforeNavigate2(const
pDisp: IDispatch; var
URL: OleVariant; var
Flags:
OleVariant; var
TargetFrameName: OleVariant; var
PostData: OleVariant; var
Headers: OleVariant; var
Cancel: WordBool);
begin
// Call assigned event
if
Assigned(FBeforeNavigate2) then
FBeforeNavigate2(Self, pDisp, URL, Flags, TargetFrameName, PostData, Headers, Cancel);
end
;
procedure
TIEEvents.DoNewWindow2(var
ppDisp: IDispatch; var
Cancel: WordBool);
var
pvDisp: IDispatch;
begin
// Call assigned event
if
Assigned(FNewWindow2) then
begin
if
Assigned(ppDisp) then
pvDisp := ppDisp
else
pvDisp := nil
;
FNewWindow2(Self, pvDisp, Cancel);
ppDisp := pvDisp;
end
;
end
;
procedure
TIEEvents.DoNavigateComplete2(const
pDisp: IDispatch; var
URL: OleVariant);
begin
// Call assigned event
if
Assigned(FNavigateComplete2) then
FNavigateComplete2(Self, pDisp, URL);
end
;
procedure
TIEEvents.DoDocumentComplete(const
pDisp: IDispatch; var
URL: OleVariant);
begin
// Call assigned event
if
Assigned(FDocumentComplete) then
FDocumentComplete(Self, pDisp, URL);
end
;
procedure
TIEEvents.DoOnQuit;
begin
// Call assigned event
if
Assigned(FOnQuit) then
FOnQuit(Self);
end
;
procedure
TIEEvents.DoOnVisible(Visible: WordBool);
begin
// Call assigned event
if
Assigned(FOnVisible) then
FOnVisible(Self, Visible);
end
;
procedure
TIEEvents.DoOnToolBar(ToolBar: WordBool);
begin
// Call assigned event
if
Assigned(FOnToolBar) then
FOnToolBar(Self, ToolBar);
end
;
procedure
TIEEvents.DoOnMenuBar(MenuBar: WordBool);
begin
// Call assigned event
if
Assigned(FOnMenuBar) then
FOnMenuBar(Self, MenuBar);
end
;
procedure
TIEEvents.DoOnStatusBar(StatusBar: WordBool);
begin
// Call assigned event
if
Assigned(FOnStatusBar) then
FOnStatusBar(Self, StatusBar);
end
;
procedure
TIEEvents.DoOnFullScreen(FullScreen: WordBool);
begin
// Call assigned event
if
Assigned(FOnFullScreen) then
FOnFullScreen(Self, FullScreen);
end
;
procedure
TIEEvents.DoOnTheaterMode(TheaterMode: WordBool);
begin
// Call assigned event
if
Assigned(FOnTheaterMode) then
FOnTheaterMode(Self, TheaterMode);
end
;
procedure
Register
;
begin
// Register the component on the Internet tab of the IDE
RegisterComponents('Internet', [TIEEvents]);
end
;
end
.
--- Project source ----
//Notes: Add a button and the IEEvents component to Form1. The button1 click event
// shows how the IE enumeration is achieved, and shows how the binding is done:
unit
Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IEEvents, StdCtrls, ActiveX, SHDocVw;
type
TForm1 = class
(TForm)
IEEvents1: TIEEvents;
Button1: TButton;
procedure
FormCreate(Sender: TObject);
procedure
FormDestroy(Sender: TObject);
procedure
IEEvents1Quit(Sender: TObject);
procedure
IEEvents1DownloadBegin(Sender: TObject);
procedure
IEEvents1DownloadComplete(Sender: TObject);
procedure
Button1Click(Sender: TObject);
procedure
IEEvents1ProgressChange(Sender: TObject; Progress,
ProgressMax: Integer);
private
{ Private declarations }
FTimeList: TList;
public
{ Public declarations }
end
;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure
TForm1.Button1Click(Sender: TObject);
var
pvShell: IShellWindows;
pvWeb2: IWebBrowser2;
ovIE: OleVariant;
dwCount: Integer;
begin
// Create the shell windows interface
pvShell := CoShellWindows.Create;
// Walk the internet explorer windows
for
dwCount := 0 to
Pred(pvShell.Count) do
begin
// Get the interface
ovIE := pvShell.Item(dwCount);
// At this point you can evaluate the interface (LocationUrl, etc)
// to decide if this is the one you want to connect to. For demo purposes,
// the code will bind to the first one
ShowMessage(ovIE.LocationURL);
// QI for the IWebBrowser2
if
(IDispatch(ovIE).QueryInterface(IWebBrowser2, pvWeb2) = S_OK) then
begin
IEEvents1.ConnectTo(pvWeb2);
// Release the interface
pvWeb2 := nil
;
end
;
// Clear the variant
ovIE := Unassigned;
// Break if we connected
if
IEEvents1.Connected then
break;
end
;
// Release the shell windows interface
pvShell := nil
;
end
;
procedure
TForm1.FormCreate(Sender: TObject);
begin
// Create the time list
FTimeList := TList.Create;
end
;
procedure
TForm1.FormDestroy(Sender: TObject);
begin
// Free the time list
FTimeList.Free;
end
;
procedure
TForm1.IEEvents1DownloadBegin(Sender: TObject);
begin
// Add the current time to the list
FTimeList.Add(Pointer(GetTickCount));
end
;
procedure
TForm1.IEEvents1DownloadComplete(Sender: TObject);
var
dwTime: LongWord;
begin
// Pull the top item off the list (make sure there is one)
if
(FTimeList.Count > 0) then
begin
dwTime := LongWord(FTimeList[Pred(FTimeList.Count)]);
FTimeList.Delete(Pred(FTimeList.Count));
// Now calculate total based on current time
dwTime := GetTickCount - dwTime;
// Display a message showing total download time
ShowMessage(Format('Download time for "%s" was %d ms', [IEEvents1.WebObj.LocationURL, dwTime]));
end
;
end
;
procedure
TForm1.IEEvents1Quit(Sender: TObject);
begin
ShowMessage('About to disconnect');
end
;
procedure
TForm1.IEEvents1ProgressChange(Sender: TObject; Progress,
ProgressMax: Integer);
begin
Caption := IntToStr(Progress);
end
;
end
.