Solved

ActiveX form input for html page

Posted on 2001-06-29
27
541 Views
Last Modified: 2010-06-18
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
Comment
Question by:egono
  • 13
  • 8
  • 5
  • +1
27 Comments
 
LVL 6

Expert Comment

by:edey
ID: 6238404
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
 
LVL 2

Author Comment

by:egono
ID: 6238516
mike:
1. I don't know - it's just a fact.
2. I have to do this in delphi.
0
 
LVL 4

Expert Comment

by:jsweby
ID: 6238520
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
 
LVL 6

Expert Comment

by:edey
ID: 6238594
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
 
LVL 2

Author Comment

by:egono
ID: 6244227
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
 
LVL 6

Expert Comment

by:edey
ID: 6245465
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
 
LVL 2

Author Comment

by:egono
ID: 6245691
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
 
LVL 6

Expert Comment

by:edey
ID: 6246624
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
 
LVL 2

Author Comment

by:egono
ID: 6248021
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
 
LVL 2

Author Comment

by:egono
ID: 6248850
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
 
LVL 6

Accepted Solution

by:
edey earned 100 total points
ID: 6249227
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
 
LVL 2

Author Comment

by:egono
ID: 6250231
thanks - i will try that tomorrow
0
 
LVL 2

Author Comment

by:egono
ID: 6255166
I had no time to test it so far
where did you find these articles?
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 6

Expert Comment

by:edey
ID: 6255705
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
 
LVL 2

Author Comment

by:egono
ID: 6270066
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
 
LVL 13

Expert Comment

by:Epsylon
ID: 6270569
Just a comment to receive notifications...
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 6271328
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
 
LVL 13

Expert Comment

by:Epsylon
ID: 6271364
You can also post data inside the ActiveForm directly using the WebBrowser.Navigate method.
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 6280095
Hi, can you get it to work?
0
 
LVL 2

Author Comment

by:egono
ID: 6280166
I'm busy at customers - hopefully next week I'm back at work, then I will try it - thanks so far ...
0
 
LVL 2

Author Comment

by:egono
ID: 6293050
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
 
LVL 2

Author Comment

by:egono
ID: 6364028
Epsylon, edey - are you still listening?
any suggestions how to give the points?
0
 
LVL 6

Expert Comment

by:edey
ID: 6364516
Hmm, I think that's something you'd have to talk to C/S about.

GL
Mike
0
 
LVL 2

Author Comment

by:egono
ID: 6364650
Mike - are 50 points ok for you?
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 6364675
Give the points to edey...
0
 
LVL 2

Author Comment

by:egono
ID: 6364737
ok - Epsylon next time you will get some more :-)

thanks again to both of you!
0
 
LVL 6

Expert Comment

by:edey
ID: 6364778
Thanks, Glad to be of service.

GL
Mike
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now