El otro d铆a me qued茅 con ganas de mejorar un poco la barra de botones con las ventanas MDI.

deumare@gmail.com

LOCAL aButtonsMdi:={}ON PAINT aButtonsMdi:=ACT_BOT_MODULOS(oBar22,aButtonsMdi)#include "Fivewin.ch"
#include "xbrowse.ch"
STATIC oWnd
STATIC oMenu
STATIC cRuta := "C:\DEUMARE\ICONS\" 聽 聽// pon aqu铆 una tu ruta, si quieres para tus iconos, imagenes
STATIC lBarAllwaysTop := .t. 聽 聽 聽 聽 聽 // only for test purpose. if .t. show all bars on top
STATIC lImageSelect 聽 := .f. 聽 聽 聽 聽 聽 // only for test purpose. if .t. show red or green dot
function Main()
LOCAL oFont, oIco, oBar
聽 聽DEFINE FONT oFont 聽NAME "Segoe UI Light" SIZE 0,-12
聽 聽DEFINE ICON oIco FILE cRuta+"DM_ICON2.ICO"
聽 聽DEFINE WINDOW oWnd MDI TITLE "Test BarMdi" ICON oIco
聽 聽ACTIVATE WINDOW oWnd ON INIT ( oWnd:oMenu:End(), oWnd:oMenu:=NIL, Child() ) 聽MAXIMIZED
oFont:End()
RETURN(NIL)
//-----------------------------------------------------------------------------
function BuildMenu()
local oMenu2
聽 聽MENU oMenu2 POPUP
聽 聽 聽 MENUITEM "&Salir" ACTION oWnd:End()
聽 聽 聽 SEPARATOR
聽 聽 聽 MENUITEM "&Clientes" 聽 聽ACTION IF( Activa_MDI("Clientes") 聽 , ,Modulo_clientes() )
聽 聽 聽 MENUITEM "&Proveedores" ACTION IF( Activa_MDI("Proveedores"), ,Modulo_proveedores() )
聽 聽 聽 MENUITEM "&Art铆culos" 聽 ACTION IF( Activa_MDI("Art铆culos") 聽, ,Modulo_articulos() )
聽 聽ENDMENU
RETURN(oMenu2)
//------------------------------------------------------------------------------
STATIC FUNCTION CHILD()
LOCAL oWnd2, oBar, oBar2
LOCAL aBotones:=ARRAY(2)
LOCAL oFont
LOCAL oCheck1, oCheck2
oMenu:=BuildMenu()
DEFINE FONT oFont NAME "Segoe UI Light" SIZE 0,-18
DEFINE WINDOW oWnd2 MDICHILD OF oWnd TITLE "Menu" COLOR CLR_BLACK, RGB(240,240,240)
聽 DEFINE BUTTONBAR oBar OF oWnd2 BUTTONSIZE 40,40
聽 聽 聽 oBar:SetColor(CLR_BLACK, RGB(240,240,240))
聽 聽 聽 oBar:bRClicked := {|| nil }
聽 聽 聽 @01,000 BTNBMP aBotones[1] FILE cRuta+"POWER-OFF.BMP" SIZE 40,40 OF oBar UPDATE NOBORDER ACTION oWnd:End()
聽 聽 聽 聽 聽aBotones[1]:cToolTip=CRLF+" 聽 Salir 聽 "+CRLF+" "
聽 聽 聽 @01,040 BTNBMP aBotones[2] FILE cRuta+"W10_MENU.BMP" SIZE 40,40 OF oBar UPDATE NOBORDER ACTION oMenu:Activate(40,41,oBar,.f.)
聽 聽 聽 聽 聽aBotones[2]:cToolTip=CRLF+" 聽 Men煤 principal 聽 "+CRLF+" "
聽 聽 聽 @01,080 BTNBMP FILE cRuta+"W10_CLIENTES.BMP" 聽SIZE 40,40 OF oBar UPDATE NOBORDER ACTION IF( Activa_MDI("Clientes") 聽 聽, ,Modulo_clientes() )
聽 聽 聽 @01,120 BTNBMP FILE cRuta+"W10_PROVE.BMP" 聽 聽 SIZE 40,40 OF oBar UPDATE NOBORDER ACTION IF( Activa_MDI("Proveedores") , ,Modulo_proveedores() )
聽 聽 聽 @01,160 BTNBMP FILE cRuta+"W10_ARTICUL.BMP" 聽 SIZE 40,40 OF oBar UPDATE NOBORDER ACTION IF( Activa_MDI("Art铆culos") 聽 , ,Modulo_articulos() )
聽 聽 聽 @100,140 BTNBMP FILE cRuta+"W10_CLIENTES.BMP" 聽PROMPT "Clientes" 聽 聽SIZE 200,80 OF oWnd2 UPDATE TOP ACTION IF( Activa_MDI("Clientes") 聽 聽, ,Modulo_clientes() )
聽 聽 聽 @200,140 BTNBMP FILE cRuta+"W10_PROVE.BMP" 聽 聽 PROMPT "Proveedores" SIZE 200,80 OF oWnd2 UPDATE TOP ACTION IF( Activa_MDI("Proveedores") , ,Modulo_proveedores() )
聽 聽 聽 @300,140 BTNBMP FILE cRuta+"W10_ARTICUL.BMP" 聽 PROMPT "Art铆culos" 聽 SIZE 200,80 OF oWnd2 UPDATE TOP ACTION IF( Activa_MDI("Art铆culos") 聽 , ,Modulo_articulos() )
聽 聽@ 100,400 CHECKBOX oCheck1 VAR lBarAllwaysTop PROMPT "BarMdi on TOP" OF oWnd2 FONT oFont SIZE 200,28 PIXEL
聽 聽@ 140,400 CHECKBOX oCheck2 VAR lImageSelect 聽 PROMPT "Show red/green dots" OF oWnd2 FONT oFont SIZE 200,28 PIXEL
ACTIVATE WINDOW oWnd2 MAXIMIZED
oFont:End()
return nil
///////////////////////////////////////////////////////////////////////////////
// MODULOS QUE SUELEN IR EN PRG DIFERENTES
FUNCTION MODULO_CLIENTES()
LOCAL oWndC, oBar, oBar2, oBar22
LOCAL aBotones:=ARRAY(2)
LOCAL aButtonsMdi:={}
LOCAL oFont, oBrw, aData
DEFINE FONT oFont 聽NAME "Segoe UI Light" SIZE 0,-18
DEFINE WINDOW oWndC MDICHILD OF oWnd TITLE "Clientes" COLOR CLR_BLACK, RGB(240,240,240)
聽 DEFINE BUTTONBAR oBar OF oWndC BUTTONSIZE 40,40
聽 聽 聽 oBar:SetColor(CLR_BLACK, RGB(240,240,240))
聽 聽 聽 oBar:bRClicked := {|| nil }
聽 聽 聽 @01,000 BTNBMP aBotones[1] FILE cRuta+"CLOSE.BMP" SIZE 40,40 OF oBar UPDATE NOBORDER ACTION oWndC:End()
聽 聽 聽 聽 聽aBotones[1]:cToolTip=CRLF+" 聽 Cerra m贸dulo de CLIENTES 聽 "+CRLF+" "
聽 聽 聽 @01,040 BTNBMP aBotones[2] FILE cRuta+"W10_MENU.BMP" SIZE 40,40 OF oBar UPDATE NOBORDER ACTION oMenu:Activate(40,41,oBar,.f.)
聽 聽 聽 聽 聽aBotones[2]:cToolTip=CRLF+" 聽 Men煤 principal 聽 "+CRLF+" "
聽 聽@40,0 BUTTONBAR oBar22 SIZE 1400,40 BUTTONSIZE 100,40 OF oWndC
聽 聽@100,50 SAY "CLIENTES Objects [BarMdi TOP position]" OF oWndC PIXEL COLOR CLR_BLUE SIZE 500,50 FONT oFont
聽 聽 aData:={{"","",""}}
聽 聽 oBrw:=TxBrowse():New(oWndC)
聽 聽 oBrw:nDataLines := 1
聽 聽 oBrw:SetArray(aData)
聽 聽 oBrw:nTop 聽 聽 := 150
聽 聽 oBrw:nLeft 聽 聽:= 50
聽 聽 oBrw:nBottom 聽:= 600
聽 聽 oBrw:nRight 聽 := 750
聽 聽 oBrw:oFont 聽 聽:= oFont
聽 聽 oBrw:aCols[1]:cHeader 聽 聽 聽:= "Object"
聽 聽 oBrw:aCols[2]:cHeader 聽 聽 聽:= "Id"
聽 聽 oBrw:aCols[3]:cHeader 聽 聽 聽:= "Caption/Data"
聽 聽 oBrw:aCols[1]:nWidth 聽 聽 聽 := 150
聽 聽 oBrw:aCols[2]:nWidth 聽 聽 聽 := 100
聽 聽 oBrw:aCols[3]:nWidth 聽 聽 聽 := 500
聽 聽 oBrw:nRowHeight 聽 聽 :=26
聽 聽 oBrw:CreateFromCode()
ACTIVATE WINDOW oWndC MAXIMIZED ON PAINT ( aButtonsMdi:=ACT_BOT_MODULOS(oBar22,aButtonsMdi), aData:=ACT_BROWSE(aData,oBrw,oBar22,oWndC,aButtonsMdi) )
oFont:End()
return nil
//-----------------------------------------------------------------------------
FUNCTION MODULO_PROVEEDORES()
LOCAL oWndPr, oBar, oBar23
LOCAL aBotones:=ARRAY(2)
LOCAL aButtonsMdi:={}
LOCAL oFont, oBrw, aData
DEFINE FONT oFont 聽NAME "Segoe UI Light" SIZE 0,-18
DEFINE WINDOW oWndPr MDICHILD OF oWnd TITLE "Proveedores" COLOR CLR_BLACK, RGB(240,240,240)
聽 DEFINE BUTTONBAR oBar OF oWndPr BUTTONSIZE 40,40
聽 聽 聽 oBar:SetColor(CLR_BLACK, RGB(240,240,240))
聽 聽 聽 oBar:bRClicked := {|| nil }
聽 聽 聽 @01,000 BTNBMP aBotones[1] FILE cRuta+"CLOSE.BMP" SIZE 40,40 OF oBar UPDATE NOBORDER ACTION oWndPr:End()
聽 聽 聽 聽 聽aBotones[1]:cToolTip=CRLF+" 聽 Cerrar m贸dulo de proveedores 聽 "+CRLF+" "
聽 聽 聽 @01,040 BTNBMP aBotones[2] FILE cRuta+"W10_MENU.BMP" SIZE 40,40 OF oBar UPDATE NOBORDER ACTION oMenu:Activate(40,41,oBar,.f.)
聽 聽 聽 聽 聽aBotones[2]:cToolTip=CRLF+" 聽 Men煤 principal 聽 "+CRLF+" "
聽 聽 聽 @05,085 IMAGE FILE cRuta+"SEPARADOR.JPG" SIZE 1,30 OF oBar PIXEL NOBORDER
聽 聽 聽 Botones_ABM( oBar ) 聽// simula botones de alta, baja, modificacion ...
聽 聽IF lBarAllwaysTop = .t.
聽 聽 聽 @40,0 BUTTONBAR oBar23 SIZE 1400,40 BUTTONSIZE 100,40 OF oWndPr
聽 聽 聽 @100,250 SAY "PROVEEDORES Objects [BarMdi TOP position]" OF oWndPr PIXEL COLOR CLR_BLUE SIZE 500,50 FONT oFont
聽 聽ELSE
聽 聽 聽 @40,0 BUTTONBAR oBar23 SIZE 200,800 BUTTONSIZE 100,40 OF oWndPr
聽 聽 聽 @100,250 SAY "PROVEEDORES Objects [BarMdi LEFT position]" OF oWndPr PIXEL COLOR CLR_BLUE SIZE 500,50 FONT oFont
聽 聽ENDIF
聽 聽 aData:={{"","",""}}
聽 聽 oBrw:=TxBrowse():New(oWndPr)
聽 聽 oBrw:nDataLines := 1
聽 聽 oBrw:SetArray(aData)
聽 聽 oBrw:nTop 聽 聽 := 150
聽 聽 oBrw:nLeft 聽 聽:= 250
聽 聽 oBrw:nBottom 聽:= 600
聽 聽 oBrw:nRight 聽 := 950
聽 聽 oBrw:oFont 聽 聽:= oFont
聽 聽 oBrw:aCols[1]:cHeader 聽 聽 聽:= "Object"
聽 聽 oBrw:aCols[2]:cHeader 聽 聽 聽:= "Id"
聽 聽 oBrw:aCols[3]:cHeader 聽 聽 聽:= "Caption/Data"
聽 聽 oBrw:aCols[1]:nWidth 聽 聽 聽 := 150
聽 聽 oBrw:aCols[2]:nWidth 聽 聽 聽 := 100
聽 聽 oBrw:aCols[3]:nWidth 聽 聽 聽 := 500
聽 聽 oBrw:nRowHeight 聽 聽 :=26
聽 聽 oBrw:CreateFromCode()
ACTIVATE WINDOW oWndPr MAXIMIZED ON PAINT ( aButtonsMdi:=ACT_BOT_MODULOS(oBar23,aButtonsMdi), aData:=ACT_BROWSE(aData,oBrw,oBar23,oWndPr,aButtonsMdi) )
oFont:End()
return nil
//-----------------------------------------------------------------------------
FUNCTION MODULO_ARTICULOS()
LOCAL oWndA, oBar, oBar24
LOCAL aBotones:=ARRAY(2)
LOCAL aButtonsMdi:={}
LOCAL oFont, oBrw, aData
DEFINE FONT oFont 聽NAME "Segoe UI Light" SIZE 0,-18
DEFINE WINDOW oWndA MDICHILD OF oWnd TITLE "Art铆culos" COLOR CLR_BLACK, RGB(240,240,240) FROM 0,0 TO 2000,2000
聽 聽DEFINE BUTTONBAR oBar OF oWndA BUTTONSIZE 40,40
聽 聽oBar:SetColor(CLR_BLACK, RGB(240,240,240))
聽 聽oBar:bRClicked := {|| nil }
聽 聽 聽 @01,000 BTNBMP aBotones[1] FILE cRuta+"CLOSE.BMP" SIZE 40,40 OF oBar UPDATE NOBORDER ACTION oWndA:End()
聽 聽 聽 聽 聽aBotones[1]:cToolTip=CRLF+" 聽 Cerra m贸dulo de ARTICULOS 聽 "+CRLF+" "
聽 聽 聽 @01,040 BTNBMP aBotones[2] FILE cRuta+"W10_MENU.BMP" SIZE 40,40 OF oBar UPDATE NOBORDER ACTION oMenu:Activate(40,41,oBar,.f.)
聽 聽 聽 聽 聽aBotones[2]:cToolTip=CRLF+" 聽 Men煤 principal 聽 "+CRLF+" "
聽 聽IF lBarAllwaysTop
聽 聽 聽 @40,0 BUTTONBAR oBar24 SIZE 1400,40 BUTTONSIZE 100,40 OF oWndA
聽 聽 聽 @100,300 SAY "ARTICULOS objects [BarMdi TOP position]" OF oWndA PIXEL SIZE 500,50 COLOR CLR_RED FONT oFont
聽 聽ELSE
聽 聽 聽 @150,100 BUTTONBAR oBar24 SIZE 180,450 BUTTONSIZE 180,40 OF oWndA
聽 聽 聽 @100,300 SAY "ARTICULOS objects [BarMdi FREE position]" OF oWndA PIXEL SIZE 500,50 COLOR CLR_RED FONT oFont
聽 聽ENDIF
聽 聽 aData:={{"","",""}}
聽 聽 oBrw:=TxBrowse():New(oWndA)
聽 聽 oBrw:nDataLines := 1
聽 聽 oBrw:SetArray(aData)
聽 聽 oBrw:nTop 聽 聽 := 150
聽 聽 oBrw:nLeft 聽 聽:= 300
聽 聽 oBrw:nBottom 聽:= 600
聽 聽 oBrw:nRight 聽 := 900
聽 聽 oBrw:oFont 聽 聽:= oFont
聽 聽 oBrw:aCols[1]:cHeader 聽 聽 聽:= "Object"
聽 聽 oBrw:aCols[2]:cHeader 聽 聽 聽:= "Id"
聽 聽 oBrw:aCols[3]:cHeader 聽 聽 聽:= "Caption/Data"
聽 聽 oBrw:aCols[1]:nWidth 聽 聽 聽 := 150
聽 聽 oBrw:aCols[2]:nWidth 聽 聽 聽 := 100
聽 聽 oBrw:aCols[3]:nWidth 聽 聽 聽 := 500
聽 聽 oBrw:nRowHeight 聽 聽 :=26
聽 聽 oBrw:CreateFromCode()
ACTIVATE WINDOW oWndA MAXIMIZED ON PAINT ( aButtonsMdi:=ACT_BOT_MODULOS(oBar24,aButtonsMdi), aData:=ACT_BROWSE(aData,oBrw,oBar24,oWndA,aButtonsMdi) )
oFont:End()
return nil
// ----------------------------------------------------------------------------
// only for test purpose
FUNCTION ACT_BROWSE(aData,oBrw,oBar,oWnd,aButtonsMdi)
local i
聽 聽aData:={}
聽 聽// MDI window
聽 聽AADD( aData, { oWnd:ClassName(), "nil" , oWnd:cCaption } )
聽 聽// MDI Bar
聽 聽AADD( aData, { " 聽- "+oBar:ClassName(), ALLTRIM(STR(oBar:nId)), oBar:cCaption } )
聽 聽// MDI BAR Buttons
聽 聽for i=1 to LEN(oBar:aControls)
聽 聽 聽 AADD( aData, { " 聽 聽- "+oBar:aControls[i]:ClassName(), ALLTRIM(STR(oBar:aControls[i]:nId)), oBar:aControls[i]:cCaption } )
聽 聽next i
聽 聽// Othe MDI Controls
聽 聽for i=1 to LEN(oWnd:aControls)
聽 聽 聽 AADD( aData, { " 聽- "+oWnd:aControls[i]:ClassName(), ALLTRIM(STR(oWnd:aControls[i]:nId)), oWnd:aControls[i]:cCaption } )
聽 聽next i
聽 聽// aButtonsMdi
聽 聽AADD( aData, {"","",""})
聽 聽AADD( aData, {" 聽aButtonsMdi","","Elements "+str(len(aButtonsMdi))})
聽 聽for i=1 to LEN(aButtonsMdi)
聽 聽 聽 AADD( aData, { " 聽 聽aButtonsMdi "+ALLTRIM(STR(i)),"","Valtype() "+VALTYPE(aButtonsMdi[i]) } )
聽 聽next i
oBrw:aArrayData=aData
oBrw:Refresh()
return(aData)
//-----------------------------------------------------------------------------
// MDI BUTTONS FUNCTIONS
FUNCTION ACT_BOT_MODULOS(oBar,aBMdi)
local i:=0
local acCaptions:={}
local aCaptionButtons := {} 聽 // lista de los caption de los botones existentes
local nPos:=2
local lEncontrado:=.f.
LOCAL X:=0
LOCAL oFont := oBar:oFont
LOCAL aoBt:={}
LOCAL nCaso:=0
LOCAL nDelete:=0
oBar:SetColor(CLR_BLACK, RGB(240,240,240))
oBar:bRClicked := {|| nil }
acCaptions:=genera_botones_mdi() 聽 聽 聽 聽 // GENERA UNA LISTA DE LAS VENTANAS EXISTENTES
aoBt:=ARRAY( LEN(acCaptions) ) 聽 聽 聽 聽 聽 // crea un array de la longuitud de los botones necesarios
// creamos el array con el caption de los botones que ya tenemos, por si necesitamos borrarlos
aCaptionButtons:={}
for i=1 to len(oBar:aControls)
聽 aadd(aCaptionButtons, oBar:aControls[i]:cCaption)
next i
IF LEN(aCaptionButtons)>LEN(acCaptions) 聽 // tenemos mas botones que ventanas
聽 聽nCaso:=1
ENDIF
IF LEN(aCaptionButtons)<LEN(acCaptions) 聽 // tenemos menos botones que ventanas
聽 聽nCaso:=2
ENDIF
IF LEN(aCaptionButtons)=LEN(acCaptions) 聽 // tenemos igual botones que ventanas
聽 聽RETURN(aBMdi)
ENDIF
IF nCaso = 1
聽 聽* determinar numero de elemento a borrar
聽 聽nDelete:=QueElementoBorrar(aCaptionButtons,acCaptions)
聽 聽 聽 aBMdi[nDelete]:Hide()
聽 聽 聽 aBMdi[nDelete]:End()
聽 聽 聽 aDel(aBMdi,nDelete)
聽 聽 聽 aSize(aBMdi, Len( aBMdi )-1 )
聽 聽 聽 *oBar:Del(2) 聽 // no usar. recoloca los botones por defecto en la parte superior
聽 聽 聽 ADel( oBar:aControls, nDelete )
聽 聽 聽 ASize( oBar:aControls, Len( oBar:aControls ) - 1 )
聽 聽 聽 oBar:Refresh()
聽 聽// recoloco los botones y asigno nuevo Code block
聽 聽aoBt:={}
聽 聽for i=1 to len(aBMdi)
聽 聽 聽 AADD(aoBt, aBmdi[i])
聽 聽 聽 // position
聽 聽 聽 IF (oBar:nRight-oBar:nLeft)>(oBar:nBottom-oBar:nTop) 聽 // si es mas ancho que alto
聽 聽 聽 聽 聽aoBt[i]:nLeft:=(i-1)*oBar:nBtnWidth
聽 聽 聽 ELSE
聽 聽 聽 聽 聽aoBt[i]:nTop:=(i-1)*oBar:nBtnHeight
聽 聽 聽 ENDIF
聽 聽 聽 aoBt[i]:bAction := HazBlock( i )
聽 聽next i
聽 聽oBar:Refresh()
聽 聽RETURN(aoBt)
ENDIF
IF nCaso=2
聽 聽for i=1 to len(acCaptions)
聽 聽 聽 x=1
聽 聽 聽 lEncontrado:=.f.
聽 聽 聽 DO WHILE .T.
聽 聽 聽 聽 聽IF x>LEN(aCaptionButtons) ; EXIT ; ENDIF
聽 聽 聽 聽 聽IF aCaptionButtons[x]=acCaptions[i]
聽 聽 聽 聽 聽 聽 lEncontrado:=.t.
聽 聽 聽 聽 聽ENDIF
聽 聽 聽 聽 聽++x
聽 聽 聽 ENDDO
聽 聽 聽 IF lEncontrado=.f. 聽 // si no ha encontrado el boton, lo crea
聽 聽 聽 聽 聽IF (oBar:nRight-oBar:nLeft)>(oBar:nBottom-oBar:nTop) 聽 // si es mas ancho que alto
聽 聽 聽 聽 聽 聽 @1,(i-1)*oBar:nBtnWidth BTNBMP aoBt[i] OF oBar PROMPT acCaptions[i] UPDATE NOBORDER SIZE oBar:nBtnWidth-2,oBar:nBtnHeight-2 FONT oFont
聽 聽 聽 聽 聽ELSE
聽 聽 聽 聽 聽 聽 @(I-1)*OBar:nBtnHeight,0 BTNBMP aoBt[i] OF oBar PROMPT acCaptions[i] UPDATE NOBORDER SIZE (oBar:nRight-oBar:nLeft)-2,oBar:nBtnHeight-2 FONT oFont
聽 聽 聽 聽 聽ENDIF
聽 聽 聽 聽 聽aoBt[i]:bAction := HazBlock( i )
聽 聽 聽 ELSE
聽 聽 聽 聽 聽aoBt[i]:=aBMdi[i]
聽 聽 聽 ENDIF
聽 聽 聽 // Colours & images
聽 聽 聽 IF aoBt[i]:cCaption=oBar:oWnd:cCaption
聽 聽 聽 聽 聽aoBt[i]:SetColor( CLR_BLACK, RGB(216,234,249) )
聽 聽 聽 聽 聽IF lImageSelect = .t.
聽 聽 聽 聽 聽 聽 aoBt[i]:SetFile(cRuta+"BOTON_VERDE.BMP")
聽 聽 聽 聽 聽 聽 aoBt[i]:nLayout := 1
聽 聽 聽 聽 聽ENDIF
聽 聽 聽 ELSE
聽 聽 聽 聽 聽aoBt[i]:SetColor( CLR_BLACK, RGB(250,250,250) )
聽 聽 聽 聽 聽IF lImageSelect = .t.
聽 聽 聽 聽 聽 聽 aoBt[i]:SetFile(cRuta+"BOTON_ROJO.BMP")
聽 聽 聽 聽 聽 聽 aoBt[i]:nLayout := 1
聽 聽 聽 聽 聽ENDIF
聽 聽 聽 ENDIF
聽 聽next i
ENDIF
return(aoBT)
//----------------------------------------------------------------------------
// DEVUELVE LA POSICION DEL ELEMENTO DEL PRIMER ARRAY QUE NO ESTA EN EL SEGUNDO ARRAY
FUNCTION QueElementoBorrar(aCaptionButtons,acCaptions)
local x:=0, z:=0
local cBuscar:=""
local nDevolver:=0
local lEncontrado:=.f.
for x:=1 to len(aCaptionButtons)
聽 聽cBuscar:=aCaptionButtons[x]
聽 聽lEncontrado:=.f.
聽 聽for z:=1 to len(acCaptions)
聽 聽 聽 IF cBuscar=acCaptions[z]
聽 聽 聽 聽 聽lEncontrado=.t.
聽 聽 聽 ENDIF
聽 聽NEXT z
聽 聽IF lEncontrado=.f.
聽 聽 聽 nDevolver:=x
聽 聽ENDIF
next x
return(nDevolver)
//-----------------------------------------------------------------------------
// Make code block with number of any MDI windows
Function HazBlock( x )
Return &("{ || SelectMdi(" +LTrim(Str(x))+" ) }" )
//----------------------------------------------------------------------------
// Select MDI window with their number
FUNCTION SelectMdi(nNumeroVentana)
oWnd:oWndClient:aWnd[nNumeroVentana]:SetFocus()
return(nil)
//-------------------------------------------------------------------------------
// SetFocus the MDI window with ::cCaption = cTitle if are in use
FUNCTION Activa_MDI(cTitle)
LOCAL i:=0, lSuccess:=.f.
cTitle:=upper(cTitle)
FOR i=1 TO LEN(oWnd:oWndClient:aWnd)
聽 聽IF UPPER( oWnd:oWndClient:aWnd[i]:cCaption )=cTitle
聽 聽 聽 oWnd:oWndClient:aWnd[i]:SetFocus()
聽 聽 聽 lSuccess:=.t.
聽 聽ENDIF
NEXT
RETURN lSuccess
//////////////////////////////////////////////////////////////////////////
// Return an array with all mdi windows in use
FUNCTION Genera_botones_mdi()
LOCAL aDevolver:={}, i:=1
FOR i=1 TO LEN(oWnd:oWndClient:aWnd)
聽 聽AADD(aDevolver, oWnd:oWndClient:aWnd[i]:cCaption )
NEXT i
RETURN( aDevolver )
////////////////////////////////////////////////////////////////////////////
// only for test visual use
FUNCTION BOTONES_ABM(oBar)
聽 聽 聽 @1,090 BTNBMP 聽OF oBar FILE cRuta+"FIRST.BMP" 聽 SIZE 40,40 UPDATE NOBORDER
聽 聽 聽 @1,130 BTNBMP OF oBar FILE cRuta+"PREV.BMP" 聽 聽 SIZE 40,40 UPDATE NOBORDER
聽 聽 聽 @1,170 BTNBMP OF oBar FILE cRuta+"NEXT.BMP" 聽 聽 SIZE 40,40 UPDATE NOBORDER
聽 聽 聽 @1,210 BTNBMP OF oBar FILE cRuta+"LAST.BMP" 聽 聽 SIZE 40,40 UPDATE NOBORDER
聽 聽 聽 @1,250 BTNBMP OF oBar FILE cRuta+"NEW.BMP" 聽 聽 聽SIZE 40,40 UPDATE NOBORDER
聽 聽 聽 @1,290 BTNBMP OF oBar FILE cRuta+"EDIT.BMP" 聽 聽 SIZE 40,40 UPDATE NOBORDER
聽 聽 聽 @1,330 BTNBMP OF oBar FILE cRuta+"OK.BMP" 聽 聽 聽 SIZE 40,40 UPDATE NOBORDER
聽 聽 聽 @1,370 BTNBMP OF oBar FILE cRuta+"CANCEL.BMP" 聽 SIZE 40,40 UPDATE NOBORDER
聽 聽 聽 @1,410 BTNBMP OF oBar FILE cRuta+"PRINT.BMP" 聽 聽SIZE 40,40 UPDATE NOBORDER
聽 聽 聽 @1,450 BTNBMP OF oBar FILE cRuta+"FIND.BMP" 聽 聽 SIZE 40,40 UPDATE NOBORDER
return(nil)Estimado Jes煤s,
Gracias por compartirlo
Buenos dias.
Como os dec铆a .... me aburr铆a y he seguido probando cosas con las ventanas MDI.
En esta 煤ltima versi贸n:
1) Los botones simulan ser pesta帽as de un Folder. Cada pesta帽a es una ventana MdiChild
2) Se pueden abrir multiples ventanas del mismo prg. Con su alias y area de trabajo distintas, para simular entornos de red.
3) Soporta movimiento de la posici贸n o puntero de las solapas cuando el tama帽o total de las solapas es mayor que el ancho de la ventana.
4>) Se han evitado parpadeos.
Nota : En el video, no se aprecia del todo bien el dise帽o de las solapas. Al pasar el rat贸n por algunos botones el video produce una sombras. En realidad no se ven estas sombras.
Para algunos efectos visuales o de dise帽o, he utlizado alguna clase modificada por mi. Pero se puede utilizar con las clases originales.
Las oBar se han sustituido por oImage para efectos visuales.

This new video is looking good! Will you share the code ?
+1
Muy guay.
Vamos tengo un cliente que me esta pidiendo eso exactamente.
Un gran avance visual.
Me apunto si puede ser al c贸digo.
Muchas gracias.
+1
vilian wrote:This new video is looking good! Will you share the code ?Yes of course.
Maravilloso.
Muchas gracias por tu esfuerzo y trabajo.
En la firma tienes mi email.
Un saludo y de nuevo muchas gracias, y creo que no me equivoco si te lo digo de parte de todos.
jmurugosa (arroba) gmail (punto) com
+1