At one point it was thought that DirectX under RapidQ might be improved by custom programming. However, because of the inability to RapidQ to properly handle function pointers, this is not recommended. The easier way to do write DirectX code in FreeBasic and make it into a DLL. With that said, here is the Quick but Lame Tutorial on COM interface and RapidQ
First make sure you know the abbreviations:
API – application programming interface. How you talk with the operating system to get it to do what you program asks.
DLL - Dynamic Link Library an EXTERNAL file that contains machine code. Your program can use DLL to run Windows API. DLLs load in the same process space (memory area) as your program. You cannot compile a DLL into your program.
GUID - Globally Unique identifier. A 16-bye code that identifies a specific COM object. That is DirectDraw (one little piece of DirectX) has a GUID that is for a DirectDraw version. That way all new versions are known from old ones and other pieces of DirectX. You might remember the QOLEOBJECT example in which
Microsoft Word has a GUID "{000209FE-0000-0000-C000-000000000046}" that thing has 16 bytes of hexadecimal codes.
POINTER – a variable that holds the memory address (location in computer memory) of a variable, User defined TYPE, a SUB, Func, etc. etc. RapidQ does not give you all pointers (see below)
DIM a AS INTEGER
DIM lp AS LONG
A = 5
Lp = VARPTR(a) ‘lp is now the pointer, it does not = 5!!! But a memory address. lp =@a 'the @ symbol also says get the address of the variable
COM - Component
Object Model. You never get a straight answer from M$. Basically, this is an
advanced way to improve a DLL. Once a COM is made it is standard and new versions
will work with older programs. They are suited for C++ coding. It kind of turns
DLLs into object oriented programming.
Instead of using API
functions like this:
A = GetWidth (myObject)
B = GetHeight (myObject)
You would have a DLL with
an object oriented programming interface:
A = NewObject.Width (myObject)
A = NewObject.Height (myObject)
It’s just cleaner coding but it is a hassle to get it working in RapidQ.
The BASICs of DirectX
___________________
DirectX uses the COM interface. It is not the same as “OLE automation”, which also uses a COM interface but with a different format.
Instead of calling one or many individual SUB/Func like this:
Declare Function GetForegroundWindow Lib "user32" Alias "GetForegroundWindow" () As Long
Declare Function GetDC Lib "user32" Alias "GetDC" (hwnd As Long) As Long
….. on and on
Declare Function DirectDrawCreate Lib "ddraw.dll" ALIAS "DirectDrawCreate" (ByVal lpGUID As Long, ByVal lplpDD As Long, ByVal pUnkOuter As Long) As Long
Wow, that was easy! Wrong….
What happens is this Function returns a POINTER TO A STRUCTURE, that can be used to IMPLEMENT the INTERFACE. This is explained later. Here is how you run it:
$DEFINE LPDIRECTDRAW LONG ‘ variables of “LPxxxx” are pointers
$DEFINE LPDIRECTDRAWSURFACE LONG ‘use LONG for 32-bit windows
$DEFINE IDirectDraw LPDIRECTDRAW
$DEFINE HRESULT LONG ‘handle for a return value
$DEFINE DD_OK 0 ‘this checks if it ran OK
‘The API to create our DirectDraw “OBJECT”
Declare Function DirectDrawCreate Lib "ddraw.dll" ALIAS "DirectDrawCreate"_
(ByVal lpGUID As Long, ByVal lplpDD As Long, ByVal pUnkOuter As Long) As Long
DIM result AS HRESULT
DIM lpDD AS LPDIRECTDRAW ‘our pointer
lpDD = 0 ‘null it out
result = DirectDrawCreate(0, @lpDD,0) ‘get the pointer to the interface
‘first parameter is 0, which is the default active display, second parm passes the Pointer of lpDD using the ‘@’ symbol to the FUNCTION
‘last parameter must be 0 for ‘future expansion’ by windows
IF result <> DD_OK THEN
ShowMessage "Create direct draw Failed"
ELSE
ShowMessage STR$(lpDD)
END IF
‘end of program…………………………
This program actually runs and returns a large number in lpDD. This is the starting address of the INTERFACE. IF you run it, you cannot close down the directDraw interface because you are supposed to RELEASE it, so windows can use the memory
Here is the c code:
lpDD ->Release();
You can’t do it in RapidQ, yet. So if you run the program you just used up some memory…
With the line
result = DirectDrawCreate(0, @lpDD,0)
We now have a pointer to a pointer that points to a structure, the pointer is lpDD !! But how do we start calling the DirectDraw functions? You need to declare the structure and then use that pointer to the stucture. You know what a structure is (use TYPE or STRUCT)
TYPE MyType
A AS LONG
B AS INTEGER
END TYPE
Then what does the DirectDraw structure look like?
The code for a SUB or FUNCTION sits in some memory address space in the computer. The program knows where that code is by a pointer. Pointers are only numbers, and for Windows 32-bit, the pointer is of a LONG type. The pointer holds the memory address of the starting location of the code. So if you know the value of the pointer, you can "jump" that memory location and run the code in that "process space." Before you can run that code, the program must know how many, and what type of parameters there are to run the code
SUB Add(a as integer, b as integer)
CODEPTR(Add)-- will be the memory where start code of Add SUBroutine. Now you need to call the sub so the computer knows there are two parameters (a and b), which are both integers
In RapidQ, you must first BIND the SUB/Func to a LONG
DIM fptr AS LONG
BIND fptr TO Add
*** in C you don't do this
now you can run the code so the computer knows the right number and type of parameters
CALLFUNC(fptr(a,b))
NOW FOR DIRECTX, DIRECT3D, DIRECT Play, etc--
When you start DirectX, it GIVES YOU the memory address of its code in a pointer!! That is you have no idea where the CODEPTR is!! So if
CALLFUNC(CreateDirect3D, my3Ddisplay, etc., etc) you know that "CreateDirect3D" is the starting memory address and "my3Ddisplay, etc., etc..." are the parameters to pass to that SUB/FUNC. How does the program know the correct number and type of parameters for DirectX? From those HUGE, HUGE, C header files!
Since CALLFUNC uses some internal table for memory addresses
(in the sample program it returns "1", NOT a real memory address)
then I can't see how to develop DirectX, DirectPlay, DirectMusic in RapidQ .
The bottom line, you will need a C-like programming language such as BCX or
FreeBasic to program in DirectX