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:

Saber si punto de dialogo esta fuera de pantalla SOLUCIONADO

Post by leandro »

Buenos días para todos,

En esta ocasión me surge la necesidad de saber, si el ultimo punto (parte inferior derecha) de un dialogo se encuentra fuera de pantalla. Como se muestra en la imagen.

Image

De antemano gracias,


LEANDRO AREVALO
Last edited by leandro on Fri Jan 31, 2020 9:26 pm, edited 1 time in total.
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 »

Interesante pregunta.

pero,.... dentro de su dialogo ? dentro de la ventana que contiene el dialogo ? dentro de la ventana principal ( si la anterior es MDICHILD) ?
Marcelo Via Giglio
Posts: 1033
Joined: Fri Oct 07, 2005 3:33 pm
Location: Cochabamba - Bolivia

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

Post by Marcelo Via Giglio »

Leandro,

los objetos de FW , tienen propiedades como nTop, nLeft, nBottom, nRight y otros metodos como GetCliRect() con los que puedes conseguir, la ubicación del objeto y su tamaño, en base a esa información podrías deducir lo que necesitas en función de la resolucion de la pantalla o el criterio de consulta que deseas

saludos

Marcelo
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 »

Jesus y Marcelo, gracias por responder, una imagen dice mas que mil palabras.

Image

La idea es que si el punto mencionado se encuentra fuera de la pantalla, el dialogo aparezca centrado.

Como dice Marcelo, con estas instrucciones se puede identificar la posición del dialogo, pero como se si están fuera o dentro de la pantalla.

Code: Select all

nTopR     := oDlg:nTop       
nLeftR    := oDlg:nLeft
nAltura   := oDlg:nHeight
 
De antemano gracias.
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 »

Una pregunta Leandro.
La ventana a desplegar (aquella que quieres saber si se queda fuera de pantalla), de qué tipo es ?

Lo pregunto porque, dependiendo del tipo de ventana o dialogo, se quedara dentro de su dialogo o ventana contenedor. ¿no?

Se puede calcular, casi lo he conseguido, la posición relativa dentro de la aplicación :

GetSysMetrics(1) devuelve la resolución vertical del monitor

Sabiendo la posición donde se encuentra el dialogo, su MDICHILD contenedor y luego su MDIFRAME, se puede calcular si cabe o no.

Solo me falla una cosa. Saber donde se está ejecutando la aplicación. Si el MDIFRAME esta maximizado es fácil, pero cuando no lo esta, el ::nTop devuelve 0 (cero), con lo que el calcula relativo a la resolución vertical no vale. Para el resto de casos si.


Por ejemplo. Quiero desplegar un xBrowse dentro de un dialogo (oDlg), que está dentro de una ventana (oMDI), que esta dentro de una ventana principal (oWnd)

GetSysMetrics(1), devuelve una resolución vertical de 768 puntos
oWnd, que es la ventana principal de la aplicación (TMDIFRAME), está en ::nTop -8 y ::nBottom +736
oMdi, ventana hija, esta en ::nTop 100 y ::nBottom 600

Por tanto, si quiere colocar otra ventana o dialogo (oNuevoObjeto) en la posición vertical 300 del oMdi, estaré en 100+300 (oMdi:nTop+oNuevoObjeto:nTop)
Si hay mas ventanas contenedoras, puedes anidar el cálculo de la posición relativa, hasta que llegas al TMDIFRAME

El resultado que obtienes, sería la posición ::nTop relativa del nuevo objeto (oNuevoObjeto)

Si este resultado + la altura del objeto (oNuevoObjeto:nHeight) es mayor que GetSysMetrics(1), entonces se queda fuera de la pantalla.
Esto funciona si el TMDIFRAME está maximizado.

Tal vez alguno de los SABIOS podría decirnos como saber la posición relativa dentro del monitor de la ventana principal y de esa manera calcularlo para todos _

Nota : Luego _ el punto de la derecha con los mismos cálculos pero utilizando GetSysMetrics(0) para la resolución horizontal de la pantalla y ::nLeft, ::nRight de las ventanas o diálogos.

Nota 2 : Igual me he explicado fatal. :)
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 »

Gracias Jesús por responder:
Nota 2 : Igual me he explicado fatal. :)
Algo entendí jejejejeje

Es un dialogo, el que deseo saber si esta por fuera de las coordenadas de la pantalla. Me surge una pregunta, en donde se consigue documentación sobre las funciones GetSysMetrics y las relacionadas a estos, la verdad es que la mayoría de información la he sacado del foro pero aun es un poco confuso para mi el manejo de las mismas.

De antemano gracias
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 »

en donde se consigue documentación sobre las funciones GetSysMetrics y las relacionadas a estos ???

Ni idea.... yo las saco de leer en el foro, a veces leyendo las clases ….

¿ puedes ponerme el código de cómo creas ese diálogo ?

el DEFINE y el ACTIVATE

A ver si te puedo montar un ejemplo.
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 »

Claro que si aquí el código:

Saludos

Code: Select all

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

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

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

::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 ) }

ACTIVATE DIALOG oDlgBar ON INIT (oDlgBar:SetPos( aPoint[ 1 ], aPoint[ 2 ] ) )
::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 ]
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 »

Buenas tardes Leandro.

Creo que será mas fácil.

¿Dónde estas definiendo el tamaño del DIALOGO ?

Supongo que desde recursos, no ?
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 »

Si señor, efectivamente desde recursos. :D
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, prueba este código por si van por ahí los tiros

Code: Select all

STATIC FUNCTION PRUEBA_DIALOGO()

LOCAL oWnd

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

@100,100 BUTTON "CREA UN DIALOGO EN 100" SIZE 200,20 OF oWnd PIXEL ACTION Prueba2(oWnd,100)   // de tamaño 500,500
@300,100 BUTTON "CREA UN DIALOGO EN 300" SIZE 200,20 OF oWnd PIXEL ACTION Prueba2(oWnd,300)   // de tamaño 500,500
@500,100 BUTTON "CREA UN DIALOGO EN 500" SIZE 200,20 OF oWnd PIXEL ACTION Prueba2(oWnd,500)   // de tamaño 500,500


ACTIVATE WINDOW oWnd MAXIMIZED

RETURN(NIL)

static function prueba2(oWnd,nVerticalPos)

local odlg

DEFINE DIALOG oDlg FROM nVerticalPos,305 TO 500,nVerticalPos+500 TITLE "Posicion oDlg"  PIXEL  OF OWND
oDlg:nTop:=nVerticalPos      
oDlg:nLeft:=305
oDlg:nBottom:=nVerticalPos+500
oDlg:nRight:=305+500

@10,10 BUTTON "DIME" OF oDlg size 100,20 PIXEL ACTION msgalert(str(oDlg:nTop)+"-"+str(oDlg:nBottom))


IF MeCabe(oDlg)
   ACTIVATE DIALOG oDlg
ELSE
   ACTIVATE DIALOG oDlg CENTER
ENDIF
return(nil)

STATIC FUNCTION MeCabe(oDlg)

IF oDlg:nBottom>GetSysMetrics(1)
   msgalert("el dialogo no cabe de alto")
   RETURN(.F.)
ENDIF
RETURN(.T.)

// Para comprobar el ancho usa GetSysMetrics(0)
// Debes tener en cuenta que el valor de oDlg:nTop cambia segun su ventana contenedora, si tiene menu, etc...
// Para rizar el rizo, en vez de centrar el dialogo, pues calcular cuanto espacio libre te queda y dimensionar el dialogo
// Tambien puedes hacer que en vez de mostrarse hacia abajo y hacia la derecha, se muestre hacia arriba y/o hacia la izquierda


 
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. Con esta otra versión se calcula la posición correcta del ::nTop del dialogo contando el marco de la ventana, menú..... (me falta probar con barra de botones, etc...) pero creo que lo calculará bien.

Además he calculado un pequeño diferencial de ajuste por abajo y el tamaño de la barra inferior de Windows. GetSysMetrics devuelve el total de la resolución pero no descuenta la barra. Esta barra se puede cambiar de lugar y al hacerlo el dialogo se reposiciona (es curioso).

Pruébalo y me vas contando.

Code: Select all

STATIC FUNCTION PRUEBA_DIALOGO()

LOCAL oWnd
LOCAL oMenu

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

      ENDMENU

DEFINE WINDOW oWnd FROM 100,100 TO 600,1200 PIXEL  TITLE "POSICION DIALOGO - MAXIMA ALTURA "+STR(GetSysMetrics(1)) COLOR CLR_BLACK, CLR_GRAY //MENU oMenu

@100,100 BUTTON "CREA UN DIALOGO EN 100" SIZE 200,20 OF oWnd PIXEL ACTION Prueba2(oWnd,100)   // de tamaño 500,500
@200,100 BUTTON "CREA UN DIALOGO EN 200" SIZE 200,20 OF oWnd PIXEL ACTION Prueba2(oWnd,200)   // de tamaño 500,500
@500,100 BUTTON "CREA UN DIALOGO EN 500" SIZE 200,20 OF oWnd PIXEL ACTION Prueba2(oWnd,500)   // de tamaño 500,500


ACTIVATE WINDOW oWnd MAXIMIZED

RETURN(NIL)

static function prueba2(oWnd,nVerticalPos)

local odlg
LOCAL nAjustar:=CuantoAjustar(oWnd)


DEFINE DIALOG oDlg FROM nVerticalPos+nAjustar,305 TO nVerticalPos+nAjustar+500,305+500 TITLE "Posicion oDlg"  PIXEL  OF OWND
oDlg:nTop:=nVerticalPos+nAjustar     
oDlg:nLeft:=305
msgalert("nTop vale "+str(oDlg:nTop))
oDlg:nBottom:=nVerticalPos+500-8   //-8 que crea el dialogo
oDlg:nRight:=305+500

@10,10 BUTTON "DIME" OF oDlg size 100,20 PIXEL ACTION msgalert(str(oDlg:nTop)+"-"+str(oDlg:nBottom))


IF MeCabe(oDlg)
   ACTIVATE DIALOG oDlg
ELSE
   ACTIVATE DIALOG oDlg CENTER
ENDIF
return(nil)

STATIC FUNCTION MeCabe(oDlg)

IF oDlg:nBottom>GetSysMetrics(1)-25-50    // pongo 25 de margen y 50 barra inferior de windows
*   msgalert("el dialogo no cabe de alto")
   RETURN(.F.)
ENDIF
RETURN(.T.)

// Para comprobar el ancho usa GetSysMetrics(0)
// Debes tener en cuenta que el valor de oDlg:nTop cambia segun su ventana contenedora, si tiene menu, etc...
// Para rizar el rizo, en vez de centrar el dialogo, pues calcular cuanto espacio libre te queda y dimensionar el dialogo
// Tambien puedes hacer que en vez de mostrarse hacia abajo y hacia la derecha, se muestre hacia arriba y/o hacia la izquierda


STATIC FUNCTION CuantoAjustar(oWnd)

local nAjuste:=0
local oDlg

DEFINE DIALOG oDlg FROM 100,100 TO 200,200 TITLE "Cuanto tengo que ajustar"  PIXEL  OF OWND


ACTIVATE DIALOG oDlg ON INIT (nAjuste:=100-oDlg:nTop, oDlg:End() )

return(nAjuste)

 
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 »

Jesus buenas noches, gracias por responder

probé tu código, pero abra el dialogo donde lo abra, siempre me devuelve los mismos valores

Code: Select all

msginfo(oDlg:nBottom) // Retorna 151
msginfo(GetSysMetrics(1)) // Retorna 768
 

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 )

::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 ) }

IF MeCabe(oDlgBar)
    ACTIVATE DIALOG oDlgBar ON INIT (oDlgBar:SetPos( aPoint[ 1 ], aPoint[ 2 ] ) )
ELSE
    ACTIVATE DIALOG oDlgBar CENTER
ENDIF
::retorna()
return nil

FUNCTION MeCabe(oDlg)
msginfo(oDlg:nBottom)
msginfo(GetSysMetrics(1))
IF oDlg:nBottom>GetSysMetrics(1)
   msgalert("el dialogo no cabe de alto")
   RETURN(.F.)
ENDIF
RETURN(.T.)
 
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 »

Buenos días Leandro.

A mi si me abre el dialogo en la posición vertical que le indico :

ACTION Prueba2(oWnd,100)

En este caso en la posición vertical 100

Sigo avanzando. Ahora ya puedo determinar donde esta y cuanto mide la barra de tareas de Windows

aPos := GetCoors( FindWindow( "Shell_TrayWnd", "" ) )

Una pregunta Leandro, lo que tu necesitas realmente es posicionar el dialogo a la derecha y abajo ( si cabe ), de otro objeto. En este caso un GET.
¿Es así?
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 »

Buenas tardes Leandro.

Me está volviendo loco la posición absoluta del dialogo. Pero yo creo que ya está muy conseguido. Mira el código, pruébalo.... mira la imagen que te adjunto.
A mi me funciona perfecto a la hora de calcular la posición vertical. (falta desarrollar la posición horizontal, pero es lo mismo con el resto de parámetros)

Esto funciona perfectamente.
Como desconozco que objeto va a contener tu objeto get (el de referencia para desplegar el dialogo), he hechos las pruebas con un botón en vez de un get, dentro de un TGROUP, dentro de una MDICHILD, dentro de una MDIFRAME, para obtener sus posiciones relativas y calcular la posición absoluta.

Mueve las ventanas, maximizalas, etc... veras que siempre se muestra bien.

Luego al compararlo con la resolución de la pantalla, sabemos si el dialogo será visible o no.

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 oGroup
LOCAL oBtn
DEFINE WINDOW oWndChild MDICHILD OF oWnd FROM 200,500 TO 600,1000 PIXEL  TITLE "oWndChild" COLOR CLR_BLACK, CLR_WHITE

@10,10 GROUP oGroup TO 110,200 PROMPT "GRUPO" OF oWndChild PIXEL


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

ACTIVATE WINDOW 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

// Recuerda que puedes rizar el rizo. 
// En vez de centrar el dialogo, puedes pensar (si no te cabe por abajo), ponerlo hacia arriba.
// Si tampoco te cabe hacia arriba, centrarlo verticalmente.
// Lo mismo a derecha e izquierda.
// Y si no cabe en ninguna de las 4 posiciones, entonces lo centras.


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()="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

   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)




 
La imagen de como lo veo yo.

Image

nota: Ten en cuenta que yo utilizo la versión DEMO 6.12
En esta versión, si no me equivoco, las coordenadas para los diálogos son distintas que las versiones mas recientes. Creo que se utiliza la clausula TRUEPIXEL. Si la estás utilizando deberás adaptarlo.
Post Reply