• Welcome to PlanetSquires Forums.
 

Could need some guiding using AfxCom

Started by Eigil Dingsor, January 14, 2020, 12:58:45 PM

Previous topic - Next topic

Eigil Dingsor

Hi, I try to translate the following XMLHTTP code by using Jose's WinFBX include files ie AfxCom syntax, but  the FB 1.07.1 Win32 Compiler throws me an error. I'm probably not assigning interface pointers correctly. Have studied the Sapi example in depth though.
This is the Disphelper XLMHTTP code that I try to convert.

'' HTTP GET example, using MSXML2

#define UNICODE
#include "disphelper/disphelper.bi"

DISPATCH_OBJ(objHTTP)

dhInitialize(TRUE)
dhToggleExceptions(TRUE)

dhCreateObject("MSXML2.XMLHTTP.4.0", NULL, @objHTTP)

dhCallMethod(objHTTP, ".Open(%s, %s, %b)", "GET", "http://sourceforge.net", FALSE)
dhCallMethod(objHTTP, ".Send")

Dim As ZString Ptr szResponse
dhGetValue("%s", @szResponse, objHTTP, ".ResponseText")

Print "Response: "; *szResponse
dhFreeString(szResponse)

SAFE_RELEASE(objHTTP)
dhUninitialize(TRUE)


Here's my translated code that doesn't work

#pragma once
#include once "Afx/AfxSpError.bi"
#include once "Afx/AfxCOM.inc"
using Afx

NAMESPACE Afx
'' // The definition for BSTR in the FreeBASIC headers was inconveniently changed to WCHAR
#ifndef AFX_BSTR
   #define AFX_BSTR WSTRING PTR
#endif

'----------------------------Start Copy------------------------------------
'Excerpts copied from  msxlm3.dll TypeLib via Jose's TypeLib Browser for Freebasic

   CONST AFX_PROGID_Msxml2_XMLHTTP = "Msxml2.XMLHTTP"
  CONST AFX_CLSID_XMLHTTP = "{F6D90F16-9C73-11D3-B32E-00C04F990BB4}"
  CONST AFX_IID_IXMLHTTPRequest = "{ED8C108D-4349-11D2-91A4-00C04F7969E8}"
 
    TYPE Afx_IXMLHTTPRequest AS  IXMLHTTPRequest_

  TYPE IXMLHTTPRequest_ EXTENDS Afx_iDispatch
   DECLARE ABSTRACT FUNCTION open (BYVAL bstrMethod AS BSTR, BYVAL bstrUrl AS BSTR, BYVAL varAsync AS VARIANT = TYPE(VT_ERROR,0,0,0,DISP_E_PARAMNOTFOUND), BYVAL bstrUser AS VARIANT = TYPE(VT_ERROR,0,0,0,DISP_E_PARAMNOTFOUND), BYVAL bstrPassword AS VARIANT = TYPE(VT_ERROR,0,0,0,DISP_E_PARAMNOTFOUND)) AS HRESULT
   DECLARE ABSTRACT FUNCTION setRequestHeader (BYVAL bstrHeader AS BSTR, BYVAL bstrValue AS BSTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION getResponseHeader (BYVAL bstrHeader AS BSTR, BYVAL pbstrValue AS BSTR PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION getAllResponseHeaders (BYVAL pbstrHeaders AS BSTR PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION send (BYVAL varBody AS VARIANT = TYPE(VT_ERROR,0,0,0,DISP_E_PARAMNOTFOUND)) AS HRESULT
   DECLARE ABSTRACT FUNCTION abort () AS HRESULT
   DECLARE ABSTRACT FUNCTION get_status (BYVAL plStatus AS LONG PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION get_statusText (BYVAL pbstrStatus AS BSTR PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION get_responseXML (BYVAL ppBody AS IDispatch PTR PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION get_responseText (BYVAL pbstrBody AS BSTR PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION get_responseBody (BYVAL pvarBody AS VARIANT PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION get_responseStream (BYVAL pvarBody AS VARIANT PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION get_readyState (BYVAL plState AS LONG PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION put_onreadystatechange (BYVAL rhs AS IDispatch PTR) AS HRESULT
END TYPE
 
end namespace
 
'--------------------------End Copy-----------------------------------------------
' // Initialize the COM library
     CoInitialize(NULL)
 
         dim pXlm AS   Afx_IXMLHTTPRequest PTR    = AfxNewCom(AFX_PROGID_Msxml2_XMLHTTP )
       
         ' // Create an instance of the MSXLM object
         
         IF pXlm THEN   print "yes"
         'Get compiler error:    error 18: Element not defined, open in 'pXlm->open("GET","http://sourceforge.net" ,false)'
         
        pXlm->open("GET","http://sourceforge.net" ,false)
   ' // Uninitalize COM
   CoUninitialize
   sleep



Any hints?


Eigil

José Roca

#1
Be careful with old examples because they may try to use COM servers that are obsolete or not installed in your computer. The latest version that I have installed is the 6.0, so I have changed the code accordingly. You have generated identifiers for version 3.0, that does not work in my computer. Also note that the valid url is no longer "http://sourceforge.net/", but "https://sourceforge.net/".


'#CONSOLE ON
#include once "Afx/AfxCOM.inc"
using Afx

'----------------------------Start Copy------------------------------------
'Excerpts copied from  msxlm3.dll TypeLib via Jose's TypeLib Browser for Freebasic

'  CONST AFX_PROGID_Msxml2_XMLHTTP = "Msxml2.XMLHTTP"
'  CONST AFX_CLSID_XMLHTTP = "{F6D90F16-9C73-11D3-B32E-00C04F990BB4}"

CONST AFX_PROGID_Msxml2_XMLHTTP_6_0 = "Msxml2.XMLHTTP.6.0"
CONST AFX_CLSID_XMLHTTP60 = "{88D96A0A-F192-11D4-A65F-0040963251E5}"
CONST AFX_IID_IXMLHTTPRequest = "{ED8C108D-4349-11D2-91A4-00C04F7969E8}"

TYPE Afx_IXMLHTTPRequest AS Afx_IXMLHTTPRequest_

TYPE Afx_IXMLHTTPRequest_ EXTENDS Afx_iDispatch
   DECLARE ABSTRACT FUNCTION open (BYVAL bstrMethod AS BSTR, BYVAL bstrUrl AS BSTR, BYVAL varAsync AS VARIANT = TYPE(VT_ERROR,0,0,0,DISP_E_PARAMNOTFOUND), BYVAL bstrUser AS VARIANT = TYPE(VT_ERROR,0,0,0,DISP_E_PARAMNOTFOUND), BYVAL bstrPassword AS VARIANT = TYPE(VT_ERROR,0,0,0,DISP_E_PARAMNOTFOUND)) AS HRESULT
   DECLARE ABSTRACT FUNCTION setRequestHeader (BYVAL bstrHeader AS BSTR, BYVAL bstrValue AS BSTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION getResponseHeader (BYVAL bstrHeader AS BSTR, BYVAL pbstrValue AS BSTR PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION getAllResponseHeaders (BYVAL pbstrHeaders AS BSTR PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION send (BYVAL varBody AS VARIANT = TYPE(VT_ERROR,0,0,0,DISP_E_PARAMNOTFOUND)) AS HRESULT
   DECLARE ABSTRACT FUNCTION abort () AS HRESULT
   DECLARE ABSTRACT FUNCTION get_status (BYVAL plStatus AS LONG PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION get_statusText (BYVAL pbstrStatus AS BSTR PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION get_responseXML (BYVAL ppBody AS IDispatch PTR PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION get_responseText (BYVAL pbstrBody AS BSTR PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION get_responseBody (BYVAL pvarBody AS VARIANT PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION get_responseStream (BYVAL pvarBody AS VARIANT PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION get_readyState (BYVAL plState AS LONG PTR) AS HRESULT
   DECLARE ABSTRACT FUNCTION put_onreadystatechange (BYVAL rhs AS IDispatch PTR) AS HRESULT
END TYPE

'--------------------------End Copy-----------------------------------------------
' // Initialize the COM library
   CoInitialize(NULL)

   dim pXlm AS Afx_IXMLHTTPRequest PTR = AfxNewCom(AFX_PROGID_Msxml2_XMLHTTP_6_0)
   ' // Create an instance of the MSXLM object
   IF pXlm THEN print "yes"
         
   DIM cbsMethod AS CBSTR = "GET"
   DIM cbsUrl AS CBSTR = "https://sourceforge.net/"
   DIM varAsync AS VARIANT = TYPE(VT_BOOL,0,0,0,0)
   DIM hr AS HRESULT = pXlm->open(cbsMethod, cbsUrl, varAsync)
   hr = pXlm->Send
   DIM cwsResponse AS CBSTR
   hr = pXlm->get_responseText(cwsResponse.vptr)
   print cwsResponse

   ' // Release the interface
   AfxSafeRelease(pXlm)

   ' // Uninitalize COM
   CoUninitialize
   sleep


PS. I have added Afx_ to IXMLHTTPRequest_ because, otherwise, it conflicts with the declaration in the FB headers. Will change my TypeLib Browser to always add the Afx_ prefix.

Eigil Dingsor

Many thanks for answer Josè.
It is somewhat  comforting that I was on right track, but worked on «obsolete» code framework.
Eigil

José Roca

#3
Alternate way using the CDispInvoke class:


'#CONSOLE ON
#include once "Afx/CDIspInvoke.inc"
using Afx

' // Create an instance of the Msxml2 object
DIM pDisp AS CDispInvoke = "Msxml2.XMLHTTP.6.0"
' // To check for success, see if the value returned by the DispPtr method is not null
IF pDisp.DispPtr = NULL THEN END

pDisp.Invoke("open", "GET", "https://sourceforge.net/", 0)
pDisp.Invoke("Send")
DIM strResponse AS STRING = pDisp.Get("ResponseText")
print strResponse

SLEEP


Similar to dispHelper, but easier and without the need to use an external DLL. And it works with both 32 and 64 bit.


Eigil Dingsor

Thank you again Josè,
Think I'll proceed with the CDispinvoke class. Less code and less verbose than my initial approach. The XMLHTTP communication is just a small part of my code.
Eigil