На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
Страницы: (2) 1 [2]  все  ( Перейти к последнему сообщению )  
> Как сделать автоматическое нажатье по ссылке в окне браузера?
    Цитата Katerina1993 @
    Работает, только первые две строчки не пойму для чего getAttribute и WideCharToString? Мне удалось запусить только через Elem.setAttribute.

    Первые две строчки это получение. Необходима дополнительная переменная типа WideString перед преобразованием кодировок. Свойство Caption у формы требует для установки строку в кодировке ANSI, а из интерфейса будет получен OleVariant. Присвоение его к строке нужного типа автоматически преобразует данные в строку WideString. А вот дальше из WideString надо руками преобразовать текст в ANSI путем вызова WideCharToString. Но в качестве параметра этой функции нужна строка типа PWideChar. Преобразовать сразу из OleVariant в PWideChar не так просто. Гораздо проще использовать дополнительную переменную, которая уже будет содержать исходные данные для перекодировки в ANSI. И уже в заголовке формы строка будет отображена в правильной кодировке символов.

    И третья строка изменяет значение свойства value на 'Send text!'. Но помните, что там тоже используются не String, а WideString и требуется соблюдать и преобразовывать кодировку текста.
      Ошибку выдает, на строке где Caption.
      ExpandedWrap disabled
        var
          Elem: IHTMLElement;
          Text: OleVariant;
          Caption : WideString;
         
        .....
         
         
         Text := Elem.getAttribute('value', 0);
         Caption := WideCharToString(@Text[1]);



      Цитата
      [Error] Unit1.pas(232): Variable required
      Сообщение отредактировано: Katerina1993 -
        Так где вы это вызываете. Если вне метода основного окна программы, тогда используйте Form1.Caption
          В процедуре вызываю:
          ExpandedWrap disabled
            procedure TForm1.Button4Click(Sender: TObject);
            var
              Elem: IHTMLElement;
              Text: OleVariant;
              Caption : WideString;
            begin
              try
             
                Elem := GetElementById(WebBrowser1.Document, 'title', 1, 'input') as IHTMLElement; // Поиск только среди ссылок
                if Assigned(Elem) then begin
                    Text := Elem.getAttribute('value', 0);
                    Caption := WideCharToString(@Text[1]);
             
                end;
             
             
              except
             
              end;
            end;
            Тогда зачем вам там переменная Caption?
            ExpandedWrap disabled
              procedure TForm1.Button4Click(Sender: TObject);
              var
                Elem: IHTMLElement;
                Text: WideString;
              begin
                try
               
                  Elem := GetElementById(WebBrowser1.Document, 'title', 1, 'input') as IHTMLElement; // Поиск только среди ссылок
                  if Assigned(Elem) then begin
                      Text := Elem.getAttribute('value', 0);
                      Caption := WideCharToString(@Text[1]);
               
                  end;
               
               
                except
               
                end;
              end;
              Еще замечание по поиску элементов по классу. Я этого не делал, но значение className у элемента будет содержать не имя класса, а список классов через разделитель. Необходимо перечислять все классы при поиске или сделать разделение className на соответствующие классы и искать среди них. Как один из вариантов функцию можно организовать так
              ExpandedWrap disabled
                const
                  constInvalidHTML = 'Invalid HTML document';
                  constInvalidHTMLStructure = constInvalidHTML + ' structure';
                 
                // Функция поиска элемента на странице с учетом тэга, индекса и имени идентификатора (id) или класса (className)
                // aDocument = WebBrowser.Document,
                // iNum = номер вхождения элемента в документ с таким ID (начинаются с 1),
                // sClassNameOrID = строка с именем класса начинающимся с точки
                //                  или строка с id (не должна начинаться с точки),
                // sTagName = имя тэга у элемента
                function QueryElement(const aDocument: IDispatch; iNum: LongInt = 1;
                                      const sClassNameOrID: String = '';
                                      const sTagName: WideString = ''): IDispatch;
                  function AnyID(const s1: String; const s2: String): Boolean; begin Result := True; end;
                  function min(a, b: LongInt): LongInt; inline; begin if a < b then Result := a else Result := b; end;
                  function PosDef(const aPattern: WideString; const aText: WideString; iDefault: LongInt): LongInt;
                    begin Result := Pos(aPattern, aText); if Result = 0 then Result := iDefault; end;
                const
                  aTabChar: WideString = ' ';
                  aSpaceChar: WideString = #9;
                var
                  Doc: IHTMLDocument2;
                  Body: IHTMLElement2;
                  Tags: IHTMLElementCollection;
                  Tag: IHTMLElement;
                  c, i, l, n, Count: LongInt;
                  f, m: Boolean;
                  w, s: WideString;
                  comp: function (const s1: String; const s2: String): Boolean;
                begin
                  f := False;
                  Result := nil;
                  if iNum < 1 then Exit;
                  if (sClassNameOrID <> '*') and (sClassNameOrID <> '') then begin
                    comp := @AnsiSameText;
                    f := sClassNameOrID[1] = '.';
                  end else comp := @AnyID;
                  if Supports(aDocument, IHTMLDocument2, Doc) then begin
                    if Supports(Doc.body, IHTMLElement2, Body) then begin
                      if sTagName = ''
                        then Tags := Body.getElementByTagName('*')
                        else Tags := Body.getElementsByTagName(sTagName);
                      Count := Tags.length;
                      c := 0;
                      for i := 0 to Count - 1 do begin
                        Tag := Tags.item(i, EmptyParam) as IHTMLElement;
                        if f then begin // Если ищем по имени класса, тогда надо вручную
                // разбить строку className на составляющие и сравнивать имя класса отдельно для каждого класса у элемента
                          m := False; // Флаг совпадения одного из классов
                          w := Tag.className; // сохраняем значение в локальную переменную для изменения
                          l := Length(w); // можно не буду описывать тривиальные действия
                          while l > 0 do begin // цикл достижения конца строки (в строке не осталось имен классов)
                            inc(l); // можно не буду описывать тривиальные действия
                            // нахождение позиции ближайшего к началу строки разделителя имен классов
                            n := min(PosDef(aSpaceChar, w, l), PosDef(aTabChar, w, l));
                            s := '.' + Copy(w, 1, n - 1); // копирование очередного имени класса в отдельную переменную
                            // пропуск всех символов разделителей между именами (вместо этого можно воспользоваться trim после Delete, но так лучше)
                            while (n < l) and ((w[n] = aSpaceChar) or (w[n] = aTabChar)) do inc(n);
                            Delete(w, 1, n - 1); // Убираем из строки className очередное имя класса со всеми последующими разделителями
                            l := Length(w); // можно не буду описывать тривиальные действия
                            if comp(s, sClassNameOrID) then begin // Сравнение имен классов с именем в параметре
                              m := True; // При совпадении устанавливаем флаг ...
                              break; // ... и прерываем цикл по именам классов
                            end;
                          end;
                          if m then inc(c); // Если флаг установлен, тогда совпадение найдено и просто увеличиваем счетчик совпадений
                        end else if comp(Tag.id, sClassNameOrID) then inc(c); // тоже самое, но для id
                        if c = iNum then begin // Счетчик совпадений равен индексу элемента из параметра
                          Result := Tag; // Возвращаем этот элемент как найденный...
                          break; // ... и прерываем цикл по элементам
                        end;
                      end;
                    end else raise Exception.Create(constInvalidHTMLStructure + '!');
                  end else raise Exception.Create(constInvalidHTML + '!');
                end;
              Вот как-то так. Но проверьте код. Я опять печатал в браузере. Могут быть очепятки или не исправленные имена переменных. Пройдите по шагам для лучшего представления о происходящем.
              Я оставил комментарии в коде. Надеюсь они помогут вам исправить ошибки (особенно проверьте индексы).

              Добавлено
              Ну и примеры поиска элементов с её помощью
              ExpandedWrap disabled
                procedure TForm1.Button4Click(Sender: TObject);
                var
                  Elem: IHTMLElement;
                  Text: WideString;
                begin
                  try
                 
                    Elem := QueryElement(WebBrowser1.Document, 'title', 1) as IHTMLElement; // Поиск первого среди всех на странице по id
                    if Assigned(Elem) then begin
                        Text := Elem.getAttribute('value', 0);
                        Caption := WideCharToString(@Text[1]);
                    end;
                    Elem := QueryElement(WebBrowser1.Document, '.submitbutton', 1) as IHTMLElement; // Поиск первого среди всех на странице по className
                    if Assigned(Elem) then begin
                        Text := Elem.getAttribute('value', 0);
                        Caption := WideCharToString(@Text[1]);
                    end;
                    Elem := QueryElement(WebBrowser1.Document, 'title', 5) as IHTMLElement; // Поиск пятого элемента среди всех на странице по id и индексу
                    if Assigned(Elem) then begin
                        Text := Elem.getAttribute('value', 0);
                        Caption := WideCharToString(@Text[1]);
                    end;
                    Elem := QueryElement(WebBrowser1.Document, '.submitbutton', 3) as IHTMLElement; // Поиск третьего элемента по className и индексу
                    if Assigned(Elem) then begin
                        Text := Elem.getAttribute('value', 0);
                        Caption := WideCharToString(@Text[1]);
                    end;
                 
                 
                    Elem := QueryElement(WebBrowser1.Document, 'title', 1, 'input') as IHTMLElement; // Поиск только среди input по id
                    if Assigned(Elem) then begin
                        Text := Elem.getAttribute('value', 0);
                        Caption := WideCharToString(@Text[1]);
                    end;
                    Elem := QueryElement(WebBrowser1.Document, '.submitbutton', 1, 'input') as IHTMLElement; // Поиск только среди input по className
                    if Assigned(Elem) then begin
                        Text := Elem.getAttribute('value', 0);
                        Caption := WideCharToString(@Text[1]);
                    end;
                    Elem := QueryElement(WebBrowser1.Document, 'title', 2, 'input') as IHTMLElement; // Поиск второго элемента только среди input по id и индексу
                    if Assigned(Elem) then begin
                        Text := Elem.getAttribute('value', 0);
                        Caption := WideCharToString(@Text[1]);
                    end;
                    Elem := QueryElement(WebBrowser1.Document, '.submitbutton', 4, 'input') as IHTMLElement; // Поиск четвертого элемента только среди input по className и индексу
                    if Assigned(Elem) then begin
                        Text := Elem.getAttribute('value', 0);
                        Caption := WideCharToString(@Text[1]);
                    end;
                 
                 
                    Elem := QueryElement(WebBrowser1.Document, '') as IHTMLElement; // Поиск первого элемента на странице по индексу (неявно)
                    if Assigned(Elem) then begin
                        Text := Elem.getAttribute('value', 0);
                        Caption := WideCharToString(@Text[1]);
                    end;
                    Elem := QueryElement(WebBrowser1.Document, '*', 1) as IHTMLElement; // Поиск первого элемента на странице по индексу (явно)
                    if Assigned(Elem) then begin
                        Text := Elem.getAttribute('value', 0);
                        Caption := WideCharToString(@Text[1]);
                    end;
                    Elem := QueryElement(WebBrowser1.Document, '', 3, '*') as IHTMLElement; // Поиск третьего элемента на странице по индексу (явно и с указанием маски тэгов)
                    if Assigned(Elem) then begin
                        Text := Elem.getAttribute('value', 0);
                        Caption := WideCharToString(@Text[1]);
                    end;
                    Elem := QueryElement(WebBrowser1.Document, '*', 4, 'input') as IHTMLElement; // Поиск четвертого элемента только среди input по индексу
                    if Assigned(Elem) then begin
                        Text := Elem.getAttribute('value', 0);
                        Caption := WideCharToString(@Text[1]);
                    end;
                 
                 
                  except
                 
                  end;
                end;
              Сообщение отредактировано: macomics -
                macomics, Inline поддерживается начиная с delphi 2005, а у меня Delphi 7.
                  Цитата Katerina1993 @
                  macomics, Inline поддерживается начиная с delphi 2005, а у меня Delphi 7.

                  Это не критично, если она будет не inline (просто уберите этот модификатор, я по привычке его использовал). У меня так вообще Lazarus на Linux и адаптировать под Delphi 7 c Internet Explorer бывает сложно.
                  Сообщение отредактировано: macomics -
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script execution time: 0,0459 ]   [ 16 queries used ]   [ Generated: 27.04.24, 10:55 GMT ]