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
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
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)
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
and then comment the line after those 3
Code: Select all
If pDocument2\elementFromPoint(WindowMouseX() , WindowMouseY() , @pElement) = #S_OK
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.
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
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.
