Page 1 of 1
CONTRUIR UN MENU en ventana principal desde una tabla o dbf
Posted: Mon Aug 12, 2013 7:37 pm
by joseluisysturiz
Necesito crear menues personalizados dependiendo de los niveles de usuarios los cuales las opciones a mostrar estaran en una tabla mysql o una dbf, se que en el foro habia algo parecido o un sample, pero tengo bastante rato buscandolo y nada que lo consigo, si alguien por casualidad tiene el lnk del tema o un sample se lo agradeceria, las opciones de menu las creare basado en un modelo que contiene todas las opciones del menu, y luego voy seleccionando las que el usuario puede o no tener disponible, saludos...
Re: CONTRUIR UN MENU en ventana principal desde una tabla o dbf
Posted: Mon Aug 12, 2013 10:24 pm
by noe aburto
En lo personal, tengo una una variable publica x una cadena con 150 digitos: ej. '0001000100010000111111110001111111111...
cada caracter indica el numeto de permiso en el sistema de cada opcion dentro del menu, para contruir el menu hago algo asi:
if PasaProceso(i)
MENUITEM OPCI_OBJ(i) PROMPT OPCI_TIT(i) ACTION OPCI_ACC(i) BLOCK OPCI_BLO(i) RESOURCE OPCI_BMP(i)
else
MENUITEM OPCI_OBJ(i) PROMPT OPCI_TIT(i) ACTION OPCI_ACC(i) BLOCK OPCI_BLO(i) RESOURCE OPCI_BMP(i) DISABLED
endif
la funcion PasaProceso(i) lo unico que hace es tomas de la variable publica el caracter equivalente a (i), si es 1 pasa, si es 0, no
y la opcion del menu esta DISABLED
Re: CONTRUIR UN MENU en ventana principal desde una tabla o dbf
Posted: Mon Aug 12, 2013 11:58 pm
by horacio
Re: CONTRUIR UN MENU en ventana principal desde una tabla o dbf
Posted: Tue Aug 13, 2013 12:27 am
by joseluisysturiz
Gracias a los que han respondido, pero Horacio, lo que me dices es para llamar el nuevo menu, lo que necesito es como seria el algortimo para construir el menu, ya que las opciones de menu en _ unos deberan mostrarse y en otros no, dependiendo las que se le haya asiganado a dicho usuario, imagino debere usar un for o do while o algo parecido, doy ejemplo...saludos...
para un usuario a lo mejor tiene asignado las siguientes opciones:
Code: Select all
MENU oMenu 2007
MENUITEM "&Archivo"
MENU
MENUITEM "Salir del Sistema" ;
RESOURCE "SALIR16" ;
ACTION ( oDatos:oWndPpal:END() ) ;
ENDMENU
MENUITEM "&Inventario"
MENU
MENUITEM "Productos" ACTION ( productos() )
MENUITEM "Marcas" ACTION ( marcas() )
MENUITEM "Clases" ACTION ( lineas() )
SEPARATOR
MENUITEM "Movimientos" ACTION ( movinv() )
SEPARATOR
MENUITEM "Reportes" ACTION msginfo("Listados y Reportes")
ENDMENU
ENDMENU
pero para otro solo estas...
Code: Select all
MENU oMenu 2007
MENUITEM "&Archivo"
MENU
MENUITEM "Salir del Sistema" ;
RESOURCE "SALIR16" ;
ACTION ( oDatos:oWndPpal:END() ) ;
ENDMENU
MENUITEM "&Inventario"
MENU
MENUITEM "Productos" ACTION ( productos() )
MENUITEM "Clases" ACTION ( lineas() )
MENUITEM "Reportes" ACTION msginfo("Listados y Reportes")
ENDMENU
ENDMENU
voy asignando las opciones principales y derivadas en linea, las grabo en una tabla o dbf como si fueran los detalles de una factura, el punto es que el menu debe construirse solo dinamicamente al momento de validar la clave de acceso del usuario, dependiendo de sus opciones asignadas, algo como un tree que vi que ramifica el menu ppal y luego sus derivados y al final un checkbox para seleccionar las opciones a asignar.
Espero no haber enredado mas el papagallo, gracias, saludos...
Re: CONTRUIR UN MENU en ventana principal desde una tabla o dbf
Posted: Tue Aug 13, 2013 2:15 am
by russimicro
FUNCTION MenuPrincipal(oWnd)
LOCAL cPatTem := "C:\TEMP\"
LOCAL cNombas := 'Menu'+ALLTRIM(STR(hb_random(10000000),8,0))+M->cCiaAct+cNroUsr
LOCAL cFilTem := cNombas+'.TMD'
LOCAL cFilTeI := cNombas+'.CDX'
LOCAL oGif
LOCAL nUsuSis := VAL(cNroUsr)
LOCAL cAliAct := ALIAS()
LOCAL cNomba1 := 'SEGURIDAD'+ALLTRIM(STR(hb_random(10000000),8,0))+M->cCiaAct+cNroUsr
LOCAL cFilTe1 := cNomba1+'.TMD'
LOCAL cFilTe2 := cNomba1+'.CDX'
LOCAL cPatLoc := "C:\TEMP\"
LOCAL cNroOpc := ""
IF !lUsaTab(M->cPatSis+"\","OPCIONES.DAT","OPC",{"OPCIONES.CDX"},.T.)
IF !EMPTY(cAliAct)
SELECT &cAliAct
ENDIF
RETURN
ENDIF
SELECT OPC
DBSETORDER(1)
filtrarScope("OPC",1,STR(VAL(M->cNroUsr),2,0),STR(VAL(M->cNroUsr),2,0))
FERASE("C:\TEMP\"+cFilTeI)
COPY_FILE_DBF_DBF( "MENU.DAT", "C:\TEMP\"+cFilTem )
IF !FILE("C:\TEMP\"+cFilTem)
MYMEN("Error. No existe archivo de configuraci¢n de menus")
RETURN
ENDIF
IF SELECT("MEN") <> 0
CLOSE MEN
ENDIF
IF !lUsaTab(cPatTem, cFilTem,"MEN",{},.F.,NIL,"DBFCDX")
RETURN
ENDIF
SELECT MEN
INDEX ON CCODIGOMEN TAG ORDER1 TO &("C:\TEMP\"+cFilTeI)
DBSETORDER(1)
GO TOP
MENU oMenu 2007
DO WHILE MEN->( !EOF() )
cNroOpc := ALLTRIM(MEN->cNroOpcSeg)
IF XXVALOPUSR(cNroOpc)
MENUITEM HB_OEMTOANSI( ALLTRIM(MEN->cNombreMen) )
ELSE
MENUITEM HB_OEMTOANSI( ALLTRIM(MEN->cNombreMen) ) DISABLED
ENDIF
MENU
MENUX(1)
ENDMENU
ENDDO
ENDMENU
// CLOSE MEN
// CLOSE OPC
RETURN
//**************************************************************************************
FUNCTION MENUX( nNroNiv )
LOCAL bBloEje, nNivAct
LOCAL cNroOpc := ""
nNivAct := SUBS( MEN->cCodigoMen, 1, nNroNiv * 2 )
DO WHILE MEN->( !EOF() ) .AND. SUBS( MEN->cCodigoMen,1,nNroNiv * 2 ) == nNivAct
IF LEN(ALLTRIM(MEN->cCodigoMen)) > nNroNiv * 2
cFunEje := MEN->cFunEjeMen
cNomOpc := MEN->cNombreMen
cRegAct := ALLTRIM(MEN->cCodigoMen)
cNroOpc := ALLTRIM(MEN->cNroOpcSeg)
MEN->( DBSKIP() )
cRegSig := SUBS( MEN->cCodigoMen,1,( nNroNiv + 1 ) * 2 )
IF cRegAct == cRegSig
IF XXVALOPUSR(cNroOpc) // cRegAct
MENUITEM HB_OEMTOANSI( ALLTRIM(cNomOpc) )
ELSE
MENUITEM HB_OEMTOANSI( ALLTRIM(cNomOpc) ) DISABLED
ENDIF
SELECT MEN
SKIP -1
MENU
MenuX( nNroNiv + 1 )
ENDMENU
ELSE
bBloEje := &( "{||" + IF( EMPTY( cFunEje ), ".T.", ALLTRIM( cFunEje ) ) + "}" )
IF XXVALOPUSR(cNroOpc)
MENUITEM HB_OEMTOANSI( ALLTRIM(cNomOpc) ) ACTION ( bBloEje ) BLOCK bBloEje // FILENAME getImage( BITMAP )
ELSE
MENUITEM HB_OEMTOANSI( ALLTRIM(cNomOpc) ) DISABLED ACTION ( bBloEje ) BLOCK bBloEje // FILENAME getImage( BITMAP )
ENDIF
ENDIF
ELSE
MEN->( DBSKIP() )
ENDIF
ENDDO
RETURN NIL
//**********************************************
Re: CONTRUIR UN MENU en ventana principal desde una tabla o dbf
Posted: Tue Aug 13, 2013 2:50 am
by joseluisysturiz
Saludos russimicro, estoy revisando lo que me distes, creo es lo que ando buscando, luego te comento, estamos a la orden por aca en Venezuela, saludos...
Re: CONTRUIR UN MENU en ventana principal desde una tabla o dbf
Posted: Tue Aug 13, 2013 2:54 am
by cmsoft
Yo lo hago de ésta manera:
Code: Select all
// --------------------------------------------------------------------//
// ------------- Funcion men£ de la pantalla principal ----------------//
// --------------------------------------------------------------------//
STATIC FUNCTION HazMenu(musuario,nItems) // Musuario es el nombre de un usuario válido, ;
// y nItems se pasa por referencia para poner en que nivel queda el menuinfo
LOCAL i, oMenu, j, oMenuItem, nivel, nivel1, ult
MEMVAR oWPpal
use menues ALIAS "menu1" SHARED NEW
SET INDEX TO menues
menu1->(DBSEEK(musuario))
MENU oMenu
j := 0
aproce :={}
nItems := 1
nivel := 1
ult := "N"
DO WHILE menu1->usuario = musuario
IF menu1->submenu = "S" && Si es submenu
MENUITEM ALLTRIM(menu1->detalle)
ult := "S"
MENU
ELSE
ult := "N"
IF menu1->submenu = "-" && Si un separador
SEPARATOR
ELSE && Si un proceso
j++
AADD(aproce,menu1->modulo) && Cargo la tabla de procesos
MENUITEM oMenuItem PROMPT ALLTRIM(menu1->detalle);
ACTION ejecfunc(oMenuItem:nHelpid) HELPID j
ENDIF
ENDIF
IF nivel = 1 && Si es un titulo
nItems++ && Cuento los items del menu principal
ENDIF
nivel1 := AT("0",menu1->orden1) - 1
menu1->(DBSKIP(1))
nivel := AT("0",menu1->orden1) - 1
IF nivel < nivel1 .and. menu1->usuario = musuario && Si retrocedo
FOR i := nivel TO (nivel1 - 1) && en nivel pongo
ENDMENU && los ENDMENU
NEXT i
IF ult = "S" .and. nivel = 1 && Si es titulo
ENDMENU && solo tambien
ENDIF
ELSE
IF ult = "S" .and. nivel = 1 && Si es titulo
ENDMENU && solo tambien
ENDIF
ENDIF
ENDDO
ENDMENU
** Esta parte del menu siempre va
MENUITEM "&Salir"
MENU
MENUITEM "&Salir" ACTION (oWPpal:end)
SEPARATOR
MENUITEM "Calc&uladora" ACTION WinExec( "Calc.exe" )
MENUITEM "Configuar &Impresora" ACTION PrinterSetup()
ENDMENU
ENDMENU
CLOSE menu1
RETURN oMenu
STATIC FUNCTION ejecfunc(mifunc)
LOCAL fun
fun := ALLTRIM(aproce[mifunc])
DO &fun
RETURN NIL
El proceso se base un una DBF que contiene que items del menú son visibles para cada usuario (basados en una tabla que contiene el menú completo, y que obviamente tiene su ABM de usuarios y menues)
La tabla es la siguiente:
Code: Select all
USUARIO MODULO DETALLE SUBMENU ORDEN1
Donde usuario es el usuario, módulo es la función que debe ejecutar, detalle es lo que sale en el menu, submenu indica si es submenu, separador o item, y orden1 es el orden del item de menu general (en formato cuenta contable, 100000, 110000, 120000, 200000, 210000, 211000, etc)
Es una función que utilizo desde mis viejos programas CLIPPER y que me ha servido mucho.
Si te interesa también la he desarrollado para MySql con Dolphin, avisame y te la paso.
Saludos y espero te sirva
Re: CONTRUIR UN MENU en ventana principal desde una tabla o dbf
Posted: Tue Aug 13, 2013 3:05 am
by joseluisysturiz
Saludos cmsoft, es lo que busco, la igual que del otro colega de Colombia, leer y revisare sus .prg, la unica diferencia entre comillas, es que en vez de una dbf uso una tabla con mysql, ya habia creado la tabla con _ parecido a los tuyos, gracias y saludos...
Re: CONTRUIR UN MENU en ventana principal desde una tabla o dbf
Posted: Tue Aug 13, 2013 8:09 am
by Antonio Mart.
Hola,
Para mi la cuestión principal de los menues configurables sería separar la construccion del menu de su configuración.
Para ello necesitaríamos que el comando MENUITEM dispusiera de un tag (etiqueta) ID. Otra opción sería ponérselo nosotros mismos redefiniendo el comando MENUITEM.
Teniendo este ID, el resto lo haríamos así
1) Funcion. Encerrariamos la funcion del menu en una funcion BuildMenu()
2) Configuración. Invocariamos a BuildMenu() para la UI (interfaz) de configuracion del menu. En ese caso nos sirve para obtener los distintos menuitem para configurar un tree de configuración que se guardaría en una .dbf o un .txt o lo que sea.
3) Carga menú. Invocaríamos a BuildMenu() para construir el menu de la Window. El menú se crearía según lo configurado en 2.
Se podría profundizar en la forma de hacerlo, pero creo que a grandes rasgos podría ser así.
Espero que a alguien le sirva la idea.
Saludos
Re: CONTRUIR UN MENU en ventana principal desde una tabla o dbf
Posted: Tue Aug 13, 2013 2:29 pm
by jcenteno
José Luis,
Mira si te sirve:
FUNCTION BldMenu()
*----------------------------------------------------------------*
LOCAL oMainMenu, oMnuItem, lRight, cValue, cMnuAlias, i:= 1, nRec, fAction, cFileBmp, cResName
LOCAL cQry, oQry, nL, nEnd
IF ! oApp:lMySql && Si es DBF
IF !AbreDbf( @cMnuAlias, oSystem:csysmenu, 1 )
oWnd:PostMsg(WM_CLOSE)
ENDIF
nRec := (cMnuAlias)->( AdsKeyCount( ,,ADS_RESPECTSCOPES ) ) //nRec := (cMnuAlias)->( LastRec() )
MENU oApp:oMainMenu 2007 // MENU oMainMenu 2007
FOR i := 1 To nRec
IF (cMnuAlias)->FLDSEPARAT //== TRUE
SEPARATOR
ENDIF
IF (cMnuAlias)->FLDVIRTKEY == 0
MENUITEM oMnuItem PROMPT OemToAnsi(ALLTRIM((cMnuAlias)->FLDTXTOPT)) ;
MESSAGE OemToAnsi(ALLTRIM((cMnuAlias)->FLDMESSAGE))
ELSE
MENUITEM oMnuItem PROMPT OemToAnsi(ALLTRIM((cMnuAlias)->FLDTXTOPT)) ;
MESSAGE OemToAnsi(ALLTRIM((cMnuAlias)->FLDMESSAGE)) ;
ACCELERATOR (cMnuAlias)->FLDNSTATE, (cMnuAlias)->FLDVIRTKEY
ENDIF
oMnuItem:lChecked := (cMnuAlias)->FLDCHECK
oMnuItem:lActive := ( lRight:= Eval( {||&(ALLTRIM((cMnuAlias)->FLDCONDI))} ) )
IF ! EMPTY( fAction := ALLTRIM((cMnuAlias)->FLDACTION) )
oMnuItem:bAction := &( fAction )
ENDIF
IF FILE( cFileBmp := oGraph:cmnuimgpath + ALLTRIM((cMnuAlias)->FLDFILEBMP) )
oMnuItem:hBitmap:= ReadBitmap( 0, cFileBmp )
ENDIF
IF ! EMPTY( cResName := ALLTRIM((cMnuAlias)->FLDRESBMP) )
oMnuItem:hBitmap:= LoadBitmap( GetResources(), cResName )
ENDIF
IF ! EMPTY( ALLTRIM((cMnuAlias)->FLDSYS) )
AAdd( oApp:aObjSys, oMnuItem )
ENDIF
cValue := ALLTRIM((cMnuAlias)->CNEXT)
DO CASE
CASE cValue == 'M0'
MENU
CASE cValue == 'M1'
MENU
CASE cValue == 'E1'
ENDMENU
CASE cValue == 'E2'
ENDMENU ; ENDMENU
CASE cValue == 'E3'
ENDMENU ; ENDMENU ; ENDMENU
CASE cValue == 'E4'
ENDMENU ; ENDMENU ; ENDMENU ; ENDMENU
CASE cValue == 'E5'
ENDMENU ; ENDMENU ; ENDMENU ; ENDMENU ; ENDMENU
CASE cValue == 'E6'
ENDMENU ; ENDMENU ; ENDMENU ; ENDMENU ; ENDMENU ; ENDMENU
END CASE
(cMnuAlias)->(dbSkip())
NEXT i
MENUITEM 'A&yuda' HELP
MENU
MENUITEM '&Help' ACTION HelpIndex() RESOURCE 'AYUDA1'
MENUITEM '&Acerca de...' ACTION fAbout()
ENDMENU
ENDMENU
(cMnuAlias)->(dbCloseArea())
ELSE && Para MySql
cQry := "SELECT * FROM " + oSystem:csysmenu + " WHERE lActive ORDER BY fldnivel ASC"
IF !AbreDbf( @oQry, oSystem:csysmenu, 1,, oRDD:rdbms, cQry )
MsgInfo('Error de apertura')
oWnd:PostMsg(WM_CLOSE)
ENDIF
nRec := oQry:LastRec()
oApp:oMainMenu := MenuBegin( ,,, TRUE ) // MENU oApp:oMainMenu 2007
FOR i := 1 To nRec
IF ( oQry:FLDSEPARAT ) //== TRUE
*SEPARATOR
oMnuItem:= MenuAddItem()
ENDIF
IF FILE( cFileBmp := oGraph:cmnuimgpath + ALLTRIM(oQry:FLDFILEBMP) )
ENDIF
IF ! EMPTY( cResName := ALLTRIM(oQry:FLDRESBMP) )
ENDIF
IF ! EMPTY( ALLTRIM(oQry:FLDACTION) )
fAction := &( ALLTRIM(oQry:FLDACTION) )
ENDIF
&& Crea nuevo Item del Menú
WITH OBJECT ( oMnuItem := MenuAddItem( ,,,,, cFileBmp, cResName, oApp:oMainMenu ) )
:cPrompt := ALLTRIM( oQry:FLDTXTOPT )
:cMsg := ALLTRIM( oQry:FLDMESSAGE )
:bAction := fAction
:lActive := ( lRight:= Eval( {||&( ALLTRIM( oQry:FLDCONDI ) )} ) ) //lRight:= Eval( {|| &(ALLTRIM((cMnuAlias)->FLDCONDI)) } )
:lBreak := FALSE
:lChecked := oQry:FLDCHECK
:lHelp := FALSE
:oMenu := oApp:oMainMenu
:nVKState := oQry:FLDNSTATE
:nVirtKey := oQry:FLDVIRTKEY
END
IF ! EMPTY( ALLTRIM(oQry:FLDSYS) )
AAdd( oApp:aObjSys, oMnuItem )
ENDIF
cValue := ALLTRIM(oQry:CNEXT) && Próximo nivel a crear o eliminar
nEnd := oQry:NLOOP
FOR nL := 1 TO nEnd
DO CASE
CASE Left(cValue,1) = 'M'
MenuBegin( ,,, TRUE )
CASE Left(cValue,1) = 'E'
MenuEnd()
END CASE
NEXT nL
oQry:Skip()
NEXT i
MENUITEM 'A&yuda' HELP
MENU
MENUITEM '&Help' ACTION HelpIndex() RESOURCE 'AYUDA1'
MENUITEM '&Acerca de...' ACTION fAbout()
ENDMENU
ENDMENU
oQry:End()
ENDIF
RELEASE lRight, cValue, cMnuAlias, i, nRec, fAction, cFileBmp, cResName, cQry
RETURN oApp:oMainMenu
Re: CONTRUIR UN MENU en ventana principal desde una tabla o dbf
Posted: Wed Aug 14, 2013 12:59 am
by cmsoft
Jose Luis:
Por si te interesa, te dejo la función pero para una tabla MySql con Dolphin. También le agregré al menú el estilo 2007 con íconos en el menú
Code: Select all
// --------------------------------------------------------------------//
// ------------- Funcion men£ de la pantalla principal ----------------//
// --------------------------------------------------------------------//
STATIC FUNCTION HazMenu(musuario,nItems)
LOCAL i, oMenu, j, oMenuItem, nivel, nivel1, ult, oQry
MEMVAR oWnd
oQry := oServer:Query( "SELECT * FROM menues WHERE usuario="+ClipValue2SQL(musuario))
MENU oMenu 2007
j := 0
aproce :={}
nItems := 1
nivel := 1
ult := "N"
DO WHILE !oQry:Eof()
IF oQry:submenu = "S" && Si es submenu
MENUITEM ALLTRIM(oQry:detalle) RESOURCE ALLTRIM(oQry:icono)
ult := "S"
MENU
ELSE
ult := "N"
IF oQry:submenu = "-" && Si un separador
SEPARATOR
ELSE && Si un proceso
j++
AADD(aProce,oQry:modulo) && Cargo la tabla de procesos
MENUITEM oMenuItem PROMPT ALLTRIM(oQry:detalle);
ACTION ejecfunc(oMenuItem:nHelpid) HELPID j;
RESOURCE ALLTRIM(oQry:icono)
ENDIF
ENDIF
IF nivel = 1 && Si es un titulo
nItems++ && Cuento los items del menu principal
ENDIF
nivel1 := AT("0",oQry:orden1) - 1
oQry:Skip()
nivel := AT("0",oQry:orden1) - 1
IF nivel < nivel1 .and. oQry:usuario = musuario && Si retrocedo
FOR i := nivel TO (nivel1 - 1) && en nivel pongo
ENDMENU && los ENDMENU
NEXT i
IF ult = "S" .and. nivel = 1 && Si es titulo
ENDMENU && solo tambien
ENDIF
ELSE
IF ult = "S" .and. nivel = 1 && Si es titulo
ENDMENU && solo tambien
ENDIF
ENDIF
ENDDO
ENDMENU
** Esta parte del menu siempre va
MENUITEM "&Salir"
MENU
MENUITEM "&Salir" ACTION (oWnd:end) RESOURCE "SALIR1"
SEPARATOR
MENUITEM "&Acerca" ACTION MsgInfo("Sistema XXXXXXXXXX" +CHR(10)+;
"CM Soft - 2013"+CHR(10)+;
"www.cmsoft.com.ar"+CHR(10)+;
"Desarrollo de sistemas"+CHR(10)+;
"Todos los derechos reservados","Acerca de XXXXXXXXXXXXX")
MENUITEM "Calc&uladora" ACTION WinExec( "Calc.exe" ) RESOURCE "CALCU1"
MENUITEM "Configuar &Impresora" ACTION PrinterSetup()
ENDMENU
ENDMENU
oQry:End()
RETURN oMenu
Saludos!
Re: CONTRUIR UN MENU en ventana principal desde una tabla o dbf
Posted: Wed Aug 14, 2013 3:10 am
by joseluisysturiz
Muchas gracias CMSOFT, estoy descargando y analizando lo enviado para adaptarlo a mi sistema, luego comento, saludos...