TWebBrowser Double Click????

Hi there,

Does anyone know a simple way of catching Double-Click in a TWebBrowser component.

I would be greatful for a neat, clean example.

Thanks in Advance.
JamesLondonAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

DaFoxCommented:
Hi James.

private
  procedure AppMessage(var Msg: TMsg; var Handled: Boolean);

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := AppMessage;
end;

procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if (Msg.Message = WM_LBUTTONDBLCLK) then
  begin
    if PtinRect(Webbrowser1.BoundsRect, ScreenToClient(Msg.pt)) then ShowMessage('Webbrowser doubleclick');
  end;
end;

Markus
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
JamesLondonAuthor Commented:
Thanks Markus,

I tried something similar with the TAppEvents component but was relying on the Browser hWnd which didn't march the Messages Handle.

Your example worked perfectly. Thanks.
0
JamesLondonAuthor Commented:
Hi Markus,

The example you gave doesn't seem to work reliably (I didn't test it properly at first)...

1) Sometimes it has no effect (i.e. the ShoeMessage is not triggered.

2) I used a TAppEvents component instead so that I can set Handled to "False". The reason is that I want to be able to Double click a word and when TWebBrowser highlights it, get the selection. - When the code you gave works it doesn't let the Highlighting occur even when Handled = False, other times the text is highlighted on double click, but the ShowMessage doesn't happen!

Any suggestions??

Best Regards,
James
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

DaFoxCommented:
Could you show the source that you're using?
I have no clue how to solve this, but give me a try...

Markus
0
DaFoxCommented:
James,

to 1) Could it be that the ShowMessage function is the cause of the problem? In my tests the MessageBox wasn't triggerd, too. If I replace the ShowMessage with a Label the code works perfectly.
Please show me your code so that we can get it to work!

Markus
0
JamesLondonAuthor Commented:
Hi Markus,

Thanks for your resonse.

Check out this example, add a Memo to a form and add the following event, double click and the word you double clicked will show...

procedure TForm1.Memo1DblClick(Sender: TObject);
begin
  ShowMessage(Memo1.SelText);
end;


I need this same behaviour for the WebBrowser component...

The code is exactly as you gave, but I set Handled = False, because I need the message to go through to the component so that it does the selecting of the word...

procedure TfrmMain.AppEventsMessage(var Msg: tagMSG; var Handled: Boolean);
begin
 if (Msg.Message = WM_LBUTTONDBLCLK) then
 begin
   if PtinRect(Browser.BoundsRect, ScreenToClient(Msg.pt)) then ShowMessage(Test);
 end;
 Handled := False;
end;


I already implemented and fully tested a SelText property on my TWebBrowser descendant, but the problem is detecting the Double Click.


Is there some way of doing this with COM/OLE??? i.e. the Set_ondblclick in MSHTML unit - problem is I'm new to COM and OLE.

Tearing my hair out!

- James.

0
JamesLondonAuthor Commented:
Hi Markus,

Thanks for your resonse.

Check out this example, add a Memo to a form and add the following event, double click and the word you double clicked will show...

procedure TForm1.Memo1DblClick(Sender: TObject);
begin
  ShowMessage(Memo1.SelText);
end;


I need this same behaviour for the WebBrowser component...

The code is exactly as you gave, but I set Handled = False, because I need the message to go through to the component so that it does the selecting of the word...

procedure TfrmMain.AppEventsMessage(var Msg: tagMSG; var Handled: Boolean);
begin
 if (Msg.Message = WM_LBUTTONDBLCLK) then
 begin
   if PtinRect(Browser.BoundsRect, ScreenToClient(Msg.pt)) then ShowMessage(Test);
 end;
 Handled := False;
end;


I already implemented and fully tested a SelText property on my TWebBrowser descendant, but the problem is detecting the Double Click.


Is there some way of doing this with COM/OLE??? i.e. the Set_ondblclick in MSHTML unit - problem is I'm new to COM and OLE.

Tearing my hair out!

- James.

0
JamesLondonAuthor Commented:
Hi Markus,

Thanks for your resonse.

Check out this example, add a Memo to a form and add the following event, double click and the word you double clicked will show...

procedure TForm1.Memo1DblClick(Sender: TObject);
begin
  ShowMessage(Memo1.SelText);
end;


I need this same behaviour for the WebBrowser component...

The code is exactly as you gave, but I set Handled = False, because I need the message to go through to the component so that it does the selecting of the word...

procedure TfrmMain.AppEventsMessage(var Msg: tagMSG; var Handled: Boolean);
begin
 if (Msg.Message = WM_LBUTTONDBLCLK) then
 begin
   if PtinRect(Browser.BoundsRect, ScreenToClient(Msg.pt)) then ShowMessage(Test);
 end;
 Handled := False;
end;


I already implemented and fully tested a SelText property on my TWebBrowser descendant, but the problem is detecting the Double Click.


Is there some way of doing this with COM/OLE??? i.e. the Set_ondblclick in MSHTML unit - problem is I'm new to COM and OLE.

Tearing my hair out!

- James.

0
JamesLondonAuthor Commented:
Markus,

Apparently Hitting F5 on my browser posted my message three times!!!! - A Bad programmer day!!


Regarding ShowMessage, I understand what your implication, regarding something funny happening with the focus. However I've just tried the following without success...

if PtinRect(Browser.BoundsRect, ScreenToClient(Msg.pt)) then
Begin
  SelStr := Browser.SelText;
  Label1.Caption := SelStr;
End;

This doesn't work either, the caption is set to garbage.
Problem is not with the SelText implementation because Selecting Text then hitting a button that Shows Browser.SelText works fine!!



0
DaFoxCommented:
Hi James.

> Apparently Hitting F5 on my browser posted my message three times!!!! - A Bad programmer day!!

No problem, happens to me sometimes, too ;-)


What do you think about this code. Does it fit your needs?

{ uses SHDocVw_TLB, MSHTML_TLB, ActiveX }

private
  function SelText: String;
  procedure AppMessage(var Msg: TMsg; var Handled: Boolean);

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := AppMessage;
end;

function TForm1.SelText: String;
var
  Doc: IHTMLDocument2;
  Selection: IHTMLSelectionObject;
  TextRange: IHTMLTxtRange;
begin
  try
    Doc := WebBrowser1.Document as IHTMLDocument2;
    Selection := Doc.Selection;
    TextRange := Selection.CreateRange as IHTMLTxtRange;
    result := TextRange.text;
  except
    result := EmptyStr;
  end;
end;


procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
 handled := IsDialogMessage(Webbrowser1.Handle, Msg) = true;
 if (Msg.Message = WM_LBUTTONDBLCLK) then
 begin
   if PtinRect(Webbrowser1.BoundsRect, ScreenToClient(Msg.pt)) then Label1.Caption := SelText;
 end;
end;


initialization
   OleInitialize(nil);

finalization
   OleUninitialize;


end.

Markus
0
JamesLondonAuthor Commented:
Hi Markus,

Apologies for the Time difference!

Thanks for your code, your SelText is pretty much identical to mine, I actually managed to solve the problem before reading your post, though I will also try your code.

Here is what I'm doing...

FIRSTLY A BROWSER-EVENT COMPONENT DESCENDING FROM IDISPATCH

type
  TBrowserEvent = Class( TComponent, IUnknown, IDispatch)
  private
    { Private declarations }
    FOnEvent : TNotifyEvent;
    FRefCount : integer;
    function QueryInterface( const IID : TGUID; out Obj) : Integer; stdcall;
    function _AddRef : Integer; stdcall;
    function _Release : Integer; stdcall;
    function Invoke( DispID : Integer; const IID : TGUID; LocaleID : Integer; Flags : Word; var Params; VarResult, ExcepInfo, ArgErr : Pointer) : HResult; stdcall;
  protected
    { Protected declarations }
  public
    { Public declarations }
  published
    { Published declarations }
    property OnEvent : TNotifyEvent read FOnEvent write FOnEvent;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('IE', [TBrowserEvent]);
end;

function TBrowserEvent.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
  if GetInterface(IID, Obj) then
    Result := S_OK
  else
    Result := E_NOINTERFACE;
end;

function TBrowserEvent._AddRef: Integer;
begin
  Inc(FRefCount);
  Result := FRefCount;
end;

function TBrowserEvent._Release: Integer;
begin
  Dec(FRefCount);
  Result := FRefCount;
end;

function TBrowserEvent.Invoke( DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;
begin
  if Assigned(OnEvent) then OnEvent(Self);
  Result := S_OK;
end;


ASSIGN THE ONEVENT IN THE COMPONENT TO THE CODE

procedure TfrmMain.breDoubleClickEvent(Sender: TObject);
begin
  // Do something
end;

ASSIGN THE BROWSER-EVENT TO THE TWEBBROWSER DOCUMENT

procedure TfrmMain.BrowserTitleChange(Sender: TObject;
  const Text: WideString);
// JJA Implemented
// Best place to Assign all TWebBrowser Events
Var
 Doc: OLEVariant;
begin
  Doc := Browser.Document;
  Doc.attachEvent('ondblclick', OleVariant( breDoubleClick as IDispatch) );
end;

SUMMARY

I can create multiple browser-event objects, each having it's own single OnEvent and assign them using attachEvent...

Doc.attachEvent('ondblclick', OleVariant( breDoubleClick as IDispatch) );


Anyway, I really appreciate your efforts, I will also try your code aswell - There was a problem with my example because the best place to assign the events was onNaviationComplete2 but this didn't work so I used BrowserTitleChange instead.

By the way, first time i've seen the API IsDialogMessage!

Thanks again,
Please Let me know what you think.

Best Regards,
- James
0
DaFoxCommented:
James, nice code, really. Why do you spend 120 points when your code is better than mine? :o)
Thank god you posted your code and I got it in my paqs now! ;-)
I'll test the code in the near future, I just looked at it yet.

Markus
0
JamesLondonAuthor Commented:
Hi Markus,

LOL. What can I say? - I'm a big spender!

Actually I did ask for a net clean example, which you gave in the Message hander - Your logic was perfect though Micro$oft didn't allow it! - I was also desperate because I had loads of other problems to solve - I was trying to Multitask the problem solving.

Appreciate the comments.

Best Regards
James
0
DaFoxCommented:
> Your logic was perfect though Micro$oft didn't allow it!

The new code seems to work now ;-)

Markus

PS: Did I ever told you that I really enjoy reading this thread (and also working with you)?
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.