Форум программистов, компьютерный форум, киберфорум C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
5 / 5 / 2
Регистрация: 29.08.2012
Сообщений: 46
1

Как перейти к закладке в документе, загруженном в CppWebBrowser?

06.03.2016, 21:01. Показов 563. Ответов 0
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Кучу всего перелопатил - горы инфы, а того, что надо - не могу собрать. Помогите, пожалуйста.
Задача в следующем. Пишу справку в мою программу. Пишу в вёрде, сохраняю в *.mht Загружаю в CppWebBrowser:

C++ (Qt)Выделить код
1
#include <mshtml.h>
В событии нажатия на кнопку загрузки файла:

C++ (Qt)Выделить код
1
2
3
4
string s;
s = GetCurrentDir().c_str();
s += "\\1.mht";
CppWebBrowser1 -> Navigate(WideString(s.c_str()));
Далее. В тексте документа справки описывается моя программа и описывается назначение параметров, которые вводит пользователь. Текст с картинками (может, и таблицы будут). При клике мышкой на Label с названием параметра - на панели, на которой находится CppWebBrowser1 программа должна автоматически перемещаться в соответствующее место в документе. За двое суток танцев с бубном нарыл в инете и слепил до кучи следующую функцию:

C++ (Qt)Выделить код
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void ScrollToInHelp(TCppWebBrowser *WB, int Pos)
{LPDISPATCH pDispatch = WB -> Document;
 if (pDispatch)
 {IHTMLDocument2* pHTMLDocument2 = NULL;
  HRESULT hr = pDispatch -> QueryInterface(IID_IHTMLDocument2, (void**)&pHTMLDocument2);
  if (SUCCEEDED(hr))
  {IHTMLWindow2* pHTMLWindow2 = NULL;
   hr = pHTMLDocument2 -> get_parentWindow(&pHTMLWindow2);
   if (SUCCEEDED(hr))
   {pHTMLWindow2 -> scrollTo(0, Pos);
    pHTMLWindow2 -> Release();
   }
   pHTMLDocument2->Release();
  }
 }
}
Перехожу к нужному месту в документе так:

C++ (Qt)Выделить код
1
ScrollToInHelp(CppWebBrowser1, HelpPos);
Проблема в том, что значение переменной Pos - это расстояние от начала документа до нужного места.... в пикселях. Можно, конечно, подолбаться и повбивать фиксированные значения пикселей для каждого параметра. Тем более, что размер панели со справкой фиксирован и формат текста от размеров окна не зависит. Но! Параметров у меня невдолбенно много и если мне захочется дописать что-либо в текст справки или исправить его, то придётся всё перевбивать... В общем, было бы намного проще, если б в вёрде подобавлять закладок в ключевые места и навигироваться не по пикселям, а по ним. По идее, это должно выглядеть как-то так:

C++ (Qt)Выделить код
1
2
CppWebBrowser1->OleObject.OlePropertyGet("Document").OlePropertyGet("All").OleFunction("Item", i).OlePropertyGet("InnerText");
//именно эта запись возвращает текст i-го блока данных в документе (просто для примера)
Только надо в кавычках писать что-то типа "закладка" и как-то переходить к ним, каким-то образом видоизменив ту функцию ScrollToInHelp(...).

В общем, как перейти к закладке в mht документе, загруженном в CppWebBrowser? Заранее спасибо!

Добавлено через 23 часа 10 минут
В общем, не без помощи, но разобрался. Выкладываю ответ, может, кому пригодится.

Т.к. в mht-документе закладок много, то чтоб не анализировать весь документ при каждом новом поиске следующей закладки - использую вектор структур, в который записываю имена закладок и отступ в пикселях от начала документа до закладки.

В Unit1.h пишу:

C++ (Qt)Выделить код
1
2
3
4
struct AllHelpAnchors
{BSTR* Anch; // Здесь будут имена закладок
 long Pos; // здесь отступ в пикселях от начала документа
};
В Unit1.cpp:

C++ (Qt)Выделить код
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <mshtml.h>
#include <vector.h>
 
HRESULT hr;
bool HelpLoaded, VectorCreated;
BSTR* Anch;
 
vector<struct AllHelpAnchors > HelpAnchors;
 
string CurDir;
//---------------------------------------------------------------------------
void __fastcall TForm1::FormActivate(TObject *Sender)
{string filename;
 CurDir = GetCurrentDir().c_str();
 filename = CurDir + "\\Doc\\1.mht";
 
 Anch = new BSTR;
 HelpAnchors.resize(0);
 
 HelpLoaded = false;
 VectorCreated = false;
 
 if (FileExists(filename.c_str()))
 {CppWebBrowser1 -> Navigate(WideString(filename.c_str()));
  HelpLoaded = true;
 }
}
Теперь функция заполнения вектора структур:

C++ (Qt)Выделить код
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
void CreateHelpVector(TCppWebBrowser *WB)
{if (VectorCreated == false)
 {struct AllHelpAnchors ha; // вспомогательная структура, которую я хотел заталкивать в HelpAnchors с помощью .push_back(), но не получилось, видимо, из-за указателей. Переделывать не стал.
  ha.Anch = new BSTR;
  long QuantityOfAnchors;
  int i;
  long l;
  IDispatch* retVal;
  IHTMLElement* pElem;
  IHTMLAnchorElement* pAnchElem;
  LONG pos;
  VARIANT varIndex;
  varIndex.vt = VT_UINT;
  VARIANT var2;
  IHTMLDocument2* pHTMLDocument2 = NULL;
  LPDISPATCH pDispatch = WB -> Document;
  hr = pDispatch -> QueryInterface(IID_IHTMLDocument2, (void**)&pHTMLDocument2);
  if (SUCCEEDED(hr))
  {IHTMLElementCollection* pIHTMLElementCollection = NULL;
   hr = pHTMLDocument2 -> get_anchors(&pIHTMLElementCollection);
   if (SUCCEEDED(hr))
   {pIHTMLElementCollection -> get_length(&QuantityOfAnchors); // количество закладок в документе
    for (i = 0; i < QuantityOfAnchors; i++)
    {varIndex.lVal = i;
     VariantInit(&var2);
     l = pIHTMLElementCollection -> item(varIndex, var2, &retVal);
     if (l == S_OK)
     {hr = retVal -> QueryInterface(IID_IHTMLAnchorElement, (void**)&pAnchElem);
      if (SUCCEEDED(hr))
      {l = pAnchElem -> get_name(ha.Anch);
       if (l == S_OK)
       {hr = retVal -> QueryInterface(IID_IHTMLElement, (void **)&pElem);
        if (SUCCEEDED(hr))
        {hr = pElem -> get_offsetTop(&ha.Pos);
         if (SUCCEEDED(hr))
         {HelpAnchors.resize(HelpAnchors.size() + 1);
          HelpAnchors[HelpAnchors.size() - 1].Anch = new BSTR;
          *HelpAnchors[HelpAnchors.size() - 1].Anch = *ha.Anch;
          HelpAnchors[HelpAnchors.size() - 1].Pos = ha.Pos;
         }
        }
       }
      }
     }
    }
   }
  }
  VectorCreated = true;
 }
}
Вектор заполнен, теперь функция перехода к закладке (модифицированная приведенная в первом сообщении

C++ (Qt)Выделить код
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void ScrollToInHelp(TCppWebBrowser *WB, BSTR* Anch)
{LPDISPATCH pDispatch = WB -> Document;
 if (pDispatch)
 {IHTMLDocument2* pHTMLDocument2 = NULL;
  HRESULT hr = pDispatch -> QueryInterface(IID_IHTMLDocument2, (void**)&pHTMLDocument2);
  if (SUCCEEDED(hr))
  {IHTMLWindow2* pHTMLWindow2 = NULL;
   hr = pHTMLDocument2 -> get_parentWindow(&pHTMLWindow2);
   if (SUCCEEDED(hr))
   {int i;
    for (i = 0; i < HelpAnchors.size(); i++)
     if (wcscmp(*HelpAnchors[i].Anch, *Anch) == 0) // сравнивает, совпадает ли закладка с требуемой
    {pHTMLWindow2 -> scrollTo(0, HelpAnchors[i].Pos - 7); // вычитаю 7 пикселей, чтоб красивый отступ сверху оставить
     pHTMLWindow2 -> Release();
     break;
    }
   }
   pHTMLDocument2->Release();
  }
 }
}
Вот и всё. При первом вызове окна справки вызываю функцию:

C++ (Qt)Выделить код
1
2
3
//...
CreateHelpVector(CppWebBrowser1);
//...
При клике на элементе, для которого в справке есть закладка делаю так:

C++ (Qt)Выделить код
1
2
3
4
//...
*Anch = L"z019"; // "z019" - это имя девятнадцатой закладки в *.mht
ScrollToInHelp(CppWebBrowser1, Anch);
//...
Всем спасибо за активное участие и посильную помощь!
1
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.03.2016, 21:01
Ответы с готовыми решениями:

Как поменять текст в закладке?
Народ, помоги чем можешь проблема такая: есть закладка, зовут 'myBM ' она содержит текст...

Как удалить ярлык в закладке игры? :D
Как удалить этот ярлык там где нет данных? :(

Как выполнить код в Form1_Load в уже загруженном приложении
Добрый вечер! Никак не соображу как вызывать: есть Form1 c private void Form1_Load(object...

Как вызвать Popup меню на закладке TTabset
Для удаления закладки в Runtime режиме, хочу сделать чтобы при нажатии правой кнопкой мыши над...

0
06.03.2016, 21:01
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.03.2016, 21:01
Помогаю со студенческими работами здесь

Как установить свой фон в закладке компонента PageControl
В программе используется PageControl. Нужно изменить его фон на тот, который установлен в форме (...

Как преобразовать текст в документе из латиницы в кириллицу ("только в кавычках") во всем документе
Здравствуйте уважаемые форумчане! Собственно сабж. Нашел интересную функцию которая работает а...

Как спрятать CppWebBrowser?
Всем привет. Суть проблемы при динамическом создание TCppWebBrowser, нужно указывать где будет...

Как полностью закрыть cppwebbrowser?
После работы cppwebbrowser'a программа ест примерно 80-100 озу. Как я могу закрыть браузер, не...

Как нажать ссылку в CppWebBrowser
Доброго времени суток :) нужно с помощьюу/в cppwebbrowser, выбрать нужную ссылку и кликнуть ее...

Как динамически создать компонент CppWebBrowser
Создаю динамически форму (newform), на ней динамически создаю копонент CppWebBrowser (Browser). Но...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru