List of known bugs as of January, 2009

Thanks to Andrew's Bug List
and to David Burkley's comments


  1. ARRAYS There is no checking for limits on data arrays. You can "read" an array value outside that used in DIM, giving unpredictable results.

  2. UBOUND/LBOUND do not work properly with arrays passed to a FUNCTION as parameter (returns the UBOUND/LBOUND of first DIMensioned  array, may work ok in a SUB. Also UBOUND/LBOUND does not work properly with array's names ended by 
    %, ! etc.  Just keep track of your array bounds in separate variables.
    DIM A%(-50 TO 100) AS INTEGER 
    L% = UBOUND(A%)    '-- Returns 0

  3. BYTE, SHORT, WORD, SINGLE, and DOUBLE must be stored in a 32-bit long if passing ByVal to a DLL. 
    When passing ByVal, put BYTE, SHORT, and WORD variables a 32-bit variable such as INTEGER, DWORD, or LONG. If your DLL needs less than 2 SINGLE or more than 2 DOUBLE variables, these will not be passed correctly! The safest way to pass these variables ByRef if possible. If you must pass them ByVal then you should just state them as INTEGERS or LONG, in the DECLARE statement.

    'here is the actual API call
    SUB gluPerspective(fovy as Double, aspect as Double, zNear as Double, zFar as Double)
    'here is how to implement it
    DECLARE SUB gluPerspective_API LIB "glu32.dll" ALIAS "gluPerspective" _
       (f1 as long, f2as long, a1 as long, a2 as long, z1 as long, z2 as long, z3 as long, z4 as long)
       DEFDBL d: DEFINT i(7)
       d = fovy:   MemCpy (VarPtr(i(0)), VarPtr(d), 8)
       d = aspect: MemCpy (VarPtr(i(2)), VarPtr(d), 8)
       d = zNear:  MemCpy (VarPtr(i(4)), VarPtr(d), 8)
       d = zFar:   MemCpy (VarPtr(i(6)), VarPtr(d), 8)
       gluPerspective_API(i(0), i(1), i(2), i(3), i(4), i(5), i(6), i(7))
    END SUB

    'here is another example of BYTE
    Declare Sub keybd_event Lib "user32" Alias "keybd_event" _
    (bVk As BYTE, bScan As Long, dwFlags As Long, dwExtraInfo As Long)

    'all you have to do is change BYTE to LONG, and it will work fine
    Declare Sub keybd_event Lib "user32" Alias "keybd_event" _
    (bVk As Long, bScan As Long, dwFlags As Long, dwExtraInfo As Long)


  4. If you make a RapidQ component array, one more instance is created.
        dim form as qform 
        dim edit(1) as qedit 
        for i = 0 to 2 
            edit(i).parent = form 
            edit(i).top = (40 * i) 
            edit(i).text = "Edit_" + str$(i) 
        next i
        form.showmodal


  5. VARPTR and QUICKSORT do not work for arrays passed to a SUB/FUNCTION :
        SUB MySub (MyArray () AS INTEGER) 
            addr = VARPTR(MyArray(0)) ' doesn't recognize MyArray ! 
       END SUB 

    -- Be sure to pass the address of the array if you want to use MEMCPY or  QUICKSORT, etc.

  6. Local variables in SUB/FUNCTION use shared memory. Always initalize or set local variables in a SUB/FUNCTION, never assume a variable is initialized to zero. If you use STATIC this will not happen.
    Sub TestSub1
       Dim I As Long
       ShowMessage("I = " + Str$(I))
       I++
    End Sub

    Sub TestSub2
       Dim NotI As Long
       Dim J As Long   'not shared because it is 2nd
       ShowMessage("NotI = " + Str$(NotI))
       ShowMessage("J = " + Str$(J))
       NotI++
    End Sub

    For x = 1 to 3
      TestSub1
      TestSub2
    Next x


  7. Use the Fixed Libraries if you use EXIT SUB and EXIT FUNCTION, otherwise it will cause a memory leak.
    This is caused by a minor problem in the rapidQ.LIB files. Replace the .LIB files with the "Snakedile Fixed libraries version 1.02  ( dated October, 2005 or later) If you cannot use the new libraries, use GOTO to exit the SUB/FUNCTION like this:
    FUNCTION  Foo() AS INTEGER
      IF i > Max THEN GOTO ExitFunction
         ' do calculations here
    ExitFunction:
    END FUNCTION

  8. If you have an array of QIMAGE then the OnMouseMove and OnMouseDown events don't work.

  9. The $MACRO command is unstable and should be avoided completely unless the argument is very simple.. $DEFINE should be used for simple positive number replacement only. For instance,  negative numbers in a $DEFINE statement will not compile correctly.
    $DEFINE  MyConst -1
    in this case MyConst will be equal to 0. This is a bug in the RapidQ compiler. Use CONST instead

  10. Only one CODEPTR for each function with the same  number of arguments. RapidQ2.inc demonstrates how to fix this problem.
    i.e., you can use CODEPTR( FuncA) and CODEPTR(FuncB) only if FuncA and FuncB have different number of parameters,  and so on. If both functions have the same number of parameters the address from first CODEPTR is always used.
     
  11. The RIGHT$ function doesn't work properly with >32k strings.  Replace the .LIB files with the "Snakedile Fixed libraries version 1.06  (dated November, 2006 or later)

  12. QLISTVIEW - ColumnsCount returns the wrong number on Read
    QLISTVIEW -
    OnColumnClick (SUB (Column%)) - Always returns 0 in Column%
    Replace the .LIB files with the "Snakedile Fixed libraries version 1.07 (dated December, 2006) or later. If you cannot get the new libs try QListViewEx instead (in the RapidQ2.INC).


  13. QFILESTREAM.ReadStr(n) adds a space character to the end of the string read, which can make string comparisons to fail. Also QFILESTREAM.LineCount counts LineFeeds. It  loads file in 30 KB at a time but does not to check the first byte of each block. This means it can miss some lines.

  14. Many RapidQ Objects are FUNCTIONS rather than SUBs. For example, QFileStream.Open is not a SUB as stated in the RQ HTML Documentation, but a FUNCTION that returns ZERO when the file has an Open Failure.

  15. The original QCOMPORT was too buggy and removed from rapidq5.lib by the author. Use the QCOMPORT component in RAPIDQ2.INC. It uses Win32API calls so Windows only.  If you use the new QCOMPORT the name of the object cannot have the word "Comport" in it:
    DIM myComport AS QCOMPORT  'compiler gives an error
    DIM myCmprt AS QCOMPORT     ' should work

  16. Logical NOT operation is same as bitwise NOT. For RapidQ you should compare a boolean expression for (IF xx = False OR yy = True) etc.

  17. Many QObjects also have a SENDER parameter that is not documented.

  18. QLISTBOX.OnEnter doesn't work, use the Form's OnKeyUp event to call a routine that traps the Enter key with the Form's KeyPreview property set to 1 or True.
     
  19. QTABCONTROL.DelTabs requires the Fixed version 1.06 RC.EXE  ( dated November, 2006 or later).

  20. Custom components created using CreateWindows API function can generate runtime error 216 when form closing.
    To prevent this, use Application.Terminate in the Form.OnClose event handler.

  21. Use QRichEdit to get around the 64k limit in QEDIT (this problem exists in earlier versions of Windows only): 
    'Place SendMessage after you create the richedit
    'and before your show your main form.
    CREATE form AS QFORM
    CREATE richedit AS QRICHEDIT
    END CREATE
    END CREATE
    SendMessage RichEdit.Handle, &HC5, 0, 1048576
    form.ShowModal

  22. In "For i=n0 To n1...Next" statement, sometimes the variable i will always equal to n0 throughout the whole loop though the cycle number is right.

  23. CONVBASE$() only accepts upper-case hex string and takes an argument less than  "FFFFFFFF" Replace the .LIB files with the "Snakedile Fixed libraries version 1.06  ( dated November, 2006 or later).

  24. QCheckBox cannot be passed as an argument even declared "ByRef".

  25. BYTE cannot be returned correctly from a FUNCTION. An INTEGER should be used instead.

  26. Direct3D: requires the D3DRM.DLL from the Windows XP distribution to work under Windows VISTA and later.

  27. The "Cannot focus a disabled or invisible window" problem. See Chapter 1.  Simply put the older  richedit dll (dated 3/2003) into the rapidQ directory.

  28. There is poor error checking with EXIT statements. Be sure to use the correct EXIT statement:
    Sub test()
    Dim j As Integer
        For j=1 To 2
         ' test=1 ' When 2 or more, only one loop i.
          Exit Sub
        Next j
    End Sub

    And in both cases, when Exit Function/Sub is replaced by Exit For everything is OK ! Always use EXIT FOR inside a For-next loop.

  29. If you use QListview.Clear, QListBox.Clear, QComboBox.Clear, QStringGrid.Clear, 
    and find that it's really very Slow, do this :
    Object.Visible = False
    Object.Clear
    Object.Visible = True


  30. If you don't  have a sub for your  onClose event (but declare it) then there is no way to close the form.
    $TYPECHECK ON
    DECLARE SUB Strange
    CREATE Form AS QFORM
      Caption = "12345"
      OnClose = Strange
      ShowModal
    END CREATE


  31. Avoid REM for comments, especially with comments containing "\\" or "\"
    rem c:\werwer\\      'causes error
    a=5    rem fkfkl     :not working.

  32. QPOPUPMENU does not close when it loses focus. Your program will have to close it by deleting all QMenuItems with QPOPUPMENU.DelItems.

  33. REDIM has a memory leak and does not clean up after each time it is called. Be carefully with REDIM, strange bugs can occur if you Redim Array without REDIM AS. RapidQ will let you REDIM arrays of Qobjects/QForms, etc. but it actually does not work -- memory is not deallocated or added components are not really added.

  34. The FORMAT$ statement has a large memory leak and may crash your program if called many times. Use the STRF$ function instead if needed.

  35. Nested UDTs are not supported. You must recode them manually. 
    This will not work:
    TYPE QField
         fName as String*30
         fType as String*30
         fData as String*30
    END TYPE

    TYPE QTable
         tName as String*30
         Field(20) as QField  'error here
    END TYPE

    This will work instead:
    TYPE QTable
         tName as String*30
         'Field(20) as QField
         fName as String*30
         fType as String*30
         fData as String*30
    END TYPE

  36. TYPE ... END TYPE, appears to allocate at least 32k memory for each DIM xx AS TYPE:

create form as qform
caption = "Memory test"
end create

TYPE SecInfoWarp
warps AS BYTE      'Number of warps \/\/\/
warp1 AS WORD
warp2 AS WORD
warp3 AS WORD
warp4 AS WORD
warp5 AS WORD
warp6 AS WORD
END TYPE

DIM SecInfo(1000) AS SecInfoWarp
form.showmodal
'end here

In two trials i got 32Mb, and 36Mb for the second... Now i know that includes what ever DLL's the rapidq uses, which is approx 9Mb (or maybe4.??Mb???) of those values... But that still means that for an array of 1000 of my UDT equals approx. 23 - 27 Mb's... The UDT should be like about 13 bytes, so 

1000 times that should only equal 13,000 bytes!!! Im running Win98SE with 96Mb RAM, and a 330Mb swap file, and while i could compile that routine at10,000, it caused such a drag on my system that Norton System Info wouldn't run! Means that pretty much all availible memory PLUS swap file was used!!! That means that on my system it must have used somewhere between 350Mb and 400Mb for my UDT array of only 10,000!!! So what is going on here?!?!?!?

I even removed the warp AS BYTE/WORD and replaced them with a single "warps AS STRING*13", and it still tells me that it is useing 36Mb!!!
If i removed the UDT, and dimension the array like so...

DIM SecInfo(1000) AS WORD
... then the program only use 4.7Mb(total including DLL's)!!! So it must be a bug with UDT's!

Be carefully with Arrays of UDT.

TYPE TTest
S AS STRING*8
N AS INTEGER na(5) as integer END TYPE DIM Test AS TTest
Dim Testa (10) as TTest

CREATE Form AS QFORM Caption = "Test UDT": Center
CREATE RichEdit1 AS QRICHEDIT BorderStyle = 0: END CREATE END CREATE Test.s="qwerty"
Test.n=12345
for j%=1 to 5 : Test.na(j%)=j%: next RichEdit1.AddStrings "Test.na(1)="+ str$(Test.na(1)) Testa(2)=Test ' RichEdit1.AddStrings Testa(2).s+" "+str$(Testa(2).n)+" "+str$(Testa(2).na(1)) '------- 1'

Testa(2).na(1)=Test.na(1) ' ----- It doesn't work ! Why??
RichEdit1.AddStrings Testa(2).s+" "+str$(Testa(2).n)+" "+str$(Testa(2).na(1)) '---------2'

d=Test.na(1):Testa(2).na(1)=d '----- Wow! It works
RichEdit1.AddStrings Testa(2).s+" "+str$(Testa(2).n)+" "+str$(Testa(2).na(1)) '----------3'

Testa(2).na(1)=1'Test.na(1) '-------- It's simply ;-)
RichEdit1.AddStrings Testa(2).s+" "+str$(Testa(2).n)+" "+str$(Testa(2).na(1)) '----------4'

Form.ShowModal

Testa(2)=Test ' be careful setting equal to one UDT to another may not work!!