Example 6: The Final Cut at the Menu Non-modal Application

Here's yet another iteration on the menu non-modal application that cleans up its remaining problems.

#include <vv_mouse.h>

#include <vv_menu.h>

#include <vv_memo.h>

#include <vv_des.h>

#include <vv_main.h>



int stub(MFORMPTR);

int view(MFORMPTR);

int quit(MFORMPTR);



#include "app6.h"



GLOBAL WINDOWPTR _wnp;

int main()

{

    DLIBPTR libp;

    MFORMPTR main_menu;



    vv_init();



    if (libp = dl_open("app6.vvd"))

    {

        main_menu = dl_mnget("M_Main", SUBMENUS, app6, NULLP, libp);

        dl_close(libp);



        mn_proc(0, main_menu);

    }



    vv_exit();

    return(0);

}





int stub(mfmp)

MFORMPTR mfmp;

{

    beep_vv(BPMEDIUM, BPLOW);

    return(SAMELEVEL);

}



int quit(mfmp)

MFORMPTR mfmp;

{

    if (_wnp && wn_isup(_wnp))

        wn_dn(_wnp);

    return(EXITMENU);

}



int view(mfmp)

MFORMPTR mfmp;

{

    UCHAR name[256];

    int qrows, qcols;

    DFORMPTR fmp;

    static MFILEPTR mfp;

    MFILEPTR tmfp;

    DLIBPTR libp;



    if (libp = dl_open("app6.vvd"))

    {

        fmp = dl_fmget("F_FileName", &name, NULLP, NULLP, libp);



        name[0] = '\0';

        if (fm_proc(0, fmp) == AC_EXIT)

        {

            if (mf_size(name, &qrows, &qcols))

            {

                if (!_wnp)

                    _wnp = dl_wnget("W_View", libp);

                                                

                if (_wnp && (tmfp = mf_def(qrows, qcols)))

                {

                    if (mfp)

                        mf_free(mfp);

                    mfp = tmfp;

        

                    sw_mf(mfp, _wnp);

                    mf_rd(name, mfp);

                    wn_proc(_wnp);

                }

            }

            else

            {

                v_stpl(24, 0, "File not found.", FULL_WNP);

                bell_vv();

            }

        }

        fm_free(fmp);

        dl_close(libp);

    }

    return(TOPLEVEL);

}

We solved the problem with Quit by adding logic to the quit() function to remove the W_View window from the screen if necessary. In general, you would have to remove all other windows from the screen in the quit() function. Alternatively, we could have used the following logic:

int quit(mfmp)

    MFORMPTR mfmp;

    {

        vs_clr();

        do_application_cleanup();

        vv_exit();

        exit();

    }

This alternative would exit the application without the original mn_proc() call returning in main(). Therefore, no statements after the mn_proc() call would ever be executed.

We solved the problem with the sub-menu remaining on the screen by specifying TOPLEVEL as the return code in the menu action function. In general, you would always use TOPLEVEL as the return code from a menu action function that processed a non-modal object.

We changed the logic in view() so that only one W_View structure and one MFILE structure would be in memory at any time. The drawback to this approach is that these two structures would be in memory even if the W_View window was removed from the screen when the user pressed Esc.

You can use the same techniques to call a non-modal form from a menu action function. For data and menu forms, use the Vermont Views function, fm_namptr(), to determine if the specified form is already in memory. You can't use fm_namptr() with windows or choice lists serving as stand-alone menus because these objects do not have names.

When using non-modal objects from menu action functions, there are three points to remember:

int wrong_way(mfmp)

MFORMPTR mfp;

{

    FORM1 data;

    DLIBPTR libp;

    DFORMPTR fmp;



    fmp = fm_namptr("form1);

    if (!fmp)

    {

        libp = dl_open("app.vvd");

        fmp = dl_fmget("form1", &data, NULLP, NULLP, libp);

        dl_close(libp);

    }

    if (fmp)

        fm_proc(fmp);



    return(TOPLEVEL);

}


Home Contents Previous