JamesLondon
asked on
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.
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.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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
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
Could you show the source that you're using?
I have no clue how to solve this, but give me a try...
Markus
I have no clue how to solve this, but give me a try...
Markus
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
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
ASKER
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(Sende r: 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.BoundsRec t, 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.
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(Sende
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(
begin
if (Msg.Message = WM_LBUTTONDBLCLK) then
begin
if PtinRect(Browser.BoundsRec
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.
ASKER
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(Sende r: 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.BoundsRec t, 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.
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(Sende
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(
begin
if (Msg.Message = WM_LBUTTONDBLCLK) then
begin
if PtinRect(Browser.BoundsRec
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.
ASKER
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(Sende r: 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.BoundsRec t, 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.
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(Sende
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(
begin
if (Msg.Message = WM_LBUTTONDBLCLK) then
begin
if PtinRect(Browser.BoundsRec
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.
ASKER
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.BoundsRec t, 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!!
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.BoundsRec
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!!
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(Webbrowser 1.Handle, Msg) = true;
if (Msg.Message = WM_LBUTTONDBLCLK) then
begin
if PtinRect(Webbrowser1.Bound sRect, ScreenToClient(Msg.pt)) then Label1.Caption := SelText;
end;
end;
initialization
OleInitialize(nil);
finalization
OleUninitialize;
end.
Markus
> 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(Webbrowser
if (Msg.Message = WM_LBUTTONDBLCLK) then
begin
if PtinRect(Webbrowser1.Bound
end;
end;
initialization
OleInitialize(nil);
finalization
OleUninitialize;
end.
Markus
ASKER
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.QueryInterfa ce(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.breDoubleClickEve nt(Sender: TObject);
begin
// Do something
end;
ASSIGN THE BROWSER-EVENT TO THE TWEBBROWSER DOCUMENT
procedure TfrmMain.BrowserTitleChang e(Sender: TObject;
const Text: WideString);
// JJA Implemented
// Best place to Assign all TWebBrowser Events
Var
Doc: OLEVariant;
begin
Doc := Browser.Document;
Doc.attachEvent('ondblclic k', 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('ondblclic k', 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
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.QueryInterfa
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.breDoubleClickEve
begin
// Do something
end;
ASSIGN THE BROWSER-EVENT TO THE TWEBBROWSER DOCUMENT
procedure TfrmMain.BrowserTitleChang
const Text: WideString);
// JJA Implemented
// Best place to Assign all TWebBrowser Events
Var
Doc: OLEVariant;
begin
Doc := Browser.Document;
Doc.attachEvent('ondblclic
end;
SUMMARY
I can create multiple browser-event objects, each having it's own single OnEvent and assign them using attachEvent...
Doc.attachEvent('ondblclic
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
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
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
ASKER
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
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
> 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)?
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)?
ASKER
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.