WebGadget - retreiving URL of link under pointer
WebGadget - retreiving URL of link under pointer
hello, here is another challenge for the WebGadget experts..
how do I retreive the URL of a link that the mouse is pointing to? (when, for example, the right mouse button is pressed)
ps. I also wondered, does the WebGadget control send some event when a page is finished loading? (so that we don't have to use the busy waiting stuff)
how do I retreive the URL of a link that the mouse is pointing to? (when, for example, the right mouse button is pressed)
ps. I also wondered, does the WebGadget control send some event when a page is finished loading? (so that we don't have to use the busy waiting stuff)
I've got some working code here but it needs a little more clean up before I post it. I hope to have it here within the next 24 hours.how do I retreive the URL of a link that the mouse is pointing to? (when, for example, the right mouse button is pressed)
Yes, I believe there is a better method. All this WebGadget interface stuff has my head spinning 8O right now so I'll take a closer look this weekend (time permitting).ps. I also wondered, does the WebGadget control send some event when a page is finished loading? (so that we don't have to use the busy waiting stuff)
What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
Slowly but surely, I'm beginning to get a grasp on this Interface stuff. I'm still a little fuzzy on some parts, especially on the Release() of Interface pointers. What exactly happens if I don't release an Interface pointer along the way? Having said that, I have tested and things appear to be ok here on WinXP with PB 3.91F.
The following code is just a beginnnig. As soon as I can get a better grasp of things like
This may also work on PB < 3.91. Because I use WindowMouseX() , WindowMouseY() you'll have to uncomment the 3 lines for PB ver < 3.91
and then comment the line after those 3
When the web page loads, you can right-click on *most* links and see the href in the statusbar. At this time, it only seems to work for text links. Image links seem to require something else so I'll continue looking to find a way.
Also, I have disabled the context menu but you can enable it by changing result = 1 to result = 0 in the MouseProc() procedure.
Ok, here's what I have so far.
Any and all input is greatly appreciated. I'd really like to get a better understanding of how and why Interfaces work (or not), and more importantly how to use them properly.
The following code is just a beginnnig. As soon as I can get a better grasp of things like
I'll be able to (I hope) use more conventional methods. For now I'm using a hooked mouse on the WegGadget window to detect #WM_RBUTTONDOWN and #WM_RBUTTONUP. There is a much better way to do this but it's still zooming over my head at this time. (see above quote)Pointer to a variable of type VARIANT of type VT_DISPATCH that receives the IDispatch interface of an object with a default method that is invoked when the event occurs 8O
This may also work on PB < 3.91. Because I use WindowMouseX() , WindowMouseY() you'll have to uncomment the 3 lines for PB ver < 3.91
Code: Select all
;GetCursorPos_(@cpos.POINT);
;ScreenToClient_(hBrowser, @cpos)
;If pDocument2\elementFromPoint(cpos\x, cpos\y, @pElement) = #S_OK
Code: Select all
If pDocument2\elementFromPoint(WindowMouseX() , WindowMouseY() , @pElement) = #S_OK
Also, I have disabled the context menu but you can enable it by changing result = 1 to result = 0 in the MouseProc() procedure.
Ok, here's what I have so far.
Code: Select all
pElement.IHTMLElement
pAnchor.IHTMLAnchorElement
pDispatch.IDispatch
pDocument2.IHTMLDocument2
WebObject.IWebBrowser2
Global pDispatch, pElement, pAnchor, pDocument2, hBrowser, WebObject, webInit
Procedure doweb()
If pDispatch : pDispatch\Release() : EndIf
If WebObject\get_document(@pDispatch) = #S_OK
If pDispatch\QueryInterface(?IID_IHTMLDocument2, @pDocument2) = #S_OK
hChild1 = FindWindowEx_(GadgetID(0), 0, "Shell Embedding", 0)
hChild2 = FindWindowEx_(hChild1, 0, "Shell DocObject View", 0)
hBrowser = FindWindowEx_(hChild2, 0, "Internet Explorer_Server", 0)
If hBrowser = 0 ; is our browser window available yet
If pDispatch : pDispatch\Release() : EndIf
webInit = #False ; browser window not available yet
Else
webInit = #True ; browser window available
EndIf
EndIf
EndIf
EndProcedure
Procedure MouseProc(nCode, wParam, lParam)
*ms.MOUSEHOOKSTRUCT = lParam
Select wParam
Case #WM_RBUTTONUP
StatusBarText(1, 0, "")
currentsb$ = ""
Case #WM_RBUTTONDOWN
If pDocument2
;- I use WindowMouseX() and WindowMouseY() so for
;- PureBasic ver < 3.91, uncomment the next 3 lines
;GetCursorPos_(@cpos.POINT);
;ScreenToClient_(hBrowser, @cpos)
;If pDocument2\elementFromPoint(cpos\x, cpos\y, @pElement) = #S_OK
;- for PureBasic ver < 3.91, comment the next line
If pDocument2\elementFromPoint(WindowMouseX() , WindowMouseY() , @pElement) = #S_OK
If pElement\QueryInterface(?IID_IHTMLAnchorElement, @pAnchor)= #S_OK
pElement\Release()
pAnchor\get_href(@BSTR_Anchor)
aLen = WideCharToMultiByte_(#CP_ACP, 0, BSTR_Anchor, -1, 0, 0, 0, 0)
anchor$ = Space(aLen)
WideCharToMultiByte_(#CP_ACP, 0, BSTR_Anchor, -1, @anchor$, aLen, 0, 0)
SysFreeString_(BSTR_Anchor)
If currentsb$ <> anchor$
StatusBarText(1, 0, anchor$)
currentsb$ = anchor$
EndIf
pAnchor\Release()
Else
StatusBarText(1, 0, "")
currentsb$ = ""
EndIf
EndIf
EndIf
result = 1 ;result = 0 enables context menu
EndSelect
ProcedureReturn result
EndProcedure
If OpenWindow(0, 0, 0, 700, 500, #PB_Window_SystemMenu , "Hypertext Info")
If CreateStatusBar(1, WindowID())
EndIf
If CreateGadgetList(WindowID())
hWeb = WebGadget(0, 0, 0, WindowWidth(), WindowHeight()-25, "http://www.purearea.net/pb/CodeArchiv/English.html")
WebObject = GetWindowLong_(GadgetID(0), #GWL_USERDATA)
EndIf
hInstance = GetModuleHandle_(0)
lpdwProcessId = GetWindowThreadProcessId_(WindowID(), 0)
hhook = SetWindowsHookEx_(#WH_MOUSE, @MouseProc(), 0, lpdwProcessId)
EndIf
Repeat
Event = WaitWindowEvent()
If Event = 32770 And webInit = #False
doweb()
EndIf
Until Event = #PB_Event_CloseWindow
If hhook : UnhookWindowsHookEx_(hhook) : EndIf
If pDispatch : pDispatch\Release() : EndIf
End
DataSection
IID_IHTMLDocument2:
;332C4425-26CB-11D0-B483-00C04FD90119
Data.l $332C4425
Data.w $26CB, $11D0
Data.b $B4, $83, $00, $C0, $4F, $D9, $01, $19
IID_IHTMLAnchorElement:
;3050F1DA-98B5-11CF-BB82-00AA00BDCE0B
Data.l $3050F1DA
Data.w $98B5, $11CF
Data.b $BB, $82, $00, $AA, $00, $BD, $CE, $0B
EndDataSection
What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
. I would have never figured that out.. Thanks!
which references do you use? how do you know that you can query the element-interface for an 'anchor'-interface, and from where do you get the numbers in the data section..?!
there are some things in your code that I don't understand:
1. what is the event 32770 and why does the mainwindow repeatedly receive a timer event?
2. what is the difference between hBrowser and hWeb? I think you are only getting the hBrowser to support 3.90 (?)
besides that I don't understand why you are saying that there is a better way than using a hook - is there something wrong with that?
I'm still very interested if you know a way to avoid the busy waiting for the browser to become ready, and if you find a way to make it work with picture links - I will also look into that myself now..
which references do you use? how do you know that you can query the element-interface for an 'anchor'-interface, and from where do you get the numbers in the data section..?!
there are some things in your code that I don't understand:
1. what is the event 32770 and why does the mainwindow repeatedly receive a timer event?
2. what is the difference between hBrowser and hWeb? I think you are only getting the hBrowser to support 3.90 (?)
besides that I don't understand why you are saying that there is a better way than using a hook - is there something wrong with that?
I'm still very interested if you know a way to avoid the busy waiting for the browser to become ready, and if you find a way to make it work with picture links - I will also look into that myself now..
That's what I thought too. Just takes a little patience and some good research. If I can do it, anyone can.I would have never figured that out...
For window and gadget info, I use WinDowse
For more detailed window / gadget / message info WinSpector
For finding VB / C / C++ code to convert to PB GoogleGroups
For constants ApiViewer
For API functions / interfaces / messages / structures MS full PSDK
And of course my favorite source is Home Sweet Home!
It's all in the PSDK I downloaded. For online reference, you can use the MSDN Libraryhow do you know that you can query the element-interface for an 'anchor'-interface...
The PSDK download has a Tool (OLE-COM Object viewer) that supplies that info....from where do you get the numbers in the data section..?!
I don't know, but read this and this. I use 32770 only because it seems to appear as soon as the WebGadget is ready to go. Problem is, the 32770 continues to appear throuout the session.1. what is the event 32770 and why does the mainwindow repeatedly receive a timer event?
hBrowser returns the handle to the actual web window (Internet Explorer_Server class).what is the difference between hBrowser and hWeb
hWeb returns the handle to the WebGadget (AtlAxWin class)
I need hBrowser in PB ver < 3.91 to get the correct ScreenToClient mouseX, mouseY positions. In PB 3.91, this is handled by the WindowMouseX() and WindowMouseY(). I also need hBrowser to return #False unitl the Internet Explorer_Server class window is created. When #True, I know I have the window. I can then start querying the interface.
I think I will now start to use WebObject\get_ReadyState(@rs), as this seems to work for my use. Other than get_ReadyState giving you more detail, there doesn't seem to be much difference from get_Busy....I'm still very interested if you know a way to avoid the busy waiting for the browser to become ready
get_ReadyState
get_Busy...Retrieves the ready state of the object.
#READYSTATE_LOADING = 1,
# READYSTATE_LOADED = 2,
# READYSTATE_INTERACTIVE = 3,
# READYSTATE_COMPLETE = 4
READYSTATE_UNINITIALIZED
Default initialization state.
READYSTATE_LOADING
Object is currently loading its properties.
READYSTATE_LOADED
Object has been initialized.
READYSTATE_INTERACTIVE
Object is interactive, but not all of its data is available.
READYSTATE_COMPLETE
Object has received all of its data.
Retrieves a BOOL value indicating whether the object is engaged in a navigation or downloading operation.
#TRUE The control is busy.
#FALSE The control is not busy.
Nothing wrong with the hook. I would rather use the onmouseover property of the interface. Just seems cleaner to me.besides that I don't understand why you are saying that there is a better way than using a hook - is there something wrong with that?
I'm sure it's possible, so we'll see who finds the answer first....and if you find a way to make it work with picture links
What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
thanks for the references. WinDowse looks interesting, I guess I could find a use for that.. however, it doesn't seem to work with the application I made (nothing happens when I move the mouse over its main window, as does when I do that with another applications main window)
from the psdk I installed the 'Core' and the 'Internet development' references. Now I've been browsing arround for hours, but I still can't figure out how to know which interfaces I can query the objects for.. how did you know that you can get an IHTMLAnchorElement from the IHTMLElement?!
about the problem of finding the url of a picture link: with a lot of patience and fruitless research I've made it so far as to guess that I can get an 'IHTMLImgElement' from the IHTMLElement. Now I'm wondering if there is some way to get the IHTMLAnchortElement (a href tag) that must be kind of 'surrounding' it.....
I'm afraid to open the psdk again.
ps. how/where did you learn about the AtlAxWin and Internet Explorer_Server classes?
from the psdk I installed the 'Core' and the 'Internet development' references. Now I've been browsing arround for hours, but I still can't figure out how to know which interfaces I can query the objects for.. how did you know that you can get an IHTMLAnchorElement from the IHTMLElement?!
about the problem of finding the url of a picture link: with a lot of patience and fruitless research I've made it so far as to guess that I can get an 'IHTMLImgElement' from the IHTMLElement. Now I'm wondering if there is some way to get the IHTMLAnchortElement (a href tag) that must be kind of 'surrounding' it.....
I'm afraid to open the psdk again.
ps. how/where did you learn about the AtlAxWin and Internet Explorer_Server classes?
Most likely due to a conflict between my mousehook and the mousehook of WinDowse. I'll take a look at my code again and see if i can fix that. Until then, you can comment out my mousehook...(nothing happens when I move the mouse over its main window
Code: Select all
;hhook = SetWindowsHookEx_(#WH_MOUSE, @MouseProc(), 0, lpdwProcessId)
To be honest, I'm not sure how I figured that out. I either got lucky or I found a post here or in Google Groups that helped show me the way. I'm pretty sure it was the latter....how did you know that you can get an IHTMLAnchorElement from the IHTMLElement?!
I've been working on the getting the image anchor to cooperate, but so far all I get on right-click is the url to the image itself. I must be missing a step along the way.
If you mean where did I learn of their existence, WinDowse revealed that info to me. If you mean how did I learn to code for them, I haven't yet.ps. how/where did you learn about the AtlAxWin and Internet Explorer_Server classes?
What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
Another Way, what you think of it?
Code: Select all
; Original code by Sparkie
WebObject.IWebBrowser2
Global WebObject
Procedure link()
If WebObject\get_document(@pDispatch.IDispatch) = #S_OK
If pDispatch\QueryInterface(?IID_IHTMLDocument2, @pDocument2.IHTMLDocument2) = #S_OK
If pDocument2\elementFromPoint(WindowMouseX() , WindowMouseY() , @pElement.IHTMLElement) = #S_OK
If pElement\QueryInterface(?IID_IHTMLAnchorElement, @pAnchor.IHTMLAnchorElement)= #S_OK
pAnchor\get_href(@BSTR_Anchor)
aLen = WideCharToMultiByte_(#CP_ACP, 0, BSTR_Anchor, -1, 0, 0, 0, 0)
anchor$ = Space(aLen)
WideCharToMultiByte_(#CP_ACP, 0, BSTR_Anchor, -1, @anchor$, aLen, 0, 0)
SysFreeString_(BSTR_Anchor)
If currentsb$ <> anchor$
StatusBarText(0, 0, anchor$)
currentsb$ = anchor$
EndIf
pAnchor\Release()
EndIf
pElement\Release()
EndIf
pDocument2\Release()
EndIf
pDispatch\Release()
EndIf
EndProcedure
If OpenWindow(0, 10, 10, 700, 500, #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget, "WebGadget ReadyState")
If CreateStatusBar(0, WindowID())
StatusBarText(0, 0, "")
EndIf
If CreateGadgetList(WindowID())
WebGadget(0, 10, 10, 680, 460, "http://www.purearea.net/pb/CodeArchiv/English.html")
WebObject = GetWindowLong_(GadgetID(0), #GWL_USERDATA)
EndIf
EndIf
Repeat
EventID.l=WaitWindowEvent()
If hBrowser = 0
hChild1 = FindWindowEx_(GadgetID(0), 0, "Shell Embedding", 0)
hChild2 = FindWindowEx_(hChild1, 0, "Shell DocObject View", 0)
hBrowser = FindWindowEx_(hChild2, 0, "Internet Explorer_Server", 0)
SetParent_(hBrowser,WindowID(0))
EndIf
If isBusy
WebObject\get_ReadyState(@isReady)
Select isReady
Case 1
page=0
StatusBarText(0, 0, "Page Loading")
Case 2
StatusBarText(0, 0, "Page Loaded")
Case 3
page=1
StatusBarText(0, 0, "Page is interactive with some data missing")
Case 4
page=1
StatusBarText(0, 0, "Page finished loading")
EndSelect
EndIf
WebObject\get_busy(@isBusy)
Select EventID
Case #WM_MOUSEMOVE
Hcursor=GetCursor_()
If page
If Hcursor<>65555 And Hcursor<>65553
link()
Else
StatusBarText(0, 0, "")
EndIf
EndIf
Case #WM_CLOSE
quit=1
EndSelect
Until quit=1
End
DataSection
IID_IHTMLDocument2:
;332C4425-26CB-11D0-B483-00C04FD90119
Data.l $332C4425
Data.w $26CB, $11D0
Data.b $B4, $83, $00, $C0, $4F, $D9, $01, $19
IID_IHTMLAnchorElement:
;3050F1DA-98B5-11CF-BB82-00AA00BDCE0B
Data.l $3050F1DA
Data.w $98B5, $11CF
Data.b $BB, $82, $00, $AA, $00, $BD, $CE, $0B
EndDataSection
- Kwai chang caine
- Always Here
- Posts: 5353
- Joined: Sun Nov 05, 2006 11:42 pm
- Location: Lyon - France
hello at all.
Excuse my bad english
For me two, nothing happens when I move the mouse over its main window.
I have comment out the mousehook
and it's not good
I have Windows 2000
That is the reason ????
Thanks
Excuse my bad english
For me two, nothing happens when I move the mouse over its main window.
I have comment out the mousehook
Code: Select all
;hhook = SetWindowsHookEx_(#WH_MOUSE, @MouseProc(), 0, lpdwProcessId)
I have Windows 2000
That is the reason ????
Thanks
The happiness is a road...
Not a destination
Not a destination
Take a look into this post from freak (first post):
http://www.purebasic.fr/english/viewtopic.php?t=16837
Download his incude file "WebGadgetExtras.PB"
http://freak.purearea.net/code/WebGadgetExtras.pb
And paste the example code from his first posting into your IDE.
If using PB 4.x, change
to
and change
to
and voila, it's working...
http://www.purebasic.fr/english/viewtopic.php?t=16837
Download his incude file "WebGadgetExtras.PB"
http://freak.purearea.net/code/WebGadgetExtras.pb
And paste the example code from his first posting into your IDE.
If using PB 4.x, change
Code: Select all
If OpenWindow(0, 0, 0, 800, 600, #PB_Window_SystemMenu|#PB_Window_ScreenCentered, "WebGadget example")
Code: Select all
If OpenWindow(0, 0, 0, 800, 600, "WebGadget example", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
Code: Select all
If CreateGadgetList(WindowID())
Code: Select all
If CreateGadgetList(WindowID(0))
- Kwai chang caine
- Always Here
- Posts: 5353
- Joined: Sun Nov 05, 2006 11:42 pm
- Location: Lyon - France
- a_carignan
- User
- Posts: 82
- Joined: Sat Feb 21, 2009 2:01 am
- Location: Canada
Re: WebGadget - retreiving URL of link under pointer
Hello,
Oddly it gives incomprehensible Chinese characters.
I would like to have a code that really gives the links.
tank you.
Oddly it gives incomprehensible Chinese characters.
I would like to have a code that really gives the links.
tank you.
Re: WebGadget - retreiving URL of link under pointer
Then simply adapt the code to the new version of PB.
Hint: ASCII -> Unicode
And about which code you are talking?
Here are listed and referenced many of them.
Hint: ASCII -> Unicode
And about which code you are talking?
Here are listed and referenced many of them.
- a_carignan
- User
- Posts: 82
- Joined: Sat Feb 21, 2009 2:01 am
- Location: Canada
Re: WebGadget - retreiving URL of link under pointer
I'm talking about the two sample code on this page.
I tried to convert the text with its command lines:
But it doesn't work, it's still Chinese.
I tried to convert the text with its command lines:
Code: Select all
*ascii=Ascii(anchor$)
anchor$=PeekS(*ascii,-1)