Fog Creek Software
Discussion Board




WinInet Using VB

I have been trying to use the WinInet.dll within an Activex DLL that I am trying to make in VB. I know that Joel has used the WinInet library for CityDesk, and I know that CityDesk was written in VB, but the IDE keeps telling me that it cannot get load the DLL as a reference. Anyone else have this problem?

Did I dream up using WinInet in VB? Please help, I would rather use WinInet instead of Winsock.

Giampiero
Thursday, November 07, 2002

Here's a starting point (without comment or explanations):

Private Const scUserAgent = "MyApplication"
Private Const INTERNET_USER_AGENT = "My own WinInet"

Private Const INTERNET_OPEN_TYPE_PRECONFIG = 0
Private Const PRE_CONFIG_INTERNET_ACCESS = 0
Private Const INTERNET_INVALID_PORT_NUMBER = 0
Private Const INTERNET_FLAG_RELOAD = &H80000000

Private Declare Function InternetOpen Lib "wininet.dll" Alias _
    "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType _
    As Long, ByVal sProxyName As String, ByVal sProxyBypass As _
    String, ByVal lFlags As Long) As Long

Private Declare Function InternetOpenUrl Lib "wininet.dll" Alias _
    "InternetOpenUrlA" (ByVal hOpen As Long, ByVal sUrl As String, _
    ByVal sHeaders As String, ByVal lLength As Long, ByVal lFlags _
    As Long, ByVal lContext As Long) As Long

Private Declare Function InternetCloseHandle Lib "wininet.dll" _
(ByVal hInet As Long) As Integer

Private Declare Function InternetReadFile Lib "wininet.dll" ( _
    ByVal hFile As Long, _
    ByVal sBuffer As String, _
    ByVal lNumBytesToRead As Long, _
    lNumberOfBytesRead As Long) _
    As Integer


Private Sub Form_Load()
Dim hNet As Long
Dim hUrlFile As Long
Dim buffer As String
Dim BytesRead As Long
Dim bRead As Integer

hNet = InternetOpen("My Test", PRE_CONFIG_INTERNET_ACCESS, _
    vbNullString, INTERNET_INVALID_PORT_NUMBER, 0)
hUrlFile = InternetOpenUrl(hNet, _
    "http://www.microsoft.com", _
    vbNullString, 0, INTERNET_FLAG_RELOAD, 0)

buffer = String(102400, 0)
bRead = InternetReadFile(hUrlFile, buffer, Len(buffer), BytesRead)
buffer = Left(buffer, BytesRead)

Debug.Print buffer

Call InternetCloseHandle(hUrlFile)

Call InternetCloseHandle(hNet)

End Sub

Philip Dickerson
Thursday, November 07, 2002

Why are you trying to use WinInet at all? You can probably use XmlHTTP, which is included with MSXML. It may use urlmon or wininet behind the scenes, but you don't need to know about that.

mb
Thursday, November 07, 2002

Oh, one more thing: is this ActiveX control running in a user's web browser? And you want to use it to get documents from elsewhere? You can easily create a big security hole with this, please be aware of that and embed appropriate restrictions into your control.

(One security hole: evil popup ad site creates a page with your activex control on it, telling it do download something bad--maybe a well known email site or banking site. then they can upload the email/banking data back to themselves.)

mb
Thursday, November 07, 2002

To expand on Philip's explanation: There are 2 types of dlls.  COM and non COM.  Wininet.dll is a Non COM dll.  You cannot load these using the add reference menu in VB.  You need to specify the prototype of the functions you wish to use in that dll.  Then you can call these functions from your vb app and the vb runtime will find the actual dll and call the functions in it.

Kevin

Kevin
Thursday, November 07, 2002

To expand a little on the code sample that I entered earlier...

As explained by Kevin, WinInet is an "API" style DLL, not a COM DLL. A reference to the WinInet DLL cannot be added to a VB project, the DLL must be called similar to Windows API's - by declaring the appropriate functions and constants for the DLL and then calling those functions from VB. You don't need to declare ALL the functions and constants for the DLL, only those that are called in your VB code.

Warning - when string values are returned by API methods, the strings must be pre-allocated to be large enough to hold the return value (otherwise, depending on the particular API, you will either get an empty string or cause a fatal error in your program). The function used in the example code includes a parameter for the length of the string, so it won't attempt to write past the end of the string buffer. However, not every Windows API functions includes a length parameter. Also, do not use fixed-length strings for these return parameters - this will cause a different type of error.

That's the reason for the statement:
buffer = String(102400, 0)
The number in this statement needs to be large enough for the expected return string. Alternatively, you can check the "BytesRead" value - if this return value is equal to the length of the pre-allocated string, then you need to increase the size of the string and call the function again.

A few useful articles for using WinInet are:

Platform SDK: Windows Internet - Using WinINet
http://msdn.microsoft.com/library/en-us/wininet/wininet/using_wininet.asp

WinInet: Enable HTTP Communication in Windows-Based Client Applications
http://msdn.microsoft.com/msdnmag/issues/01/06/UseMon/default.aspx

Platform SDK: Windows Internet - WinINet Reference
http://msdn.microsoft.com/library/en-us/wininet/wininet/wininet_reference.asp

Note that a few (less common) WinInet functions are only available if later versions of Internet Explorer are installed on the client system - see:
INFO: WinInet APIs and Internet Explorer Version Information
http://support.microsoft.com/default.aspx?scid=KB;en-us;Q252369


Using XMLHTTP is often a better alternative to WinInet, but it requires that you can ensure that a sufficiently recent version of MSXML (or a very recent version of Interent Explorer or the operating system) is installed on the client system.

Philip Dickerson
Friday, November 08, 2002

*  Recent Topics

*  Fog Creek Home