Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

ActiveX form input for html page

Posted on 2001-06-29
27
Medium Priority
?
565 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
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 400 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
 
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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
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…
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Suggested Courses

722 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