Page 1 of 2

Brush issue

PostPosted: Tue Jul 10, 2012 12:55 am
by TimStone
I use a brush background on my screens that is a cloud bmp. It has worked fine for a long time.

I was defining the brush each time I defined a dialog, and that seemed like a huge waste. So I declared the brush in the main( ) routine as a public object, and then refer to it with every dialog.

Several of my clients reported a problem where the brush background was not showing up, and thus the transparent dialog was being viewed against the previous screen or window.

I have checked and I never intentionally release the brush.

This seems to have started in 12.05 and may be continuing in 12.06.

It is happening in a couple of screens. It doesn't happen every time, but it happens to the same dialogs when it does occur.

I would appreciate any suggestions.

Tim

Re: Brush issue

PostPosted: Tue Jul 10, 2012 11:37 am
by ukoenig
Tim,

maybe test it like :

DEFINE BRUSH oBrush1 COLOR 14853684
DEFINE BRUSH oBrush2 FILENAME c_path + "\Images\Stone.bmp"

// You can test, if the Brush still exists.
// with < oBrush2:End() > You will get a Errormessage from the Dialog !!!

DEFINE DIALOG oDlg1 RESOURCE "Group" TITLE "Dialog-test" FONT oDlgFont ;
PIXEL // TRANSPARENT
..
..
ACTIVATE DIALOG oDlg1 CENTERED ; // NOWAIT ;
ON INIT IIF( oBrush2:hBitmap != 0, oDlg1:SetBrush( oBrush2 ), MsgAlert( "Brush not defined !", "ERROR" ) )

Best Regards
Uwe :?:

Re: Brush issue

PostPosted: Tue Jul 10, 2012 12:52 pm
by Antonio Linares
Tim,

Brushes also use a counter to share them between different objects.

How are you assigning it ? Must use <oObj>:SetBrush( oBrush )

Re: Brush issue

PostPosted: Wed Jul 11, 2012 12:07 am
by TimStone
Antonio,

I just use the BRUSH argument in the REDEFINE for a dialog created in a resource.

Re: Brush issue

PostPosted: Wed Jul 11, 2012 6:36 pm
by TimStone
This is getting urgent

I use one Brush in my system for ALL dialogs.

In the past, I used the following code in every function that had a dialog:

DEFINE BRUSH oBrush RESOURCE "SKY"
DEFINE DIALOG oDlg RESOURCE "PRO100M" BRUSH oBrush TRANSPARENT OF oWnd FONT oWnd:oFont

It seemed silly to constantly redefine oBrush since there was never an alternative brush used on any dialog. SKY is a bitmap ( clouds ) stored in my .res file that is linked to the program.

So, I declared oBrush a public variable in the Main( ) program ( thinking that would make it global ), and in each dialog I eliminated the DEFINE BRUSH statement.

Antonio said to modify the code to use the following:

DEFINE DIALOG oDlg RESOURCE "PRO100M" TRANSPARENT OF oWnd FONT oWnd:oFont
oDlg:SetBrush( oBrush )

So I did that on the major routines where this was happening.
I also tried an alternative where I set the brush to a color rather than to a .bmp resource

It all seems to work fine, but then two clients report after awhile, the brush disappears, and so the top level dialog ( in focus ) is transparent and shows all the text below it !

The only thing in common is both of these clients are using Windows XP.

I cannot duplicate this problem no matter what I try. I did have another person who reported it, but then they said it resolved and I haven't heard from them since.

When it does occur, the only solution is to leave the program and then re-enter it.

PLEASE ... does anyone have a clue ?

Tim

Re: Brush issue

PostPosted: Wed Jul 11, 2012 6:51 pm
by ukoenig
Tim,

did You test it the way I posted above ?
I never had any problems.

DEFINE DIALOG oDlg RESOURCE "PRO100M" TRANSPARENT OF oWnd FONT oWnd:oFont
// oDlg:SetBrush( oBrush )

ACTIVATE DIALOG oDlg ;
ON INIT oDlg:SetBrush( oBrush )


Best Regards
Uwe :lol:

Re: Brush issue

PostPosted: Wed Jul 11, 2012 8:35 pm
by TimStone
I changed it to your style and now its even worse.

I'll have to go back and see what else I can do.

I think I'll revert it back to what I had originally with no problems.

Tim

Re: Brush issue

PostPosted: Wed Jul 11, 2012 9:06 pm
by ukoenig
Tim,

I don't know, why the brush gets lost.
Another solution could be to define the brush LOCAL :


FUNCTION Main()
LOCAL oBrush2

c_path := GETCURDIR()

DEFINE BRUSH oBrush2 FILENAME c_path + "\Images\Stone.bmp"

DEFINE WINDOW oWnd TITLE "Testing Brush
...
...
DEFINE BUTTON oButt1 OF oBar FILE c_path + "\Logo\16x16N.bmp" ;
MESSAGE "Resource" ;
ACTION D_RESOURCE(oBrush2) ;
PROMPT "Resource"

ACTIVATE WINDOW oWnd MAXIMIZED

oBrush2:End()

RETURN NIL

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

FUNCTION D_RESOURCE(oBrush2)
LOCAL oDlg1

DEFINE DIALOG oDlg1 RESOURCE "Group" TITLE "Dialog-test" PIXEL TRANSPARENT

ACTIVATE DIALOG oDlg1 CENTERED NOWAIT ;
ON INIT IIF( oBrush2:hBitmap != 0, oDlg1:SetBrush( oBrush2 ), MsgAlert( "Brush not defined !", "ERROR" ) )

RETURN NIL

Best Regards
Uwe :?:

Re: Brush issue

PostPosted: Wed Jul 11, 2012 9:18 pm
by TimStone
That is what I'm doing right now. I'll see if that resolves the problem.

Tim

Re: Brush issue

PostPosted: Thu Jul 12, 2012 8:33 am
by Enrico Maria Giordano
TimStone wrote:SKY is a bitmap ( clouds ) stored in my .res file that is linked to the program.


Please open the "Memory options" of your bitmap (if you are using BRW) and remove the check from Discardable option.

EMG

Re: Brush issue

PostPosted: Thu Jul 12, 2012 8:56 am
by Antonio Linares
Tim,

Somewhere in your app, your brush counter is decreasing down to zero and so the brush is released.

Please place a log in your app when you return from a certain option and check the brush counter:

LogFile( "brushes.txt", { oBrush:nCounter, "exiting from function ..." } )

As a workaround you could increase the counter: oBrush:nCount++ so it will not reach zero.

Re: Brush issue

PostPosted: Thu Jul 12, 2012 4:02 pm
by TimStone
Antonio,

Here is where it gets interesting, and very strange.

I started monitoring oBrush:ncount. I initialize the public object oBrush, then I increment it 5 times, so nCount should be 6. I enter a function, so some work, and come out, and ncount is now 7. No where in that function do I increment oBrush. In fact, I don't reference it in the function, but it still gets incremented. This continues to happen anytime I go into that function.

In that .prg, whcih is rather complex, I create and use a different brush, olbrush which is locally declared for each dialog.

This is getting very strange.

Also, one of the clients having this issues is using an old XP Home edition computer ( in a network ) with a 600 mhz processor, 700 MB of RAM and a small hard drive. I'm wondering if he is "hardware challenged" and perhaps that is leading to these problems ?

Tim

Re: Brush issue

PostPosted: Sat Jul 21, 2012 10:27 pm
by nageswaragunupudi
So I declared the brush in the main( ) routine as a public object, and then refer to it with every dialog.

This should work correctly as expected.
One possibility is that you might have forgotten to delete the line "RELEASE BRUSH oBrush" in one or two of the modules. This is possible because earlier you had defined and released the brush in each module and now changed it to PUBLIC variable.
You may please search in all prg modules for "RELEASE BRUSH" and ":End()" statements and make sure no such code is still left out there.
Premature destruction of the brush might be happening only in cases where such module(s) is/are used by the users.

Re: Brush issue

PostPosted: Sat Jul 21, 2012 11:21 pm
by TimStone
It was all very confusing, but in the end, only two clients had problems, and they were with older machines. One was using XP Home. He replaced his computer with a new box and has no further problems.

I made enough changes, and called the brush LOCAL to each routine, and that solved the last of the problems with the other user. He was also on an XP machine that had numerous problems.

Thanks ...

Tim

Re: Brush issue

PostPosted: Mon Jul 23, 2012 12:51 pm
by Rick Lipkin
Tim

I am doing my best to try to stop using Static variables in all my routines .. even though many of my routines are single .prg with multiple Static Functions that would lend themselves to Static variables.

I have found using MDI\MDIchildren that if you open the same routine twice the Static variables blend together ( almost like public ) and in the second instance where you update Gets with cGet := "this value" oGet:ReFresh() .. that same field in the first instance gets updated.

I have decided that I will use all Local variables and pass them by reference @cGet to other functions and routines just to MAKE SURE the memory space does not get co-mingled with any other function or event that may open in my application at the same time.

Rick Lipkin