Subversion Repositories factorylink.pvb_util

Rev

Blame | Last modification | View Log | Download

/**************************************************************
 *
 * Object  : pvb_util.dll
 *
 * File    : menu.c
 *
 * Purpose : Menu handling for FactoyyLink, usage of functions
 *           with PVB.
 *
 **************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <windows.h>

/* 
 * Defines 
 */
#define        PVB_MAX_MENU            25

/* 
 * Global variables 
 */
int     menu_init = 0;
int     menu_busy = 0;

int  looping = 0;
extern short act_cur_type;

HMENU   menu_bar[ PVB_MAX_MENU];               /* supported menu bar items */
HMENU   menu_itm[ PVB_MAX_MENU];               /* supported sub menu's for menu bar */
HMENU   menu_sub[ PVB_MAX_MENU];               /* supported sub menu's for menu bar */

short   menu_bar_type[ PVB_MAX_MENU];          /* supported menu bar items */
short   menu_itm_type[ PVB_MAX_MENU];          /* supported sub menu's for menu bar */
short   menu_sub_type[ PVB_MAX_MENU];          /* supported sub menu's for menu bar */

HWND    menu_hwnd[ PVB_MAX_MENU];
HWND    capt_hwnd[ PVB_MAX_MENU];
WNDPROC lpPrevWndFunc[ PVB_MAX_MENU];
POINT   menu_point[ PVB_MAX_MENU];
POINT   dummy_point[ PVB_MAX_MENU];
UINT    last_event[ PVB_MAX_MENU];
UINT    last_type[ PVB_MAX_MENU];
short   mark[ PVB_MAX_MENU];
short   new_event[ PVB_MAX_MENU];

HWND xhwnd; 
UINT xuMsg;
WPARAM xwParam;
LPARAM xlParam;

extern HWND  status_hwnd;


/**************************************************************
 *
 * Function: short WINAPI pvb_menu_init( void)
 *
 * Purpose : Initialise handling of the menu's.
 *           Prepare all the DLL's global parameters.
 *
 * Return  : 0  - Success
 *           -1 - Failure
 **************************************************************/
short WINAPI pvb_menu_init( void)
{
  
  int    i;


  /* clear all menu items */
  memset( menu_bar, 0, PVB_MAX_MENU * sizeof( HMENU));
  memset( menu_itm, 0, PVB_MAX_MENU * sizeof( HMENU));
  memset( menu_sub, 0, PVB_MAX_MENU * sizeof( HMENU));

  memset( menu_bar_type, 0, PVB_MAX_MENU * sizeof( short));
  memset( menu_itm_type, 0, PVB_MAX_MENU * sizeof( short));
  memset( menu_sub_type, 0, PVB_MAX_MENU * sizeof( short));

  memset( menu_hwnd, 0, PVB_MAX_MENU * sizeof( HWND));
  memset( last_event, 0, PVB_MAX_MENU * sizeof( long));
  memset( mark, 0, PVB_MAX_MENU * sizeof( short));
  memset( new_event, 0, PVB_MAX_MENU * sizeof( short));
  memset( menu_point, 0, PVB_MAX_MENU * sizeof( POINT));
  memset( dummy_point, 0, PVB_MAX_MENU * sizeof( POINT));

  for (i = 0; i < PVB_MAX_MENU; i++)
  {

    menu_bar[ i] = CreateMenu();
    menu_itm[ i] = CreateMenu();
    menu_sub[ i] = CreateMenu();
  }

  menu_busy = 0;
  menu_init = 1;

  return 0;
} /* pvb_menu_init */


/**************************************************************
 *
 * Function : short WINAPI pvb_menubar_append( short index, 
 *                                             short item, 
 *                                             short type, 
 *                                             char *title, 
 *                                             short id)
 *
 * Purpose  : Append a menu itme to the mneu bar.
 *           
 * Parameter: index - Index (1 .. 100) for menu bar element.
 *            item  - Index of sub menu, zero for no sub menu.
 *            type  - Type of menu item:
 *                    bit 0: String, Separator.
 *                    bit 1: Not checked, Checked.
 *                    bit 2: Enabled, Disabled and grayed.
 *            title - Text for the item
 *            id    - User id, returned if item is selected.
 *
 * Return   : 0  - Success
 *            -1 - Failure
 **************************************************************/
short WINAPI pvb_menubar_append( short index, short item, 
                                 short type, char *title, short id)
{

  UINT    ident = id;
  UINT    flags = 0;
  short   ret = 0;


  /* check initialisation */
  if (!menu_init)
    return -1;

  /* check the index */
  if ((index < 1) || (index > PVB_MAX_MENU))
    return -1;

  if ((item < 0) || (item > PVB_MAX_MENU))
    return -1;

  if ((id < 0) || (id > 999999))
    return -1;

  ident += 97000000;

  /* build the type */
  if (type & 0x1)
    flags |= MF_SEPARATOR;
  else
    flags |= MF_STRING;

  if (type & 0x2)
    flags |= MF_CHECKED;

  if (type & 0x4)
    flags |= MF_GRAYED;

  /* save the menu item type */
  menu_bar_type[ index - 1] = type;

  if (!item)
  {
  
    /* no sub menu for menu bar element */  
    if (AppendMenu( menu_bar[ index - 1], flags, ident, title) != TRUE)
      ret = -1;
  }
  else
  {

    /* connect a sub menu */
    if (AppendMenu( menu_bar[ index - 1], MF_POPUP, (unsigned int)menu_itm[ item - 1], title) != TRUE)

      ret = -1;
  }

  return ret;
} /* pvb_menu_bar_append */


/**************************************************************
 *
 * Function : short WINAPI pvb_menuitm_append( short index, 
 *                                             short sub, 
 *                                             short type, 
 *                                             char *title, 
 *                                             short id)
 *
 * Purpose  : Append a menu item to a menu item from the menubar.
 *           
 * Parameter: index - Index (1 .. 100) for menu item element.
 *            sub   - Index of sub menu, zero for no sub menu.
 *            type  - Type of menu item:
 *                    bit 0: String, Separator.
 *                    bit 1: Not checked, Checked.
 *                    bit 2: Enabled, Disabled and grayed.
 *            title - Text for the item
 *            id    - User id, returned if item is selected.
 *
 * Return   : 0  - Success
 *            -1 - Failure
 **************************************************************/
short WINAPI pvb_menuitm_append( short index, short sub, 
                                 short type, char *title, short id)
{

  UINT    ident = id;
  UINT    flags = 0;
  short   ret = 0;


  /* check initialisation */
  if (!menu_init)
    return -1;

  /* check the index */
  if ((index < 1) || (index > PVB_MAX_MENU))
    return -1;

  if ((sub < 0) || (sub > PVB_MAX_MENU))
    return -1;

  if ((id < 0) || (id > 999999))
    return -1;

  ident += 97000000;

  /* build the type */
  if (type & 0x1)
    flags |= MF_SEPARATOR;
  else
    flags |= MF_STRING;

  if (type & 0x2)
    flags |= MF_CHECKED;

  if (type & 0x4)
    flags |= MF_GRAYED;

  /* save the menu item type */
  menu_itm_type[ index - 1] = type;

  if (!sub)
  {
  
    /* no sub menu for menu bar element */  
    if (AppendMenu( menu_itm[ index - 1], flags, ident, title) != TRUE)
      ret = -1;
  }
  else
  {

    /* connect a sub menu */
    if (AppendMenu( menu_itm[ index - 1], MF_POPUP, (unsigned int)menu_sub[ sub - 1], title) != TRUE)
      ret = -1;
  }

  return ret;
} /* pvb_menuitm_append */


/**************************************************************
 *
 * Function : short WINAPI pvb_menusub_append( short index, 
 *                                             short type, 
 *                                             char *title, 
 *                                             short id)
 *
 * Purpose  : Append a menu sub item to a menu item.
 *           
 * Parameter: index - Index (1 .. 100) for menu sub element.
 *            type  - Type of menu item:
 *                    bit 0: String, Separator.
 *                    bit 1: Not checked, Checked.
 *                    bit 2: Enabled, Disabled and grayed.
 *            title - Text for the item
 *            id    - User id, returned if item is selected.
 *
 * Return   : 0  - Success
 *            -1 - Failure
 **************************************************************/
short WINAPI pvb_menusub_append( short index, short type, 
                                 char *title, short id)
{

  UINT    ident = id;
  UINT    flags = 0;
  short   ret = 0;


  /* check initialisation */
  if (!menu_init)
    return -1;

  /* check the index */
  if ((index < 1) || (index > PVB_MAX_MENU))
    return -1;

  if ((id < 0) || (id > 999999))
    return -1;

  ident += 97000000;

  /* build the type */
  if (type & 0x1)
    flags |= MF_SEPARATOR;
  else
    flags |= MF_STRING;

  if (type & 0x2)
    flags |= MF_CHECKED;

  if (type & 0x4)
    flags |= MF_GRAYED;

  /* save the menu item type */
  menu_sub_type[ index - 1] = type;

  /* no sub menu for menu bar element */  
  if (AppendMenu( menu_sub[ index - 1], flags, ident, title) != TRUE)
    ret = -1;

  return ret;
} /* pvb_menusub_append */


#ifdef kldjfdkljdkdlfj
BOOL CALLBACK EnumChildProc(hwndChild, lParam) 
HWND hwndChild; 
LPARAM lParam; 
{ 
    LPRECT rcParent; 
    int i, idChild; 
 
    // Retrieve the child-window identifier. Use it to set the 
    // position of the child window. 
 
    idChild = GetWindowLong(hwndChild, GWL_ID); 
 
    if (idChild == ID_FIRSTCHILD) 
        i = 0; 
    else if (idChild == ID_SECONDCHILD) 
        i = 1; 
    else 
        i = 2; 
 
    // Size and position the child window.  
 
    rcParent = (LPRECT) lParam; 
    MoveWindow(hwndChild, 
        (rcParent->right / 3) * i, 
        0, 
        rcParent->right / 3, 
        rcParent->bottom, 
        TRUE); 
 
    // Make sure the child window is visible. 
 
    ShowWindow(hwndChild, SW_SHOW); 
 
    return TRUE; 
}
#endif
/**************************************************************
 *
 * Function: LRESULT WINAPI PVB_MenuWndProc(HWND hwnd, 
 *                                          UINT uMsg,
 *                                          WPARAM wParam,
 *                                          LPARAM lParam)
 *
 *
 * Purpose : Callback function for window message handling.
 *
 * Return  : Handling result of original call back function.
 **************************************************************/
LRESULT WINAPI PVB_MenuWndProc(HWND hwnd, 
                               UINT uMsg,
                               WPARAM wParam,
                               LPARAM lParam)
{

  RECT            rect;
  RECT            rcClient;
  RECT            rcParent;
  short           index;
  long            x, y;
  float           screen_x,
                  screen_y,
                  width,
                  height,
                  border_x,
                  border_y,
                  menu,
                  caption,
                  pvb_x,
                  pvb_y;
  LONG            style;


  /* now we need to find the index */
  for (index = 0; index < PVB_MAX_MENU; index++)
  {

    if (hwnd == menu_hwnd[ index])
      break;
  }

  if (index < PVB_MAX_MENU)
  {

    /* Filter for the needed messages */
    if (mark[ index])
    {
    
      SetCursorPos( menu_point[ index].x, menu_point[ index].y);

      SetCapture( capt_hwnd[ index]);
      mark[ index] = 0;
    }

    switch (uMsg)
    {

      case WM_ENTERMENULOOP:
      case WM_EXITMENULOOP:
      case WM_ENTERIDLE:
      case WM_INITMENU:
      case WM_INITMENUPOPUP:
      case WM_MENUSELECT:
      case WM_SYSCHAR:
      case WM_MENUCHAR:
      case WM_SYSCOMMAND:
          break;

      case WM_SIZE:   // main window changed size 

        // Get the dimensions of the main window's client 
        // area, and enumerate the child windows. Pass the 
        // dimensions to the child windows during enumeration. 
        // WM_SIZE  
        // fwSizeType = wParam;      // resizing flag 
        // nWidth = LOWORD(lParam);  // width of client area 
        // nHeight = HIWORD(lParam); // height of client area 
        if (status_hwnd != NULL)
        {

//          if (!looping)
//          {
          GetClientRect(status_hwnd, &rcClient); 
          GetClientRect(hwnd, &rcParent); 

          MoveWindow( status_hwnd, 0, rcParent.bottom - rcClient.bottom,
                      rcParent.right, rcClient.bottom, TRUE);

//          MoveWindow( hwnd, 0, 0,
//                      rcParent.right, rcParent.bottom - rcClient.bottom, TRUE);
          // Make sure the child window is visible. 

          //ShowWindow(hwndChild, SW_SHOW); 

//          lParam -= rcClient.bottom;
//          lParam /=2;
//          return DefWindowProc( hwnd, uMsg, wParam, lParam);
//          SetWindowPos( hwnd, HWND_TOP, 0, 0, rcParent.right, rcParent.bottom - rcClient.bottom, SWP_NOMOVE);
//            looping++;
//          }
//          else
//            looping = 0;
        }
        break;
        //return 0; 

      default:
        break;
    }

    if (uMsg == WM_COMMAND)
    {

      if ((wParam >= 97000000) && (wParam <= 98000000))
      {

        /* set the event code */
        mark[ index] = 1;
        last_event[ index] = wParam;

        last_type[ index] = GetMenuState( GetMenu(hwnd),      /* handle of menu */
                                          last_event[ index], /* menu item to query */
                                          MF_BYCOMMAND);      /* menu flags */

        new_event[ index] = 1;

        /* set the coordinates */
        GetCursorPos( &menu_point[ index]);
      
        /* retrieve the window styles */
        style = GetWindowLong( hwnd, GWL_STYLE);

        screen_x = (float)GetSystemMetrics( SM_CXSCREEN);
        screen_y = (float)GetSystemMetrics( SM_CYSCREEN);

        if ((style & WS_THICKFRAME) == WS_THICKFRAME)
        {
          border_x = (float)(1 * GetSystemMetrics( SM_CXFRAME));
          border_y = (float)(1 * GetSystemMetrics( SM_CYFRAME));
        }
        else
        {
          border_x = (float)(1 * GetSystemMetrics( SM_CXFIXEDFRAME));
          border_y = (float)(1 * GetSystemMetrics( SM_CYFIXEDFRAME));
        }

        if ((style & WS_DLGFRAME) == WS_DLGFRAME)
          caption  = (float)GetSystemMetrics( SM_CYCAPTION);

        menu     = (float)GetSystemMetrics( SM_CYMENU);
        
        /* get window placement on screen */
        GetWindowRect( menu_hwnd[ index], /* handle of window */
                       &rect);            /* address of structure for window coordinates */

        width = (float)(rect.right - rect.left) - border_x;
        height = (float)(rect.bottom - rect.top) - border_y - menu - caption;
 
        if (width < (float)0)
          width = (float)0;

        if (height < (float)0)
          height = (float)0;

        /* now we need to correct for screen size, cause FL does it!!!! */
        if ((width / height) < (screen_x /screen_y))
        {

          /* adjust the height of the graphics */
          height = (screen_y * width) / screen_x;

        }
        else
        {

          /* adjust the width of the graphics */
          width = (screen_x * height) / screen_y;
        }

        /* get PVB coordinates */
        pvb_x = (float)32767;
        pvb_y = (float)((32767 * screen_y) / screen_x);

        /* correct bottom or right */
        x = (long)((width * dummy_point[ index].x) / pvb_x);
        x += rect.left;
        x += (long)border_x;

        y = (long)(height * (pvb_y - dummy_point[ index].y) / pvb_y);
        y += rect.top;
        y += (long)(menu + caption + border_y);

        capt_hwnd[ index] = GetCapture();
        SetCapture( hwnd);

        SetCursorPos( x, y);

        return 0;
      }
    }
  }

  /* execute the original callback function for handling messages */
  return CallWindowProc( lpPrevWndFunc[ index], /* pointer to previous procedure */
                         hwnd,                  /* handle to window */
                         uMsg,                  /* message */
                         wParam,                /* first message parameter */
                         lParam);               /* second message parameter */
}


/**************************************************************
 *
 * Function : short WINAPI pvb_menu_create( short index, 
 *                                          char *title, 
 *                                          long x, 
 *                                          long y)
 *
 * Purpose  : Create menu for user.
 *           
 * Parameter: index - Index (1 .. 100) for menu bar element.
 *            title - Window title name for which menu is to be 
 *                    displayed.
 *            x     - Mouse position (x) for begin_pointed_at event.
 *            y     - Mouse position (y) for begin_pointed_at event.
 *
 * Return   : >= 1  - Success, return window handle.
 *            -1    - Failure
 **************************************************************/
short WINAPI pvb_menu_create( short index, char *title, long x, long y)
{

  HWND  hwnd;
  short i;
  LONG  style;


  if ((index < 1) || (index > PVB_MAX_MENU))
    return -1;

  if ((hwnd = FindWindow( NULL, title)) != NULL)
  {

    /* check if window is already in use */
    for (i = 0; i < PVB_MAX_MENU; i++)
    {

      if (menu_hwnd[ i] == NULL)
        break;
    }

    if (i >= PVB_MAX_MENU)
      return -2;


    if ((lpPrevWndFunc[ i] = (WNDPROC)SetWindowLong( hwnd, GWL_WNDPROC, (LONG)PVB_MenuWndProc)) != 0)
    {

      style = GetWindowLong( hwnd, GWL_STYLE);
      style &= (~WS_POPUP);
      style &= (~WS_CLIPSIBLINGS);
//      style |= WS_CLIPCHILDREN;
      SetWindowLong( hwnd, GWL_STYLE, style);

      menu_hwnd[ i] = hwnd;
      SetMenu( hwnd, menu_bar[ index - 1]);
      DrawMenuBar( hwnd);

      dummy_point[ i].x = x;
      dummy_point[ i].y = y;
    }
    else 
      return -1;
  }

  return (i);
} /* pvb_menu_create */


/**************************************************************
 *
 * Function : short WINAPI pvb_menu_object( short index, 
 *                                          long x, 
 *                                          long y)
 *
 * Purpose  : Adjust return object position.
 *           
 * Parameter: index - Index (1 .. 100) for menu bar element.
 *            x     - Mouse position (x) for begin_pointed_at event.
 *            y     - Mouse position (y) for begin_pointed_at event.
 *
 * Return   : 0  - Success, return window handle.
 *            -1 - Failure
 **************************************************************/
short WINAPI pvb_menu_object( short index, long x, long y)
{

  if (menu_hwnd[ index] == NULL)
    return -1;

  dummy_point[ index].x = x;
  dummy_point[ index].y = 24600L - y + GetSystemMetrics( SM_CYMENU);

  return 0;
} /* pvb_menu_object */


/**************************************************************
 *
 * Function : short WINAPI pvb_menu_close( char *title)
 *
 * Purpose  : Remove menu from window.
 *           
 * Parameter: index - Window handle used in DLL.
 *                    Returned by the function 'pvb_menu_create'.
 *
 * Return   : 0  - Success
 *            -1 - Failure
 **************************************************************/
short WINAPI pvb_menu_close( short index)
{


  if ((index < 0) || (index >= PVB_MAX_MENU))
    return -1;

  /* see if the window exists */
  if (menu_hwnd[ index] == NULL)
    return -1;

  /* remove the hook */
  SetWindowLong( menu_hwnd[ index], GWL_WNDPROC, (LONG)lpPrevWndFunc[ index]);

  /* remove the menu bar */
  SetMenu( menu_hwnd[ index], NULL);
  DrawMenuBar( menu_hwnd[ index]);

  menu_hwnd[ index] = NULL;

  new_event[ index] = 0;
  mark[ index] = 0;

  return 0;
} /* pvb_menu_close */


/**************************************************************
 *
 * Function : short WINAPI pvb_menu_event( short index, 
 *                                         short *checked)
 *
 * Purpose  : Check for last choosen menu item.
 *           
 * Parameter: index - Window handle used in DLL.
 *                    Returned by the function 'pvb_menu_create'.
 *            flags - bit 0: checked (ON) or unchecked (OFF).
 *                    bit 1: grayed (ON) of enabled (OFF).
 *            new   - ON if this is a new choice, else OFF
 *
 * Return   : 0  - Success
 *            1  - New event
 *            -1 - Failure
 **************************************************************/
short WINAPI pvb_menu_event( short index, short *flags, short *new)
{

  short    ret = 0;


  if (!menu_init)
    return -1;

  if ((index < 1) || (index > PVB_MAX_MENU))
    return -1;

  if (menu_hwnd[ index - 1] == NULL)
    return -1;

  if ((ret = (short)(last_event[ index - 1] - 97000000)) < 0)
    ret = 0;

  if ((last_type[ index - 1] & MF_CHECKED) == MF_CHECKED)
    *flags = 1;
  else
    *flags = 0;

  if ((last_type[ index - 1] & MF_GRAYED) == MF_GRAYED)
    *flags += 2;
  
  *new = new_event[ index - 1];

  new_event[ index - 1] = 0;

  return ret;
} /* pvb_menu_event */


/**************************************************************
 *
 * Function : short WINAPI pvb_menu_checked( short type, 
 *                                           short index, 
 *                                           short item, 
 *                                           short checked)
 *
 * Purpose  : Change look of menu item to checked or non checked.
 *           
 * Parameter: type  - Type of menu item, 0 = last selected one
 *                                       1 = menu bar
 *                                       2 = menu item
 *                                       3 = sub menu item
 *            index - Menuar index, starting at one
 *            item  - Only used for types 1, 2, or 3, it is the 
 *                    order number in the menu
 *            check - New check status, 0 = non checked, 1 = checked.
 *
 * Return   : 0  - Success
 *            -1 - Failure
 **************************************************************/
short WINAPI pvb_menu_checked( short type, short index, 
                               short item, short checked)
{

  short      ret = 0;
  UINT       uCheck = 0;


  if (checked)
    uCheck = MF_CHECKED;
  else
    uCheck = MF_UNCHECKED;

  switch (type)
  {

    case 0:

      /* no type, use last selected item */
      if ((index < 0) || (index > PVB_MAX_MENU))
        return -1;

      uCheck |= MF_BYCOMMAND;

      CheckMenuItem( menu_bar[ index -1],     /* handle to menu */
                     last_event[ index - 1],  /* menu item to check or uncheck */
                     uCheck);                 /* menu item flags */
      break;

    case 1:

      uCheck |= MF_BYPOSITION;

      CheckMenuItem( menu_bar[ index - 1],    /* handle to menu */
                     item - 1,                /* menu item to check or uncheck */
                     uCheck);                 /* menu item flags */
      break;

    case 2:

      uCheck |= MF_BYPOSITION;

      CheckMenuItem( menu_itm[ index -1],     /* handle to menu */
                     item - 1,                /* menu item to check or uncheck */
                     uCheck);                 /* menu item flags */
      break;

    case 3:

      uCheck |= MF_BYPOSITION;

      CheckMenuItem( menu_sub[ index -1],     /* handle to menu */
                     item - 1,                /* menu item to check or uncheck */
                     uCheck);                 /* menu item flags */
      break;

    default:
      ret = -1;
      break;
  }

  return ret;
} /* pvb_menu_checked */


/**************************************************************
 *
 * Function : short WINAPI pvb_menu_enabled( short type, 
 *                                           short index, 
 *                                           short item, 
 *                                           short checked)
 *
 * Purpose  : Change look of menu item to enabled or disabled.
 *           
 * Parameter: type  - Type of menu item, 0 = last selected one
 *                                       1 = menu bar
 *                                       2 = menu item
 *                                       3 = sub menu item
 *            index - Menuar index, starting at one
 *            item  - Only used for types 1, 2, or 3, it is the 
 *                    order number in the menu
 *            check - New enable status, 0 = enabled, 1 = disabled.
 *
 * Return   : 0  - Success
 *            -1 - Failure
 **************************************************************/
short WINAPI pvb_menu_enabled( short type, short index, 
                               short item, short checked)
{

  short      ret = 0;
  UINT       uCheck = 0;


  if (checked)
    uCheck = MF_GRAYED;
  else
    uCheck = MF_ENABLED;

  switch (type)
  {

    case 0:

      /* no type, use last selected item */
      if ((index < 0) || (index > PVB_MAX_MENU))
        return -1;

      uCheck |= MF_BYCOMMAND;

      EnableMenuItem( menu_bar[ index -1],      /* handle to menu */
                      last_event[ index - 1],   /* menu item to check or uncheck */
                      uCheck);                  /* menu item flags */
      break;

    case 1:

      uCheck |= MF_BYPOSITION;

      EnableMenuItem( menu_bar[ index - 1],     /* handle to menu */
                      item - 1,                 /* menu item to check or uncheck */
                      uCheck);                  /* menu item flags */
      break;

    case 2:

      uCheck |= MF_BYPOSITION;

      EnableMenuItem( menu_itm[ index -1],      /* handle to menu */
                      item - 1,                 /* menu item to check or uncheck */
                      uCheck);                  /* menu item flags */
      break;

    case 3:

      uCheck |= MF_BYPOSITION;

      EnableMenuItem( menu_sub[ index -1],      /* handle to menu */
                      item - 1,                 /* menu item to check or uncheck */
                      uCheck);                  /* menu item flags */
      break;

    default:
      ret = -1;
      break;
  }

  return ret;
} /* pvb_menu_enabled */