PARA ANTONIO Y LOS MASTER SOBRE POSICIONES::

PARA ANTONIO Y LOS MASTER SOBRE POSICIONES::

Postby mantonio_08 » Mon Aug 17, 2009 9:45 pm

como se podria obtener la posicion dnd se crea un popup o en su defecto el tamaño del mismo, ancho y alto

no doy con el asunto::

me refiero a su posicion en pixeles dentro de la pantalla.. no dentro del objeto q lo contiene...

GRACIAS
mantonio_08
 
Posts: 330
Joined: Fri May 25, 2007 9:06 pm

Re: PARA ANTONIO Y LOS MASTER SOBRE POSICIONES::

Postby Daniel Garcia-Gil » Tue Aug 18, 2009 12:25 pm

Hola mantonio_08

El asunto es un poco enredado pero creo que de facil solucion...
Cuando se crea un popmenu este es creado "vacio" en la esquina superior izquierda del contenedor, despues la funcion TrackPopup se encargara de ubicarlo segun las coordenadas dadas en el ACTIVATE AT
La parte sencilla es tener la ubicacion de la fila y columna del comando ACTIVATE AT, estas se convierten a coordenadas de pantalla y esta resuelto ese problema (ClientToScreen), pero.... la bendicion de los "peros", el popmenu ajusta su posicion si sobrepasa los limites de la pantalla (derecha o inferior), ahora como saber donde lo ubica? hay que calcularlo (o hacer la intencion de hacerlo), pienso que la forma es saber cuanto se ha fugado de la pantalla y hacer los calculos respectivos (lo veremos en el ejemplo adjunto).
La otra parte algo mas complicado, si no tienes las funciones, el determinar el ancho y alto del Popup, hay una funcion del API (creo que no esta en FWH) que nos devuelve el rectangulo de los items de un menu (GetMenuItemRect ), en el ejemplo ya esta la funcion incluida, ahora buscamos el 1er y ultimo elemento para obtener posicion superior izquierda ( 1er elemento ) e inferior derecha (ultimo elemento) y ya podremos calcular el ancho y el alto.
Para mejor te dejo el codigo y el EXE para que lo descargues, como lo has solicitado y es posible "jugar" con esos datos, estan convertidos a coordenadas de pantalla
nota: los elementos de un menu para el API comeinzan en 0 (cero)

La primera opcion del menu muestra la informacion

http://www.sitasoft.com/fivewin/test/infopop.zip

Code: Select all  Expand view
// Testing Popup Menus in FiveWin

#include "FiveWin.ch"

static oWnd, oMenu, nRowPop, nColPop

//----------------------------------------------------------------------------//

function Main()

 DEFINE WINDOW oWnd ;
    FROM 1, 1 TO 20, 65 ;
    TITLE "FiveWin - Testing Popup Menus"

 SET MESSAGE OF oWnd TO "Press Mouse Left Button to activate the Popup"

 ACTIVATE WINDOW oWnd ;
    ON CLICK ShowPopUp( nRow, nCol )

return nil

function Otra()

 DEFINE WINDOW oWnd ;
    FROM 1, 1 TO 20, 65 ;
    TITLE "FiveWin - Testing Popup Menus"

 SET MESSAGE OF oWnd TO "Press Mouse Left Button to activate the Popup"

 ACTIVATE WINDOW oWnd ;
    ON CLICK ShowPopUp( nRow, nCol )

return nil


//----------------------------------------------------------------------------//

function BuildPopup()

   local oMenu

   MENU oMenu POPUP                             // Creating a POPUP
      MENUITEM "Open" ACTION ShowInfo()
      MENUITEM "Close"
      MENUITEM "Select"  ACTION Otra()
      MENUITEM "All"
      SEPARATOR
      MENUITEM "More..."
   ENDMENU

return oMenu

//----------------------------------------------------------------------------//

function ShowPopup( nRow, nCol )

   oMenu := BuildPopup()
   
   nRowPop = nRow
   nColPop = nCol

   ACTIVATE POPUP oMenu WINDOW oWnd AT nRow, nCol

return nil

//----------------------------------------------------------------------------//

function ShowInfo( )
   local aRectFirst
   local aRectLast
   local nLast
   local aRect
   local aCoor, aClientCoor
   local nWidth, nHeight
   local nTopPos, nLeftPos
   local nOffSet
   local hWndTaskBar
   local lTaskBarVisible
   local nXScreen, nYScreen

   hWndTaskBar = FindWindow("Shell_TrayWnd", 0)  // Barra de tareas

   nLast = GetMItemCount( oMenu:hMenu )  // Ultimo Elemento
   
   aRect := GetWndRect( oWnd:hWnd ) // Coord de pantalla del contenedor
   aCoor := ClientToScreen( oWnd:hWnd, { nRowPop, nColPop } ) //Coord de pantalla de AT row, col
   
   aRectFirst = GetMenuItemRect( oWnd:hWnd, oMenu:hMenu, 0 )         // RECT 1er Elemento
   aRectLast  = GetMenuItemRect( oWnd:hWnd, oMenu:hMenu, nLast - 1 ) // RECT Ultimo Elemento

   nXScreen = GetSysMetrics( 0 ) // Res. Horizontal
   nYScreen = GetSysMetrics( 1 ) // Res. Vertical

   IF hWndTaskBar != 0
      lTaskBarVisible = WndTop( hWndTaskBar ) <= nYScreen - WndHeight( hWndTaskBar )
   ELSE
      lTaskBarVisible = .F.
   ENDIF  

   nWidth  = aRectLast[ 4 ] - aRectFirst[ 2 ] // Ancho
   nHeight = aRectLast[ 3 ] - aRectFirst[ 1 ] // Alto
   

   // Calculamos posision horizontal
   IF aCoor[ 2 ] + nWidth > nXScreen
      nOffSet = aCoor[ 2 ] + nWidth - nXScreen
      nLeftPos = aCoor[ 2 ] - nOffSet
   ELSE
      nLeftPos = aCoor[ 2 ]
   ENDIF
   
   // Calculamos posision vertical dependiendo se existe la barra de tarreas
   IF lTaskBarVisible
      IF aCoor[ 1 ] + nHeight > WndTop( hWndTaskBar )
         nTopPos = aCoor[ 1 ] - nHeight - GetSysMetrics( 32 ) // Ancho del borde horizontal
      ELSE
         nTopPos = aCoor[ 1 ] - GetSysMetrics( 32 )
      ENDIF
   ELSE
      IF aCoor[ 1 ] + nHeight > nYScreen
         nTopPos = aCoor[ 1 ] - nHeight - GetSysMetrics( 32 )
      ELSE
         nTopPos = aCoor[ 1 ] - GetSysMetrics( 32 )
      ENDIF
   ENDIF
   
   aClientCoor = ScreenToClient( oWnd:hWnd, { nTopPos, nLeftPos } )

   ? "COORDENADAS DE PANTALLA",;
     "TOP"    + Chr( 9 ) + ":" + Chr( 9 ) + Str( nTopPos ),  ;
     "LEFT"   + Chr( 9 ) + ":" + Chr( 9 ) + Str( nLeftPos ), ;
     "WIDTH"  + Chr( 9 ) + ":" + Chr( 9 ) + Str( nWidth ),   ;
     "HEIGHT" + Chr( 9 ) + ":" + Chr( 9 ) + Str( nHeight )

 
   ? "COORDENADAS DE CLIENTE",;
     "TOP"    + Chr( 9 ) + ":" + Chr( 9 ) + Str( aClientCoor[ 1 ] ),  ;
     "LEFT"   + Chr( 9 ) + ":" + Chr( 9 ) + Str( aClientCoor[ 2 ] )

//   oWnd:Say( aClientCoor[ 1 ], aClientCoor[ 2 ], ".............................", , , , .T. )
   
   
return nil



//**********************************************************************//
#pragma BEGINDUMP
#include <windows.h>
#include <hbapi.h>


//-----------------------------------------------------//

HB_FUNC( GETMENUITEMRECT ) // hWnd, hMenu, nItem --> { nTop, nLeft, nBottom, nRight }
{
   RECT rct;
   HWND hWnd   = ( HWND ) hb_parnl( 1 );
   HMENU hMenu = ( HMENU ) hb_parnl( 2 );
   UINT uItem  = hb_parni( 3 );
   
   GetMenuItemRect( hWnd, hMenu, uItem, &rct );

   hb_reta( 4 );
     
   hb_storni( rct.top,    -1, 1 );
   hb_storni( rct.left,   -1, 2 );
   hb_storni( rct.bottom, -1, 3 );
   hb_storni( rct.right,  -1, 4 );
   
}    


#pragma ENDDUMP
 
User avatar
Daniel Garcia-Gil
 
Posts: 2365
Joined: Wed Nov 02, 2005 11:46 pm
Location: Isla de Margarita


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 80 guests