🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.internet.web
6 messages
6 total messages Started by Hans Galema Mon, 30 Oct 2006 23:12
TWebBrowser how to put_value() for <input type="file">
#724
Author: Hans Galema
Date: Mon, 30 Oct 2006 23:12
147 lines
4260 bytes
For TWebBrowser in Turbo C++ I'm puzzled how to use put_value()
for <input type="file">

I can handle that for <input type="text" > using IHTMLInputElement.

IHTMLInputFileElement used for <input type="file"> does find the input
but put_value() has no effect.

To demonstrate the problem take a TForm and put two TSpeedButtons
on it a a TWebBrowser.

The first speedbutton will load a specific url:

void __fastcall TForm3::SpeedButton1Click(TObject *Sender)
{
	WebBrowser1->Navigate ( "http://video.tinypic.com/vidiframe.php" );
}

That page has the following <input>'s which I try to fill:
void __fastcall TForm3::SpeedButton2Click(TObject *Sender)
{
//<input type="file" name="the_file" size="30">
//<input type="text" name="the_tag" size="25" maxlength="30">

   PlaceInputFileText ( "the_file",  "a filename" );
   PlaceInputText ( "the_tag", "a title" );
}

Only the title is set.

Here the two used functions:

#include <mshtml.h>
bool __fastcall TForm3::PlaceInputText ( char *inputname, AnsiString Text )
{
bool done = false;

IHTMLDocument2 *HTMLDoc = NULL;

if(SUCCEEDED(WebBrowser1->Document->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&HTMLDoc)))
{
	IHTMLElementCollection *pAll = NULL;
	if(SUCCEEDED(HTMLDoc->get_all(&pAll)))
	{
	  // <input type="text" name="the_tag">

	  Variant name = inputname;
	  Variant index = 0;

	  IDispatch *pDisp = NULL;

	   if(SUCCEEDED(pAll->item(name, index, &pDisp)))
		  {
		  if ( pDisp )
				{
			   //	IHTMLInputFileElement *pInput = NULL;     // mshtml.h
				IHTMLInputElement *pInput = NULL;     // mshtml.h
			   // IHTMLFormElement *pForm = NULL;         // mshtml.h

				pDisp->QueryInterface(IID_IHTMLInputElement, (LPVOID*)&pInput);
				pDisp->Release();

				if(pInput)
						{
						pInput->put_value(WideString(Text));

						done = true;

						/*
						WideString mybuffer;
						pInput->get_value ( &mybuffer );
						ShowMessage ( mybuffer );
						*/

						pInput->Release();
						}
				}
		  }
		  pAll->Release();
		}

	 HTMLDoc->Release();
	 }

  return done;
}


bool __fastcall TForm3::PlaceInputFileText ( char *inputname, AnsiString Text )
{
bool done = false;

IHTMLDocument2 *HTMLDoc = NULL;

if(SUCCEEDED(WebBrowser1->Document->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&HTMLDoc)))
	{
	IHTMLElementCollection *pAll = NULL;
	if(SUCCEEDED(HTMLDoc->get_all(&pAll)))
	{
			// <input type="file" name="the_file">

	  Variant name = inputname;
	  Variant index = 0;

	  IDispatch *pDisp = NULL;

	   if(SUCCEEDED(pAll->item(name, index, &pDisp)))
		  {
		  if ( pDisp )
				{
				IHTMLInputFileElement *pInput = NULL;     // mshtml.h
				//  IHTMLInputElement *pInput = NULL;     // mshtml.h
			   // IHTMLFormElement *pForm = NULL;         // mshtml.h

			  //	pDisp->QueryInterface(IID_IHTMLInputElement, (LPVOID*)&pInput);
				pDisp->QueryInterface(IID_IHTMLInputFileElement, (LPVOID*)&pInput);
				pDisp->Release();

				if(pInput)
						{
						pInput->put_value(WideString(Text.c_str()));

						done = true;

						/*
						WideString mybuffer;
						pInput->get_value ( &mybuffer );

						ShowMessage ( mybuffer );
						*/

						pInput->Release();
						}
				}
		  }
		  pAll->Release();
		}

	 HTMLDoc->Release();
	 }

  return done;
}

Who knows how to set Video input prgammatically?

Hans.
Re: TWebBrowser how to put_value() for <input type="file">
#725
Author: Remy Lebeau (TeamB)
Date: Tue, 31 Oct 2006 00:24
19 lines
1619 bytes
"Hans Galema" <notused@notused.nl> wrote in message
news:45468718@newsgroups.borland.com...

> For TWebBrowser in Turbo C++ I'm puzzled how to use
> put_value() for <input type="file">

You cannot use it at all.  The IHTMLInputFileElement::value property is
read-only.  This is by design as part of Microsoft's security model.

The only way to fill in the field programmably is to set focus to the edit
control itself (use IHTMLElement::focus()) and then send keystrokes to it.
Otherwise, you will have to stop using TWebBrowser to submit the forms at
all.  Use an HTTP library to program to the HTTP protocol directly.  Indy,
for example, has a special TStream class specifically for uploading
form-based fields, including files.


Gambit
Re: TWebBrowser how to put_value() for <input type="file">
#726
Author: Hans Galema
Date: Tue, 31 Oct 2006 14:36
100 lines
3628 bytes
Remy Lebeau (TeamB) wrote:

> You cannot use it at all.  The IHTMLInputFileElement::value property is
> read-only.  This is by design as part of Microsoft's security model.

Ok. Thanks.

> The only way to fill in the field programmably is to set focus to the edit
> control itself (use IHTMLElement::focus()) and then send keystrokes to it.

Setting focus was possible with IHTMLElement2::focus()   // 2 added

But sending keystrokes took me hours before I had managed that.
It appears that using keybd_event() for a TEdit is easier then
to a TWebBrowser.

Using WM_CHAR like:

	 SendMessage(WebBrowser1->Handle, WM_CHAR, 'G', 2);

does nothing.

   SendMessage ( WebBrowser1->Handle, WM_KEYDOWN, 'w', 0);

does not work either. So I constructed a function ( see below )
that uses keybd_event(). This works but only after taking
special care for char's like : \ ' . - +

For the moment this function will do but as soon as there
are other special chars in filenames it will fail.

Isn't there a function that will convert a char to VK_XXXX ?

Hans.

void SendKeys(char *s)
   {
   if (s)
	{
	do
	  {
	  bool withshift = false;

	  char key= *s++;

	  if ( key == '.' )
		key = VK_OEM_PERIOD ;
	  else if ( key == ',' )
		key = VK_OEM_COMMA;
	  else if ( key == '-' )
		key = VK_OEM_MINUS;
	  else if ( key == '+' )
		key = VK_OEM_PLUS;
	  else if ( key == ':' )
		{
		key = VK_OEM_1;

		withshift = true;
		}
	  else if ( key == '\\' )
		key = VK_OEM_5 ;
	  else if ( isupper (key ) )
		{
		withshift = true;
		}
	  else key = UpCase (key);

	  if ( withshift )
		{
		WPARAM param =WPARAM(VK_LSHIFT);
		keybd_event(param,0,0, 0);
		}

	  WPARAM param =WPARAM(key);
	  keybd_event(param,0,0,0);
	  keybd_event(param,0,KEYEVENTF_KEYUP,0);

	  if ( withshift)
		{
		WPARAM param =WPARAM(VK_LSHIFT);
		keybd_event(param,0,KEYEVENTF_KEYUP,0);
		}

	  } while (*s);
	}
   }

> Otherwise, you will have to stop using TWebBrowser to submit the forms at
> all.  Use an HTTP library to program to the HTTP protocol directly.  Indy,
> for example, has a special TStream class specifically for uploading
> form-based fields, including files.

As can be seen in the source op the url tat I provided earlier there is
javascript onsubmit() to be executed. Will TIdHTTP care for that too?
I don't think so.

At the moment things run. The program can upload a directory with videos
to the specified url and extract the resulting url's for use in webpages.

Hans.
Re: TWebBrowser how to put_value() for <input type="file">
#727
Author: Remy Lebeau (TeamB)
Date: Tue, 31 Oct 2006 18:02
57 lines
3263 bytes
"Hans Galema" <notused@notused.nl> wrote in message
news:45475fb0@newsgroups.borland.com...

> But sending keystrokes took me hours before I had managed that.
> It appears that using keybd_event() for a TEdit is easier then
> to a TWebBrowser.

Do not use keybd_event().  There is no way to gaurantee which window it
directs keystrokes to.  If the user switches windows while keybd_event() is
still running, the keystrokes will go to the wrong window.  You have to use
SendMessage() to ensure the proper window is used.  Also, use WM_KEYDOWN/UP
instead of WM_CHAR.

> Using WM_CHAR like:
>
> SendMessage(WebBrowser1->Handle, WM_CHAR, 'G', 2);
>
> does nothing.
>
>    SendMessage ( WebBrowser1->Handle, WM_KEYDOWN, 'w', 0);
>
> does not work either.

That is because you are sending the messages to the wrong window.  You are
sending them to the browser's container window when you need to send them to
the edit control of the <input> element itself instead.

> This works but only after taking special care for char's like : \ ' . - +

You do not need to do that.  There is nothing "special" about those
characters.  WM_CHAR handles them just fine without special handling.

> Isn't there a function that will convert a char to VK_XXXX ?

No.

> As can be seen in the source op the url tat I provided earlier there is
> javascript onsubmit() to be executed. Will TIdHTTP care for that too?

No, but then again it doesn't need to.  All that script does is disables the
upload button and then pops up a progress window during the upload.  Since
you would be programming to the HTTP protocol directly, there would be no
upload button at all (except in your own UI, if any), and you could show
your own progress information as you have direct access to the connection
that is sending the data to the server.

> At the moment things run. The program can upload a directory with videos
> to the specified url and extract the resulting url's for use in webpages.

All the more reason not to use TWebBrowser at all for that.  It would be a
major bottleneck in that process.  If you go to the HTTP protocol directly,
you can automate the uploading much much cleaner, and eliminate Microsoft's
UI altogether.


Gambit
Re: TWebBrowser how to put_value() for <input type="file">
#728
Author: Hans Galema
Date: Wed, 01 Nov 2006 09:45
28 lines
2074 bytes
Remy Lebeau (TeamB) wrote:
> ..  If the user switches windows while keybd_event() is
> still running, the keystrokes will go to the wrong window. 

Yes. That's exactly what happened.

> You have to use
> SendMessage() to ensure the proper window is used.  Also, use WM_KEYDOWN/UP
> instead of WM_CHAR.
> .... you need to send them to
> the edit control of the <input> element ...

Ok. I will do that.

> All the more reason not to use TWebBrowser at all for that.  It would be a
> major bottleneck in that process. 

At the moment it is indeed.

> If you go to the HTTP protocol directly,
> you can automate the uploading much much cleaner, and eliminate Microsoft's
> UI altogether.

The strange thing in me is that I first want to run this perfect
with TWebBrowser. And having done that I will make a different version
with TIdHTTP.

Hans.
Re: TWebBrowser how to put_value() for <input type="file">
#352
Author: Enrique
Date: Sat, 09 Dec 2006 14:44
11 lines
1385 bytes
[HANS]
> The strange thing in me is that I first want to run this perfect
> with TWebBrowser. And having done that I will make a different version
> with TIdHTTP.
>
> Hans.


Hello Hans ! Could you paste your code here when it be working?
Thanks !
enrique. 
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads