Przemek

>Yes, it is.

I suspected so.

<<<<<
It's enough to overload PUTCHAR() method and call TOUCHCELL() inside,
f.e. add to gtwvg.c:

   static BOOL hb_gt_wvg_PutChar( PHB_GT pGT, int iRow, int iCol,
                                  BYTE bColor, BYTE bAttr, USHORT usChar )
   {
      if( HB_GTSUPER_PUTCHAR( pGT, iRow, iCol, bColor, bAttr, usChar ) )
      {
         HB_GTSELF_TOUCHCELL( pGT, iRow, iCol );
         return TRUE;
      }
      return FALSE;
   }

and to hb_gt_FuncInit() function:

   pFuncTable->PutChar              = hb_gt_wvt_PutChar;

It will cause that "touched" screen characters will be always redrawn.
>>>>>>>

Yes it is ok with above change, so I need to include this in GTWVG.


<<<<<
This is sth what we should probably discuss in the future. It's not clear
for me how GTWVG uses different display context and merge it to show final
screen, what is the priority of text and GUI objects, how it interacts with
SAVE/REST screen. Of course I can see what happens in current code but I'd
like to know the ideas rather then results of implementation because it is
hardly oriented to MS-Windows API.
>>>>>

The priority:
a) Text 
b) GUI elements based on the coordinates of the region retrieved by
GetUpdateRect() in WM_PAINT window message.  GUI elements are stored in an
array as per this structure:
    
   1) cObjectID . Character ID to handle in-place change/retrieve particular
paint object 
   2) nIDinObject . Numeric ID to change a particular paint block in
<cObjectID>
   3) bPaintFunc . Block to a paint function in wvtcore.c
   4) aCoOrdinates . Optional. An array of screen coordinates where that
object belongs to { nTop, nLeft, nBottom, nRight } in row/columns.

    This is a sample of such placement: 

    SetPaint( 'MSGBOX', 1009, ;
              {|| Wvt_DrawLabel( 10, 10, 'Vouch', nAlign, nil, nRGBText,
nRGBBack, ;
                            cFontName, 18, 0, 700, nil, .f. ) },  {
9,9,11,30 } )

And this functions set is employed to store/restore/paint the GUI elements
in WvtPaint.prg

//-------------------------------------------------------------------//
static paint_:= { { '', {} } }
//-------------------------------------------------------------------//
//
//        This function must have to be defined in your appls
/*
function Wvt_Paint()

   WvtPaintObjects()

   return nil
*/
//-------------------------------------------------------------------//

function WvtPaintObjects()
   LOCAL i, lExe, nLeft, nRight, b, tlbr_, aBlocks, nBlocks
   
   aBlocks := WvtSetPaint()
   
   if ( nBlocks := len( aBlocks ) ) > 0
      tlbr_:= Wvt_GetPaintRect()
   
      for i := 1 to nBlocks
         lExe := .t.
   
         if aBlocks[ i,3 ] <> nil .and. !empty( aBlocks[ i,3 ] )
            //  Check parameters against tlbr_ depending upon the
            //  type of object and attributes contained in aAttr
            //
            do case
            case aBlocks[ i,3,1 ] == WVT_BLOCK_GRID_V
               b := aBlocks[ i,3,6 ]
               if len( b:aColumnsSep ) == 0
                  lExe := .f.
               else
                  nLeft  := b:aColumnsSep[ 1 ]
                  nRight := b:aColumnsSep[ len( b:aColumnsSep ) ]
                  if !( tlbr_[ 1 ] <= aBlocks[ i,3,4 ] .and. ; // top   <
bottom
                        tlbr_[ 3 ] >= aBlocks[ i,3,2 ] .and. ; // bootm >
top
                        tlbr_[ 2 ] <= nRight + 1       .and. ; // left  <
right
                        tlbr_[ 4 ] >= nLeft  - 2             ) // right >
left
                     lExe := .f.
                  endif
               endif
   
            case aBlocks[ i,3,1 ] == WVT_BLOCK_GETS
               if !( tlbr_[ 1 ] <= aBlocks[ i,3,4 ] .and. ; // top   < bott
                     tlbr_[ 3 ] >= aBlocks[ i,3,2 ] .and. ; // bootm > top
                     tlbr_[ 2 ] <= aBlocks[ i,3,5 ] .and. ; // left  < righ
                     tlbr_[ 4 ] >= aBlocks[ i,3,3 ]       ) // right > left
                  lExe := .f.
               endif
   
            otherwise
               // If refreshing rectangle's top is less than objects' bottom
               // and left is less than objects' right
               //
               if !( tlbr_[ 1 ] <= aBlocks[ i,3,4 ] .and. ; // top   <=
bottom
                     tlbr_[ 3 ] >= aBlocks[ i,3,2 ] .and. ; // bootm >= top
                     tlbr_[ 2 ] <= aBlocks[ i,3,5 ] .and. ; // left  < right
                     tlbr_[ 4 ] >= aBlocks[ i,3,3 ]       ) // right > left
                  lExe := .f.
               endif
            endcase
         endif
   
         if lExe
            eval( aBlocks[ i,2 ] )
         endif
      next
   endif
   
   return ( 0 )

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

function WvtSetPaint( a_ )
   local o
   static s := {}

   o := s

   if a_ <> nil
      s := a_
   endif

   return o

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

function SetPaint( cID, nAction, xData, aAttr )
   local n, n1, oldData

   if xData <> nil
      if ( n := ascan( paint_, { |e_| e_[ 1 ] == cID } ) ) > 0
         if ( n1 := ascan( paint_[ n,2 ], {|e_| e_[ 1 ] == nAction } ) ) > 0
            oldData := paint_[ n,2,n1,2 ]
            paint_[ n,2,n1,2 ] := xData
            paint_[ n,2,n1,3 ] := aAttr
         else
            aadd( paint_[ n,2 ], { nAction,xData,aAttr } )
         endif
      else
         aadd( paint_, { cID, {} } )
         n := len( paint_ )
         aadd( paint_[ n,2 ], { nAction, xData, aAttr } )
      endif
   endif

   return oldData

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

function GetPaint( cID )
   local n

   if ( n := ascan( paint_, { |e_| e_[ 1 ] == cID } ) ) > 0
      return paint_[ n,2 ]
   endif

   return {}

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

function DelPaint( cID, nAction )
   local xData, n1, n

   if ( n := ascan( paint_, { |e_| e_[ 1 ] == cID } ) ) > 0
      if ( n1 := ascan( paint_[ n,2 ], {|e_| e_[ 1 ] == nAction } ) ) > 0
         xData := paint_[ n,2,n1,2 ]
         paint_[ n,2,n1,2 ] := {|| .t. }
      endif
   endif

   return xData

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

function PurgePaint( cID,lDummy )
   local n, aPaint

   DEFAULT lDummy TO .f.

   if ( n := ascan( paint_, { |e_| e_[ 1 ] == cID } ) ) > 0
      aPaint := paint_[ n ]
      ADel( paint_, n )
      aSize( paint_, len( paint_ ) - 1 )
   endif

   if lDummy
      WvtSetPaint( {} )
   endif

   return ( aPaint )

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

function InsertPaint( cID, aPaint, lSet )
   local n

   DEFAULT lSet TO .f.

   if ( n := ascan( paint_, { |e_| e_[ 1 ] == cID } ) ) > 0
      paint_[ n ] := aPaint
   else
      aadd( paint_, aPaint )
   endif

   if lSet
      WvtSetPaint( aPaint )
   endif

   return nil

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

When GT window receives WM_PAINT message through WndProc, after drawing the
text region, prg defined function WVT_PAINT() is fired which calls
WvtPaintObjects(). In WvtPaintObject() it is checked if any paint object
array exists. If yes, then if 4th parameter <aCoordinates> is defined then
it is checked for if the reqion being painted falls within its preview, if
yes, the paint block is executed. In case <aCoordinates> is undefined, the
paint block is executed irrespective of screen reqion under request.

For SAVE/REST another function is employed,
Wvt_SaveScreen()/Wvt_RestScreen(). Wvt_SaveScreen() creates a memory bitmap
of the requested region and returns its handle to the application which is
passed to Wvt_RestScreen() with a flag as if this need be destroyed.

For events beyond application control. mainly, KILLFOCUS; MINIMIZE;
OVERLAPPING by another Window; etc; are handled differently than SAVE/REST
mechanism, and this is transparent to the user, I mean automatic. GTWVG
writes to a compatible DC every screen command, text and gui. At any time
window receives WM_SETFOCUS/WM_KILLFOCUS message,  it sets a flag to this
effect. When WM_PAINT callback is entertained, the next action is based on
this flag. If previously window had lost foct, which is not an appln
behavior, it transfers the screen region from compatible DC to window DC.

I wished to SAVE/REST functionality to be GT dependent, but because I was
not having any knowledge of core GT layer, I ended up with above solution.
Theoretically this can be accomplished with core functions SaveScreen() and
RestScreen(). Just we need to design a mechanism to save bitmap info tie
with DispCount() as there could be n number of Save/Restores.

Hope this will be useful in understanding GUI behavior.

Regards
Pritpal Bedi, INDIA-USA


-- 
View this message in context: 
http://www.nabble.com/Screen-Painting---SetColor%28-%27N-W%27-%29---Bug-tp14232149p14299299.html
Sent from the Harbour - Dev mailing list archive at Nabble.com.

_______________________________________________
Harbour mailing list
[email protected]
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to