-1

i try to fix up my activex project and i had errors , i have 2 forms in my activex project first form hold tmemo and button to call second form as parented form every thing works fine till now but i cannot set any record from second form to first form control always get access violation so i decided to show result before set tmemo.text control in the first form and actually result is showing but but cannot be set into the first form here is my project code

unit main1;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ActiveX, AxCtrls, embed_TLB, StdVcl, Vcl.StdCtrls;

type
  Tform1 = class(TForm, Iform1)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }


  protected
    { Protected declarations }

  public
    { Public declarations }
    procedure showEmo(L,T:Integer);

  end;

  var
  Form1 : Tform1;

implementation

uses ComObj, ComServ, main2;

{$R *.DFM}

{ Tform1 }

procedure Tform1.Button1Click(Sender: TObject);
var
  Rect: TRect;
begin
  GetWindowRect(Self.button1.Handle, Rect);
  showEmo(Rect.Left + 70,(Rect.Top - 290));
end;

procedure Tform1.FormCreate(Sender: TObject);
begin
  Form2 := TForm2.Createparented(0);
end;

procedure TForm1.showEmo(L,T:Integer);
var
  Rect: TRect;
begin
  try
    GetWindowRect(button1.Handle, Rect);
    begin
      Form2.FormStyle := fsStayOnTop;
    end;
    Form2.Left := L;//Rect.Left;
    Form2.top := T;//Rect.Top - emo.Height;
  finally
    Form2.Visible := not (Form2.visible);
  end;

end;

initialization
  TActiveFormFactory.Create(
    ComServer,
    TActiveFormControl,
    Tform1,
    Class_form1,
    0,
    '',
    OLEMISC_SIMPLEFRAME or OLEMISC_ACTSLIKELABEL,
    tmApartment);
end.

Form 2

unit main2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.OleCtrls, SHDocVw_EWB, EwbCore,
  EmbeddedWB, MSHTML_EWB, Vcl.StdCtrls;

type
  TForm2 = class(TForm)
    ewbpage: TEmbeddedWB;
    load: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure ewbpageBeforeNavigate2(ASender: TObject; const pDisp: IDispatch;
      var URL, Flags, TargetFrameName, PostData, Headers: OleVariant;
      var Cancel: WordBool);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

uses main1;

{$R *.dfm}

procedure TForm2.ewbpageBeforeNavigate2(ASender: TObject; const pDisp: IDispatch;
  var URL, Flags, TargetFrameName, PostData, Headers: OleVariant;
  var Cancel: WordBool);
  var
  MousePos: TPoint;
  HtmlElement: IHTMLElement;
  iHTMLDoc: IHtmlDocument2;
begin
  if Pos('#sm',URL)>0 then
  begin
    if Supports(ewbpage.Document, IHtmlDocument2, iHTMLDoc) then
    begin
      if GetCursorPos(MousePos) then
      begin
        MousePos := ewbpage.ScreenToClient(MousePos);
        HtmlElement := iHTMLDoc.ElementFromPoint(MousePos.X, MousePos.Y);
        if Assigned(HtmlElement) then
          showmessage(HtmlElement.getAttribute('id', 0));
        form1.Memo1.Text :=  HtmlElement.getAttribute('id', 0);
        Cancel := True;
        Self.Close;
      end;
    end;
  end;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  ewbpage.LoadFromStrings(load.Lines);
end;

end.

and the question is why i get this error

Access violation at address 07C734FC in module 'EMBEDA~1.OCX'. Read of address 000003B4.

at this line

form1.Memo1.Text :=  HtmlElement.getAttribute('id', 0);

why i cannot set result from second form to first form ? what i did wrong here is the full project for better understand

http://www.mediafire.com/download/zn7hzoxze2390a3/embeddedactivex.zip

Sir Rufo
  • 18,395
  • 2
  • 39
  • 73
DelphiStudent
  • 384
  • 1
  • 7
  • 23

1 Answers1

1

You will see this issue once you start to format your code properly

procedure TForm2.ewbpageBeforeNavigate2(ASender: TObject; const pDisp: IDispatch;
  var URL, Flags, TargetFrameName, PostData, Headers: OleVariant;
  var Cancel: WordBool);
  var
  MousePos: TPoint;
  HtmlElement: IHTMLElement;
  iHTMLDoc: IHtmlDocument2;
begin
  if Pos('#sm',URL)>0 then
  begin
    if Supports(ewbpage.Document, IHtmlDocument2, iHTMLDoc) then
    begin
      if GetCursorPos(MousePos) then
      begin
        MousePos := ewbpage.ScreenToClient(MousePos);
        HtmlElement := iHTMLDoc.ElementFromPoint(MousePos.X, MousePos.Y);

        // if we have a valid HtmlElement ...
        if Assigned(HtmlElement) 
        then // show a message
          showmessage(HtmlElement.getAttribute('id', 0));

        // now we do not care about if HtmlElement is valid or not
        form1.Memo1.Text :=  HtmlElement.getAttribute('id', 0);

        Cancel := True;
        Self.Close;
      end;
    end;
  end;
end;

To only solve your current access violation you simply put a begin end block around all the lines that will use HtmlElement.

        HtmlElement := iHTMLDoc.ElementFromPoint( MousePos.X, MousePos.Y );

        if Assigned( HtmlElement ) 
        then
          begin
            showmessage( HtmlElement.getAttribute( 'id', 0 ) );
            form1.Memo1.Text := HtmlElement.getAttribute( 'id', 0 );
          end;

But there are some more issues in your code. You should not use the global variables form1 and form2. Instead pass the form instance to the created TForm2 instance or even better a callback method.

Sir Rufo
  • 18,395
  • 2
  • 39
  • 73
  • 1
    adding begin and end will define start and end point thanks for this notice , but this wil not solve my access violation , iam interested in the last sentences , `instead pass the form instance to create TFORM2 even better callback` any example about this ? – DelphiStudent Mar 31 '15 at 15:30