Saber si punto de dialogo esta fuera de pantalla SOLUCIONADO

User avatar
leandro
Posts: 958
Joined: Wed Oct 26, 2005 2:49 pm
Location: Colombia
Contact:

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

Post by leandro »

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

#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 ALFONSO
SISTEMAS LYMA - BASE
Bogotá (Colombia)
[ FWH 19.09 ] [ xHarbour 1.2.3 Intl. (SimpLex) (Build 20190613) ] [ Embarcadero C++ 7.30 for Win32 ]
JESUS MARIN
Posts: 91
Joined: Wed Jan 02, 2019 8:36 am

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

Post by JESUS MARIN »

Leandro.

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

SI es así, te intento montar un ejemplo.
JESUS MARIN
Posts: 91
Joined: Wed Jan 02, 2019 8:36 am

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

Post by JESUS MARIN »

Leandro. Aquí tienes un ejemplo en un TDIALOG

Como te explicaba en el código anterior, debes implementarlo para todos _ 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

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)






 
User avatar
leandro
Posts: 958
Joined: Wed Oct 26, 2005 2:49 pm
Location: Colombia
Contact:

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

Post by leandro »

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

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 ALFONSO
SISTEMAS LYMA - BASE
Bogotá (Colombia)
[ FWH 19.09 ] [ xHarbour 1.2.3 Intl. (SimpLex) (Build 20190613) ] [ Embarcadero C++ 7.30 for Win32 ]
Post Reply