Buenos dias
El otro día me quedé con ganas de mejorar un poco la barra de botones con las ventanas MDI.
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)
vilian wrote:This new video is looking good! Will you share the code ?
Return to FiveWin para Harbour/xHarbour
Users browsing this forum: Google [Bot] and 102 guests