• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 579
  • Last Modified:

Resource recovery after using SetWindowRgn

How can I use "SetWindowRgn" without losing resources?  TurboPower's Memsleuth tells me that I lose a Region resource every time.  The following code produces the fault - or is a Memsleuth fault?


procedure TForm1.Button1Click(Sender: TObject);
var R:HRgn;
begin
  R := CreateRectRgn(0, 0, Width, Height);
  SetWindowRgn(Handle, R, false);
  SetWindowRgn(Handle, 0, false);
  DeleteObject(R);  { this call is unsucessful }
end;
0
wfy
Asked:
wfy
  • 6
  • 3
1 Solution
 
mheacockCommented:
I believe you are misusing the SetWindowsRgn function
above.

Windows owns the region after you create it.  You should never try freeing it after you've created it.  Windows will do that for you.  So when your program closes down, MemSleuth will notify you that some memory has not been freed (the Rgn) since Windows has probably not freed it yet.

You will not lose memory...Windows will free the Rgn soon after your program shuts down.

Here's a blurb from the API help file:

"After a successful call to SetWindowRgn, the operating system owns the region specified by the region handle hRgn. The operating system does not make a copy of the region. Thus, you should not make any further function calls with this region handle. In particular, do not close this region handle.  

To obtain the window region of a window, call the GetWindowRgn function. "

0
 
mheacockCommented:
Concerning your comment about multiple calls to SetWindowRgn...

Each Window handle has but one 'region', therefore multiple
calls SHOULD automatically (automagically) release the previous
HRGN, then reset it to the new value.

I'm not positive on this point, so you may want to do some
testing, then get back to me via a comment here.
0
 
wfyAuthor Commented:
Hi,  I have done some testing - on Win95 and WinNT.  On Win95 I terminated the test after a few hundred thousand repititions of the sample code.  My PC was very unhappy - the program took about 90 seconds (or so) to close down.  It was running through MemSleuth and MemSleuth had to be terminated with Ctrl-Alt-Delete.  The test on WinNT has now been going for 1.5 million repititions, and it is complaining of being low on memory.  So there definitely is a problem with this code being repeatedly called.  Maybe it would help if I stored the region handle between successive calls, and used the same handle again, without recreating the region?  But the Windows Documentation says that the window now owns the region and I should not alter it after calling SetWindowRgn.  So.... does that mean that SetWindowRgn should never be called repeatedly, but only once per window???  (I hope not).
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
mheacockCommented:
Experiment some more...use the same handle repeatedly...see if
it makes your system unstable...try various ways of deleting
the HRGN object after the call to SetWindowRgn...perhaps
SetWindowRgn just uses a copy of the HGN you use in CreateRectRgn??  The docs are pretty sparse on this function and I wasn't even able to locate it in my Win32 API Bible.  It's in the Delphi help docs...but that is it.  There might be some more help on Microsoft...perhaps a search of their site for SetWindowRgn might turn up something...

I'd be interested in your results...if you don't mind posting them to this question, I'd be curious to see them.

0
 
mheacockCommented:
Here's some sample code I found:

HRGN tempRgn = CreateRectRgnIndirect(&rcIXect);
SetWindowRgn(GetOuterWindow(), tempRgn, TRUE);
 
if (m_hRgn != NULL)
    DeleteObject(m_hRgn);
m_hRgn = tempRgn;


I guess you need two variables to hold the rect.  Create
a temp region, SET temp region, delete previous region (m_hRgn),
assign temp region to m_hRgn.

I also see they are using CreateRectRgnIndirect which is different than your CreateRectRgn.  Perhaps this is the key.

Happy programming.
0
 
wfyAuthor Commented:
Firstly, using the same handle repeatedly is real bad - the system becomes unstable very quickly. (less than 10 iterations)
I have tried deleting previous regions passed to SetWindowRgn using DeleteObject as your code suggests.  But the return value from DeleteObject always indicates that it is unsuccessful, and Memsleuth's reports still indicate loss of region resources.
I doubt that using CreateRectRgn or CreateRectRgnIndirect will make any difference.  Using a parameter of true or false to SetWindowRgn (3rd parameter) doesn't seem to make any difference either.
0
 
wfyAuthor Commented:
Firstly, using the same handle repeatedly is real bad - the system becomes unstable very quickly. (less than 10 iterations)
I have tried deleting previous regions passed to SetWindowRgn using DeleteObject as your code suggests.  But the return value from DeleteObject always indicates that it is unsuccessful, and Memsleuth's reports still indicate loss of region resources.
I doubt that using CreateRectRgn or CreateRectRgnIndirect will make any difference.  Using a parameter of true or false to SetWindowRgn (3rd parameter) doesn't seem to make any difference either.

P.S.  You MS WWW link gave me an empty search.  Could you e-mail the actual page to me??  wfy@ee.ed.ac.uk
0
 
mheacockCommented:
Just go to MS...click the SEARCH graphic at the top of the
page...search for SetWindowRgn.  There is a code link...it
gives the sample I gave above.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 6
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now