# Native Code > برنامه نویسی در Delphi > مقالات مرتبط با Delphi/Win32 >  نحوه مقداردهي به كنترلهاي يك فرم وب از طريق دلفي

## s.mostafa.rahmani

اگه شما روي فرمتون در دلفي يك كنترل WebBrowser داشته باشيد و در اون يك صفحه رو باز كرده باشيد، و اون فرم وب شامل يك يا چند فرم باشه، با كدهاي زير مي‌تونيد كنترلهاي اون فرم وب رو مقدار دهي و همچنين اون فرم وب رو Submit كنيد:

با اين پروسيجر مي‌تونيد يك كنترل (فيلد) خاص رو از يك فرم مقداردهي كنيد:
procedure WebFormSetFieldValue(const document: IHTMLDocument2;
  const formNumber: integer;
  const fieldName, newValue: string) ;
var
  form : IHTMLFormElement;
  field: IHTMLElement;
begin
  form := WebFormGet(formNumber, document) ;
  field := form.Item(fieldName,'') as IHTMLElement;
  if field = nil then Exit;

  if field.tagName = 'INPUT' then
    (field as IHTMLInputElement).value := newValue
  else
  if field.tagName = 'SELECT' then
    (field as IHTMLSelectElement).value := newValue
  else
  if field.tagName = 'TEXTAREA' then
    (field as IHTMLTextAreaElement).value := newValue;
end;البته تابع WebFormGet كه در پروسيجر بالا به كار برده شده، اين شكليه:
function WebFormGet(const formNumber: Integer;
  const document: IHTMLDocument2): IHTMLFormElement;
var
  forms: IHTMLElementCollection;
begin
  forms := document.forms as IHTMLElementCollection;
  Result := forms.item(formNumber, '') as IHTMLFormElement;
end;
و نحوه استفاده:
WebFormSetFieldValue((WebBrowser1.Document as IHTMLDocument2), 0, 'q', 'test');پارامتر اول كه Document كنترل WeBrowserتون رو ارسال مي‌كنه، پارامتر دوم شماره فرم وب هست، اگه صفحه باز شده در WebBrowser فقط يك فرم داشته باشه شماره‌اش صفره و اگه بيشتر شماره‌اش هم بيشتر مي‌شه (از صفر شروع مي‌شه).
پارامتر سوم، اسم كنترل هست. مثلاً در فرم صفحه اول سايت گوگل، كنترلي كه داخلش متن رو براي جستجو تايپ مي‌كنيد اسمش q است.
و پارامتر آخر مقداريه كه بايد داخل اون كنترل قرار بگيره.

اما نحوه Submit كردن فرم:
form := WebFormGet(0, WebBrowser1.Document AS IHTMLDocument2);
form.submit;

مشخصه كه اون صفر شماره فرمه، (يعني اگه بيشتر از يك فرم داشتيد بايد شماره فرم مورد نظر رو به جاي صفر قرار بديد).
ضمن اينكه اين متغير form از نوع IHTMLFormElement هست.
اما يك تابع براي اينكه اسم كنترلهاي فرم وب رو بتونيد بدست بياريد:
function WebFormFields(wBrowser: TWebBrowser;
  const formNo: Integer): TStringList;
var
  form: IHTMLFormElement;
  field: IHTMLElement;
  fName: string;
  idx : integer;
begin
  form := WebFormGet(formNo, wBrowser.Document as IHTMLDocument2);
  Result := TStringList.Create;
  for idx := 0 to form.length - 1 do
  begin
    field := form.item(idx, '') as IHTMLElement;
    if field = nil then
      Continue;
    fName := field.id;
    if field.tagName = 'INPUT' then
      fName := (field as IHTMLInputElement).name
    else
    if field.tagName = 'SELECT' then
      fName := (field as IHTMLSelectElement).name
    else
    if field.tagName = 'TEXTAREA' then
      fName := (field as IHTMLTextAreaElement).name;
    Result.Add(fName);
  end;
end;


و البته حتماً مي‌خواهيد كه اسامي فرمهاي داخل صفحه وب رو هم داشته باشيد. شايد اون صفحه بيشتر از يك فرم داشته باشه:
function WebFormNames(const document: IHTMLDocument2): TStringList;
var
  forms: IHTMLElementCollection;
  form: IHTMLFormElement;
  idx: Integer;
begin
  forms := document.forms as IHTMLElementCollection;
  Result := TStringList.Create;
  for idx := 0 to forms.length - 1 do
  begin
    form := forms.item(idx, 0) as IHTMLFormElement;
    Result.Add(form.name);
  end;
end;

همون طور كه مي‌بينيد كه مقداري كه دو تابع آخر برمي‌گردونن از نوع TStringList هست، مي‌تونيد اونها رو به شكل زير به Memo نسبت بديد:
ابتدا در قسمت var يك متغير از نوع TStringList تعريف كنيد:
Str: TStringList;
حال در يك پروسيجر مثلاً در OnClick يك Button بنويسيد:
Str := WebFormFields(WebBrowser1, 0);
Memo1.Lines.Assign(Str);
منبع: delphi.about.com

.

----------


## AlirezaBahredar

باسلام.....
سید ممنون از ترجمه ای که انجام داده بودی و واقعا مفید واقع شد.اما.....
به یک مشکلی برخوردم.من از طریق این روش می خوام به یک وب سایت وارد بشم.این سایت یک صفحه Login داره.
براحتی با کد بالا می تونم نام فیلدها رو بدست بیارم و به فیلد کاربر و رمز ورود مقدار نسبت بدم.اما عملیات Login صورت نمی گیره.علت هم به نظر خودم وجود فیلدهای پنهان (Hide Filed) هست که در این صفحه وجود داره.ممنون میشم واسم بگی چجوری می تونم با وجود این فیلدها وارد سایت بشم.
با تشکر.

----------


## s.mostafa.rahmani

راستشو بگم نمي‌دونم :(
من براي وارد شدن به Gmail و Yahoo استفاده كردم و جواب داد.
شرمندتم.

----------


## AlirezaBahredar

داداش این چه حرفیه.....دشمنت شرمنده...
موفق باشی.
از دوستان دیگه کسی در اینباره نظری نداره؟
با تشکر.

----------


## ali_sorouri2005

دوستان اگه امكان داره راهنمايي بفرماييد كه اين  IHTMLDocument2 از كجا اومده؟؟؟

با تشكر

----------


## ali_sorouri2005

من اين كدارو استفاده كردم ولي رو همين IHTMLDocument2 خطا ميده!!!
ميگه تعريف نشده!!
چه جوري تعريفش كنم؟؟؟

----------


## ali_sorouri2005

يعني واقعا هيچ كس نميدونه!!!
به نظرم فقط چندتا كلاس لازمه كه در قسمت uses اضافه بشه.
يه نفر اسماشونو به من بگه ممنون ميشم

----------


## vcldeveloper

> من اين كدارو استفاده كردم ولي رو همين IHTMLDocument2 خطا ميده!!!


uses MSHTML را اضافه کنید

----------


## ali_sorouri2005

ممنون اضافه  كردم
ولي اين دفعه روي WebFormGet خطا ميده.
يه uses ديگه هم مي خواد.
اگه يه لطف بكنيد اين رو هم بگيد ممنون ميشم.

----------


## vcldeveloper

function WebFormGet(const formNumber: Integer;
  const document: IHTMLDocument2): IHTMLFormElement;
var
  forms: IHTMLElementCollection;
begin
  forms := document.forms as IHTMLElementCollection;
  Result := forms.item(formNumber, '') as IHTMLFormElement;
end;

----------


## ali_sorouri2005

دوستان اين كد خيلي عالي بود .
اما نيازهاي منو هنوز برطرف نكرده.
چون اين كد فقط ميتونه submit كنه ولي من ميخوام يه دكمه توي صفحه رو از بين چندتا دكمه كه هيچ ربطي به submit نداره رو كليك كنم.
لطفا راهنماييم كنيد .
خيلي كارم گيره !
با تشكر فراوان

----------


## AlirezaBahredar

> دوستان اين كد خيلي عالي بود .
> اما نيازهاي منو هنوز برطرف نكرده.
> چون اين كد فقط ميتونه submit كنه ولي من ميخوام يه دكمه توي صفحه رو از بين چندتا دكمه كه هيچ ربطي به submit نداره رو كليك كنم.
> لطفا راهنماييم كنيد .
> خيلي كارم گيره !
> با تشكر فراوان


برای این کار شما بایستی با کمک دلفی با جاوااسکریپت ارتباط برقرار کنی.در این صورت به کلیه Element های موجود در وب فرمت و کلیه Event هاشون دسترسی پیدا می کنی.
این لینک کمکت می کنه.
موفق باشی.
https://barnamenevis.org/showth...8C%D9%BE%D8%AA

----------


## ali_sorouri2005

ممنونم
ولي من دكمه هايي كه توي صفحه دارم اسكريبتشون تو صفحه نيست كه من اسم اون اسكريبت رو به اون كدي كه در لينك بالا نوشتين بدم!
اين دكمه در حقيقت به تابع رو اجرا ميكنن!كه اين تابع سمت سرور اجرا ميشه!
چون صفحه با asp.net هستش.
واسه اين بايد چه كار كنم؟؟

با تشكر

----------


## vcldeveloper

شما باید ابتدا با مفاهیم مربوط به توسعه صفحات وب آشنا باشید. دکمه ها در یک صفحه وب (اگر Flash نباشه)، یا کنترل های استاندارد هستند که در یک فرم HTML قرار داده شدند، یا تصاویری هستند که یک لینک به آنها اختصاص داده شده، و با کلیک بر روی تصویر، لینک مربوطه باز می شود. اگر دکمه شما تصویر باشه، باید ببینید به چه لینکی اشاره میکنه، و آن را باز کنید. اگر دکمه ایی در یک فرم باشه، کدی به آن اختصاص داده شده، یا کدی را در سمت سرور اجرا می کند (که اسمش در سورس صفحه آمده)، یا یک کد جاوا اسکریپت را اجرا می کند. این کد جاوا اسکریپت هم ممکن هست یا در خودِ صفحه وجود داشته باشه، یا در فایل دیگه ایی نگهداری بشه که صفحه به آن ارجاع داده. اگر دکمه ایی از فرم باشه، و فرم را Submit میکنه، باید متناسب با روشی که برای ارسال داده در نظر گرفته شده (Post یا Get)، داده های فرم را هم به سرور ارسال کنید. البته یک فرم HTML می تواند علاوه بر فیلدهای Visible، فیلدهای Hidden هم داشته باشد، که در صفحه نمایش داده نمی شوند، ولی در سورس موجود هستند.

----------


## AlirezaBahredar

> ممنونم
> ولي من دكمه هايي كه توي صفحه دارم اسكريبتشون تو صفحه نيست كه من اسم اون اسكريبت رو به اون كدي كه در لينك بالا نوشتين بدم!
> اين دكمه در حقيقت به تابع رو اجرا ميكنن!كه اين تابع سمت سرور اجرا ميشه!
> چون صفحه با asp.net هستش.
> واسه اين بايد چه كار كنم؟؟
> 
> با تشكر


در تایید صحبتهای علی آقا می تونی یک سری به این لینک بزنی که کاملا دراین باره بحث شده
http://forum.p30world.com/showthread.php?t=262728

----------


## ali_sorouri2005

با تشكر از همه دوستاني كه منو راهنمايي كردن.
با كمك شما مشكل حل شد.
كاري كه مي خواستم با همون اجراي يه كد جاوا كه مثالشو alireza گذاشت (البته با كمي تغيير)حل شد.
و بقيه كار رو هم همين كد جاوا انجام ميده.

----------


## AlirezaBahredar

البته دوست عزیز کد "جاوااسکریپت" نه جاوا.

----------


## nasr

سلام

آقا این را من یه حالت دیگه میخوام

حالتی که پنجره ای باز میشه و یوزر و پسورد میخواد

مثل عکس ضمیمه

----------


## Hamid_PaK

حتی فایرفاکس، IE هم در این حالت پنجره ای جهت دریافت این اطلاعات نمایش میدهند، چرا که این نوع درخواست authenticationها فرم HTML ندارند که بتوان اطلاعات را وارد کرد، نوع اطلاعات درخواست شده (User و Pass) را از سرور دریافت کرده و  فرم مورد نظر را نمایش می دهند.

یا حق ...

----------


## nasr

پس یعنی میفرمایید نمیشه؟

----------


## ali_sorouri2005

نه اين صفحه نميشه.
چون كد html نداره اين صفحه كه بخواي با دلفي submit كني.

----------


## sp1000

سلام دوستان

من می خواستم صفحه ای از اینترنت رو توی برنامه ام لود کنم سپس با شناسایی قسمت هایی اون صفحه منظورم کلیدها و ادیت ها و گزینه ها و غیره ... است بتونم خودکار گزینه ها رو پر کنه سپس روی کلید کلیک کنه

حالا من با استفاده از WebBrowser تونستم این کارها رو انجام بدم

1- صفحه مورد نظرم رو به دلفی فرا خوانی کنم
2- متنی رو توی یک edit قرار بدم
3- گزینه ای رو از بین چند گزینه کشویی انتخاب کنم

و حالا توی دو مرحله مشکل دارم
1 - چند تا radiobutton هستش که من می خوام هر کدوم از اونها رو که بخوام انتخاب کنم (متاسفانه اسم همه ی این شی ها مثل هم هستند . اسمشون هست = bankname)


2- توی این صفحه دو تا button هست که من می خوام روی ثبت کلیک بشه ( بعد وصل میشه به بانک برای پرداخت) که متاسفانه وقتی submait می کنم به صفحه خطا منتقل میشه 

در ضمن از توی قسمت سورس صفحه درمورد اون button  این اطلاعات رو دارم
کد:

</td>
</tr>


<tr>
    <td class="titletd" height="100">
    </td>
    <td class="formfieldtd" style="text-align: left" valign="bottom">
        <p>
        <button type="submit" class="btn" style="width: 200; height: 22" onclick="setAction(method,'save');">
            <img border="0" src="/html/image/blt_01.gif" width="13" height="11"
                 align="absmiddle">
            ثبت
            . . .
        </button>
    </td>



از این کد استفاده می کنم برای submaite

کد:
var
form :IHTMLFormElement ;
begin
form := WebFormGet(0, WebBrowser1.Document AS IHTMLDocument2);
form.submit;


این هم اسم كنترلهاي فرم اون صفحه هستش

کد:
method
mobileNumber
requestedAmount

bankName
bankName
bankName
bankName
bankName
passlineEncoded
passline


لطفا بگید چی کار باید انجام بدم :ناراحت:

----------


## dark-man

سلام . برای لاگین به سایتهایی که با asp .net نوشته شدند از این کد هم می تونید استفاده کنید . 


unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  OleCtrls, SHDocVw, StdCtrls, mshtml, ExtCtrls, Buttons;
type
  TForm1 = class(TForm)
    WebBrowser1: TWebBrowser;
    Panel1: TPanel;
    BitBtn1: TBitBtn;
    Label1: TLabel;
    Button1: TButton;
    procedure WebBrowser1DocumentComplete(Sender: TObject;
      const pDisp: IDispatch; var URL: OleVariant);
    procedure BitBtn1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure WebBrowser1ProgressChange(Sender: TObject; Progress,
      ProgressMax: Integer);

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
var
  Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
var iDoc: IHtmlDocument2;
  i: integer;
  ov: OleVariant;
  iDisp: IDispatch;
  iColl: IHTMLElementCollection;
  iInputElement: IHTMLInputElement;
  iWindow : IHTMLWindow2;
begin
  WebBrowser1.ControlInterface.Document.QueryInterfa  ce(IHtmlDocument2, iDoc);
  if not assigned(iDoc) then begin
    Exit;
  end;
  ov := 'INPUT';
  IDisp := iDoc.all.tags(ov);
  if assigned(IDisp) then begin
    IDisp.QueryInterface(IHTMLElementCollection, iColl);
    if assigned(iColl) then begin
      for i := 1 to iColl.Get_length do begin
        iDisp := iColl.item(pred(i), 0);
        iDisp.QueryInterface(IHTMLInputElement, iInputElement);
        if assigned(iInputElement) then begin
          if iInputElement.Get_name = '__ViewStateGuid' then 
          begin
              iInputElement.Set_value('e34ab1f3-7047-48dd-8b81-c3b4830f2905');
          end;
          if iInputElement.Get_name = 'UsrNam' then 
          begin
              iInputElement.Set_value('****');
          end;
          if iInputElement.Get_name = 'UsrPwd' then 
          begin          
              iInputElement.Set_value('*****');
          end;
          if iInputElement.Get_name = 'CheckIt' then
          begin
              iWindow := iDoc.parentwindow;
              iWindow.execscript('javascript**:document.getElement  ById(' + QuetedStr('CheckIt') + ').click()', 'javascript');
          end;
        end;
      end;
    end;
  end;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  webbrowser1.Navigate('آدرس صفحه لاگین سایت رو اینجا قرار بدید');
end;

end.


فکر کنم کد به اندازه کافی واضح باشه اما توضیح میدم . مرورگر تحت دلفی یه متد داره که ondocumentcompelet هست که من برای لاگین از این متد استفاده کردم . اومدم فیلدهایی که لازم هست نوشته شوند رو پیدا کردم و بهشون مقدار دادم اما بخشی که تو سایتهای asp .net خودم هم به مشکل خورده بودم submit کردن فرم بود برای این کار یه متغیر به نام iWindow تعریف کردم IDیا name دکمه sunmit رو برداشتم و از طریق اون متد ()click. اونو با کد جاوا اسکریپت فراخوانی کردم . 

اگه بازم مشکلی بود بفرمایید در خدمتم .

----------

