Delphi Pages Forums  

Go Back   Delphi Pages Forums > Delphi Forum > VCL

Lost Password?

Reply
 
Thread Tools Display Modes
  #1  
Old 01-28-2016, 02:32 AM
lexd lexd is offline
Senior Member
 
Join Date: Feb 2015
Posts: 268
Default Make my own WMpaint procedure

TWinControl is a complicated paint procedure because child objects need painting. I've tried to strip away child objects, create a bitmap sized inside the scroll bars and run delphi's paint. This paints at the beginning of run state but does not work after that like I have a memory leak that's blocking things.

PHP Code:
procedure TAbVCLControl.RecreateSelf;
var
  
DCMemDCHDC;
  
MemBitmapOldBitmapHBITMAP;
  
PSTPaintStruct;
  
ClientPointTPoint;
begin
    
If FScrollBars in[ssBothssVerticalthen
      ClientPoint
.:= Left Width GetSystemMetrics(SM_CXVSCROLL)
      else 
ClientPoint.:= Left Width;
    If 
FScrollBars in[ssBothssHorizontalthen
      ClientPoint
.:= Top Height GetSystemMetrics(SM_CYHSCROLL)
      else 
ClientPoint.:= Top Height;

    
DC := GetDC(0);
    
MemBitmap := CreateCompatibleBitmap(DCClientPoint.XClientPoint.Y);
    
ReleaseDC(0DC);
    
MemDC := CreateCompatibleDC(0);
    
OldBitmap := SelectObject(MemDCMemBitmap);
    try
      
DC := BeginPaint(HandlePS);
      
Canvas.Lock;
    try
      
Canvas.Handle := MemDC;
      try
        
Paint;
      
finally
        Canvas
.Handle := 0;
      
end;
    
finally
      Canvas
.Unlock;
    
end;
      
BitBlt(DC00ClientRect.RightClientRect.BottomMemDC00SRCCOPY);
      
EndPaint(HandlePS);
    
finally
      SelectObject
(MemDCOldBitmap);
      
DeleteDC(MemDC);
      
DeleteObject(MemBitmap);
    
end;
end
Reply With Quote
  #2  
Old 01-28-2016, 07:31 AM
Norrit Norrit is offline
Moderator
 
Join Date: Aug 2001
Location: Landgraaf
Posts: 7,333
Default

Turn on ReportMemoryLeaksOnShutdown (in .dpr add ReportMemoryLeaksOnShutdown := True; as the first line)
Perhaps it gives you a clue on the type it leaks.

My guess is that it's the OldBitmap that isn't released, but that's just a guess...
Reply With Quote
  #3  
Old 01-28-2016, 11:31 AM
lexd lexd is offline
Senior Member
 
Join Date: Feb 2015
Posts: 268
Default

Thats just it no leeks are found

I guessing hear but I have not executed a InvalidateRect or RedrawWindow.
to windows. In other words I've gone and painted a canvas when there must be something else to be done in windows.
Is there some commands I need to execute in windows before all this as above.
Reply With Quote
  #4  
Old 01-28-2016, 01:18 PM
Norrit Norrit is offline
Moderator
 
Join Date: Aug 2001
Location: Landgraaf
Posts: 7,333
Default

If there's no memory leak, how do you assume you have one?

I guess you see your memory usage go sky-high and keep building.
I'm not a Delphi developer anymore, so cannot validate. But what if you change the HBITMAP in a TBitmap implementation. Then your .Free should be equal (in this case OldBitmap for example doesn't get a release).
What I also dislike about your code is that you get do some things with DC after ReleaseDC has been called. Not sure if it results in memory consumption, but I usually like to free/release stuff after I'm truly done with them
Reply With Quote
  #5  
Old 01-28-2016, 08:27 PM
lexd lexd is offline
Senior Member
 
Join Date: Feb 2015
Posts: 268
Default

reading articles on windows canvas...........
They all say repeat updates and when things go funny you have a memory leek
I think because too a canvas uses a lot of memory..
{---------------------------------------------------------------------------}

This Get DC .... release DC
copied from Delphi code

DC := GetDC(0);
MemBitmap := CreateCompatibleBitmap(DC, ClientPoint.X, ClientPoint.Y);
ReleaseDC(0, DC);

This is what I understand I think.
Getting the DC like this is based on the thread and the related form
example if the canvas is 32 bit or something else

CreateCompatibleBitmap makes a bit map 32 bit or something or comparable

ReleaseDC drops the DC as its not needed

CreateCompatibleDC
SelectObject
These make and create a DC for the bitmap that is handed over as a canvas
Handle. hearing your thoughts I have decided to place ReleaseDC at the bottom of the procedure with still the query that that may use more memory but safer to get potential errors out of the way.

I still get a first paint at run time and then no updates of canvas

Please comment
Reply With Quote
  #6  
Old 01-28-2016, 10:29 PM
lexd lexd is offline
Senior Member
 
Join Date: Feb 2015
Posts: 268
Default

Just after runtime, After the first print of the canvas, Can Delphi lock my canvas some were else in Delphi?

Is there a way to count the No of locks and remove them safely?
Reply With Quote
  #7  
Old 01-29-2016, 07:36 AM
Norrit Norrit is offline
Moderator
 
Join Date: Aug 2001
Location: Landgraaf
Posts: 7,333
Default

And how and where do you call this RecreateSelf?
Because it's an own procedure, no override available. Could be as easy as a mistake in your calling part so it triggers once
or perhaps you call it too soon, which will give you the exact same result, so it triggers and does it job always with the same output (so you think it only works 1 time)
Reply With Quote
  #8  
Old 01-29-2016, 11:33 PM
lexd lexd is offline
Senior Member
 
Join Date: Feb 2015
Posts: 268
Default

Its the simple procedure as I have given you (above)
Remember
All WM_paint methods are listed as private in the TWinContol object and these methods contain Perform(WM_ERASEBKGND that
I'm trying to avoid using as it produces a major flicker problem painting the canvas the brush color of the Form.
The Perform(WM_ERASEBKGND is badly placed in Delphi code and should be placed after the Paint procedure just before the BitBlt.

I have realised I need a :- RedrawWindow(handle, @Rect,............. Statement to allow the canvas to be redrawn. But do not know how to get a HRGN hrgnUpdate for it, It has a flag to not call the WM_paint message too.

How would you use RedrawWindow in Delphi.

Last edited by lexd; 01-30-2016 at 02:29 AM.
Reply With Quote
  #9  
Old 01-30-2016, 03:27 AM
lexd lexd is offline
Senior Member
 
Join Date: Feb 2015
Posts: 268
Default

I have been trying This in my code without success to get it to go.

HTML Code:
    Rect.TopLeft := BoundsRect.TopLeft;
    Rect.Bottom := ClientPoint.Y;
    Rect.Right := ClientPoint.X;
    RedrawWindow(Handle, @Rect, SIMPLEREGION,
                 RDW_NOINTERNALPAINT or RDW_INVALIDATE);
    DC := GetDC(0);
    MemBitmap := CreateCompatibleBitmap(DC, ClientPoint.X, ClientPoint.Y);
    ReleaseDC(0, DC);
    MemDC := CreateCompatibleDC(0);
    OldBitmap := SelectObject(MemDC, MemBitmap);
    Perform(WM_ERASEBKGND, DC, DC);
    try
It does not even erase background
Reply With Quote
  #10  
Old 02-01-2016, 03:51 AM
lexd lexd is offline
Senior Member
 
Join Date: Feb 2015
Posts: 268
Default

More study on the subject MS always seem to talk about
SetWindowExtEx
SetViewportExtEx
Ref https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

So I'm playing with this but do not fully understand
Sometimes It's talking screen coordinates that I have to get out of Delphi
The main question is what i'm doing like
SetWindowExtEx sets the top left?
SetViewportExtEx sets the printable area?

HTML Code:
      DC := BeginPaint(Handle, PS);
      SetWindowExtEx(DC, Left, Top, Nil);
      SetViewportExtEx(DC, Left + Width, Top + Height, Nil);
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 01:24 AM.


Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2019, vBulletin Solutions, Inc.