Is there a way in VFP to pass a DWORD to an API function from VFP?

A customer asked:


Is there a way in VFP to pass a DWORD to an API function from VFP?


The Beep API function used in Create your own typing tutor! uses DWORDs and is called via the DECLARE – DLL Command . A DWORD is just a 32 bit value. An integer in VFP is a 32 bit value (4 bytes).


DECLARE integer Beep IN WIN32API integer Freq, integer DurationMs



Other examples of 32 bit values in the Win API abound. A LPDWORD is a Long Pointer to a DWORD, which is a 32 bit value as well (on a 32 bit machine).


See the Windows Data Types MSDN topic for more details.


The Data Type Ranges topic shows the sizes of the various types.  For example, an HWND is a HANDLE which is a PVOID which is a void * which means a pointer to anything. A pointer is 32 bits (on a 32 bit machine).


The SetWindowText Function is declared:


BOOL SetWindowText(      

    HWND hWnd,
    LPCTSTR lpString

and thus is called:


DECLARE integer SetWindowText IN WIN32API integer,string




A VFP string is just a sequence of bytes. If a Windows API requires a structure to be passed, just pass a string of the right size. For example, see Inspect your memory image and see fragmentation for a call to VirtualQueryEx  which returns a MEMORY_BASIC_INFORMATION structure. That structure is simply a sequence of bytes, so the DECLARE command looks like:


DECLARE integer VirtualQueryEx IN WIN32API integer hProcess, integer lpAddress,string @, integer dwLength


To decode/encode the string the CTOBIN( ) Function and the BINTOC( ) Function are very useful.

Comments (10)

  1. Steve Stamm says:

    How about passing a DWORD to an OCX control? Can this be done?


  2. Calvin_Hsia says:

    A DWORD is just a 32 bit value, so you can just use INTEGER for an ActiveX control

  3. Doug Kimzey says:

    Would the steps below be correct?

    1. Convert the numeric FoxPro variable to be passed to a 4-byte string.


    * +—————————————————————————-+


    * DESCRIPTION: Converts a VFP numeric value to a string that can be passed

    * to Windows API functions as a DWORD (adapted from


    * REVISION: 1.0 January 23, 2006

    * DEVELOPER: Anatoliy Mogylevets borrowed by Doug Kimzey


    * +—————————————————————————-+

    #DEFINE m0 256

    #DEFINE m1 65536

    #DEFINE m2 16777216

    LOCAL b0, b1, b2, b3

    b3 = Int(nVal/m2)

    b2 = Int((nVal – b3 * m2)/m1)

    b1 = Int((nVal – b3*m2 – b2*m1)/m0)

    b0 = Mod(nVal, m0)

    RETURN Chr(b0)+Chr(b1)+Chr(b2)+Chr(b3)

    * +—————————————————————————-+


    * +—————————————————————————-+

    2. Call the OCX method with CTOBIN( FOXNUMTODWORD(nValue))

  4. Calvin_Hsia says:

    Doug: I don’t see why you’re converting a number from a VFP integer to a string and then using CTOBIN to convert back to an integer. Why not just pass the integer?

  5. Doug Kimzey says:


    The problem seems to occur when a numeric value is passed from a cursor. If I called OCX method:

    void CeNetOCXCtrl::DisconnectPeer(DWORD Address, LONG Port)

    from VFP using values from a cursor:

    THISFORM.eNet.DisconnectPeer( eNetCursor->nAddress, eNetCursor->nHost )

    ;where nAddress(N,12,0) = 2147942666 and nHost(I) = 48620; produces an error: Incorrect number of parameters.

    A call like this:

    THISFORM.eNet.DisconnectPeer( 2147942666, eNetCursor->nHost )

    works without a problem.

    I am not sure why this is occurring but, to be honest, I am suspicious of the OCX. I will dig in further and keep you in the loop as what the cause is.


  6. Calvin_Hsia says:

    Doug: it looks like nAddress is a real number N(12,0) and not an integer. The OCX expects an integer. Try something like INT(eNetCursor->nAddress)

  7. Doug Kimzey says:


    I’m sure your right. Thank you most kindly. I’ll give that a shot.


  8. Franta says:

    Functions CTOBIN( ) and BINTOC( ) is useful to convert INT (32-bit signed integer, range -2147483648..+2147483647 ) or SHORT (16-bit signed, range -32768..+32767).

    But there is NO way how convert by these functions DWORD (32-bit unsigned integer, range 0..4294967295) or WORD (16-bit unsigned integer, range 0..65535).

    I need it very much, why isn’t any more parameter for these functions to make it possible?

    Sorry for my English


  9. I was writing a sample about DECLARE DLL to show some of its features which I implemented about 12 years…

  10. John L Veazey says:

    I know this is an old blog, but I thought this might be useful to people like Franta.  I ran into the same problem that he did.  I needed unsigned int/short because I was converting an MD5 hash (ADVAPI32 functions) into hex and BINTOC() threw me off.

    To deal with this, I added an additional line of code to create an adjustment value based on the length of the binary value.

    FUNCTION BinToUInt (cBinary as String) as String

    nAdjustment = 2 ^ ((LEN(cBinary) * 8) – 1)

    RETURN CTOBIN(cBinary) + nAdjustment