Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

TWebBrowser Double Click????

Posted on 2003-03-08
14
Medium Priority
?
377 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
  • 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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

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…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Integration Management Part 2
Loops Section Overview
Suggested Courses

580 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