Saber si punto de dialogo esta fuera de pantalla SOLUCIONADO

Re: Saber si punto de dialogo esta fuera de la pantalla

Postby leandro » Fri Jan 31, 2020 3:49 pm

Jesús amigo probé tu ejemplo y funciona de maravilla, intente adecuarlo a lo que necesito. Pero no logro hacerlo andar desde un dialogo, te copio el código para ver si lo puedes compilar y checar que hago mal.

Code: Select all  Expand view  RUN

#include "FiveWin.ch"

FUNCTION PRUEBA_DIALOGO()

LOCAL oWnd
LOCAL oMenu
LOCAL N:=1

    MENU oMenu
        MENUITEM "&Sistema"
            MENU
               MENUITEM "&Especificar impresora" ACTION PrinterSetup()
               SEPARATOR
               MENUITEM "&Salir"  ACTION oWnd:End()
            ENDMENU

      ENDMENU

DEFINE WINDOW oWnd MDI FROM 100,100 TO 600,1200 PIXEL  TITLE "TEST POSICION DIALOGO" COLOR CLR_BLACK, CLR_GRAY MENU oMenu


ACTIVATE WINDOW oWnd MAXIMIZED ON INIT CreaChild(oWnd)

RETURN(NIL)

function CreaChild(oWnd)

local oWndChild
local oDlg
local oGroup
LOCAL oBtn

    DEFINE DIALOG oDlg SIZE 580,220 PIXEL TRUEPIXEL TITLE "Contenedor" OF oWnd
       
        @ 20,20 BUTTONBMP oBtn of oDlg PIXEL size 95, 24 PROMPT "Muestrame" ACTION Prueba2(oBtn,oDlg)

    ACTIVATE DIALOG oDlg CENTERED

RETURN(NIL)


///////////////////////////////////////////////////////////////////////////////
function prueba2(oBtn,oDlg)
Local oDlg1
nTopR     := oBtn:nTop      
nLeftR    := oBtn:nLeft
nAltura   := oBtn:nHeight

aPoint := { nTopR+nAltura, nLeftR }
aPoint = ClientToScreen( oDlg:hWnd, aPoint )

DEFINE DIALOG oDlg1 FROM 100,100 TO 400,400 TITLE "POSICIONADO"  PIXEL OF oDlg

ACTIVATE DIALOG oDlg1 ON INIT (msginfo(GetRight(oDlg1)),oDlg1:SetPos( aPoint[ 1 ], aPoint[ 2 ] ) )
return(nil)

////////////////////////////////////////////////////////////////////////////
FUNCTION GetRight(objeto)    // Devuelve el punto derecha absoluto del objeto pasado, en este caso un boton, prueba con un get

LOCAL oWnd:=objeto:oWnd
LOCAL nRight:=0
LOCAL aRect

DO WHILE .T.
   IF oWnd:ClassName()="NIL"
      EXIT
   ENDIF

   // aqui tienes que desarrollar mas posibles casos TDIALOG, ETC...
   // Yo he hecho el TGROUP, TMDICHILD Y TMDIFRAME

   IF oWnd:ClassName()="TGROUP"
      nRight:=nRight+oWnd:nLeft
   ENDIF
   IF oWnd:ClassName()="TMDICHILD" .or. oWnd:ClassName()="TMDIFRAME"
      aRect := GetCoors( oWnd:hWnd )
      nRight:=nRight+aRect[2]
   ENDIF
   oWnd:=oWnd:oWnd

ENDDO

nRight:=nRight+objeto:nLeft+objeto:nWidth+13

return(nRight)
 
Saludos
LEANDRO AREVALO
Bogotá (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Embarcadero C++ 7.60 for Win32 ] [ FiveWin 23.07 ] [ xHarbour 1.3.0 Intl. (SimpLex) (Build 20230914) ]
User avatar
leandro
 
Posts: 1676
Joined: Wed Oct 26, 2005 2:49 pm
Location: Colombia

Re: Saber si punto de dialogo esta fuera de la pantalla

Postby JESUS MARIN » Fri Jan 31, 2020 4:55 pm

Leandro.

¿te refieres a que en vez de un MDICHILD es un DIALOG ?

SI es así, te intento montar un ejemplo.
Jesús Marín
JESUS MARIN
 
Posts: 176
Joined: Wed Jan 02, 2019 8:36 am

Re: Saber si punto de dialogo esta fuera de la pantalla

Postby JESUS MARIN » Fri Jan 31, 2020 5:22 pm

Leandro. Aquí tienes un ejemplo en un TDIALOG

Como te explicaba en el código anterior, debes implementarlo para todos los casos posibles (yo desconozco sobre que objetos quieres posicionar tu objeto de referencia)

Para calcular la posición vertical/horizontal absoluta, debes incluir los distintos tipos de clases en los que se va a anidar.
Prueba este ejemplo en un Dialogo. (tal vez falta ajustar algún pixel, porque como te decía en mi versión los diálogos no se calculan igual que las ventanas)

Code: Select all  Expand view  RUN

STATIC FUNCTION PRUEBA_DIALOGO()

LOCAL oWnd
LOCAL oMenu
LOCAL N:=1

    MENU oMenu
        MENUITEM "&Sistema"
            MENU
               MENUITEM "&Especificar impresora" ACTION PrinterSetup()
               SEPARATOR
               MENUITEM "&Salir"  ACTION oWnd:End()
            ENDMENU

      ENDMENU

DEFINE WINDOW oWnd MDI FROM 100,100 TO 600,1200 PIXEL  TITLE "TEST POSICION DIALOGO" COLOR CLR_BLACK, CLR_GRAY MENU oMenu


ACTIVATE WINDOW oWnd MAXIMIZED ON INIT CreaChild(oWnd)

RETURN(NIL)

static function CreaChild(oWnd)

local oWndChild
LOCAL oBtn

DEFINE DIALOG oWndChild TITLE "Dialogo" FROM 200,500 TO 600,1000 PIXEL OF oWnd

    @25,10 BUTTON oBtn PROMPT "CREA" SIZE 100,20 OF oWndChild PIXEL ACTION Prueba2(oBtn)

ACTIVATE DIALOG oWndChild

RETURN(NIL)


///////////////////////////////////////////////////////////////////////////////
static function prueba2(oBtn)

local odlg
LOCAL oWnd:=oBtn:oWnd
LOCAL nVerticalPos:=oBtn:nTop
LOCAL nAjustar:=CuantoAjustar(oWnd)
LOCAL nNTOP, nNLEFT, nNBOTTOM, nNRIGHT




nnTop:=nVerticalPos+nAjustar+30   // al crear el dialogo se me sube siempre 30, los añado
nnLeft:=GetRight(oBtn)
nnBottom:=nVerticalPos+nAjustar+30+100       //100 es el tamaño del dialogo, pon tu el tuyo
nnRight:=nnLeft+100                         // 100 idem


DEFINE DIALOG oDlg FROM nnTop, nnLeft TO nnBottom, nnRight TITLE "oDLG POSICIONADO" PIXEL OF oWnd



IF oDlg:nBottom>GetSysMetrics(1)-40-30    // pongo 40 barra inferior de windows y 30 de ajuste manual
   ACTIVATE DIALOG oDlg CENTER            // aqui puedes utilizar aPos := GetCoors( FindWindow( "Shell_TrayWnd", "" ) )
ELSE                                      // para saber donde esta la barra de windows
   ACTIVATE DIALOG oDlg
ENDIF


return(nil)


///////////////////////////////////////////////////////////////////////////////
STATIC FUNCTION CuantoAjustar(oWnd)

local nAjuste:=0
local oDlg
local n:=1
local nLocalAjuste:=0
local aRect



DO WHILE .T.
   IF oWnd:ClassName()="TMDIFRAME"
      EXIT
   ENDIF

   // aqui tienes que desarrollar mas posibles casos TDIALOG, ETC...
   // Yo he hecho el TGROUP y el TMDICHILD
   IF oWnd:ClassName()="TGROUP"
      nAjuste:=nAjuste+oWnd:nTop
   ENDIF
   IF oWnd:ClassName()="TDIALOG"
      aRect := GetCoors( oWnd:hWnd )
      nAjuste:=nAjuste+aRect[1] +43   // 43 DEL FRAME DEL DIALOGO, también en MDICHILD pero lo calculo con el falso dialogo (que también me da 43)
   ENDIF
   IF oWnd:ClassName()="TMDICHILD"
      nLocalAjuste:=0
      DEFINE DIALOG oDlg FROM 100,100 TO 200,200 TITLE "Cuanto tengo que ajustar"  PIXEL  OF OWND
      ACTIVATE DIALOG oDlg ON INIT (nLocalAjuste:=100-oDlg:nTop, oDlg:End() )
      nAjuste:=nAjuste+nLocalAjuste
      aRect := GetCoors( oWnd:hWnd )   // esto me dice donde esta ahora la ventana
      nAjuste:=nAjuste+aRect[1]
   ENDIF
   oWnd:=oWnd:oWnd

ENDDO

RETURN(nAjuste)



////////////////////////////////////////////////////////////////////////////
STATIC FUNCTION GetRight(objeto)    // Devuelve el punto derecha absoluto del objeto pasado, en este caso un boton, prueba con un get

LOCAL oWnd:=objeto:oWnd
LOCAL nRight:=0
LOCAL aRect

DO WHILE .T.
   IF oWnd:ClassName()="NIL"
      EXIT
   ENDIF

   // aqui tienes que desarrollar mas posibles casos TDIALOG, ETC...
   // Yo he hecho el TGROUP, TMDICHILD Y TMDIFRAME  (ahora el TDIALOG)

   IF oWnd:ClassName()="TGROUP"
      nRight:=nRight+oWnd:nLeft
   ENDIF

   IF oWnd:ClassName()="TMDICHILD" .or. oWnd:ClassName()="TMDIFRAME" .OR. oWnd:ClassName()="TDIALOG"
      aRect := GetCoors( oWnd:hWnd )
      nRight:=nRight+aRect[2]
   ENDIF
   oWnd:=oWnd:oWnd

ENDDO

nRight:=nRight+objeto:nLeft+objeto:nWidth+13

return(nRight)






 
Jesús Marín
JESUS MARIN
 
Posts: 176
Joined: Wed Jan 02, 2019 8:36 am

Re: Saber si punto de dialogo esta fuera de la pantalla

Postby leandro » Fri Jan 31, 2020 9:24 pm

Bueno, encontre la solución de otra manera, gracias por todas las ideas que me brindaste Jesus, asi quedo mi código:

Code: Select all  Expand view  RUN

METHOD dibujaDialogo(oDlg,oGet) CLASS cBusc
Local vGbus := space(100)
local nTopR, nLeftR, nAltura
local aPoint,nWidth:=0
local oDlgBar

nTopR   := oGet:nTop      
nLeftR  := oGet:nLeft
nAltura := oGet:nHeight

aPoint := { nTopR+nAltura, nLeftR }
aPoint = ClientToScreen( oDlg:hWnd, aPoint ) //los puntos en x y en donde se dibujaría el dialogo referente a la pantalla
 
::variables()
::consulta()

Define Font oFont Name "Calibri" Size 0,-12 Bold
Define Font oFont1 Name "Calibri" Size 0,-13
DEFINE DIALOG oDlgBar RESOURCE "ORFACT3" OF oDlg

    REDEFINE GET oGbus VAR vGbus ID 4002 OF oDlgBar UPDATE VALID (::hacefiltro(cBrw,vGbus),.T.)

    cBrw := TXBrowse():New( oDlgBar )
    cBrw:nMarqueeStyle         := MARQSTYLE_HIGHLROW
    cBrw:nRowDividerStyle      := LINESTYLE_LIGHTGRAY
    cBrw:nColDividerStyle      := LINESTYLE_LIGHTGRAY
    cBrw:nHeaderLines          := 1
    cBrw:lColDividerComplete   := .t.
    cBrw:lRecordSelector       := .t.
    cBrw:nStretchCol           := STRETCHCOL_LAST
    cBrw:l2007                 := .f.
    cBrw:oFont                 := oFont1
    cBrw:bKeyDown              := {|nKey|iif(nKey == 13,oDlgBar:end(),)}
    cBrw:blDblClick            := {|| oDlgBar:end()}
   
    oCol          = cBrw:AddCol()
    oCol:bStrData = { || If( ::oRsBar:Eof, Space( nWidth ), ::oRsBar:Fields( ::hCampos["codigo"] ):Value ) }
    oCol:cHeader  = ::hCabecera["codigo"]
    oCol:nWidth   = 90
    oCol:nHeadStrAlign = AL_LEFT
    oCol:nDataStrAlign = AL_LEFT   
    oCol:oHeaderFont = oFont
    oCol:bLClickHeader := {|r,c,f,o| ::organiza(::hCampos["codigo"]) }

    oCol          = cBrw:AddCol()
    oCol:bStrData = { || If( ::oRsBar:Eof, Space( nWidth ), alltrim( ::oRsBar:Fields( ::hCampos["nombre"] ):Value ) ) }
    oCol:cHeader  = ::hCabecera["nombre"]
    oCol:nWidth   = 250
    oCol:nHeadStrAlign = AL_LEFT
    oCol:nDataStrAlign = AL_LEFT   
    oCol:oHeaderFont = oFont   
    oCol:bLClickHeader := {|r,c,f,o| ::organiza(::hCampos["nombre"]) }

    cBrw:SetADO( ::oRsBar )
    cBrw:CreateFromResource( 102 )

    oDlgBar:cTitle := "Buscar Artículo"
    oDlgBar:bPostEnd := { || ::oRsBar:Close() }
    oDlgBar:nOpacity    := 240
   
    oDlgBar:bStart := { || SetCapture( oDlgBar:hWnd ),;
                        nDstx := aPoint[ 2 ] +  oDlgBar:nWidth,; //Calculamos la Distancia en X
                        nDsty := aPoint[ 1 ] +  oDlgBar:nHeight,; //Calculamos la Distancia en y
                        if( nDstx>GetSysMetrics(0) .OR. nDsty>GetSysMetrics(1),,; // La comparamos contra la medida de la pantalla
                        oDlgBar:SetPos( aPoint[ 1 ], aPoint[ 2 ] ) ) } // Si cabe la posiciona en coordenadas, si no simplemente se abre

ACTIVATE DIALOG oDlgBar
::retorna()
return nil
 
Saludos
LEANDRO AREVALO
Bogotá (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Embarcadero C++ 7.60 for Win32 ] [ FiveWin 23.07 ] [ xHarbour 1.3.0 Intl. (SimpLex) (Build 20230914) ]
User avatar
leandro
 
Posts: 1676
Joined: Wed Oct 26, 2005 2:49 pm
Location: Colombia

Previous

Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 43 guests