CWindow RC18

Started by José Roca, August 25, 2016, 09:56:54 PM

Previous topic - Next topic

Marc Pons

Jose , sincerly your code flow is like the Amazonia River...

impressive, and as always excellent.

Marc Pons

Jose in your CVar.inc :
QuoteNote: Requires Windows XP SP2 or superior.

I am under XP SP3 and that propsys.dll is not part of the system ( it is normally beginning with vista  , I think)
if needed, has to be placed a downloaded version on system32 folder for 32bits  !

is it what i've done, and seems to work ...

José Roca

#17
I have modified some comments and added the AnsiStr property to convert to ansi. The CAST () AS STRING operator returns an ansi string that contains unicode. This is a hack to workaround the problem of not being able of returning a CBSTR in an operator.

Therefore, we can use


print pDic.Item("a")


or


print pDic.Item("a").Str


that will print an unicode string,

or


print pDic.Item("a").AnsiStr


that will print an ansi string.

We can also use UTF8:


pDic.Add "a", AfxUcode("Αθήνα", CP_UTF8)


José Roca

Quote from: Marc Pons on August 29, 2016, 07:14:34 AM
Jose in your CVar.inc :
QuoteNote: Requires Windows XP SP2 or superior.

I am under XP SP3 and that propsys.dll is not part of the system ( it is normally beginning with vista  , I think)
if needed, has to be placed a downloaded version on system32 folder for 32bits  !

is it what i've done, and seems to work ...

That is what Microsoft says...

Minimum supported client
Windows XP with SP2, Windows Vista [desktop apps only]

https://msdn.microsoft.com/en-us/library/windows/desktop/bb776584(v=vs.85).aspx


José Roca

Quote from: Marc Pons on August 29, 2016, 07:02:49 AM
Jose , sincerly your code flow is like the Amazonia River...

impressive, and as always excellent.

I'm becoming old and can't wait years. Every day counts...

Each new class that I write opens new possibilities, but also the need for more classes.

I have almost finished a class for WINHTTP, but I need support for streams, so I will have to write a CStream class some day to finish it...

The new variant class will allow me to write classes for ADO, and the ADO classes will allow me to write classes for CDO.

José Roca

shlwapi.dll provides API functions to work with streams, but, of course, they aren't declared in the FB headers. What a surprise! Well, it doesn't matter.

James Fuller

Quote from: Jose Roca on August 29, 2016, 10:21:53 AM
shlwapi.dll provides API functions to work with streams, but, of course, they aren't declared in the FB headers. What a surprise! Well, it doesn't matter.

Jose,
  Just a FYI.
Peter of BaCon fame switched to dynamic loading of shared libraries quite some time ago.
With the number of linux distros you never know exactly which version of a shared library is available.
Also this way you can call the parameters just about any thing you want ala PowerBASIC. :)

Fred also did this with his TCLib.


James

José Roca

And now I'm doing it with FreeBASIC. I had a lot of problems with GdiPlus. Some functions are supported in 32 bit and not in 64 bit, and viceversa. The problem is that GdiPlus has more than 600 functions...

José Roca

#23
Another test for the new CVA data type.

CWinHTTPRequest class

Microsoft Windows HTTP Services (WinHTTP) provides developers with a server-supported, high-level interface to the HTTP/1.1 Internet protocol. WinHTTP is designed to be used primarily in server-based scenarios by server applications that communicate with HTTP servers.

https://msdn.microsoft.com/en-us/library/windows/desktop/aa382925(v=vs.85).aspx

Paul Squires

Thanks Jose for all your incredible hard work. You have driven forward FreeBasic Windows development exponentially.
Paul Squires
PlanetSquires Software

José Roca

Some examples:


' ========================================================================================
' The following example checks if the current platform is supported.
' ========================================================================================

#include "windows.bi"
#include "Afx/CWinHttpRequest.inc"
using Afx

IF AfxWinHttpCheckPlatform THEN
   PRINT "This platform is supported by WinHTTP."
ELSE
   PRINT "This platform is NOT supported by WinHTTP."
END IF

PRINT
PRINT "Press any key..."
SLEEP



' ========================================================================================
' The following example shows how to open an HTTP connection, send an HTTP request, and
' returns the "Date" header from the response.
' ========================================================================================

#include "windows.bi"
#include "Afx/CWinHttpRequest.inc"
using Afx

' // Create an instance of the CWinHttp class
DIM pWHttp AS CWinHttpRequest

' // Open an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://microsoft.com"

' // Send an HTTP request to the HTTP server
pWHttp.Send

' // Wait for response with a timeout of 5 seconds
DIM iSucceeded AS LONG = pWHttp.WaitForResponse(5)

' // Get the response headers
DIM cbsResponseHeader AS CBSTR = pWHttp.GetResponseHeader("Date")
PRINT cbsResponseHeader

PRINT
PRINT "Press any key..."
SLEEP



' ========================================================================================
' The following example shows how to open an HTTP connection, send an HTTP request, and
' returns all of the headers from the response.
' ========================================================================================

#include "windows.bi"
#include "Afx/CWinHttpRequest.inc"
using Afx

' // Create an instance of the CWinHttp class
DIM pWHttp AS CWinHttpRequest

' // Open an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://microsoft.com"

' // Send an HTTP request to the HTTP server
pWHttp.Send

' // Wait for response with a timeout of 5 seconds
DIM iSucceeded AS LONG = pWHttp.WaitForResponse(5)

' // Get the response headers
DIM cbsResponseHeaders AS CBSTR = pWHttp.GetAllResponseHeaders
PRINT cbsResponseHeaders

PRINT
PRINT "Press any key..."
SLEEP


José Roca


' ========================================================================================
' The following example shows how to open an HTTP connection, send an HTTP request, and
' returns the response body.
' ========================================================================================

#include "windows.bi"
#include "Afx/CWinHttpRequest.inc"
using Afx

' // Create an instance of the CWinHttp class
DIM pWHttp AS CWinHttpRequest

' // Open an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://microsoft.com"

' // Send an HTTP request to the HTTP server
pWHttp.Send

' // Wait for response with a timeout of 5 seconds
DIM iSucceeded AS LONG = pWHttp.WaitForResponse(5)

' // Get the response body
DIM cbsResponseBody AS CBSTR = pWHttp.GetResponseBody
PRINT cbsResponseBody

PRINT
PRINT "Press any key..."
SLEEP



' ========================================================================================
' The following example shows how to open an HTTP connection, send an HTTP request, and
' returns the response body as a stream of bytes.
' ========================================================================================

#include "windows.bi"
#include "Afx/CWinHttpRequest.inc"
using Afx

' // Create an instance of the CWinHttp class
DIM pWHttp AS CWinHttpRequest

' // Open an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://www.microsoft.com/library/homepage/images/ms-banner.gif"

' // Send an HTTP request to the HTTP server
pWHttp.Send

' // Wait for response with a timeout of 5 seconds
DIM iSucceeded AS LONG = pWHttp.WaitForResponse(5)

' // Get the response body
DIM strResponseBody AS STRING = pWHttp.GetResponseStream

' // Save the buffer into a file
IF LEN(strResponseBody) THEN
   DIM fn AS LONG = FREEFILE
   OPEN "ms-banner.gif" FOR OUTPUT AS #fn
   PUT #fn, 1, strResponseBody
   CLOSE #fn
   PRINT "File saved"
ELSE
   PRINT "Failure"
END IF

PRINT
PRINT "Press any key..."
SLEEP



' ========================================================================================
' The following example shows how to open an HTTP connection, send an HTTP request, and
' returns the response text.
' ========================================================================================

#include "windows.bi"
#include "Afx/CWinHttpRequest.inc"
using Afx

' // Create an instance of the CWinHttp class
DIM pWHttp AS CWinHttpRequest

' // Open an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://microsoft.com"

' // Send an HTTP request to the HTTP server
pWHttp.Send

' // Wait for response with a timeout of 5 seconds
DIM iSucceeded AS LONG = pWHttp.WaitForResponse(5)

' // Get the response headers
DIM cbsResponseText AS CBSTR = pWHttp.GetResponseText
PRINT cbsResponseText

PRINT
PRINT "Press any key..."
SLEEP


José Roca

Another example:


' ========================================================================================
' The following example checks if the current platform is supported.
' ========================================================================================

#include "windows.bi"
#include "Afx/CWinHttpRequest.inc"
using Afx

' // Create an instance of the CWinHttp class
DIM pWHttp AS CWinHttpRequest

' // Open an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://microsoft.com"

' // Specify the user agent
pWHttp.SetOption(WinHttpRequestOption_UserAgentString, "A WinHttpRequest Example Program")

' // Send an HTTP request to the HTTP server
pWHttp.Send

IF pWHttp.GetLastResult = S_OK THEN
   ' // Get user agent string.
   DIM cvText AS CVAR = pWHttp.GetOption(WinHttpRequestOption_UserAgentString)
   PRINT cvText
   ' // Get URL
   cvText = pWHttp.GetOption(WinHttpRequestOption_URL)
   PRINT cvText
   ' // Get URL Code Page.
   cvText = pWHttp.GetOption(WinHttpRequestOption_URLCodePage)
   PRINT cvText
   ' // Convert percent symbols to escape sequences.
   cvText = pWHttp.GetOption(WinHttpRequestOption_EscapePercentInURL)
   PRINT IIF&(cvText.vd.boolVal, "true", "false")
END IF

PRINT
PRINT "Press any key..."
SLEEP


José Roca

#28
As a demonstration of how wrappers can made things easy, see the original C++ code of the example above posted:



#include <windows.h>
#include <stdio.h>
#include <objbase.h>

#include "httprequest.h"

#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "oleaut32.lib")

// IID for IWinHttpRequest.
const IID IID_IWinHttpRequest =
{
    0x06f29373,
    0x5c5a,
    0x4b54,
    {0xb0, 0x25, 0x6e, 0xf1, 0xbf, 0x8a, 0xbf, 0x0e}
};

int main()
{
    // Variable for return value
    HRESULT    hr;

    // Initialize COM
    hr = CoInitialize( NULL );

    IWinHttpRequest *  pIWinHttpRequest = NULL;

    BSTR            bstrResponse = NULL;
    VARIANT         varFalse;
    VARIANT         varEmpty;
    VARIANT         varUserAgent;

    CLSID           clsid;

    VariantInit(&varFalse);
    V_VT(&varFalse)   = VT_BOOL;
    V_BOOL(&varFalse) = VARIANT_FALSE;

    VariantInit(&varEmpty);
    V_VT(&varEmpty) = VT_ERROR;

    varUserAgent.vt = VT_BSTR;
    varUserAgent.bstrVal = NULL;

    hr = CLSIDFromProgID(L"WinHttp.WinHttpRequest.5.1", &clsid);

    if (SUCCEEDED(hr))
    {
        hr = CoCreateInstance(clsid,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IWinHttpRequest,
                              (void **)&pIWinHttpRequest);
    }
    if (SUCCEEDED(hr))
    {
        // Open WinHttpRequest.
        BSTR bstrMethod  = SysAllocString(L"GET");
        BSTR bstrUrl = SysAllocString(L"http://microsoft.com");
        hr = pIWinHttpRequest->Open(bstrMethod,
                                    bstrUrl,
                                    varFalse);
        SysFreeString(bstrMethod);
        SysFreeString(bstrUrl);
    }
    if (SUCCEEDED(hr))
    {
        // Specify the user agent.
        varUserAgent.vt = VT_BSTR;
        varUserAgent.bstrVal =
                   SysAllocString(
                           L"A WinHttpRequest Example Program");

        //varUserAgent is L"A WinHttpRequest Example Program");
        hr = pIWinHttpRequest->put_Option(
                                 WinHttpRequestOption_UserAgentString,
                                 varUserAgent);
    }
    if (SUCCEEDED(hr))
    {    // Send Request.
        hr = pIWinHttpRequest->Send(varEmpty);
    }
    if (SUCCEEDED(hr))
    {
        // Get user agent string.
        hr = pIWinHttpRequest->get_Option(
                                 WinHttpRequestOption_UserAgentString,
                                 &varUserAgent);
        // Print response to console.
        wprintf(L"%s\n\n", varUserAgent.bstrVal);

        // Get URL.
        hr = pIWinHttpRequest->get_Option(WinHttpRequestOption_URL,
                                          &varUserAgent);
        // Print response to console.
        wprintf(L"%s\n\n", varUserAgent.bstrVal);

        // Get URL Code Page.
        hr = pIWinHttpRequest->get_Option(
                                     WinHttpRequestOption_URLCodePage,
                                     &varUserAgent);
        // Print response to console.
        wprintf(L"%u\n\n", varUserAgent.lVal);

        // Convert percent symbols to escape sequences.
        hr = pIWinHttpRequest->get_Option(
                              WinHttpRequestOption_EscapePercentInURL,
                              &varUserAgent);
        // Print response to console.
        wprintf(L"%s\n", varUserAgent.boolVal?L"True":L"False");
    }

    // Release memory.
    if (pIWinHttpRequest)
        pIWinHttpRequest->Release();
    if (bstrResponse)
        SysFreeString(bstrResponse);
    if (varUserAgent.bstrVal)
        SysFreeString(varUserAgent.bstrVal);

    CoUninitialize();
    return 0;
}


All this


        // Open WinHttpRequest.
        BSTR bstrMethod  = SysAllocString(L"GET");
        BSTR bstrUrl = SysAllocString(L"http://microsoft.com");
        hr = pIWinHttpRequest->Open(bstrMethod,
                                    bstrUrl,
                                    varFalse);
        SysFreeString(bstrMethod);
        SysFreeString(bstrUrl);


becomes reduced to


pWHttp.Open "GET", "http://microsoft.com"


José Roca

Quote from: TechSupport on August 29, 2016, 01:04:43 PM
Thanks Jose for all your incredible hard work. You have driven forward FreeBasic Windows development exponentially.


In a few months I have posted more code than the entire FB community in ten years :)

At the beginning I was a bit slow because I still had not mastered the language and had not the new data types. Now everything is becoming very simple.

It takes me more time to do the testing and write the documentation than to write the code.

Now I need a safe array class to complete the toolbox.