|
|
You should delete the Graphics you get from Graphics::FromImage().
Thanks for the double buffer example!
|
|
|
|
|
What a great little class... - CMemDC. Cheers Keith
|
|
|
|
|
salam agha mazy
man mikham dar atl az timer estefadeh konam
mamnoon
MILAD.
|
|
|
|
|
I seem's that You are iranian?
If you are mail me the answer.
I have some problems...
Thanks.
Milad.
|
|
|
|
|
I saw this message before, now i have to post my own. I tried All the ways of drawing with double buffer, and without success - my image still flickers!!!. I don't know what's wrong, and drawing takes all the performance of my processor. My friend uses the GDI+ in C# and he said that never had this problem. Am i doing something wrong??? For the first i tried to use Bitmap of GDI+, and it flicket, then i tried another way - to draw in one buffer and the with GDI function BitBlt draw this buffer on the screen, and it flicked again!!! Or i missunderstand something??? I want to make multiplication,i've made it in GDI, and it was good, but now i want to implement the antialiassing, that's why i decided to use GDI+. But i don't have a good animation. I hope you understand me.
Please HELP
I Found the PROBLEM!!!!!!!!!!!!!!!
It was in INVALIDATE()!!!!!!!
Now i avoid this function, and everything is allright now!!!!!!!!!!!
|
|
|
|
|
You said it's not interesting to wait 36 seconds each time the window redraw... well it's not interesting to wait 5 seconds neither..
|
|
|
|
|
visionz wrote:
You said it's not interesting to wait 36 seconds each time the window redraw... well it's not interesting to wait 5 seconds neither..
I guess 31 seconds is a lot in computer world !
Mazy
No sig. available now.
|
|
|
|
|
okay... no matter how hard I try or what I try, gdi+ can't seem to successfuly create a bitmap in memory. This should be simple but it's being complicated for whatever reason.
After much frustration, I leave this code at my last attempt. Here I create a DC compatible with the window client DC and select a compatible bitmap the size of the client region into it. Then I create a Graphics object off the DC and draw to it with GDI+. When done drawing, I create a GDI+ bitmap from the GDI bitmap that should have been drawn to. From there it should get drawn to the screen. Nothing gets drawn, as if there is no bitmap to draw.
I've noticed that no matter what I try, when I create a GDI+ bitmap with the new keyword, the pointer is ALWAYS null. What am I doing wrong? can anyone help?
<br />
void DrawScreen(){<br />
HDC BackDC;<br />
HBITMAP BackBMP, old;<br />
<br />
<br />
Rect ClientRect;<br />
<br />
<br />
<br />
Graphics graphics(Globals.hDC);<br />
<br />
graphics.GetClipBounds(&ClientRect);<br />
<br />
BackDC = CreateCompatibleDC(Globals.hDC);<br />
BackBMP = CreateCompatibleBitmap(BackDC,ClientRect.Width, ClientRect.Height);<br />
Graphics back(BackDC);<br />
old = (HBITMAP)SelectObject(BackDC, BackBMP);<br />
<br />
Pen pen(Color(255, 0, 255, 0));<br />
<br />
<br />
<br />
<br />
<br />
<br />
back.DrawLine(&pen, (REAL)0,(REAL)0,(REAL)ClientRect.Width,(REAL)ClientRect.Height);<br />
<br />
Bitmap bmp(BackBMP, NULL); <br />
<br />
graphics.DrawImage(&bmp,0,0,bmp.GetWidth(),bmp.GetHeight());<br />
<br />
<br />
SelectObject(BackDC, old);<br />
DeleteObject(BackBMP);<br />
DeleteDC(BackDC);<br />
<br />
};
|
|
|
|
|
This Article may be helpful!
HOWTO: Draw on a Memory Bitmap in GDI+PSS ID Number: Q299583
Article Last Modified on 09-18-2001
--------------------------------------------------------------------------------
The information in this article applies to:
Microsoft Win32 Application Programming Interface (API)
the operating system: Microsoft Windows XP
the operating system: Microsoft Windows NT 4.0
the operating system: Microsoft Windows 2000
the operating system: Microsoft Windows 98
the operating system: Microsoft Windows Millennium Edition
--------------------------------------------------------------------------------
Summary
You may sometimes want to obtain a bitmap or image that contains the image that was drawn by a graphics object.
One of the overloaded constructors for the Bitmap class takes a graphics object as a parameter. However, this constructor does not use the image drawn by the graphics object to initialize the bitmap bits. It simply creates a bitmap with properties similar to the graphics object, such as dots per inch.
More Information
Because the Bitmap constructor does not initialize the image bits by using the image from the graphics object, code like the following will NOT result in a bitmap that contains the image that was drawn by the Graphics object:
Graphics g( hWnd );
// Draw on g
Bitmap b( 100, 100, &g ); // Will not get image from g
To use a graphics object to draw on a bitmap, code like the following can be used instead:
Bitmap b(100,100);
Graphics *g = Graphics::FromImage(&b);
// Draw on g
To capture the preexisting image from a window, a Windows Graphics Device Interface (GDI) function such as BitBlt() or StretchBlt() would have to be used to copy the image from the screen to a memory bitmap. This memory bitmap could then be used in the overloaded Bitmap constructor, which takes an HBITMAP as a parameter.
References
For additional information on capturing the screen using GDI, click the article number below to view the article in the Microsoft Knowledge Base:
Q186736 HOWTO: Capture and Print an Entire Window
"Capturing an Image" in the GDI section of the Platform SDK Documentation:
http://msdn.microsoft.com/library/en-us/gdi/hh/gdi/bitmaps_5a5h.asp?frame=true
Additional query words:
Keywords: kbDSupport
Issue Type: kbhowto
Technology: kbAudDeveloper kbWin32sSearch kbWin32API
lyx in China
|
|
|
|
|
Here is what I did to implement your double buffering idea, but it seems like I cannot create the graphics unless I use CreateGraphics. But then my code doesn't do any double buffering. Any ideas to fix the problem.
Thanks in advance.
Here is the code:
#include "stdafx.h"
#using <mscorlib.dll>
#using <system.dll>
#using <system.drawing.dll>
#using <system.windows.forms< code="">.dll>
using namespace System::Windows::Forms;
using namespace System;
using namespace System::Drawing;
using namespace System::Drawing::Drawing2D;
using namespace System::ComponentModel;
using namespace System::Drawing::Imaging;
// Class that implements simple windows form
__gc class MainForm : public Form
{
// Constructor
public:
MainForm::MainForm();
public:
void MainForm::BtnClicked(Object* pSender, EventArgs* pe);
private:
};
void MainForm::BtnClicked(Object* pSender, EventArgs* pe)
{
//Graphics* pg = CreateGraphics();
Bitmap* bmp = new Bitmap(800,600);
Graphics* pg = Graphics::FromImage(bmp);
//pg->FromImage(bmp);
Pen* pen = new Pen(Color::Blue,2);
pg->DrawLine(pen,Point(0,0),Point(800,600));
pg->DrawImage(bmp,0,0);
}
MainForm::MainForm()
{
Text = S"TestWindow";
ClientSize = System::Drawing::Size(800,600);
// Add button
Button* drawBtn = new Button();
drawBtn->Text = S"Draw";
drawBtn->Location = Point(700,560);
Controls->Add(drawBtn);
drawBtn->Click += new EventHandler(this, &MainForm::BtnClicked);
}
// This is the entry point for this application
void __stdcall WinMain(void)
{
try
{
Application::Run(new MainForm());
}
catch (Exception* e)
{
MessageBox::Show(e->get_Message());
}
}
|
|
|
|
|
Hi, I get a memory leak if i don't delete the Graphics* graph at the end of my drawing code.
|
|
|
|
|
Thanks for this example of double buffering. I implemented it in my program where I draw a 150x300 pixel drawing into a static control. The drawing consists of rectangles that are filled with colour. The colour changes when one of the parameters changes, roughly every 500 ms. I call Invalidate() to provoke OnPaint() to get the window to repaint itself. Instead of a smooth change of colour the image flickers at every redraw.
Doing this in GDI with BitBlt does not give flickering.
Is there anything that I can do to make redraw even faster?
Hidde Wallaart
software engineer
www.leo-em.co.uk
|
|
|
|
|
Sorry, I have to retract on what I just said. It was the way I invoked a redraw that caused the flickering, not any slowness in GDI+ itself. Instead of calling
Invalidate();
I have to call from my dialog:
CRect rect;<br />
m_cPicture.GetClientRect(&rect);<br />
m_cPicture.InvalidateRect(&rect);<br />
to get a flicker-free redraw. The m_cPicture object is an instance of CPicStatic, a CStatic derived class. The picture box is drawn on the dialog. All the drawing takes place in CPicStatic.
I also implemented an alternative way of double buffering using the CMemDC class of Keith Rule (http://www.codeproject.com/gdi/flickerfree.asp[^]). The way to do that is:
<br />
#include "memdc.h"<br />
void CPicStatic::OnPaint() <br />
{<br />
using namespace Gdiplus;<br />
<br />
CPaintDC dc(this);<br />
<br />
CRect bounds;<br />
GetClientRect(&bounds);<br />
<br />
CMemDC memDC(&dc, &bounds);<br />
Graphics graphics(memDC.m_hDC);<br />
<br />
}
The two methods of double buffering both seem to work equally well, even when I redraw once every millisecond.
Hidde Wallaart
software engineer
www.leo-em.co.uk
|
|
|
|
|
However, this method will not work for a scroll view that is using GDI+. What should we do?
|
|
|
|
|
hi, i'm a lowly co-op and i was asked to implement a gdi+ graphing ocx, as u have probably guessed, its finished but it flickers.. i've already implemented double buffering but i still have a flickering problem (but at least its a uniform flicker now )
after creating a CStatic member variable for a picture control (i may have misunderstood your instructions there) and using the native (to the instance of cstatic) invalidaterect and setclient rect functions, my control refreshes only after it is forced to by being covered up, etc.
i have the m_cpicture.InvalidateRect(&rect) call in the same place i generally call invalidate, at the end of the paint function, but it doesn't repaint unless forced.
:-OExcuse my n00bieness
Sincere thanx in advance
|
|
|
|
|
Maybe you need to overrid your WM_ERASEBKGRND message.
Here is some code I use to double buffer a Scrollview derived class. I modified this code from some other code I got off the site:
This is in the OnDraw or OnPaint function:
void CQTTDemoView::OnDraw(CDC* pDC)
{
CRect rect;
GetClientRect(&rect);
Rect rc(rect.left, rect.top, rect.Width(), rect.Height());
Bitmap bmp(rect.Width(), rect.Height());
Color cw;
// Block for Graphics
Graphics g(pDC->GetSafeHdc());
g.SetSmoothingMode(SmoothingModeHighQuality);
g.SetInterpolationMode(InterpolationModeHighQualityBicubic);
g.SetPixelOffsetMode(PixelOffsetModeHighQuality);
if (m_bDoubleBuffer)
{
Graphics* memgraph = Graphics::FromImage(&bmp);
memgraph ->SetSmoothingMode(SmoothingModeHighQuality);
memgraph ->SetInterpolationMode(InterpolationModeHighQualityBicubic);
memgraph ->SetPixelOffsetMode(PixelOffsetModeHighQuality);
memgraph->FillRectangle(m_pBrushes[6], rect.left, rect.top, rect.Width(), rect.Height());
for (int i = 0; i < 6; i++)
{
memgraph->FillPath(m_pBrushes[i], & m_Paths[i]);
memgraph->DrawPath(m_pPens[i], & m_Paths[i]);
}
g.DrawImage(&bmp, rect.left, rect.top, rect.right, rect.bottom);
delete memgraph;
}
else
{
for (int i = 0; i < 6; i++)
{
g.FillPath(m_pBrushes[i], & m_Paths[i]);
g.DrawPath(m_pPens[i], & m_Paths[i]);
}
};
m_Tracker.Draw(pDC);
}
Also this or similiar--if you don't override this and draw the background on the backbuffer, you will get a repaint of the client with the default brush in the WNDCLASS.
BOOL CQTTDemoView::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
if (m_bDoubleBuffer)
return TRUE;
else
return CScrollView::OnEraseBkgnd(pDC);
}
Marty
|
|
|
|
|
Hi,
I'm trying to draw a customer list view with gdi plus. WS_EX_COMPOSITED is a nice window style that would give double buffering, but it screws up gdi plus alpha stuff and i can't use it. i would double buffer myself, but i am in cListControl::DrawItem(DRAWITEMSTRUCT* DrawItemInfo), which means i would have to double buffer each item individually.
any thoughts?
much thanx!
Check out Aephid Photokeeper, the powerful digital
photo album solution at www.aephid.com.
|
|
|
|
|
Hello ,
I want to use double buffering with WS_EX_COMPOSITED extended window style ,but I don't know how to use it, just set WS_EX_COMPOSITED style?
I use dialog base app , please help me
|
|
|
|
|
Hi, have you read the comment below? It says how to do double buffering in .net. I don't know too much about .net, but I believe it does give you access to the raw windows api if you need to.
The api says:
WS_EX_COMPOSITED Windows XP: Paints all descendants of a window in bottom-to-top painting order using double-buffering. For more information, see Remarks. This cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC.
So this style only works on xp, and you must specify it when the window (or dialog) is actually created. I think you need to override PreCreateWindow(), at least under mfc. Dunno about .net.
Cheers,
swine
Check out Aephid Photokeeper, the powerful digital
photo album solution at www.aephid.com.
|
|
|
|
|
.net gives you doublebuffering automatically if you set the Style property of your form/control like so
SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint,true);
|
|
|
|
|
yes,but this article is not limited to .Net frameworks
Thanks
Mazy
Don't Marry a Person You Can Live With...
Marry Someone You Can Not Live Without
|
|
|
|
|
I'm sure that this would be more obvious if your article
actually said so, or had a better introductory or technical
description. Your article is severely lacking clarity...
you might want to rework it.
|
|
|
|
|