17 de octubre de 2005

Agregar un menú en un formulario SDI

Introducción


Continuando con el tema de formularios SDI (Interfaz de un solo documento - Single Document Interface), esta vez mostraré como agregar un menú en un formulario de nivel superior.

Crear el formulario de nivel superior


Como ya vimos en un artículo anterior, para crear un formulario SDI en Visual FoxPro, debemos crear un Formulario de nivel superior, configurando la propiedad ShowWindow = 2 (Como formulario de nivel superior). Un formulario de nivel superior aparece como una ventana independiente sobre el escritorio de Windows y se muestra en la barra de tareas de Windows.

Crear el menú


La creación de un menú SDI para agregar en un formulario de nivel superior, es igual que la creación de cualquier otro menú, solo debemos marcar la casilla de verificación Formulario de nivel superior en el cuadro de dialogo Opciones generales que se muestra al seleccionar la opción Ver -> Opciones generales desde el diseñador de menú, como lo muestra la figura siguiente:

Cuando generamos el menú con esta opción activada, se deberá llamar al menú desde el método Init del formulario de nivel superior con una sentencia como la siguiente
DO MiMenu.mpr WITH THISFORM,.T.
Editando el archivo MiMenu.mpr podemos ver en las primeras líneas comentadas, una ayuda con las distintas formas de llamar al menú generado.

Código de ejemplo


El siguiente código es un ejemplo para mostrar un formulario de nivel superior con un menú incorporado. Para ejecutarlo con un menú personalizado, se debe habilitar la línea DO MiMenu.mpr WITH Thisform, .T. en el método Init del formulario, y quitar la llamada al procedimiento MiMenuEjemplo.
PUBLIC goMiForm
goMiForm=CREATEOBJECT("MiForm")
goMiForm.SHOW(1)
RETURN
*---
*--- Definición de MiForm
*---
DEFINE CLASS MiForm AS FORM
  SHOWWINDOW = 2
  DOCREATE = .T.
  AUTOCENTER = .T.
  CAPTION = "Ejemplo de menú en un formulario SDI"
  NAME = "MiForm"

  PROCEDURE INIT
    *DO MiMenu.mpr WITH Thisform, .T.
    DO MiMenuEjemplo WITH THISFORM, .T.
  ENDPROC

  PROCEDURE DESTROY
    RELEASE MENU (THIS.NAME) EXTENDED
  ENDPROC
ENDDEFINE
*---
*--- MiMenuEjemplo.spr
*---
PROCEDURE MiMenuEjemplo
  LPARAMETERS oFormRef, getMenuName, lUniquePopups
  LOCAL cMenuName, nTotPops, a_menupops, cTypeParm2, cSaveFormName
  IF TYPE("m.oFormRef") # "O" OR ;
      LOWER(m.oFormRef.BASECLASS) # 'form' OR ;
      m.oFormRef.SHOWWINDOW # 2
    MESSAGEBOX([Este menú solo puede ser llamado en un formulario de nivel superior])
    RETURN
  ENDIF
  m.cTypeParm2 = TYPE("m.getMenuName")
  m.cMenuName = SYS(2015)
  m.cSaveFormName = m.oFormRef.NAME
  IF m.cTypeParm2 = "C" OR (m.cTypeParm2 = "L" AND m.getMenuName)
    m.oFormRef.NAME = m.cMenuName
  ENDIF
  IF m.cTypeParm2 = "C" AND !EMPTY(m.getMenuName)
    m.cMenuName = m.getMenuName
  ENDIF
  DIMENSION a_menupops[3]
  IF TYPE("m.lUniquePopups")="L" AND m.lUniquePopups
    FOR nTotPops = 1 TO ALEN(a_menupops)
      a_menupops[m.nTotPops]= SYS(2015)
    ENDFOR
  ELSE
    a_menupops[1]="archivo"
    a_menupops[2]="edición"
    a_menupops[3]="ayuda"
  ENDIF
  *---
  *--- Definición del menú
  *---
  DEFINE MENU (m.cMenuName) IN (m.oFormRef.NAME) BAR
  DEFINE PAD _1mv0kg6re OF (m.cMenuName) PROMPT "\<Archivo" COLOR SCHEME 3 KEY ALT+A
  DEFINE PAD _1mv0kg6rf OF (m.cMenuName) PROMPT "\<Edición" COLOR SCHEME 3 KEY ALT+E
  DEFINE PAD _1mv0kg6rg OF (m.cMenuName) PROMPT "A\<yuda" COLOR SCHEME 3 KEY ALT+Y
  ON PAD _1mv0kg6re OF (m.cMenuName) ACTIVATE POPUP (a_menupops[1])
  ON PAD _1mv0kg6rf OF (m.cMenuName) ACTIVATE POPUP (a_menupops[2])
  ON PAD _1mv0kg6rg OF (m.cMenuName) ACTIVATE POPUP (a_menupops[3])

  DEFINE POPUP (a_menupops[1]) MARGIN RELATIVE SHADOW COLOR SCHEME 4
  DEFINE BAR 1 OF (a_menupops[1]) PROMPT "\<Nuevo" PICTRES _MFI_NEW
  DEFINE BAR 2 OF (a_menupops[1]) PROMPT "\<Abrir" PICTRES _MFI_OPEN
  DEFINE BAR 3 OF (a_menupops[1]) PROMPT "\-"
  DEFINE BAR 4 OF (a_menupops[1]) PROMPT "\<Guardar" PICTRES _MFI_SAVE
  DEFINE BAR 5 OF (a_menupops[1]) PROMPT "\<Imprimir" PICTRES _MFI_SYSPRINT
  DEFINE BAR 6 OF (a_menupops[1]) PROMPT "\<Enviar" PICTRES _MFI_SEND
  DEFINE BAR 7 OF (a_menupops[1]) PROMPT "\-"
  DEFINE BAR 8 OF (a_menupops[1]) PROMPT "\<Salir" PICTRES _MFI_QUIT
  ON SELECTION BAR 8 OF (a_menupops[1]) DO _Salir

  DEFINE POPUP (a_menupops[2]) MARGIN RELATIVE SHADOW COLOR SCHEME 4
  DEFINE BAR 1 OF (a_menupops[2]) PROMPT "\<Deshacer" PICTRES _MED_UNDO
  DEFINE BAR 2 OF (a_menupops[2]) PROMPT "\-"
  DEFINE BAR 3 OF (a_menupops[2]) PROMPT "Cor\<tar" PICTRES _MED_CUT
  DEFINE BAR 4 OF (a_menupops[2]) PROMPT "\<Copiar" PICTRES _MED_COPY
  DEFINE BAR 5 OF (a_menupops[2]) PROMPT "\<Pegar" PICTRES _MED_PASTE

  DEFINE POPUP (a_menupops[3]) MARGIN RELATIVE SHADOW COLOR SCHEME 4
  DEFINE BAR 1 OF (a_menupops[3]) PROMPT "\<Ayuda" PICTRES _MST_HPSCH
  DEFINE BAR 2 OF (a_menupops[3]) PROMPT "\-"
  DEFINE BAR 3 OF (a_menupops[3]) PROMPT "Acerca \<de..." PICTRES _MST_ABOUT

  ACTIVATE MENU (m.cMenuName) NOWAIT

  IF m.cTypeParm2 = "C"
    m.getMenuName = m.cMenuName
    m.oFormRef.NAME = m.cSaveFormName
  ENDIF
ENDPROC

PROCEDURE _Salir
  _SCREEN.ACTIVEFORM.RELEASE
ENDPROC
Al ejecutar el código anterior, veremos el formulario SDI con el menú como lo muestra la siguiente figura:


Comentarios


Recordar que Visual FoxPro trae en la aplicación "Solution" un ejemplo similar donde se muestra un formulario SDI, en el cual se agrega un menú, una barra de herramientas, y se crean ventanas secundarias. Para ver la aplicación "Solution" ejecute:
DO (HOME(2) + "Solution\Solution")
O directamente corra el ejemplo del formulario SDI ejecutando:
DO FORM (HOME(2) + "\Solution\Forms\SDIForm.scx")

Hasta la próxima.


Luis María Guayán

2 comentarios :

  1. Y en un formset como podría hacerlo??? Lo hice de esta manera y cuando lo ejecuto, el formulario en el cual lo programo para que aparezca me dice que no existe

    ResponderEliminar
  2. Tengo una aplicación que abre más de un formulario de nivel superior, pero tengo el problema siguiente: algunos de estos formularios de nivel superior llaman a otro formulario modal, en consecuencia al intentar cambiar a otro formulario de nivel superior activo no se puede... es decir mientras haya un formulario modal no puedo acceder a ninguno de los formularios de nivel superior abiertos... creí que el formulario modal aplicaba sólo al formulario de nivel superior que lo llamó, pero eso no es así, afecta a todos los demás... habrá forma en que si se llama a un form modal desde un form de nivel superior, el modo sólo afecte al form superior activo y no a los demás?

    ResponderEliminar