
Тонкая настройка
Если требуется более тонкая настройка компонента, то необходимо реализовать интерфейс IDocHostUIHandler, позволяющий программисту взять под контроль поведение TWebBrowser.
Интерфейс объявлен как:
type TDocHostInfo = packed record cbSize: ULONG; dwFlags: DWORD; dwDoubleClick: DWORD; end;
const DOCHOSTUIFLAG_DIALOG = 1; DOCHOSTUIFLAG_DISABLE_HELP_MENU = 2; DOCHOSTUIFLAG_NO3DBORDER = 4; DOCHOSTUIFLAG_SCROLL_NO = 8; DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE = 16; DOCHOSTUIFLAG_OPENNEWWIN = 32; DOCHOSTUIFLAG_DISABLE_OFFSCREEN = 64; DOCHOSTUIFLAG_FLAT_SCROLLBAR = 128; DOCHOSTUIFLAG_DIV_BLOCKDEFAULT = 256; DOCHOSTUIFLAG_ACTIVATE_CLIENTHIT_ONLY = 512;
const DOCHOSTUIDBLCLK_DEFAULT = 0; DOCHOSTUIDBLCLK_SHOWPROPERTIES = 1; DOCHOSTUIDBLCLK_SHOWCODE = 2;
type IDocHostUIHandler = interface(IUnknown) [‘{bd3f23c0-d43e-11cf-893b-00aa00bdce1a}’] function ShowContextMenu(const dwID: DWORD; const ppt: PPOINT; const pcmdtReserved: IUnknown; const pdispReserved: IDispatch): HRESULT; stdcall; function GetHostInfo(var pInfo: TDOCHOSTUIINFO): HRESULT; stdcall; function ShowUI(const dwID: DWORD; const pActiveObject: IOleInPlaceActiveObject; const pCommandTarget: IOleCommandTarget; const pFrame: IOleInPlaceFrame; const pDoc: IOleInPlaceUIWindow): HRESULT; stdcall; function HideUI: HRESULT; stdcall; function UpdateUI: HRESULT; stdcall; function EnableModeless(const fEnable: BOOL): HRESULT; stdcall; function OnDocWindowActivate(const fActivate: BOOL): HRESULT; stdcall; function OnFrameWindowActivate(const fActivate: BOOL): HRESULT; stdcall; function ResizeBorder(const prcBorder: PRECT; const pUIWindow: IOleInPlaceUIWindow; const fRameWindow: BOOL): HRESULT; stdcall; function TranslateAccelerator(const lpMsg: PMSG; const pguidCmdGroup: PGUID; const nCmdID: DWORD): HRESULT; stdcall; function GetOptionKeyPath(var pchKey: POLESTR; const dw: DWORD): HRESULT; stdcall; function GetDropTarget(const pDropTarget: IDropTarget; out ppDropTarget: IDropTarget): HRESULT; stdcall; function GetExternal(out ppDispatch: IDispatch): HRESULT; stdcall; function TranslateUrl(const dwTranslate: DWORD; const pchURLIn: POLESTR; var ppchURLOut: POLESTR): HRESULT; stdcall; function FilterDataObject(const pDO: IDataObject; out ppDORet: IDataObject): HRESULT; stdcall; end;
Наследник TWebBrowser, реализующий этот интерфейс, должен быть объявлен так:
type TCustomizedWebBrowser = class(TWebBrowser, IDocHostUIHandler) // Реализация методов IDocHostUIHandler end;
На нашем CD-ROM приведен код такого компонента, реализующего минимальную функциональность. Вы можете использовать его как основу для создания своих расширенных наследников TWebBrowser.
А теперь рассмотрим наиболее интересные, с точки зрения программиста, методы интерфейса IDocHostUIHandler.
Начнем с метода ShowContextMenu:
function ShowContextMenu(const dwID: DWORD; const ppt: PPOINT; const pcmdtReserved: IUnknown; const pdispReserved: IDispatch): HRESULT;
Эта функция вызывается в том случае, когда TWebBrowser должен показать контекстное меню. Если вы отображаете собственное меню или хотите подавить меню, то функция должна вернуть S_OK, а если меню должен показать TWebBrowser — то S_FALSE.
В функцию передаются следующие параметры:
1. DwID — идентификатор меню, который может принимать одно из следующих значений:
const CONTEXT_MENU_DEFAULT = 0; CONTEXT_MENU_IMAGE = 1; CONTEXT_MENU_CONTROL = 2; CONTEXT_MENU_TABLE = 3; CONTEXT_MENU_DEBUG = 4; CONTEXT_MENU_1DSELECT = 5; CONTEXT_MENU_ANCHOR = 6; CONTEXT_MENU_IMGDYNSRC = 7;
В зависимости от значения идентификатора вы можете вывести подходящее меню.
2. ppt — координаты, в которых должно быть показано меню.
3. pcmdtReserved — интерфейс IOleCommandTarget, позволяющий запросить состояние команд и их выполнение.
4. pdispReserved — интерфейс IDispatch объекта, для которого вызывается меню.
Простейшая реализация этого метода может выглядеть следующим образом:
function TcustomizedWebBrowser.ShowContextMenu(const dwID: DWORD; const ppt: PPOINT; const pcmdtReserved: IUnknown; const pdispReserved: IDispatch): HRESULT; begin // Предполагаем, что поле FPopupMenu хранит ссылку // на компонент TPopupMenu if Assigned(FPopupMenu) then begin pmContext.Popup(ppt.X, ppt.Y); Result := S_OK; end else Result := S_FALSE; end;
Для полного запрета контекстного меню метод должен всегда возвращать S_OK.
Следующий метод, который мы рассмотрим — GetHostInfo:
unction GetHostInfo(var pInfo: TDocHostInfo): HRESULT; stdcall;
Приложение может заполнить структуру pInfo, определенную как:
TDocHostInfo = packed record cbSize: ULONG; dwFlags: DWORD; dwDoubleClick: DWORD; end;
Здесь dwFlags — битовая маска из следующих флагов, приведенных в табл. 4, а dwDoubleClick задает реакцию на двойной щелчок мышью и может принимать одно из значений, приведенных в табл. 5.
Метод должен вернуть S_OK или код ошибки OLE.
Например, чтобы создать окно с плоскими полосами прокрутки и без трехмерной рамки, необходимо реализовать этот метод следующим образом:
function TCustomizedWebBrowser.GetHostInfo( var pInfo: TDocHostInfo): HRESULT; stdcall; begin with pInfo do dwFlags := dwFlags or DOCHOSTUIFLAG_NO3DBORDER or DOCHOSTUIFLAG_FLAT_SCROLLBAR; Result := S_OK; end;
Метод
function TranslateAccelerator(const lpMsg: TMsg; const pguidCmdGroup: TGUID; nCmdID: DWORD): HRESULT; stdcall;
позволяет перехватить исполнение команд и обработку «горячих» клавиш и заменить ее на свою.
Метод
function GetOptionKeyPath(var pchKey: PWideChar; dwReserved: DWORD): HRESULT; stdcall;
позволяет задать путь в реестре, который TWebBrowser будет использовать для хранения настроек. Это дает возможность, в частности, сделать используемый в программе компонент независимым от текущих настроек Internet Explorer.
Путь должен содержаться в ключе реестра HKEY_CURRENT_USER.
Этот метод должен выделить память под строку функцией CoTackMemAlloc. Даже в случае ошибки параметр pchKey нужно инициализировать значением NIL или адресом строки. Метод возвращает S_OK в случае успеха, а в противном случае — S_FALSE.
Типичная реализация этого метода может выглядеть так:
function TCustomizedWebBrowser.GetOptionKeyPath( var pchKey: PWideChar; dwReserved: DWORD): HRESULT; var ResultLen: Integer; begin Result := S_FALSE; // В поле TCustomizedWebBrowser.FOptionKeyPath: String // хранится путь к настройкам if Length(FOptionKeyPath) > 0 then begin // Получаем длину строки UNICODE ResultLen := MultiByteToWideChar(CP_ACP, 0, PChar(FOptionKeyPath), -1, NIL, 0); // Выделяем память под буфер pchKey := CoTaskMemAlloc(ResultLen * SizeOf(WideChar)); // Если выделение успешно, копируем строку в буфер if Assigned(pchKey) then begin MultiByteToWideChar(CP_ACP, 0, PChar(FOptionKeyPath), -1, pchKey, ResultLen); Result := S_OK; end; end else begin // Свойство не задано — инициализируем параметр в NIL pchKey := NIL; end; end;
Существует ряд настроек, которые, несмотря на наличие обработчика GetOptionKeyPath, в любом случае берут из стандартных параметров Internet Explorer. Наиболее важными из них являются колонтитулы, используемые при печати. В версиях Internet Explorer до 5.5 включительно единственным способом изменить (или подавить) колонтитулы является запись новых значений в ключ реестра:
HKCU\Software\Microsoft\Internet Explorer\PageSetup
перед печатью и восстановление их после печати.
А теперь поговорим о методе
function GetExternal(var ppDispatch: IDispatch): HRESULT; stdcall;
Он позволяет вернуть указатель на реализованный в вашем приложении интерфейс IDispatch, который будет доступен для скриптов в TWebBrowser. Если вы не реализуете этот интерфейс, то параметр ppDispatch должен быть установлен равным NIL. Метод возвращает S_OK в случае успеха или код ошибки OLE в случае ошибки.
Методы этого интерфейса доступны из скриптов, которые выполняют в TWebBrowser следующим образом:
window.external.MethodName
Реализовать IDispatch можно, например, при помощи класса TAutoObject.
Метод TranslateURL позволяет изменить URL, по которому осуществляется загрузка страницы.
function TranslateURL(dwTranslate: DWORD; pchURLIn: PWideChar;
var ppchURLOut: PWideChar): HRESULT; stdcall;
pchURLIn указывает на строку, содержащую исходный URL. Если ваше приложение осуществляет трансляцию, то оно должно выделить память под новое значение, используя функцию CoTaskMemAlloc, заполнить буфер новым значением URL и вернуть S_OK.
В противном случае вы должны присвоить ppchURLOut значение NIL и вернуть S_FALSE. При возникновении ошибки метод должен вернуть OLE-код ошибки.
Обработчик вызывается только при интерактивном переходе по ссылке из TWebBrowser и не вызывается при переходе с помощью метода Navigate.
|
|