Converting API statements to MapBasic 

Last update Sept. 25, 2002

In the course of preparing an “exhaustive” list of WIN-API statements usable directly in MapBasic, I have encountered a series of situations that I do not know how to solve. You will find them expressed in the form of questions scattered among the explanations of the “rules” I am using for translating the statements from VB to MB. I also have questions about the best way to organize the data and to define an efficient retrieval tool. 

I am calling on all of you who have some experience in the area. I will appreciate any help in finding practical answers to the problems, in offering corrections to the stated rules and in defining possible practical solutions. 

I will update that page as frequently as required to give you the most complete info on the subject. 

Jacques Paris  jacques@paris-pc-gis.com

  

Objective 

To provide statements (Declare, Type and Define) for Windows API functions and subs directly useable in MapBasic. 

Aimed at providing the proper syntax of those statements, it does not include any programming instructions or details about arguments definitions or functionalities. One should have to use established sources (books or web sites) for explanations about them.

  

Scope 

I am using the WIN32API.txt file distributed with VB version 6 as the main source. It covers all the Windows DLLs of interest for a VB programmer. 

Question 1

Should all the DLLs included in the WINAPI file be translated? If not, what are those to keep?

Ex.: could a MB programmer be really interested in MIDI functions?

 

Question 2

Should all the DLLs be put in the same bag, or should there be a separate bag for each one?

Ex.: all in one helps locating any call, separate ones are faster to handle when one knows where to go. 

 

Global 

All “Public” or “Private” that precede the statements in VB are eliminated in MB.  

If a statement cannot be converted to MB syntax, then all statements involved will be marked as unavailable. 

Example: if no solution can be found to the BYTE type, CommConfigDialog will be marked as unavailable because it uses a type that uses itself a type with BYTE definitions, as will be the two TYPES involved 

Declare Function CommConfigDialog Lib "kernel32" Alias   "CommConfigDialogA"

(ByVal lpszName As String, ByVal hWnd As Integer,

lpCC As COMMCONFIG) As Integer

 

Type COMMCONFIG

      dwSize As Integer

      wVersion As Smallint

      wReserved As Samllint

      dcbx As DCB

...

End Type

 

Type DCB

       DCBlength As Integer

      BaudRate As Integer

...

      XoffLim As Smallint

      ByteSize As Byte

      Parity As Byte

...

      wReserved1 As Smallint

End Type 

Any other function/sub using the COMMCONFIG type and any type using either one (and declares using these types) will also be marked as unavailable

  

DECLARE of functions and subs 

The variable types are converted in the following manner 

VB

MB

notes

LONG

INTEGER

 

INTEGER

SMALLINT

 

STRING

STRING

 

DOUBLE

FLOAT

Very rare

ANY

STRING

See the “Any>String” note

BYTE

???

See the “Byte>???” note

PICT ...

 

Other types that do not exist in MB and cannot be translated

 

Any>String 

The type of the arguments changed under that rule is shown in bold italics (String).

This conversion may require from the programmer that he be sure of the type of the value passed to the function. 

Question 3

Does MB make an automatic translation from a numerical variable to a string value when a call is made to a String argument?

I have found in the WINAPI.txt file few places where it is said something like: “If the Any type is replaced by String, the argument should be preceded by ByVal“. 

Question 4

Should all the instances where Any has been replaced by String be corrected with the addition of ByVal? 

There could be some logic to it, given the fact that using a string type only may force some conversion on the output of the function (assuming that the argument in question is modified by the function).

 

Byte>??? 

There is a way to pass some byte info from MB to a VB API declare but I do not know if it can be generalized. 

Question 5

Are there general rules that could be applied in the specification of the byte type?

  

TYPE statements 

The same conventions used for the argument types are applied here. 

VB includes a statement that is associated with TYPE; ENUM has no equivalent in MB. 

Type LOCALGROUP_MEMBERS_INFO_1

   pSID As Integer

   eUsage As g_netSID_NAME_USE

   psName As Integer

End Type

 

Enum g_netSID_NAME_USE

   SidTypeUser = 1&

   SidTypeGroup = 2&

   SidTypeDomain = 3&

   SidTypeAlias = 4&

   SidTypeWellKnownGroup = 5&

   SidTypeDeletedAccount = 6&

   SidTypeInvalid = 7&

   SidTypeUnknown = 8&

End Enum 

Question 6

Should a ENUM statement be replaced by a TYPE followed by the appropriate DEFINEs? How would argument types be identified from the assigned values in the ENUM?

 

CONSTANTS 

The VB format “CONST  xxx=aaa” is replaced by the MB syntax “Define xxx  aaa” 

There is a problem with multiple constant definitions, for example 

Const SCS_CHANGECLAUSE = (GCS_COMPREADCLAUSE Or GCS_COMPCLAUSE) 

The (xxx OR yyy...) syntax will be accepted by MB in a DEFINE  as a sting, but it does not work in a MB program; the following equivalent will work : 

Define SCS_CHANGECLAUSE  any(GCS_COMPREADCLAUSE, GCS_COMPCLAUSE) 

but will it work as a WINAPI call? 

Question 7

How can a VB multiple constant definition be safely translated  to MB? 

 

 

Notes to MB programmers

 

1 - The order of inclusion in the MB script of the various API-call related statements is important. 

1a/ If an argument of a function or sub is defined as a type, the TYPE must precede the function/sub DECLARE. 

1b/ If an element of a TYPE is defined as a type, that last TYPE statement must precede the one in which it is mentioned. 

Type SERVICE_STATUS

        dwServiceType As Integer

        dwCurrentState As Integer

        dwControlsAccepted As Integer

        dwWin32ExitCode As Integer

        dwServiceSpecificExitCode As Integer

        dwCheckPoint As Integer

        dwWaitHint As Integer

End Type

 

Type ENUM_SERVICE_STATUS

        lpServiceName As String

        lpDisplayName As String

        ServiceStatus As SERVICE_STATUS

End Type

 

Declare Function EnumDependentServices Lib "advapi32.dll" Alias "EnumDependentServicesA"

(ByVal hService As Integer,

ByVal dwServiceState As Integer,

lpServices As ENUM_SERVICE_STATUS,

ByVal cbBufSize As Integer, pcbBytesNeeded As Integer,

lpServicesReturned As Integer) As Integer 

1c/ If CONSTANTS are used in a function/sub, they must be DEFINEd before the function/sub is called; these DEFINE statements can thus be placed after the DECLARE of a function/sub using them but before the lines of code calling that function/sub. 

1d/ If an element of a TYPE uses a CONSTANT in the definition of that element, the DEFINE for that constant must precede the TYPE in which it is used (I have not found to date such a situation with a DECLARE, but if it was possible, the same rule should apply). 

Define STYLE_DESCRIPTION_SIZE  32

 

Type STYLEBUF

        dwStyle As Integer

        szDescription As String * STYLE_DESCRIPTION_SIZE

End Type

 

2 – I have found several instances of “duplicate” DECLAREs. They fall in two broad categories: 

a-      the alias is present or not. That should have no consequence on the quality of the call.  

Question 8

Should the “full” DECLARE only be kept? 

b-      the same function seems to exist in two different DLLs. The functionalities appear to be the same in both instances is some cases, different in other. 

Question 9

In case of “identical” functionality, should both DECLAREs be kept or only the one from the most “used” DLL? 

 

Library support structure 

This topic deals with the best way to organize the information and to retrieve it. Questions 1 and 2 are about the overall contents and structure. More specific issues are raised here in the perspective of making the use of this resource as simple and performing as possible.

Finding the proper DECLARE to use is the first step. I guess that a simple alphabetic listing is basic. 

Question 10

Could there be another way than alphabetic listing to locate easily the desired declare?

 

Question 11

Should TYPEs and DEFINEs be also accessible via alpha listings? 

Constants be called directly (in a TYPE) or as definitions applicable to specific VARIABLEs. I think that they should be treated differently, the first ones as a list of independent elements, the other as blocks identified by the calling variable names. If the same name variable calls for different constants, the DECLARE name could be added to the variable name in order to distinguish between the blocks. 

Question 12

Is that organization of DEFINEs (direct call, variable-block definition) useful? 

Many DECLAREs call for a TYPE and use constants specified in DEFINEs. The programmer is often left to his own resources to identify and retrieve TYPE and DEFINE statements.  

-           (a) Nothing special as it is the case in most existing resources. Each DECLARE, TYPE and DEFINE must be identified one by one, can be retrieved as a block in some tools. 

-          (b) Visual identification of “links” in DECLARE and TYPE statements with no direct retrieval of named elements 

Ex.: Declare XXXX ... (lpvariable as string, bidon as TYPEABC)

lpvariable relies on DEFINE(s)

TYPEABC calls a TYPE

Ex.: Define      xxx TYPX                                TYPX is a TYPE

Aba &H100

Xdet 24 * cons123                  cons123 is DEFINEd 

-          (c) Inclusion of these links in the alphabetic listing with direct retrieval for each named element. 

-          (d) Automatic retrieval of all elements relative to a DECLARE. 

(b) requires essentially a display legend and its implementation in the text files of Declares, Types and Defines. The easiest to implement using separate alpha lists for each category. 

(c) requires a more complete alpha list for the DECLAREs (the “attached” elements) and the creation of many links. Separate alpha list could be maintained for each category. 

(d) is based on the creation of ”blocs” (declare + required (possibly cascading) types + defines) but limits the number of links to be created. Easiest to use for retrieval. Huge risk of duplication of TYPEs and DEFINEs when assembling several DECLAREs. Huge data file due to multiple repetitions of TYPEs and DEFINEs. 

Question 13

What is the best way to provide help in that area?

Library tools 

There are two kinds of help system possible: on line or stand alone. The HTML solution can be conceived for downloading to the user’s installation and become a standalone.  

In the area of stand alone, there are several tools conceived to help programmers retrieving definitions from DLLs. I have identified in particular two interesting tools.  

APILOAD.EXE coming with Microsoft Visual Studio version 6 is a viewer of Declares, Types and Constants (independent alpha listings) with the possibility to select and copy to the clipboard in a cumulative way the desired elements. It uses a text file (the WIN32API.txt that I am using) or its equivalent in a data base form (larger file but more efficient to use).  

It has none of the visual markings that could help programmers and none of the possible links. It would be useful only in part for the MB translations because it would not recognize the constants (named DEFINE and not CONST) except if the CONST was kept ahead of the DEFINE, giving the programmer the responsibility to eliminate them when copied in his code. It also systematically adds PUBLIC or PRIVATE to the copied elements. 

ApiViewer2001.exe is found of the ALLAPI network (www.allapi.net, hurry up, it is closing down). It uses a specific file format (WIN32API.apv, less complete than the MS txt file) and has essentially the same functionalities as the MS viewer. Its input file format precludes the possibility to use it with the MB definitions file but the author might make the required changes to fit MB specificities.  

Question 14

Is there a tool that could be used as standalone help? 

The various sites I have found are oriented more towards the documentation of functions and subs; if a programmer can copy and paste the definitions he needs, he is also responsible to go through the maze of explanations to find what is required.

I have devised a HTML format to house the information and retrieve it on line. A demo will be available shortly from here. Declare and Type are available via the main DECLARE list.

The extraction of each element is left to the user; a simple copy paste to the MB editor will work, even if all the formatting (tabs) is lost and if line spacing may be different (saving, closing and reopening the MB file will this extra spacing). I some cases, EOL must be eliminated to create one line stings. More on it after more experimenting. 

Question 15

Does the HTLM prototype fill the needs?