ctl32_formstate bug

Topics: Bug Information
Mar 6, 2013 at 10:59 PM
I've identified a bug in the above mentioned class which is part of the CTL32 class library. In the _restoreStateAfterFormShow method is the following code:
If This._FormType = CON_FORMTYPE_DEFAULT Then
    *!* we have a standard form, get coordinates of parent.
    *!* Parent can be a Top Level Form or the VFP _Screen
    m.loParentForm = ctlGetParentForm(Thisform)

    *!* Save parent position/size:
    With m.loRect
        .Left = 0
        .Top = 0
        .Right = m.loParentForm.Width
        .Bottom = m.loParentForm.Height
    Endwith
    m.loParentForm = .Null.
Else
If for some reason ctlGetParentForm does not return an object, the assignment of .Right and .Bottom will fail. I have updated my local version as follows:
If This._FormType = CON_FORMTYPE_DEFAULT Then
    *!* we have a standard form, get coordinates of parent.
    *!* Parent can be a Top Level Form or the VFP _Screen
    m.loParentForm = ctlGetParentForm(Thisform)

    *!* Save parent position/size:
    With m.loRect
        .Left = 0
        .Top = 0
*!* - rk - 2013-3-6 - make sure that loParentForm is an object, else fall back to display
        IF VARTYPE(m.loParentForm)=[O]
            .Right = m.loParentForm.Width
            .Bottom = m.loParentForm.Height
        ELSE 
            .Right = Sysmetric(SYSMETRIC_CLIENTWIDTH)
            ** BUG! VFP reports this as too small, add one title bar height to value:
            .Bottom = Sysmetric(SYSMETRIC_CLIENTHEIGHT) + Sysmetric(SYSMETRIC_WINDOWTITLEHEIGHT)
        ENDIF 
    Endwith
    m.loParentForm = .Null.
Else
Mar 6, 2013 at 11:07 PM
Actually a better solution may be to update the ctlGetParentForm function contained in ctl32_functions.prg by doing a type check on the return value like this:
Function ctlGetParentForm(m.poForm As Form)
    Local ;
        m.lnHwnd As Integer, ;
        m.loForm As Form, ;
        m.lnX As Integer

    m.lnHwnd = apiGetParent(m.poForm.HWnd)

    If _Screen.HWnd = m.lnHwnd Then
        m.loForm = _Screen
    Else
        *!* Parent is a Top Level Form, get HWnd of form, what we have
        *!* now is HWnd of inner window of Top Level Form:
        m.lnHwnd = apiGetParent(m.lnHwnd)

        *!* Find the Top Level Form that has this HWnd:
        For m.lnX = 1 To _Screen.FormCount
            If _Screen.Forms(m.lnX).HWnd = m.lnHwnd Then
                m.loForm = _Screen.Forms(m.lnX)
                Exit
            Endif
        Endfor
    Endif
_*!* - rk - 2013-3-6 - another solution to insuring that the return value is an object
    IF VARTYPE(m.loForm)<>[O]
        m.loForm = _Screen
    ENDIF 
_   Return m.loForm