![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Кто-нибудь занимался интерфейсами на Дельфи? [D6]
star © (2002-01-17 12:32:00)Люди, помогите! Разбирался с интерфейсами - ничего не понял! Вроде документация на русском, и сам вроде не тупой, но ничего не понял !!! Нужно работать с нитерфейсом IHTMLDocument2. На мои жалкие попытки Дельфи ругались разными словами. Может кто-нибудь сможет объяснить на элементарных примерах, что такое эти интерфейсы, и как с ними работать ...
Не могу уже, голова опухла ...
star (2002-01-24 19:30:00) [1]Урррррра! Работает! Вытаскивает и текст, и ХТМЛ из IE и из Outlook Express, и даже из Проводника. Классно!
ОГРОМНОЕ СПАСИБО Romkin, ВЫ МНЕ ОЧЕНЬ ПОМОГЛИ! (Предложение про пиво остается в силе :-)))))
Спасибо так же всем, кто пытался объяснить мне, что такое интерфейсы и как с ними работать. Я, правда, еще не совсем въехал, но въеду, это точно.
star (2002-01-23 18:07:00) [2]To Romkin: Будете в Смоленске - с меня пиво! Пойду пробовать, завтра сообщу о результатах ...
Romkin (2002-01-23 17:02:00) [3]Мда, точно, spDoc2.bgColor := "red"
А насчет манипуляции - получаем IHTMLDocument, потом его окно, а потом оттуда- IHTMLDocument2
Впрочем, как видно в Romkin © (23.01.02 11:43)
просто делаешь все Variant и работаешь в нем... (spDoc: Variant), и все должно работать...
nikkie (2002-01-23 16:55:00) [4]>Romkin
большой пирожок тебе от star"a должен быть :)))
я бы только сказал, что вместо
spDoc2.bgColor := clRed
должно быть
spDoc2.bgColor := "red"
но к сути дела эта строчка никакого отношения не имеет :)
>и все равно это вызовы к IE
смотря, что ты под IE подразумеваешь. если iexplore.exe - то я не согласен.
честно говоря, в этом коде мне непонятны манипуляции
if succeeded(hr) then
begin
spDisp := spDoc.Script;
spWin := IHTMLWindow2(spDisp);
spDoc2 := spWin.Document;
end
поскольку исходный код - микрософтовский, то надо верить, что были на то причины. но я бы все же попробовал просто
spDoc2 = (spDoc as IHTMLDocument2)
Romkin (2002-01-23 16:26:00) [5]ессно, подразумевается uses Windows, Messages :-))
CoInitialize/CoUninitialize - в принципе не нужно, это делается в ActiveX.pas
Romkin (2002-01-23 16:22:00) [6]полностью star © (21.01.02 12:28) переводится примерно так
(могут быть неточности в прототипах.... ObjectFromLresult)
uses MSHTML, ActiveX;
{$R *.DFM}
function EnumChildProc(Handle:HWND; Param: LParam): BOOL; stdcall;
var
Buffer: string;
nSize: integer;
begin
nSize := GetClassName(Handle, nil, 0);
SetLength(Buffer, nSize);
GetClassName(Handle, PChar(Buffer), nSize);
if AnsiCompareText(Buffer,"Internet Explorer_Server") = 0 then
begin
HWND(Param) := Handle;
Result := False; //found
end
else Result := True; //continue Enum
end;
{
STDAPI ObjectFromLresult(
LRESULT lResult,
REFIID riid,
WPARAM wParam,
void** ppvObject
);
}
type
TObjectFromLResultProc =
function(ALRes: LResult; const IID: TGuid; WPar: WParam; out Obj): HResult; stdcall;
//Вообще-то это событие OnGetDocInterface объекта CDlg - ???
procedure GetDocInterface(AHandle: HWND);
var
hInst: HModule;
ObjectFromLResultProc:TObjectFromLResultProc;
spDoc: IHTMLDocument;
spDoc2: IHTMLDocument2;
nMsg: Cardinal;
lRes: LResult;
hWndChild: HWND;
hr: HResult;
spDisp: IDispatch;
spWin: IHTMLWindow2;
begin
if AHandle = 0 then exit;
hWndChild := 0;
//Get 1st document window
EnumChildWindows(AHandle, @EnumChildProc, hWndChild);
if hWndChild = 0 then exit; //Document not ready
hInst := LoadLibrary("OLEACC.DLL");
if hInst = 0 then exit; //не загрузилось...
CoInitialize(nil);
try
nMsg := RegisterWindowMessage("WM_HTML_GETOBJECT");
SendMessageTimeout(hWndChild, nMsg, 0, 0, SMTO_ABORTIFHUNG,
1000, DWORD(lRes));
ObjectFromLResultProc := nil;
ObjectFromLResultProc := GetProcAddress(hInst,"ObjectFromLresult");
if @ObjectFromLResultProc <> nil then begin
hr := ObjectFromLResultProc(lRes, IID_IHTMLDocument, 0, spDoc);
if succeeded(hr) then
begin
spDisp := spDoc.Script;
spWin := IHTMLWindow2(spDisp);
spDoc2 := spWin.Document; //????
//change color
spDoc2.bgColor := clRed;
end;
end;
finally
ObjectFromLResultProc := nil;
FreeLibrary(hInst);
CoUninitialize;
end;
end;
2nikkie: и все равно это вызовы к IE
Romkin (2002-01-23 15:16:00) [7]Сдаюсь. Для перевода надо бы полное описание функции ObjectFromLresult - было бы удобней
Итак:
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
{
TCHAR buf[100];
::GetClassName( hwnd, (LPTSTR)&buf, 100 );
if ( _tcscmp( buf, _T("Internet Explorer_Server") ) == 0 )
{
*(HWND*)lParam = hwnd;
return FALSE;
}
else
return TRUE;
};
Лучше перевести так
uses ComObj; //там потребуется, чтобы CoInitialize не вызывать...
function EnumChildProc(Handle:HWND; Param: LParam): BOOL; stdcall;
var
Buffer: string;
nSize: integer;
begin
nSize := GetClassName(Handle, nil, 0);
SetLength(Buffer, nSize);
GetClassName(Handle, PChar(Buffer), nSize);
if AnsiCompareText(Buffer,"Internet Explorer_Server") = 0 then
begin
HWND(Param) := Handle;
Result := False; //found
end
else Result := True; //continue Enum
end;
Вроде ошибок нет... Поправьте, если чо
nikkie (2002-01-23 14:33:00) [8]>А из любого приложения - у каждого сервера COM свой интерфейс...
вот именно. твой пример работает только с IE. с тем же Outlook"ом он работать не будет, понятное дело. а пример, приведенный star"ом видимо претендует на то, что сможет это сделать. посмотри, что он делает - это вовсе не обычный пример использования интерфейсов в си.
честно говоря, про эту Active Accessibility я первый раз услышал, поэтому весьма любопытно.
Romkin (2002-01-23 14:03:00) [9]А здесь что? Пример - загрузка документа и получение в Memo1 его боди
Browser.Visible := true; - можно выкинуть, и тогда никто не догадается, откуда HTML :-))
А из любого приложения - у каждого сервера COM свой интерфейс... Здесь - что-то, предоставляющее IWebBrowser, у меня это IE4
nikkie (2002-01-23 12:35:00) [10]>Romkin
нее... это не то. star же говорит: "одной из функций программы будет вытаскивание хтмл-а из IE-серверов" - то есть не только из IE, а из любого приложения, хостящего MSHTML.
>star
а у меня такой dll и нет... ну покажи как переводишь или конкретно - в чем проблема?
Romkin (2002-01-23 11:43:00) [11]Переводить не советую - это пример, как обращаться с интерфейсом "вручную", обычно пользуются функциями OLE.
Может, тебе нужно что-то подобное?
uses
..., shdocvw;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
Browser: Variant;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses MSHTML, COMObj;
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var
Doc: Variant;
begin
Browser := CoInternetExplorer.Create; //or GetActiveOleObject(CLASS_InternetExplorer);
Browser.Navigate(Edit1.Text);
Browser.Visible := true;
Doc := (Browser.Document);
Memo1.Text := Doc.Body.InnerHTML;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Browser.Quit;
end;
star (2002-01-23 10:20:00) [12]Есть, конечно.
nikkie (2002-01-21 15:35:00) [13]сорри, а у тебя oleacc.dll есть?
star (2002-01-21 12:28:00) [14]Вот пример из MSDN на С++, как получить IHTMLDocument2 из окна класса Internet Explorer_Server (в окно такого класса вводится текст письма в Outlook Express, такое окно создается так же IE). Я попытался переделать его на Дельфи - костьми лег, ничего не получается. В дельфи есть и IHTMLDocument2, и IHtmlWindow2 и прочее. Борланды позаботились, но как я не бился - ничего не получается. До сих пор я считал, что Дельфи ничуть не хуже С++ (а в некоторых случаях даже лучше). Теперь сомнения берут ... Может, конечно, просто знаний нехватает...
Может здесь есть знатоки обоих языков, помогут перевести?
(Просто разработана здоровенныя программа, одной из функций которой будет вытаскивание хтмл-а из IE-серверов. Она написана на дельфи, и я не в состоянии перевести ее всю на С++)
#include
#include
#include
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
{
TCHAR buf[100];
::GetClassName( hwnd, (LPTSTR)&buf, 100 );
if ( _tcscmp( buf, _T("Internet Explorer_Server") ) == 0 )
{
*(HWND*)lParam = hwnd;
return FALSE;
}
else
return TRUE;
};
//You can store the interface pointer in a member variable
//for easier access
void CDlg::OnGetDocInterface(HWND hWnd)
{
CoInitialize( NULL );
// Explicitly load MSAA so we know if it"s installed
HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") );
if ( hInst != NULL )
{
if ( hWnd != NULL )
{
HWND hWndChild=NULL;
// Get 1st document window
::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)
&hWndChild );
if ( hWndChild )
{
CComPtr spDoc;
LRESULT lRes;
UINT nMsg = ::RegisterWindowMessage(
_T("WM_HTML_GETOBJECT") );
::SendMessageTimeout( hWndChild, nMsg, 0L, 0L,
SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes );
LPFNOBJECTFROMLRESULT pfObjectFromLresult =
(LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst,
_T("ObjectFromLresult") );
if ( pfObjectFromLresult != NULL )
{
HRESULT hr;
hr = (*pfObjectFromLresult)( lRes,
IID_IHTMLDocument, 0, (void**)&spDoc );
if ( SUCCEEDED(hr) )
{
CComPtr spDisp;
CComQIPtr spWin;
spDoc->get_Script( &spDisp );
spWin = spDisp;
spWin->get_document( &spDoc.p );
// Change background color to red
spDoc->put_bgColor( CComVariant("red") );
}
}
} // else document not ready
} // else Internet Explorer is not running
::FreeLibrary( hInst );
} // else Active Accessibility is not installed
CoUninitialize();
}
iZEN (2002-01-19 19:03:00) [15]Отличная книжка: "Разработка COM-приложений в среде Delphi", Хармон, издательство: Вильямс, вышла в апреле 2000, 464 страниц.
Аннотация.
Книга посвящена методике разработки приложений на базе модели составных объектов (СОМ) в среде Delphi. В первых пяти главах детально рассматриваются основные идеи модели СОМ и способы ее реализации в среде Delphi. Здесь же достаточно подробно описаны два распространенных программных продукта, которые могут служить основой для создания разнообразных прикладных СОМ-приложений — Microsoft ADO и Microsoft Agent. В последующих четырех главах возможности СОМ-технологии рассматриваются более углубленно. Читатель знакомится с методикой создания сетевых взаимодействующих приложений, средствами хранения структурированных данных в едином файле, наборами свойств и контейнерами OLE, использованием модели СОМ для расширения возможностей оболочки Windows. Книга рассчитана на читателей, имеющих опыт работы в среде Delphi.
[ http://www.books.ru/shop/books/6414]
Владимир Васильев (2002-01-18 11:05:00) [16]Если ВСЁ ОЧЕНЬ УПРОСТИТЬ то когда вы работаете с "чужими" интерфейсами - то вы их скорее не "создаёте" - точнее будет сказать вы их их получаете :
(хотя в справке конечно вы прочтёте напр. : "Creates a single uninitialized object ... ").
Напр, для работы с WinMediaPlayer вам,сначала, нужно получить у COM сервера интерфейс IGraphBuilder
Объявляем
GB : IGraphBuilder
Проверяем, а поддерживается ли наш интерфейс есди да то GB содержит ссылку на него
hr:=CoCreateInstance(CLSID_FilterGraph, nil, CLSCTX_INPROC, IID_IGraphBuilder, GB);
if (FAILED(hr)) then
begin
messagebox(self.Handle,pchar(geterror(hr)),"Error",MB_OK);
end;
И далее уже получаем другие нужные интерфейсы используя полученный ранее GB
MC : IMediaControl
hr := GB.QueryInterface(IID_IMediaControl, MC) ;
if failed(hr) then ...
Вернёмся к IE. Вам необходимо импортировать две библиотеки типов:
Type Lib: C:\WINNT\System32\shdocvw.dll
Type Lib: C:\WINNT\System32\mshtml.tlb //IHTMLDocument2 описан здесь
Ваши шаги (предварительно прочтите хелп на команды меню)
Из Delphi:
1 : Component->Import ActiveX Control
2 : Project-> Import Type Library
Практическая работа с интерфейсами лучше всего описана
у Чарльза Калверта в его замечательных книгах Delphi UnLeashed 2
(Direct X ) и Delphi UnLeashed 4 (IE, Word, Excel ). Они, конечно, дорогие - но это лучшее, что есть в продаже.
Удачи.
star (2002-01-18 09:21:00) [17]To Владимир Васильев:
Огромное спасибо за практический пример. Мне действительно нужно вытащить ХТМЛ, но не из WebBrowser, а из чужого окна класса Internet Explorer_Server. Попробую воспользоваться Вашим примером. Единственное, что меня смущает: Дельфи кричал, что не знает что такое IHTMLDocument2. Где объявлен этот интерфейс?
Вот что мне не нравится в той документации, что я читал, так это то, что нет нормальных практических примеров использования интерфейсов. Везде начинают с "создадим свой интерфейс ..." и сюсюкаются с этим своим интерфейсом не несущим никакой полезной информации, а в следующей главе рвут с места в карьер, приводя дикое нагромождение непонятного кода и ничего не поясняя ...
oomneeq (2002-01-17 21:09:00) [18]http://195.162.48.134/Doc/Delphi/2001_05_delphi_com/#01
Владимир Васильев (2002-01-17 19:19:00) [19]Фрагмент фильтрует теги <В> и покозывает сам текст
Var
Doc : IHTMLDocument2;
All : IHTMLElementCollection;
Item : OleVariant;
Len,i : Integer;
S : String;
.....
Doc := WebBrowser1.Document as IHTMLDocument2;
while doc.readyState<>"complete"
do application.ProcessMessages;
All := Doc.All;
Len := All.Length;
for i := 0 to Len - 1 do
begin
Item := All.Item(i, varEmpty);
if Item.Tagname="B" then
begin
S:=Item.InnerText;// что там у меня такое "жирное" в тексте ?
end;
end;
Doc:=nil;
All:=nil;
vuk (2002-01-17 17:35:00) [20]>I krome togo, mehanizmi realizacii interface i override metodov
>realizovani v Delphi nastolko pohoje
В каком смысле "похоже"? Я бы не сказал. Это разные вещи как по сути, так и по результату на выходе. Возможно Вас сбивает с толку то, что реализуемые интерфейсы перечисляются в одном списке с классом-предком...