Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 572
  • Last Modified:

ActiveX form input for html page

I'm new to ActiveX.

I want to create a ActiveX form which will be embedded in a html page. The ActiveX form should be a TDateTimePicker to select a date. I want to send the selected date and some other html input fields back to the server.
Sample:

<html>
<body>
<form method="post" action="http://myserver/mycgi">
my statement: <input size=12 name="statement">
my birthday: <my ActiveX select date form>
</form>
</body>
</html>

How do I create such a ActiveX in delphi 5? Is it possible to send binary data (a image) from a ActiveX via a html form post to the server? Any help is appreciated.

I don't care about security issues and I can't use java or javascript.

thanks ...
0
egono
Asked:
egono
  • 13
  • 8
  • 5
  • +1
1 Solution
 
edeyCommented:
Just out of curiosity, if you have no security issues, why no client side javascript?  With out this limitation I'd use M$'s calander behavior.

GL
Mike
0
 
egonoAuthor Commented:
mike:
1. I don't know - it's just a fact.
2. I have to do this in delphi.
0
 
jswebyCommented:
There are many better solutions than ActiveX but this is how to create an ActiveX control:

File|New. go to the ActiveX tab and select ActiveForm.

In fact, read this article from Delphi Informant magazine, it is how I did my first one:

http://www.delphiinformant.com/features/1999/06/di199906tt_f/di199906tt_f.asp

J.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
edeyCommented:
As jsweby noted it's easy (in professional or better versions) to create activeX wrappers around a vcl.  The tricky part is posting the data to the cgi service.  If you don't have scripting support I would think you'd have to implement that functionality in the activex control - meaning your form wouldn't submit the data your activex control would.  Then that control would need to know how to access it's parent's DOM. Hmmm, have to think about that one.

GL
Mike
0
 
egonoAuthor Commented:
Ok - I created a ActiveX, but I still don't know how to transfer the data to the html form.

Any suggestions are welcome!
0
 
edeyCommented:
That's what I'm wondering - I almost think it would be easier to create the entire form as an activeX control the can send the data itself.  As far as I know there is no way to dynamically set the values of the html form without some sort of scripting.  OTOH if you  created the instance of IE in some way that left you with a ref to it's document object (ie:

var
 doc : variant;
begin
 doc := createOLEObject('InternetExplorer.Aplication');
 doc.navigate('about:blank');
 doc := doc.document;//doc now points to the html document

then you can manipulate it howver you wish.  Now there might be someway to get the document refrence if you've got  the window handle (as I would think plugin's would have to) but I really don't know how.  In light of this I would prob.:

1) alter your control to descned from TPanel instead
2) add an HTTP control, I like the indy components: http://www.nevrona.com/indy
3) add edits & buttons & such as to recreate the html form
4) let the control send all the info to the cgi.

GL
Mike
0
 
egonoAuthor Commented:
the datetimepicker is a very small part of the form and I don't want to create such a huge ActiveX with all input fields.

do you have a solution with JavaScript enabled?
0
 
edeyCommented:
Sure, MS has in their msdn library a dhtml behavior of very similar functionality.  You can get it here: http://msdn.microsoft.com/downloads/samples/internet/default.asp?url=/downloads/samples/internet/behaviors/library/calendar/default.asp.  here's an example:

<html>
<head>
<script>
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sept','Oct','Nov','Dec'];
function addDate()
{
     with (document.all.calendar)
     {
          document.all.dates.value += months[month-1]+' '+day+', '+year+'\n';
     };
};
</script>
</head>
<body>
<div style="behavior: url(c:\windows\calendar.htc);width: 100px;height: 100px;)" id="calendar"></div>
<form><input type="button" onclick="addDate();"></form>
<textArea readOnly=true id="dates"></textArea>
</body>
</html>

GL
Mike
0
 
egonoAuthor Commented:
that's not what I'm looking for
I meant do you have a solution to exchange data between the ActiveX and the html form with JavaScript enabled?
0
 
egonoAuthor Commented:
I found this article, but I don't understand it.

Accessing the Object Model from Within an ActiveX Control
http://support.microsoft.com/support/kb/articles/Q172/7/63.ASP
0
 
edeyCommented:
hmmm, it basically shows, in C++, how to get to the DOM using the IWebBrowserApp interface.  If ound this quick delphi example showing how to get the current url from inside the activeX:

uses
  SHDocVw_TLB;

function TActiveXForm1.GetUrl: string;

var
  iocs: IOleClientSite;
  isp: IServiceProvider;
  iwa: IWebBrowserApp;
  ivclco: IVCLComObject;
  ioo: IOleObject;

begin
  ivclco:=IVCLComObject(VCLComObject);
  ioo:=ivclco as IOleObject;
  ioo.GetClientSite(iocs);
  isp:=iocs as IServiceProvider;
  isp.QueryService(IWebBrowserApp, IWebBrowserApp, iwa);
  Result:=iwa.LocationURL;
end;

in addition I did find another article showing how to do a couple of thing:

Here is some code that 1) finds the top level browser container, 2)
instructs
the browser to navigate to a different page, 3) display the html code of
the browser.

This should be a good starting point.

---------------
uses
  ... SHDocVw, MSHtml;

const
  IID_IServiceProvider: TGUID =
'{6D5140C1-7436-11CE-8034-00AA006009FA}';

type
  Txxxx = class(TActiveForm, IxxxxForm, IPersistPropertyBag)
...
  private
    IeWebAppFound: Boolean;
    IeServiceProvider: IServiceProvider;
    IeWebBrowser: IWebBrowserApp;
    IeContainer: IOleContainer;
    IeDocument: HTMLDocument;
    IeFlag: OleVariant;
    IeTarget: OleVariant;
...

procedure Txxxx.SetIeWebBrowser;
begin
  IeWebAppFound := False;
  IeContainer   := nil;
  while not IeWebAppFound do
  begin
    if IeContainer = nil then
      ActiveFormControl.ClientSite.QueryInterface(IID_IServiceProvider,
IeServiceProvider)
    else
      IeContainer.QueryInterface(IID_IServiceProvider,
IeServiceProvider);
    IeServiceProvider.QueryService(IID_IWebBrowserApp,
IID_IWebBrowserApp, IeWebBrowser);
    if IeWebBrowser = nil then
      Break;
    if IeWebBrowser.TopLevelContainer then
      begin
        IeWebAppFound := True;
      end
    else
      begin
        if IeWebBrowser.Container = nil then
          Break;
        IeContainer := IeWebBrowser.Container as IOleContainer;
      end;
  end;
end;

procedure Txxxx.IeNavigate(const URL, Target: string);
begin
  if not IeWebAppFound then
    SetIeWebBrowser;
  if not IeWebAppFound then
    Exit;
  IeFlag    := 14;
  IeTarget  := Target;
  try
    IeWebBrowser.Navigate(URL, EmptyParam, IeTarget, EmptyParam,
EmptyParam);
  except
    ShowMessage('Error: Connecting to ' + URL);
  end;
end;

procedure Txxxx.ShowHTML();
begin
  IeDocument  := IeWebBrowser.Document as HTMLDocument;
  if IeDocument = nil then
    ShowMessage('Document = nil')
  else
    begin
      Buffer  :=  IeDocument.body.innerHTML;
      ShowMessage(Buffer);
    end;
end;


jtkelling@home.com wrote:

> Anyone know how to get a handle the the brower containing the activeX
> control so i can tell it to do things.  In particular, I want to

> * get a handle to the browser
> * call a method like Brower.DownloadFile('http://test.com/file.jpg',
> 'c:\file.jpg');

> Note that I want to download the jpeg, and not just display it in the
> browser, and it is important that the download happen through http.

> Thanks,

> Jeff
--
==============================
Jerry Bucci
Property2000.com
http://www.property2000.com
mailto:jbucci@property2000.com


GL
Mike
0
 
egonoAuthor Commented:
thanks - i will try that tomorrow
0
 
egonoAuthor Commented:
I had no time to test it so far
where did you find these articles?
0
 
edeyCommented:
The first example was largely based on the article you prived - the second came from a usenet article.  Usenet is a _great_ place to look for such things, I recomend deja, or rather (now) googles search engine (www.deja.com)

GL
Mike
0
 
egonoAuthor Commented:
i've got some things working - some don't ...
i'm using this procedure to get some infos

var myWebDocument:HTMLDocument;
    myWebApp:IWebBrowserApp;

[...]

procedure GetBrowserInfos;
var
 myIOleClientSite  : IOleClientSite;
 myISP             : IServiceProvider;
 myIVCLComObject   : IVCLComObject;
 myOleObject       : IOleObject;

begin
  try
    myIVCLComObject:=IVCLComObject(VCLComObject);
    myOleObject:=myIVCLComObject as IOleObject;
    myOleObject.GetClientSite(myIOleClientSite);
    myISP:=myIOleClientSite as IServiceProvider;
    myISP.QueryService(IWebBrowserApp, IWebBrowserApp, myWebApp);
    myWebDocument:=myWebApp.Document as HTMLDocument;
  except end;
end;

Now it's seems possible to access the form elements via myWebDocument.forms.item, but I have no clue how to do this. Let's say I want to access the form element named "InputField1" - myWebDocument.forms.item['InputField1'] won't work

do you have any ideas?

btw - I will increase the points if you want or I create a new question if you want your points now - just tell me
0
 
EpsylonCommented:
Just a comment to receive notifications...
0
 
EpsylonCommented:
I figured it out using edey's SetIeWebBrowser method to find the HTMLDocument. The html code below has a form named 'form1' with a text field named 'datetime'.


<html>
<head>
<title>ActiveX Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<object width="219" height="156" classid="clsid:B86D459F-E4A7-4D24-97D0-95409C2C140B" name="aform">
</object>
<form name="form1" method="post" action="">
<input type="text" name="datetime">
</form>
</body>
</html>



Here are the code snippets:


TMyActiveForm = class(TActiveForm, IMyActiveForm)
    ...
  private
    IeWebAppFound: Boolean;
    IeServiceProvider: IServiceProvider;
    IeWebBrowser: IWebBrowserApp;
    IeContainer: IOleContainer;
    IeDocument: HTMLDocument;
    ...


procedure TMyActiveForm.SetIeWebBrowser;
begin
  IeWebAppFound := False;
  IeContainer   := nil;
  while not IeWebAppFound do
  begin
    if IeContainer = nil then
      ActiveFormControl.ClientSite.QueryInterface(IID_IServiceProvider, IeServiceProvider)
    else
      IeContainer.QueryInterface(IID_IServiceProvider, IeServiceProvider);
    IeServiceProvider.QueryService(IID_IWebBrowserApp, IID_IWebBrowserApp, IeWebBrowser);
    if IeWebBrowser = nil then
      Break;
    if IeWebBrowser.TopLevelContainer then
    begin
      IeWebAppFound := True;
    end
    else begin
      if IeWebBrowser.Container = nil then
        Break;
      IeContainer := IeWebBrowser.Container as IOleContainer;
    end;
  end;
end;

procedure TMyActiveForm.DateTimePicker1Change(Sender: TObject);
var frm: HTMLFormElement;
    txt: HTMLTextAreaElement;
begin
  if not IeWebAppFound then
    SetIeWebBrowser;
  if not IeWebAppFound then
    Exit;
  IeDocument  := IeWebBrowser.Document as HTMLDocument;
  if IeDocument = nil then
    ShowMessage('Document = nil')
  else begin
    frm := (IeDocument.forms.item('form1', 0) as HTMLFormElement);
    txt := (frm.item('datetime', 0) as HTMLTextAreaElement);
    txt.value := DateTimeToStr(DateTimePicker1.DateTime);
  end;
end;
0
 
EpsylonCommented:
You can also post data inside the ActiveForm directly using the WebBrowser.Navigate method.
0
 
EpsylonCommented:
Hi, can you get it to work?
0
 
egonoAuthor Commented:
I'm busy at customers - hopefully next week I'm back at work, then I will try it - thanks so far ...
0
 
egonoAuthor Commented:
Epsylon - it seems to work, thanks! is it ok for you if give the points to edey anyway? he did the first important step
0
 
egonoAuthor Commented:
Epsylon, edey - are you still listening?
any suggestions how to give the points?
0
 
edeyCommented:
Hmm, I think that's something you'd have to talk to C/S about.

GL
Mike
0
 
egonoAuthor Commented:
Mike - are 50 points ok for you?
0
 
EpsylonCommented:
Give the points to edey...
0
 
egonoAuthor Commented:
ok - Epsylon next time you will get some more :-)

thanks again to both of you!
0
 
edeyCommented:
Thanks, Glad to be of service.

GL
Mike
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 13
  • 8
  • 5
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now