Example 4: A Non-modal Application that Uses a Menu Action Function

This section describes how to use a non-modal object from a menu action function. In the example application for this section, the main (top-level) menu is non-modal. There are two fields on this menu: File and Quit. File displays a sub-menu with three fields: Copy, Delete, and View. Quit exits the application.

Only View, on the File sub-menu is implemented in the example application. Copy and Delete are associated with stub functions that do nothing. View prompts the user for a file name using a modal form. Once the user has specified a file name, this file is read from disk and displayed in a non-modal window. The user can then scroll through this window and go back to the main menu to specify a different file to view.

Here is the first cut at this application:

#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 "app4.h"



int main()

{

    DLIBPTR libp;

    MFORMPTR main_menu;



    vv_init();



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

    {

        main_menu = dl_mnget("M_Main", SUBMENUS, app4, 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;

{

    return(EXITMENU);

}

int view(mfmp)

MFORMPTR mfmp;

{

    UCHAR name[256];

    int qrows, qcols;

    DFORMPTR fmp;

    WINDOWPTR wnp;

    MFILEPTR mfp;

    DLIBPTR libp;



    if (libp = dl_open("app4.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))

            {

                wnp = dl_wnget("W_View", libp);

                mfp = mf_def(qrows, qcols);

                if (wnp && mfp)

                {

                    sw_mf(mfp, wnp);

                    mf_rd(name, mfp);

                    wn_proc(wnp);

                    mf_free(mfp);

                    wn_free(wnp);

                }

            }

            else

            {

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

                bell_vv();

            }

        }

        fm_free(fmp);

        dl_close(libp);

    }

    return(SAMELEVEL);

}

The major problem with this implementation is when we compile and link with the Vermont Views development library and try to view any file, the Vermont Views error reporting system informs us that we're using a corrupted window structure. The problem is that we've freed the W_View window before we've had a chance to use it.

The call to wn_proc() does not immediately pass control to the user. It detects that an event processing loop is already in progress (i.e., the call to mn_proc()) and performs the following actions:

When the call to wn_proc() returns, the window is only placed on the screen. The user has not had a chance to scroll through it yet. The W_View window will not be made active until the posted AC_FMSUSPEND event is pulled from the event queue and acted upon. Therefore, the window can't be freed yet.

There are two lessons to be learned from this attempt:


Home Contents Previous Next