Jump to content


Photo

how to deal with dllcall returning boolean TRUE/FALSE?


  • Please log in to reply
11 replies to this topic

#1 jordis

jordis
  • Members
  • 81 posts

Posted 16 May 2005 - 05:30 PM

Hi
Like -I guess- many of us AHKers, I'm trying to investigate the possibilities of the new DllCall command (and btw they seem to be huge! great addition, Chris!). Thing is, I'm quite lost with types, args and syntax in general... So I did a few tests with a very simple API call to get to know better how the whole thing works...
I picked an easy one: InetIsOffline(), located in DLL url.dll
According to the usage:

InetIsOffline Function:
Determines whether or not the system is connected to the Internet.

Syntax:
BOOL InetIsOffline(
DWORD dwFlags
);

Parameters:
dwFlags
Input flags for the function. This must be set to zero.

Return Value:
Returns TRUE if the local system is not currently connected to the Internet. Returns FALSE if the local system is connected to the Internet or if no attempt has yet been made to connect to the Internet.

So, I was trying:
Result:=DllCall("url.dll\InetIsOffline","int",0)
msgbox,%Result%
About the above DllCall command, according to the usage statement the call only requires 1 parameter, which has to be set to 0 (see underlined part above). I didn't specify any "ReturnType" because according to the AHK help file, "If the function returns an integer, BOOL, or nothing at all, ReturnType may be omitted."
The problem is that %Result% is always 0 (being connected to internet or not), which I guess indicates the dllcall errorlevel 0 (success), but I can't figure out how to get the "TRUE/FALSE" that the function is supposed to return
No matter what I try (specifying types int, int64, uint, etc., specifying VarSetCapacity, specifying a ReturnType, loading the dll beforehand...) the result is always 0 (success) but I don't get my TRUE/FALSE!

Am I missing something? (sure I am, but what? ;-)
jordi

#2 Chris

Chris
  • Administrators
  • 10727 posts

Posted 16 May 2005 - 07:22 PM

The problem is that %Result% is always 0 (being connected to internet or not), which I guess indicates the dllcall errorlevel 0 (success), but I can't figure out how to get the "TRUE/FALSE" that the function is supposed to return

I think you're doing it right. I tried it on my system:

Result := DllCall("url.dll\InetIsOffline", "int", 0)
MsgBox Result: %Result%`nErrorLevel: %ErrorLevel%

The MsgBox shows zero for both, which indicates that the call succeeded and that the function returned a 0 (false), meaning Inet is online.

Perhaps the function thinks you're connected to the Internet when you're really not. Perhaps you could try it on another system that lacks a network card.

#3 jordis

jordis
  • Members
  • 81 posts

Posted 16 May 2005 - 07:51 PM

So far I tried disabling the network connection from control panel, disabling the network card from the hardware administration, starting windows in safe mode (with no network support), but in all cases I get 0... that's why I though I was doing something wrong and that I was onbly getting the errorlevel... I have no machine without network card at the moment, so I can't try it (could anybody try and report?)... Probably the function assumes you've got inet connection when there is a NIC installed, who knows...
Since I was just playing around, I'll try to play around with another API function which can be simpler to "debug"... but the list is soooo large! ;-)
I'll report back
thanks!

#4 Chris

Chris
  • Administrators
  • 10727 posts

Posted 16 May 2005 - 08:00 PM

It might also assume you have a connection if you have an IP address of any kind. Maybe see what "ipconfig" says at the command line.

#5 Guests

  • Guests

Posted 16 May 2005 - 08:22 PM

This is a somewhat common question. Go to http://groups.google.com and search for this keyword: InetIsOffline

#6 jordis

jordis
  • Members
  • 81 posts

Posted 16 May 2005 - 09:45 PM

oops you're right...
i guess i chose the wrong API call to start with...
thanks!

#7 Guests

  • Guests

Posted 16 May 2005 - 10:00 PM

This seems to work-

connected:=DllCall("Wininet.dll\InternetGetConnectedState", "str", "0x20","int",0, "Cdecl int")


if connected = 1
msgbox, You are online
else
msgbox, You are offline


#8 Chris

Chris
  • Administrators
  • 10727 posts

Posted 16 May 2005 - 10:14 PM

Thanks for the solution.

A couple of minor observations that might not affect the behavior in this case:

1) The 0x20 parameter should probably not be enclosed in quotes. In addition, the "str" that precedes it should probably be "UInt *" instead.

2) Are you sure this function is "Cdecl"? I thought most API functions were standard-call unless they accept a varying number of args such as wsprintf(). If you use the wrong calling convention, it might cause unpredictable results.

#9 Jon

Jon
  • Members
  • 349 posts

Posted 16 May 2005 - 10:35 PM

That was me posting above. I forgot to sign in.

Thanks for correcting it. I am still trying to get the hang of API calls, they are very new to me and I don't quite understand the correct syntax etc. I think you need to be a programmer in vb6 or C++ to understand it properly.

I never realised that Returntype and Cdecl were two different things :oops:. I never read the documentation properly.

#10 Chris

Chris
  • Administrators
  • 10727 posts

Posted 16 May 2005 - 10:42 PM

Yes, it takes some study to figure everything out. In general, whenever you see a prefix such as LP in something like "LPDWORD", it means the arg type should be an asterisk variable. Since a DWORD is an unsigned 32-bit integer, an LPDWORD is a pointer to that, which would have an arg type of UInt *.

#11 jordis

jordis
  • Members
  • 81 posts

Posted 17 May 2005 - 09:18 PM

Thanks Jon, I'll check it out... It's true that we need some training on dllcalls...

In general, whenever you see a prefix such as LP in something like "LPDWORD", it means the arg type should be an asterisk variable. Since a DWORD is an unsigned 32-bit integer, an LPDWORD is a pointer to that, which would have an arg type of UInt *.

Chris, I think this kind of info should *definately* be included in the help file, within the explanation of the different filetypes that dllcall supports.
This is something that non-programmers might get confused with...
Actually in all the API function usage references found in the web, what we get is a whole bunch of WORDS DWORDS LPDWORDS ... that we (or me at least) cannot really associate to their dllcall equivalent ("srt" "int" "int64" "uint" asterisks, etc.)
I would have never figured it out that LPDWORD = "Uint *"
A kind of "cheat-sheet" with all these correspondences would be greatly appreciated!
Don't you think?

#12 Chris

Chris
  • Administrators
  • 10727 posts

Posted 18 May 2005 - 01:46 AM

There are a lot of types and definitions within the system API. Although it would probably be beyond the scope of the documentation to be a complete reference of them, I intend to add a lot more examples over time. I agree that it would be good to include mention of common types such as DWORD and LPDWORD, so I'll try to work those in.

Thanks.