Diffeence between oSay:SetText() and oSay:VarPut()

Post Reply
User avatar
anserkk
Posts: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Diffeence between oSay:SetText() and oSay:VarPut()

Post by anserkk »

Hi,

I am having a peculiar problem with the update of the Tsay object. I am passing a SAY object as parameter to different functions. The say object is supposed to show the status of my different routines on a MDI Child Window.

I tried

Code: Select all

oSay:SetText("New Value of the Satus")  // Doesn't work
oSay:Refresh()  // Doesn't work

oSay:VarPut(("New Value of the Satus") // This works along with oSay:Refresh()
oSay:Refresh()  // This does the work 
I thought of pasting a sample here to demonstrate the problem and created one, but to my surprise the problem exists only in my real app. The sample app which I created to imitate the problem is working fine. :x

Anyway oSay:VarPut() + oSay:Refresh() is serving my purpose. For my knowledge/learning purpose, I would like to know why is it behaving so. :roll:
Anybody here experienced similar problem with SAY object ?

Application is on MDI Environment, I create the local SAY object on a MDI Child Window and then pass the oSay as parameter to few other functions which updates the text on the SAY object.
For Eg.

Code: Select all

Local oWnd,oSay,oBtn
DEFINE WINDOW oWnd MDICHILD OF WndMain()
@1,1 say oSay OF oWnd SIZE 200,15
@2,10 BUTTON oBtn OF oWnd SIZE 90,40 ;
    ACTION ( MyRoutine_1(oSay), ;
             MyRoutine_2(oSay) )

ACTIVATE WINDOW oWnd
Return NIL


//------------------------------------------------
Function MyRoutine_1(oSay)
  oSay:SetText:="Started Process 1"
  Do While ...
  Enddo
  oSay:SetText:="Finished Process 1"
Return

//------------------------------------------------
Function MyRoutine_2(oSay)
  oSay:SetText:="Started Process 2"
  Do While ...
  Enddo
  oSay:SetText:="Finished Process 2"
Return

....
Any hint ?

Regards
Anser
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Re: Diffeence between oSay:SetText() and oSay:VarPut()

Post by James Bott »

Anser,

Have you tried a sysRefresh()?

Also, this syntax:

oSay:SetText:="Started Process 1"

Should be:

oSay:SetText("Started Process 1")

James
User avatar
anserkk
Posts: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Diffeence between oSay:SetText() and oSay:VarPut()

Post by anserkk »

Dear Mr.James,

I have used oSay:SetText("New Value") in my application prg's. In this forum, by mistake I typed oSay:SetText:="some text". :oops:

I tried sysrefresh() too.

Regards
Anser
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Re: Diffeence between oSay:SetText() and oSay:VarPut()

Post by James Bott »

Anser,

If you look at the souce for SetText() and VarPut() you will see that SetText() handles redrawing the background also. Perhaps it is an issue with this that is the problem, especially if you are using a bitmap or brush background and have transparent text.

Regards,
James
User avatar
anserkk
Posts: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Diffeence between oSay:SetText() and oSay:VarPut()

Post by anserkk »

Dear Mr.James,

At last I am able to create a sample which shows the problem which I have explained above. I am experiencing the same problem in my real app.

Please run this code to see the problem. There are 2 buttons available to do the test.
Test 1 : Uses oSay:VarPut()
Test 2 : Uses oSay:SetText()

Code: Select all

#Include "FiveWin.Ch"
*----------------------*
Function Main()
*----------------------*
Local oWnd,oProgress,oMeter,nActual,oBtn,oSay

DEFINE WINDOW oWnd TITLE "Test" MDI


ACTIVATE WINDOW oWnd ON INIT (Test())
Return
*----------------------*
Function Test()
*----------------------*
Local oWnd,oMeter,nActual,oBtn1,oBtn2,oSayStatus

DEFINE WINDOW oWnd MDICHILD OF WndMain() TITLE "Test 2" ;
       COLOR nRGB(0,0,0), nRGB(213,228,242)

@0.5,5 SAY oSayStatus Prompt "" OF oWnd SIZE 200,15 COLOR nRGB(0,0,0), nRGB(213,228,242)
@ 2, 5 METER oMeter VAR nActual OF oWnd SIZE 400, 30                      
@8,10 BUTTONBMP oBtn1 PROMPT "oSay:VarPut()" ;
         ACTION ( DoProcess1(oMeter,oSayStatus,"V"), DoProcess2(oMeter,oSayStatus,"V") )  SIZE 250,50
@8,60 BUTTONBMP oBtn2 PROMPT "oSay:SetText()" ;
         ACTION ( DoProcess1(oMeter,oSayStatus,"S"), DoProcess2(oMeter,oSayStatus,"S") )  SIZE 250,50


ACTIVATE WINDOW oWnd
Return

*----------------------------------------
Function DoProcess1(oMeter,oSayStatus,cType)
*----------------------------------------
Local n
oMeter:nTotal:=25000
If cType == "S"
    oSayStatus:SetText("For Loop No.1")
Else
    oSayStatus:VarPut("For Loop No.1")
Endif
oSayStatus:Refresh()
SysRefresh()
for n = 1 to 25000
    oMeter:Set( n )
next
If cType == "S"
    oSayStatus:SetText("For Loop No.2")
Else
    oSayStatus:VarPut("For Loop No.2")
Endif
oSayStatus:Refresh()
SysRefresh()
for n = 1 to 25000
    oMeter:Set( n )
next
If cType == "S"
    oSayStatus:SetText("For Loop No.3")
Else
    oSayStatus:VarPut("For Loop No.3")
Endif
oSayStatus:Refresh()
SysRefresh()
for n = 1 to 25000
    oMeter:Set( n )
next
Return

*----------------------------------------
Function DoProcess2(oMeter,oSayStatus,cType)
*----------------------------------------
Local n
If cType == "S"
    oSayStatus:SetText("For Loop No.4")
Else
    oSayStatus:VarPut("For Loop No.4")
Endif
oSayStatus:Refresh()
SysRefresh()
for n = 1 to 25000
    oMeter:Set( n )
next

If cType == "S"
    oSayStatus:SetText("Completed the Test")
Else
    oSayStatus:VarPut("Completed the Test")
Endif
oSayStatus:Refresh()
SysRefresh()
Return
Please note : If I use oSay:VarPut(), then I don't need to use SysRefresh(), instead oSay:Refresh() will update the say.

In the above sample I have used the SysRefresh(), just to show that oSay:SetText() does not refresh the oSay even after a SysRefresh()

Regards
Anser
Last edited by anserkk on Thu Jan 21, 2010 7:45 am, edited 1 time in total.
User avatar
fafi
Posts: 169
Joined: Mon Feb 25, 2008 2:42 am

Re: Diffeence between oSay:SetText() and oSay:VarPut()

Post by fafi »

Dear Mr. Anser

Please ! change class say.prg :

Code: Select all

METHOD SetText( cText ) CLASS TSay

   local hDC

   if empty(cText)  // add by fafi
       return nil
   endif


   DEFAULT ::lTransparent := .f.

   ::cCaption := If( ::cPicture != nil, Transform( cText, ::cPicture ),;
                     cValToChar( cText ) )

   #ifndef __CLIPPER__
      if ::oWnd:oBrush != nil .and. Empty( ::oWnd:oBrush:hBitmap ) .and. ( IsAppThemed() .or. ::lTransparent )
         DrawPBack( ::hWnd, hDC := GetDC( ::hWnd ) )
         ReleaseDC( ::hWnd, hDC )
      endif   
   #endif

   SetWindowText( ::hWnd, ::cCaption )


return nil
 
Best Regards
Fafi
User avatar
anserkk
Posts: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Diffeence between oSay:SetText() and oSay:VarPut()

Post by anserkk »

Dear Mr.Fafi,

Modified the SAY Class as per your suggestion.

These are my observations after implementing the suggested change on the SAY Class

If I run the "SetText()" before running the "VarPut()", it is updating the SAY properly.
Once I run "Test No:1 VarPut()" then the problem which I have explained above exists while testing with SetText().

If I have confused you with the above statement, then you may try the following sequence

1) Click SetText() (Works fine)
2) Click VarPut() (works Fine)
3) Click SetText() ( Says are not updated )

I have modified the code which I have pasted on my previous post. To avoid confusions I have changed the button captions to "oSay:VarPut()" and "oSay:SetText()".

Regards
Anser
User avatar
fafi
Posts: 169
Joined: Mon Feb 25, 2008 2:42 am

Re: Diffeence between oSay:SetText() and oSay:VarPut()

Post by fafi »

Dear Sir..

>> 1) Click SetText() (Works fine)
>> 2) Click VarPut() (works Fine)
>> 3) Click SetText() ( Says are not updated )

because the last var is : "Complete the Test"

look at this :

Code: Select all

METHOD Refresh() INLINE If( ::bGet != nil, ::SetText( Eval( ::bGet ) ),)
 
when run SetText() first time -> ::bGet still NIL

then you run VarPut() ::bGet is the last one var called VarPut("Complete the Test")

if you run SetText() again..after VarPut()
will display SetWindowText( ::hWnd, ::cCaption ) twice

1. SetText("Your Text") then
2. Refresh(), SetText(::bGet value ) <- "Complete the Test" last variable on ::bGet

Code: Select all

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

METHOD VarPut( cValue ) CLASS TSay

   if ! Empty( ::cPicture )
      cValue = Transform( cValue, ::cPicture )
   else
      cValue = cValToChar( cValue )
   endif

   ::bGet = { || cValue }

return nil

 
Please test with this :

Code: Select all

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

METHOD SetText( cText ) CLASS TSay

   local hDC

   DEFAULT ::lTransparent := .f.

   ::cCaption := If( ::cPicture != nil, Transform( cText, ::cPicture ),;
                     cValToChar( cText ) )

   #ifndef __CLIPPER__
      if ::oWnd:oBrush != nil .and. Empty( ::oWnd:oBrush:hBitmap ) .and. ( IsAppThemed() .or. ::lTransparent )
         DrawPBack( ::hWnd, hDC := GetDC( ::hWnd ) )
         ReleaseDC( ::hWnd, hDC )
      endif   
   #endif
   
   MsgAlert(::cCaption) // look here
   
   if !empty(alltrim(::cCaption))  // add by fafi
      
      SetWindowText( ::hWnd, ::cCaption )
      
   endif


return nil
 
Regards
Fafi
User avatar
anserkk
Posts: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Diffeence between oSay:SetText() and oSay:VarPut()

Post by anserkk »

Dear Mr.Fafi,

You are right. Value in ::bGet is assigned only during initialization and via Method VarPut()
Your solution on SAY class works fine.

Code: Select all

METHOD SetText( cText ) CLASS TSay 
....
if !empty(alltrim(::cCaption))  // add by fafi
    SetWindowText( ::hWnd, ::cCaption )
endif
....
Mr.Fafi,

What about updating the value of ::bGet with cText inside the Method SetText(cText) ? So that we can use SetText() and VarPut() on the same SAY object and the CLASS behave the same as expected.



Dear Mr.Antonio,

Is this problem in SAY rectified in the latest versions of FWH ?

Regards
Anser
User avatar
anserkk
Posts: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Diffeence between oSay:SetText() and oSay:VarPut()

Post by anserkk »

Dear Mr.Fafi,

The following 1 line code on the SAY code is working fine. This will force the oSay:Refresh() to work as expected (update the Text change in the Say Object)
I don't know whether this would cause some other problem in the CLASS SAY. May be some seniors here would be able to confirm it.

Code: Select all

METHOD SetText( cText ) CLASS TSay 

   local hDC, nWidth 

   DEFAULT ::lTransparent := .f. 
   ::bGet = { || cText }  // Added by Anser

   ::cCaption := If( ::cPicture != nil, Transform( cText, ::cPicture ),; 
                     cValToChar( cText ) )
Regards
Anser
User avatar
fafi
Posts: 169
Joined: Mon Feb 25, 2008 2:42 am

Re: Diffeence between oSay:SetText() and oSay:VarPut()

Post by fafi »

anserkk wrote: May be some seniors here would be able to confirm it.
:D
Mr. Antonio.. Please..!!

Regards
Fafi
User avatar
anserkk
Posts: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Diffeence between oSay:SetText() and oSay:VarPut()

Post by anserkk »

Mr.Antonio or any Seniors of this forum,

Can you please confirm that the above given change in the METHOD SetText() of CLASS SAY does not effect other functionality of the SAY.
OR
Is this problem already solved in the latest FWH versions

Regards
Anser
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Re: Diffeence between oSay:SetText() and oSay:VarPut()

Post by Otto »

What is the status?
Best regrards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org

********************************************************************
Post Reply