Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

how to deal with dllcall returning boolean TRUE/FALSE?


  • Please log in to reply
11 replies to this topic
jordis
  • Members
  • 81 posts
  • Last active: Aug 22 2014 01:56 PM
  • Joined: 30 Jul 2004
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

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004

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.

jordis
  • Members
  • 81 posts
  • Last active: Aug 22 2014 01:56 PM
  • Joined: 30 Jul 2004
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!

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
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.

  • Guests
  • Last active:
  • Joined: --
This is a somewhat common question. Go to http://groups.google.com and search for this keyword: InetIsOffline

jordis
  • Members
  • 81 posts
  • Last active: Aug 22 2014 01:56 PM
  • Joined: 30 Jul 2004
oops you're right...
i guess i chose the wrong API call to start with...
thanks!

  • Guests
  • Last active:
  • Joined: --
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


Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
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.

Jon
  • Members
  • 349 posts
  • Last active: Aug 30 2011 08:35 PM
  • Joined: 28 Apr 2004
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.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
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 *.

jordis
  • Members
  • 81 posts
  • Last active: Aug 22 2014 01:56 PM
  • Joined: 30 Jul 2004
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?

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
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.