Привет всем.
использую такой код, для получения IHTMLElementCollection не нулевой длины (get_length больше 100). далее прошу IDispatch каждого элемента — все ок, НО: какой интерфейс можно поросить у этого IDispatch, если в MSDN написано, что эта коллекция состоит из "LINK Element | LINK Object" и "AREA Element | AREA Object"? если просить IHTMLLinkElement или IHLink, то вызов QueryInterface никогда не будет успешным
IUnknown *pUnk = theApp.m_pBrowser->m_spOleObject;
IHTMLDocument2 *pDoc2 = NULL;
VARIANT v, vIndex;
IHTMLElementCollection *pEColl = NULL;
long i, ECLen;
IDispatch *pDispatch;
IHTMLLinkElement *pLink;
pUnk->QueryInterface (__uuidof(IHTMLDocument2), (void**)&pDoc2);
pDoc2->get_links (&pEColl);
pEColl->get_length (&ECLen);
if (ECLen==0)
MessageBox ("IHTMLElementCollection Empty"); // это сообщение никогда не появляется
v.vt = VT_I4;
vIndex.vt = VT_I4;
vIndex.intVal = 0;
for (i=0; i<ECLen; i++)
{
v.intVal = i; pDispatch = NULL;
pEColl->item (v, vIndex, &pDispatch);
if (pDispatch)
{
pLink = NULL;
// если просить IHTMLLinkElement или IHLink, то приводимый ниже вызов QueryInterface никогда не будет успешным
pDispatch->QueryInterface (__uuidof(IHlink), (void**)&pLink);
if (pLink)
MessageBox ("Success: Target Ok", "CWrView::CorrectLinks()");
}
}
Если кратко, то какие интерфейсы (конкретные названия) можно попросить у элементов коллекции (см. сабж), если они (элементы) сами не являются коллекциями? Получив указатель на IDispatch какого-либо элемента коллекции, можно ли узнать какие интерфейсы поддерживает этот IDispatch?
Здравствуйте SVV, Вы писали:
SVV>Если кратко, то какие интерфейсы (конкретные названия) можно попросить у элементов коллекции (см. сабж), если они (элементы) сами не являются коллекциями?
Это тогда как интерфейс должен называться? IHTMLElementCollectionCollection?
SVV>Получив указатель на IDispatch какого-либо элемента коллекции, можно ли узнать какие интерфейсы поддерживает этот IDispatch?
IDispatch сам по себе поддерживает IDispatch и IUnknown. А что там ещё поддерживает класс, реализующий этот IDispatch
нада в библиотеке типа копать...
Здравствуйте DNS, Вы писали:
DNS>Пробовал __uuidof(...) на IID_... менять?
да. без разницы.
DNS>На этом мысль заканчивается...
жаль, может новый фрагмент кода поможет?
теперь кусочек программы выглядит так:
pEColl->item (v, vIndex, &pDispatch);
if (pDispatch)
{
hr = pDispatch->QueryInterface (__uuidof(IHTMLElement), (void**)&pElem);
if (SUCCEEDED(hr))
{// сюда попадаем
hr = pElem->QueryInterface (IID_IHTMLLinkElement/*__uuidof(IHTMLLinkElement)*/, (void**)&pLink);
// а здесь hr = 80004002if (SUCCEEDED(hr))
MessageBox ("Success: Target Ok"); // соотв. MessageBox я никогда не вижу
}
}
Здравствуйте SVV, Вы писали:
SVV>Здравствуйте DNS, Вы писали:
DNS>>Пробовал __uuidof(...) на IID_... менять? SVV>да. без разницы.
DNS>>На этом мысль заканчивается... SVV>жаль, может новый фрагмент кода поможет?
Просить надо IHTMLAnchorBlaBlaBla.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте DNS, Вы писали:
DNS>А попробуй таперича у своего IHTMLElement-а tagName попросить — что это за элемент-то такой....
tagName говорит что это "A" (сам не понимаю что это).
hr = pDispatch->QueryInterface (__uuidof(IHTMLElement), (void**)&pElem);
if (SUCCEEDED(hr))
{
// TK подсказал, какой интерфейс можно попросить - IHTMLAnchorBlaBlaBla (IHTMLAnchorElement)
hr = pElem->QueryInterface (IID_IHTMLAnchorElement, (void**)&pAnchor);
if (SUCCEEDED(hr))
{
bsName = L"_self";
pAnchor->put_target (bsName);
//pAnchor->put_href (bsName);
pAnchor->Release ();
}
pElem->get_tagName (&bsName);
From_BSTR_To_char (&bsName, &szName[0], 128); // переводим BSTR bsName в char szName[128] - чтоб в дебагере удобней видеть было
// в дебагере же и вижу что szName всегда = "A"
bsName = L"Test Words"; // а это чтоб убедиться что ф-я From_BSTR_To_char работает правильно
// вместо L"Test Words"; можно писать SysAllocString(L"Test Words");
From_BSTR_To_char (&bsName, &szName[0], 128); // вот здесь и убеждаемся (к сожалению только я) что szName получает "Test Words"
pElem->Release ();
}
Ну и как по tagName определить что это за элемент? может есть нормальные функции по работе с BSTR, точнее по записи и считыванию оттудава строк типа "Test Words"?
Но это пока что не важно. Раз я знаю какой интерфейс просить, смотрю в MSDN какие методы у него есть, вижу то что надо: put_href и put_target, причем put_target должен "говорить" WebBrowser'у что ссылки нужно открывать в том же окне (put_target("_self")), в новом окне ("_blank") и т.п., но это не работает — все ссылки открываются в новом окне ie. Как на это повлиять? Ради этого я и связывался с IHTMLElementCollection, и его составными частями...
Другими словами, нужно открывать все ссылки в том же окне (фрейме), используя базовый класс CView, CAxHostWindow и/или Microsoft HTA Document.
Cмотрю в MSDN какие методы есть у IHTMLAnchorElement, вижу то что надо: put_href и put_target, причем put_target должен "говорить" WebBrowser'у что ссылки нужно открывать в том же окне (put_target("_self")), в новом окне ("_blank") и т.п., но это не работает — все ссылки открываются в новом окне ie. Как на это повлиять? Ради этого я и связывался с IHTMLElementCollection, и его составными частями...
Другими словами, нужно открывать все ссылки в том же окне (фрейме), используя базовый класс CView, CAxHostWindow и/или Microsoft HTA Document.
Наверное нужно как-то начинать реализовывать IHlinkFrame? С чего начать?
Здравствуйте SVV, Вы писали:
SVV> SVV>Cмотрю в MSDN какие методы есть у IHTMLAnchorElement, вижу то что надо: put_href и put_target, причем put_target должен "говорить" WebBrowser'у что ссылки нужно открывать в том же окне (put_target("_self")), в новом окне ("_blank") и т.п., но это не работает — все ссылки открываются в новом окне ie. Как на это повлиять? Ради этого я и связывался с IHTMLElementCollection, и его составными частями...
Правильно. HTML Document сам себя перезагружать не умеет — он только уведомляет контейнер о необходимости осуществления перехода. Если контейнер этого не поддерживает, то он работает как умеет...
SVV>Другими словами, нужно открывать все ссылки в том же окне (фрейме), используя базовый класс CView, CAxHostWindow и/или Microsoft HTA Document.
SVV>Наверное нужно как-то начинать реализовывать IHlinkFrame? С чего начать?
Нужно создать класс — наследник CAxHostWindow и в нем реализовать IHlinkFrame
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте TK, Вы писали:
TK>Правильно. HTML Document сам себя перезагружать не умеет — он только уведомляет контейнер о необходимости осуществления перехода. Если контейнер этого не поддерживает, то он работает как умеет...
SVV>>Другими словами, нужно открывать все ссылки в том же окне (фрейме), используя базовый класс CView, CAxHostWindow и/или Microsoft HTA Document. SVV>>Наверное нужно как-то начинать реализовывать IHlinkFrame? С чего начать?
TK>Нужно создать класс — наследник CAxHostWindow и в нем реализовать IHlinkFrame
Так вроде бы у меня уже есть
class CWrApp : public CWinApp
{
public:
CComObject<CAxHostWindow>* m_pBrowser;
...
};
а CAxHostWindow объявлен так:
class ATL_NO_VTABLE CAxHostWindow :
public CComCoClass<CAxHostWindow , &CLSID_NULL>,
public CComObjectRootEx<CComSingleThreadModel>,
public CWindowImpl<CAxHostWindow>,
public IAxWinHostWindow,
public IOleClientSite,
public IOleInPlaceSiteWindowless,
public IOleControlSite,
public IOleContainer,
public IObjectWithSiteImpl<CAxHostWindow>,
public IServiceProvider,
public IAdviseSink,
#ifndef _ATL_NO_DOCHOSTUIHANDLER
public IDocHostUIHandler,
#endif
public IDispatchImpl<IAxWinAmbientDispatch, &IID_IAxWinAmbientDispatch, &LIBID_ATLLib>
{
public:
// ctor/dtor
CAxHostWindow()
{
...
};
а что с этим можно сделать? и стоит ли обсуждение этого вопроса вынести в отдельную ветку, с названием что-то вроде "Реализация IHlinkFrame с использованием CAxHostWindow"?
Спасибо за идею, но без вашей помощи я не смогу ею воспользоваться.
P.S. Мыши плакали, кололись, но продолжали жрать кактус.
Здравствуйте SVV, Вы писали:
SVV>>>Другими словами, нужно открывать все ссылки в том же окне (фрейме), используя базовый класс CView, CAxHostWindow и/или Microsoft HTA Document. SVV>>>Наверное нужно как-то начинать реализовывать IHlinkFrame? С чего начать?
TK>>Нужно создать класс — наследник CAxHostWindow и в нем реализовать IHlinkFrame
SVV>Так вроде бы у меня уже есть
Должно быть:
class CAxHLinkHost : public CAxHostWindow,
public IHLinkFrame
{
public:
...
BEGIN_COM_MAP(CAxHLinkHost)
COM_INTERFACE_ENTRY(IHLinkFrame)
COM_INTERFACE_ENTRY_CHAIN(CAxHostWindow)
END_COM_MAP()
...
}
И дальше везде использовать не CAxHostWindow, а CAxHLinkHost.
SVV>а что с этим можно сделать? и стоит ли обсуждение этого вопроса вынести в отдельную ветку, с названием что-то вроде "Реализация IHlinkFrame с использованием CAxHostWindow"?
Мне все равно...
SVV>P.S. Мыши плакали, кололись, но продолжали жрать кактус.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте Vi2, Вы писали:
Vi2>Здравствуйте SVV, Вы писали:
SVV>> ... SVV>> bsName = L"_self"; SVV>> pAnchor->put_target (bsName);
Vi2>А если здесь писАть bsName = SysAllocString(L"_self") или другой вариант получения именно BSTR, а не LPOLESTR ?
не думаю, что в данном случае это поможет. Навигацию то все равно осуществлять некому... (если это top document)
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте Vi2, Вы писали:
SVV>> ... SVV>> bsName = L"_self"; SVV>> pAnchor->put_target (bsName);
Vi2>А если здесь писАть bsName = SysAllocString(L"_self") или другой вариант получения именно BSTR, а не LPOLESTR ?
или другой вариант получения именно BSTR, а не LPOLESTR ? хотя это наверное уже обсуждалось, и надо поискать по форумам...