CtrlDrawFocus

CtrlDrawFocus

Postby César E. Lozada » Thu Feb 12, 2009 2:30 am

Hola, Antonio.

Intentando hacer funcionar un módulo para diseñar tarjetas de ID en PVC, incrusto controles con estilo DESIGN sobre una imagen.
El problema es que la función CtrlDrawFocus() (con FWH 8.07) no obtiene bien las coordenadas de los controles cuando éstos están sobre otro control y el cuadro de dragado queda bastante alejado de la verdadera posición del control al hacer el ::Capture().

Leí que este bug fue reparado para la última versión 9.01.

¿Es posible saber en qué consiste la solución de este bug?

Gracias mil de antemano.

Cësar Lozada
User avatar
César E. Lozada
 
Posts: 128
Joined: Wed Oct 26, 2005 12:18 pm
Location: Los Teques, Miranda, Venezuela

Re: CtrlDrawFocus

Postby Antonio Linares » Thu Feb 12, 2009 12:00 pm

César,

Este es el código corregido de CtrlDrawFocus(). Por favor pruébalo y coméntanos que tal te funciona, gracias :-)
Code: Select all  Expand view
HB_FUNC( CTRLDRAWFOCUS )  // ( hWnd, nOriginRow, nOriginCol, nMRow, nMCol, nMResize )
{
   HWND hWnd = ( HWND ) hb_parnl( 1 );
   int wRow  = hb_parnl( 2 );
   int wCol  = hb_parnl( 3 );
   int wMRow = hb_parnl( 4 );
   int wMCol = hb_parnl( 5 );
   WORD wMResize = hb_parnl( 6 );
   HWND hWndParent = GetParent( hWnd );
   HDC hDC;
   RECT rct;
   POINT pt;
   HRGN hReg;
   HBRUSH hBr = CreateSolidBrush( RGB( 127, 127, 127 ) );
   int iRop;
   int iParentsWithCaption = 0;

   if( ( GetWindowLong( hWndParent, GWL_STYLE ) & WS_CAPTION ) == WS_CAPTION )
      iParentsWithCaption++;

   while( GetParent( hWndParent ) )
   {
      hWndParent = GetParent( hWndParent );
     
      if( ( GetWindowLong( hWndParent, GWL_STYLE ) & WS_CAPTION ) == WS_CAPTION )
         iParentsWithCaption++;
   }   

   GetWindowRect( hWnd, &rct );

   if( ! wMResize || ( ! wRow && ! wCol ) )
   {
      rct.bottom += wRow;
      rct.right  += wCol;
      rct.top    += wRow;
      rct.left   += wCol;
   }
   else
   {
      pt.x = wMCol;
      pt.y = wMRow;
      ClientToScreen( hWnd, &pt );
      wMRow = pt.y;
      wMCol = pt.x;

      switch( wMResize )
      {
         case RES_NW:
              rct.top  = wMRow;
              rct.left = wMCol;
              break;

         case RES_N:
              rct.top = wMRow;
              break;

         case RES_NE:
              rct.top   = wMRow;
              rct.right = wMCol;
              break;

         case RES_E:
              rct.right = wMCol;
              break;

         case RES_SE:
              rct.bottom = wMRow;
              rct.right  = wMCol;
              break;

         case RES_S:
              rct.bottom = wMRow;
              break;

         case RES_SW:
              rct.bottom = wMRow;
              rct.left   = wMCol;
              break;

         case RES_W:
              rct.left = wMCol;
              break;
      }
   }

   pt.x = rct.left;
   pt.y = rct.top;
   ScreenToClient( hWndParent, &pt );
   rct.left = pt.x + ( iParentsWithCaption * GetSystemMetrics( SM_CXSIZEFRAME ) ) - ( ( iParentsWithCaption > 1 ) ? 5 : 0 );
   rct.top  = pt.y + ( iParentsWithCaption * ( GetSystemMetrics( SM_CYCAPTION   ) + GetSystemMetrics( SM_CYSIZEFRAME ) ) ) - ( ( iParentsWithCaption > 1 ) ? 7 : 0 );
   
   pt.x     = rct.right;
   pt.y     = rct.bottom;
   ScreenToClient( hWndParent, &pt );
   rct.right  = pt.x + 8 - ( ( iParentsWithCaption > 1 ) ? 1 : 0 );
   rct.bottom = pt.y + ( iParentsWithCaption * GetSystemMetrics( SM_CYCAPTION ) ) + 8 - ( ( iParentsWithCaption > 0 ) ? iParentsWithCaption : 0 );

   hReg = CreateRectRgn( rct.left - 2, rct.top - 2, rct.right + 2, rct.bottom + 2 );
   hDC = GetWindowDC( hWndParent );
   iRop = SetROP2( hDC, R2_XORPEN );
   FrameRgn( hDC, hReg, hBr, 2, 2 );
   SetROP2( hDC, iRop );
   ReleaseDC( hWndParent, hDC );
   DeleteObject( hReg );
   DeleteObject( hBr );
}
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41324
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: CtrlDrawFocus

Postby César E. Lozada » Thu Feb 12, 2009 2:41 pm

Gracias, Antonio. Siempre tan gentil.

Me temo que el borde de los controles de otro control sigue siendo dibujado (en modo DESIGN) de manera que no coincide con su posición verdadera. Ya comprobé que en dialogos funciona como se espera.

Te anexo un pequeño ejemplo para que lo compruebes.

Además, hay otros pequeños detalles:
1) Si se borra un objeto, no desaparecen los checkdots que lo delimitan
2) El dragado permite llevar el objeto fuera de los límites de su ventana, de manera que si lo soltamos fuera de su contenedor, ya no es visible y no puede seleccionarse de nuevo.

De nuevo te agradezco cualquier ayuda que tu tiempo libre te permita obsequiarme.

Afectuosos saludos.



//===============================================
#include "Fivewin.ch"
FUNCTION MAIN

Local oDlg, oBmp, oMenu

MENU oMenu
MENUITEM "Agregar control"
MENU
MENUITEM "Texto" ACTION AddSay(oBmp)
ENDMENU
ENDMENU
DEFINE DIALOG oDlg FROM 0,0 TO 250,322 PIXEL TITLE "Prueba CTRLDRAWFOCUS"

@ 0,0 BITMAP oBmp OF oDlg SIZE 320,200 PIXEL FILE "C:\FWH807\Bitmaps\agua2.bmp"

ACTIVATE DIALOG oDlg CENTERED ON INIT oDlg:SetMenu(oMenu)
return nil
//===============================================
Function AddSay(oBmp)
Local oSay, o
Local nText:=1, cText
//---------Busco un nombre disponible para el objeto
DO WHILE aScan(oBmp:aControls,{|o| o:ClassName()="TSAY" .and. o:Cargo=="Texto "+Str(nText,,,.t.)})>0
nText++
ENDDO
cText:="Texto "+Str(nText,,,.t.)
//---------
@ 10,10 SAY oSay PROMPT cText OF oBmp SIZE 120,20 PIXEL DESIGN
oSay:Cargo:=cText
oBmp:Refresh()
return nil
//===============================================
User avatar
César E. Lozada
 
Posts: 128
Joined: Wed Oct 26, 2005 12:18 pm
Location: Los Teques, Miranda, Venezuela

Re: CtrlDrawFocus

Postby Antonio Linares » Thu Feb 12, 2009 4:19 pm

César,

Parece que es por la altura del menu que no se esta teniendo en cuenta.

Hay que volver a modificar CtrlDrawFocus() para que detecte si algun contenedor tiene un menu y ajustar las coordenadas.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41324
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: CtrlDrawFocus

Postby César E. Lozada » Fri Feb 13, 2009 1:47 am

Hola, Antonio.

Encontré la forma en la cual los controles en controles funcionan como debe ser.

En los casos de control en control no hay que agregar nada a las datas de rct, es decir, el problema se soluciona en CtrlDrawFocus() con

rct.left = pt.x ; //+ GetSystemMetrics( SM_CXSIZEFRAME ); // - 5;
rct.top = pt.y ; //+ GetSystemMetrics( SM_CYCAPTION ) + GetSystemMetrics( SM_CYSIZEFRAME ); // - 5;
pt.x = rct.right;
pt.y = rct.bottom;
ScreenToClient( hWndParent, &pt );
rct.right = pt.x; // + 8;
rct.bottom = pt.y; // + GetSystemMetrics( SM_CYCAPTION ) + 8;

Lo que no pude hacer es adaptar CtrlDrawFocus() para que distinga un caso del otro, tal vez necesite un nuevo parámetro que haga esta distinción.

Gracias de nuevo por toda la ayuda

Saludos
User avatar
César E. Lozada
 
Posts: 128
Joined: Wed Oct 26, 2005 12:18 pm
Location: Los Teques, Miranda, Venezuela


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 3 guests