XBrowse. Bug in row painting

User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

XBrowse. Bug in row painting

Post by nageswaragunupudi »

Mr Antonio

In some circumstances, when the user selects a browse with a mouse click on a row ( say 4th row ) the xbrowse paints the first row information on the clicked row. Thereafter with arrow keys we can not go up but we can go down. 2nd row is painted on 5th row and so on. Please see the screen shot for example:
Image
This is observed occasionally several times, but I could not reproduce it earlier. Now I have reproduced it in one case and give the code below. This code uses c:\fwh\samples\customer.dbf. The code creates necessary indexes and shows parent child scoped browses. The child table is related to the parent table with ordSetRelation. I also provided an option to choose either txbtowse or twbrowse. It can be seen the TWBrowse ( also TCBrowse) works perectly, and the problem is only with TXBrowse.

Code: Select all

#include 'fivewin.ch'
#include 'xbrowse.ch'

#define ORDREL

REQUEST DBFCDX

function main()

	OpenData()
	if alert( 'Choose Browse', { 'XBrowse', 'WBrowse' } ) == 1
   	testxbrw()
   else
   	testwbrw()
   endif
	close data

return nil

function testxbrw

local odlg, obrwSt, oBrw, ocol


	define dialog odlg size 800,340 pixel title 'TXBROWSE'

	@ 15,100 say 'XBROWSE CHILD TABLE' size 290,10 pixel of odlg center

	obrwSt := txbrowse():new(odlg)
	obrwSt:ntop 		:= 30
	obrwSt:nleft		:= 10
	obrwSt:nright		:= 80
	obrwSt:nbottom	   := 150
	obrwSt:calias 	:= 'state'

	ocol				:= obrwSt:addcol()
	ocol:cheader   := 'State'
	ocol:bstrdata	:= {||state->State}

   oBrwSt:SetRDD()
	obrwSt:createfromcode()


	obrw				:= txbrowse():new(odlg)
	obrw:ntop 		:= 30
	obrw:nleft		:= 100
	obrw:nright		:= 390
	obrw:nbottom	:= 150
	obrw:calias 	:= 'cust'

	ocol				:= obrw:addcol()
	ocol:cheader   := 'No'
	ocol:bstrdata	:= {||str( cust->(ordkeyno()),4)}


	ocol				:= obrw:addcol()
	ocol:cheader   := 'First'
	ocol:bstrdata	:= {||cust->first}

	ocol				:= obrw:addcol()
	ocol:cheader   := 'Last'
	ocol:bstrdata	:= {||cust->last}

	ocol				:= obrw:addcol()
	ocol:cheader   := 'City'
	ocol:bstrdata	:= {||cust->City}


	obrw:setRDD()
	obrw:CreateFromCode()


	@ 160,100 SAY eval( obrw:bKeyNo ) picture '9999' size 40,10 pixel of odlg right update
	@ 160,160 SAY eval( obrw:bKeyCount ) picture '9999' size 40,10 pixel of odlg right update

	oBrwSt:bChange	:= {||RowChange(oBrwSt, oBrw)}
	oBrw:bChange   := {||oDlg:update() }

	activate dialog odlg centered ;
		on init oBrwSt:SetFocus()

return nil


function testwbrw

local odlg, obrwSt, oBrw, ocol


	define dialog odlg size 800,340 pixel title 'TWBROWSE'

	@ 15,100 say 'XBROWSE CHILD TABLE' size 290,10 pixel of odlg center

	@ 30,10 LISTBOX oBrwSt ;
		FIELDS state->state ;
		HEADERS 'State' ;
		SIZE 50,120 PIXEL OF oDlg ;
		ALIAS 'STATE'

	@ 30,100 LISTBOX oBrw ;
		FIELDS str(cust->(Ordkeyno()),4), cust->first, cust->last, cust->city ;
		HEADERS 'No', 'First', 'Last', 'City' ;
		SIZE 290,120 PIXEL OF odlg ;
		ALIAS 'CUST'

	obrw:bLogicLen	:= {||cust->(ordkeycount())}

//	@ 160,100 SAY eval( obrw:bKeyNo ) picture '9999' size 40,10 pixel of odlg right update
	@ 160,160 SAY eval( obrw:blogiclen ) picture '9999' size 40,10 pixel of odlg right update


	oBrwSt:bChange	:= {||RowChange(oBrwSt, oBrw)}
	oBrw:bChange   := {||oDlg:update() }

	activate dialog odlg centered ;
		on init oBrwSt:SetFocus()

return nil



static function RowChange( oBrwSt, oBrw )

#ifndef ORDREL

	cust->(OrdScope(0,state->state))
	cust->(ordscope(1,state->state))

#endif

	cust->(dbgotop())
	oBrw:gotop()
	oBrw:Refresh(.t.)

	oBrw:oWnd:update()

return nil


static function OpenData

field state, city, first

local cfile	:= '\fwh\samples\customer'

	ferase( cfile + '.cdx' )
	use (cfile) exclusive via 'DBFCDX'
	index on state tag state unique
	index on state + city + first tag city
	use

	use (cfile) new alias state shared via 'DBFCDX'
	set order to tag state
	go top

	use (cfile) new alias cust shared via 'DBFCDX'
	set order to tag city
	go top

#ifdef ORDREL
//	state->( ordsetrelation( 'cust', {||state}, 'state' ) )
//      state->( dbgotop() )
//      scoped relation can be set either way

	state->( dbsetrelation( 'cust', { || State }, 'State', .t. ) )
	state->( dbgotop() )

#else

	cust->( ordscope( 0, state->state ) )
	cust->( ordscope( 1, state->state ) )
	cust->( dbgotop() )

#endif

return nil
This program can be compiled and run straight away. No setup is required as long as the customer.dbf exists in \fwh\samples folder.

On the left parent browse of States is presented and on the right child browse of customers in that State is presented. The problem comes when a customer (other than the first line) is selected with a mouse click in the child browse. WBrowse works perfectly but not XBrowse.
Note: XBrowse works well when scope is set on child table on bhchange of the parent browse, but fails with scoped relation. The problem is NOT with scoped relation, because WBrowse works well with scoped relations also. Same is the problem with DBFCDX and also ADS. Therefore the problem is with XBrowse only.
Regards

G. N. Rao.
Hyderabad, India
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

NageswaraRao,

In Class TWBrowse we had to implement a method UpStable() to get the right painting under certain circunstances. This method is not provided in Class TXBrowse.

Maybe thats what we need to fix it. I appreciate your feedback testing it with XBrowse, thanks
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Post by nageswaragunupudi »

Mr Antonio

Thanks. Can you kindly look into this ? I faced this problem in some other circumstances also, but could not reproduce them. It is happening mostly when we bring a browse to focus by clicking on some row in the browse. I checked the lbuttondown method and could not figure out any solution.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Post by nageswaragunupudi »

In this case what is also intriguing me is why it is working when I set scope top and scope bottom in the bchange method, but failing when it is related with ordsetscope.
Regards

G. N. Rao.
Hyderabad, India
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

NageswaraRao,

Please check in Class TWBrowse from what methods the Method UpStable() is called.

Probably we have to implement it and call it in the same places from inside Class TXBrowse
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Post by nageswaragunupudi »

Mr Antonio

I like to share with you some peculiar phenomenon I observed. Let me reproduce the relevant lines of code in lbuttondown method along with two debug lines of code I inserted:

Code: Select all

METHOD LButtonDown( nRow, nCol, nFlags ) CLASS TXBrowse
  < ... code .. >
     if nRowPos > 0 .or. nColPos > 0

      if ::nMarqueeStyle == MARQSTYLE_HIGHLROWMS
         if !GetKeyState( VK_CONTROL ) .and. !GetKeyState( VK_SHIFT )
            ::Select( 0 )
         endif
      endif
      ::DrawLine()
      if nRowPos > 0
//msginfo( str(nrowpos) + str(::nrowsel) ) // for debug
sysrefresh()  // for debug

         Eval( ::bSkip, nRowPos - ::nRowSel )
         ::nRowSel := nRowPos
         if ::bChange != nil
            Eval( ::bChange, Self )
         endif
      endif
      < ... code ... >
      ::DrawLine( .t. )
       < ...code .. >
1) When I uncomment the msginfo line above, it correctly shows the clicked row number and 1 as ::nrowsel. After the msginfo, the browse behaves correctly. Displays the clicked row correctly.
2) If i comment msginfo line and uncomment SysRefresh(), then also the clicked row is displayed correctly but the first row also remains highlighted
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Post by nageswaragunupudi »

I shall check twbrowse, but meanwhile can you check the above posting? I am not able to understand why is it happening so.
Regards

G. N. Rao.
Hyderabad, India
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

MsgInfo() and SysRefresh() produce similar results as MsgInfo() uses a built-in SysRefresh() alike code (Win API code).

The difference is that MsgInfo() generates a WM_PAINT msg to the underlaying window, meanwhile SysRefresh() doesn't
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Post by nageswaragunupudi »

Thanks. Paint method sets everything right. Now I understand.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Post by nageswaragunupudi »

Mr Antonio

1) Upstable method of TWBrowse is used only in bAdd block.
2) LButtonDown methods of both TWBrowse and TXBrowse seem to the same logically.

3) BUT THE PROBLEM IS APPARENTLY SOLVED
when I inntroduced SysRefresh() just above the first ::DrawLine() in the LButtonDown Method. ( Line No. 2174 in the source of FWH 8.01).

I do not see any logic why this should work, but it is working. Can you think about it and explain why does it remedy the problem?
Regards

G. N. Rao.
Hyderabad, India
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

NageswaraRao,

SysRefresh() allows to process pending Windows msgs so the proper processing order is done

Some of the methods or functions called before DrawLine() were not processed yet. SysRefresh() gave them priority
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Post by nageswaragunupudi »

Mr Antonio

Do you think the problem is solved? I still feel uncomfortable because I could not see the real reason and found a solution for it.

Anyway for the time being shall we insert Sysrefresh() as a fix in the code?
Regards

G. N. Rao.
Hyderabad, India
User avatar
Manuel Valdenebro
Posts: 706
Joined: Thu Oct 06, 2005 9:57 pm
Location: Málaga-España

Post by Manuel Valdenebro »

nageswaragunupudi wrote:Anyway for the time being shall we insert Sysrefresh() as a fix in the code?
Antonio,

May you confirm it is a FWH bug? In afirmative case, can you write what we must changing in xbrowse class ?
Un saludo

Manuel
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Post by nageswaragunupudi »

I think it is too early to say anything. In any case this does not give problem in many cases.

Mr Antonio will study the issue in detail and advise us suitably. Let is wait.
Regards

G. N. Rao.
Hyderabad, India
User avatar
Maurilio Viana
Posts: 252
Joined: Tue Oct 25, 2005 2:48 pm
Location: Garça/Garza/Heron City - Brazil
Contact:

Post by Maurilio Viana »

Friends,

I have the same problem in my xbrowses. I will test insert SysRefresh in that method and try. Any news I post here!

Thanks!!!
Maurilio
Post Reply