?
Solved

TWebBrowser Double Click????

Posted on 2003-03-08
14
Medium Priority
?
359 Views
Last Modified: 2010-04-04
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.
0
Comment
Question by:JamesLondon
[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
  • 8
  • 6
14 Comments
 
LVL 6

Accepted Solution

by:
DaFox earned 500 total points
ID: 8094541
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
 

Author Comment

by:JamesLondon
ID: 8094637
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
 

Author Comment

by:JamesLondon
ID: 8095877
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
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.

 
LVL 6

Expert Comment

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

Markus
0
 
LVL 6

Expert Comment

by:DaFox
ID: 8096240
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
 

Author Comment

by:JamesLondon
ID: 8096242
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
 

Author Comment

by:JamesLondon
ID: 8096252
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
 

Author Comment

by:JamesLondon
ID: 8096253
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
 

Author Comment

by:JamesLondon
ID: 8096286
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
 
LVL 6

Expert Comment

by:DaFox
ID: 8097787
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
 

Author Comment

by:JamesLondon
ID: 8097910
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
 
LVL 6

Expert Comment

by:DaFox
ID: 8106679
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
 

Author Comment

by:JamesLondon
ID: 8112497
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
 
LVL 6

Expert Comment

by:DaFox
ID: 8114848
> 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

Featured Post

Enroll in August's Course of the Month

August's CompTIA IT Fundamentals course includes 19 hours of basic computer principle modules and prepares you for the certification exam. It's free for Premium Members, Team Accounts, and Qualified Experts!

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 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…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Suggested Courses
Course of the Month11 days, 11 hours left to enroll

752 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