一个VCL元件的问题,有兴趣Please...

wwwwbb78 2002-11-20 10:02:55
我写了一个TMyPicture元件,他仅提供一个画布和几个事件,为何我对他用InvalidateRect时,它是整个重画,屏幕闪动厉害..
//////////////////////////////VCL
typedef void __fastcall(__closure *TPaintEvent) (TObject *sender);
class PACKAGE TMyPicture : public TCustomControl
{
private:
TColor FBorderLineColor;
TColor FTBorderLineColor;
TPaintEvent FOnPaint;
void __fastcall SetTBorderLineColor(TColor value);
void __fastcall DoPaint();
TColor __fastcall GetTBorderLineColor();
protected:
virtual void __fastcall WndProc(TMessage& msg);
public:
__fastcall TMyPicture(TComponent* Owner);
__property Canvas ;
__published:
__property TAlign;
__property OnMouseDown;
__property OnMouseUp;
__property OnMouseMove;
__property TColor TBorderLineColor = { read=GetTBorderLineColor, write=SetTBorderLineColor };
__property TPaintEvent OnPaint = {read=FOnPaint, write=FOnPaint };
};


//cpp文件


static inline void ValidCtrCheck(TMyPicture *)
{
new TMyPicture(NULL);
}
//---------------------------------------------------------------------------
__fastcall TMyPicture::TMyPicture(TComponent* Owner)
: TCustomControl(Owner)
{
// inherited;
Width=100;
Height=100;
}
//---------------------------------------------------------------------------
namespace Untmypicture
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TMyPicture)};
RegisterComponents("WWW", classes, 0);
}
}
//---------------------------------------------------------------------------
void __fastcall TMyPicture::SetTBorderLineColor(TColor value)
{
if(FTBorderLineColor != value) {
FTBorderLineColor = value;
Paint();
}
}
TColor __fastcall TMyPicture::GetTBorderLineColor()
{
return FTBorderLineColor;
}
void __fastcall TMyPicture::WndProc(TMessage& msg)
{
if(msg.Msg ==WM_PAINT)
{
if(FOnPaint)
FOnPaint(this);
TColor PenColor=Canvas->Pen->Color ;;
int PenWidth=Canvas->Pen->Width ;
Canvas->Pen->Color =FTBorderLineColor ;
Canvas->Pen->Width =1;
Canvas->MoveTo(0,0);
Canvas->LineTo(Width-1,0);
Canvas->LineTo(Width-1,Height-1);
Canvas->LineTo(0,Height-1);
Canvas->LineTo(0,0);
Canvas->Pen->Color=PenColor;
Canvas->Pen->Width=PenWidth;
}
TCustomControl::WndProc(msg);
}
void __fastcall TMyPicture::DoPaint()
{
if(FOnPaint!=NULL)
FOnPaint(this);
}


///


/////////////////////////////调用
void __fastcall TFrmMain::MPMainPaint(TObject *Sender)/*MyPicture1的OnPaint事件*/
{
simulator->DrawMain();
}



///////////InvalidateRect
void __fastcall TFrmMain::ToolButton16Click(TObject *Sender)
{
RECT r;
SetRect(&r,0,0,40,40);
ValidateRect(MPMain->Handle,&r,true);
}
...全文
30 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
Lewolf 2002-11-25
  • 打赏
  • 举报
回复
使用TCanvas的Draw函数比CopyRect可能更快一些。
wwwwbb78 2002-11-21
  • 打赏
  • 举报
回复
基本OK
wwwwbb78 2002-11-21
  • 打赏
  • 举报
回复
非常感谢warton() ,myy() 和Lewolf(李狼) .
用幕后位图确实可以。



Graphics::TBitmap *Bitmap;
TRect MyRect, MyOther;
MyRect = Rect(0,0,1000,1000);
MyOther = Rect(0,0,1000, 1000);
Bitmap = new Graphics::TBitmap;
Bitmap->LoadFromFile("c:\\windows\\安装程序.bmp");//为何没有她就什么显示都没有
Bitmap->Canvas->Brush->Color =clRed;
Bitmap->Canvas->Ellipse(10,10,100,100);

//MPMain->Canvas->BrushCopy(MyRect, Bitmap, MyRect, clBlack);
MPMain->Canvas->CopyRect(MyOther, Bitmap->Canvas, MyOther);
delete Bitmap;
myy 2002-11-20
  • 打赏
  • 举报
回复
typedef void __fastcall(__closure *TPaintEvent) (TObject *sender);
class PACKAGE TMyPicture : public TCustomControl
{
private:
TColor FBorderLineColor;
TColor FTBorderLineColor;
TPaintEvent FOnPaint;
void __fastcall SetTBorderLineColor(TColor value);
////////void __fastcall DoPaint();////可以不要
TColor __fastcall GetTBorderLineColor();
protected:
virtual void __fastcall Paint();
public:
__fastcall TMyPicture(TComponent* Owner);
__property Canvas ;
__published:
__property TAlign;
__property OnMouseDown;
__property OnMouseUp;
__property OnMouseMove;
__property TColor TBorderLineColor = { read=GetTBorderLineColor, write=SetTBorderLineColor };
__property TPaintEvent OnPaint = {read=FOnPaint, write=FOnPaint };
};


static inline void ValidCtrCheck(TMyPicture *)
{
new TMyPicture(NULL);
}
//---------------------------------------------------------------------------
__fastcall TMyPicture::TMyPicture(TComponent* Owner)
: TCustomControl(Owner)
{
// inherited;
Width=100;
Height=100;
}
//---------------------------------------------------------------------------
namespace Untmypicture
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TMyPicture)};
RegisterComponents("WWW", classes, 0);
}
}
//---------------------------------------------------------------------------
void __fastcall TMyPicture::SetTBorderLineColor(TColor value)
{
if(FTBorderLineColor != value) {
FTBorderLineColor = value;
////////////////////////
////Paint();// 改为:Invalidate();
////////////////////////
}
}
TColor __fastcall TMyPicture::GetTBorderLineColor()
{
return FTBorderLineColor;
}
/*
*void __fastcall TMyPicture::DoPaint()
*{
* if(FOnPaint!=NULL)
* FOnPaint(this);
*}
*/
void __fastcall TMyPicture::Paint()
{
if(FOnPaint!=NULL)
FOnPaint(this);
TColor PenColor=Canvas->Pen->Color ;;
int PenWidth=Canvas->Pen->Width ;
Canvas->Pen->Color =FTBorderLineColor ;
Canvas->Pen->Width =1;
Canvas->MoveTo(0,0);
Canvas->LineTo(Width-1,0);
Canvas->LineTo(Width-1,Height-1);
Canvas->LineTo(0,Height-1);
Canvas->LineTo(0,0);
Canvas->Pen->Color=PenColor;
Canvas->Pen->Width=PenWidth;
}
wwwwbb78 2002-11-20
  • 打赏
  • 举报
回复
to:myy() (
没用
按你的方法,改动如下:它还是闪

typedef void __fastcall(__closure *TPaintEvent) (TObject *sender);
class PACKAGE TMyPicture : public TCustomControl
{
private:
TColor FBorderLineColor;
TColor FTBorderLineColor;
TPaintEvent FOnPaint;
void __fastcall SetTBorderLineColor(TColor value);
void __fastcall DoPaint();
TColor __fastcall GetTBorderLineColor();
protected:
virtual void __fastcall Paint();
public:
__fastcall TMyPicture(TComponent* Owner);
__property Canvas ;
__published:
__property TAlign;
__property OnMouseDown;
__property OnMouseUp;
__property OnMouseMove;
__property TColor TBorderLineColor = { read=GetTBorderLineColor, write=SetTBorderLineColor };
__property TPaintEvent OnPaint = {read=FOnPaint, write=FOnPaint };
};


static inline void ValidCtrCheck(TMyPicture *)
{
new TMyPicture(NULL);
}
//---------------------------------------------------------------------------
__fastcall TMyPicture::TMyPicture(TComponent* Owner)
: TCustomControl(Owner)
{
// inherited;
Width=100;
Height=100;
}
//---------------------------------------------------------------------------
namespace Untmypicture
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TMyPicture)};
RegisterComponents("WWW", classes, 0);
}
}
//---------------------------------------------------------------------------
void __fastcall TMyPicture::SetTBorderLineColor(TColor value)
{
if(FTBorderLineColor != value) {
FTBorderLineColor = value;
Paint();
}
}
TColor __fastcall TMyPicture::GetTBorderLineColor()
{
return FTBorderLineColor;
}
void __fastcall TMyPicture::DoPaint()
{
if(FOnPaint!=NULL)
FOnPaint(this);
}
void __fastcall TMyPicture::Paint()
{
if(FOnPaint!=NULL)
FOnPaint(this);
TColor PenColor=Canvas->Pen->Color ;;
int PenWidth=Canvas->Pen->Width ;
Canvas->Pen->Color =FTBorderLineColor ;
Canvas->Pen->Width =1;
Canvas->MoveTo(0,0);
Canvas->LineTo(Width-1,0);
Canvas->LineTo(Width-1,Height-1);
Canvas->LineTo(0,Height-1);
Canvas->LineTo(0,0);
Canvas->Pen->Color=PenColor;
Canvas->Pen->Width=PenWidth;
}
myy 2002-11-20
  • 打赏
  • 举报
回复
你不应在WndProc中绘制,应重载Paint()方法,
在Paint()方法中绘制,决不闪烁!
wwwwbb78 2002-11-20
  • 打赏
  • 举报
回复
对Form就可以在OnPaint事件中加入代码,然后用InvalidateRect局部更新,它就不闪
我的元件的为何不可?
我就是模仿Form
warton 2002-11-20
  • 打赏
  • 举报
回复
-----------------关注此问题------------------
warton 2002-11-20
  • 打赏
  • 举报
回复

应该在onpaint事件中加入代码,因为你一改变canvas它就paint,所有内动

wwwwbb78 2002-11-20
  • 打赏
  • 举报
回复
谢谢,myy() ,Lewolf(李狼) ,warton() 了,


{要绘制的东西很多,是几个数十万个节点的list,的连线段,
和几百个vector存储的多边形区域, }


我就用幕后位图试一下
Lewolf 2002-11-20
  • 打赏
  • 举报
回复
你这个问题到是怪,我以前都没有碰到过,TCustomerControl已经提供了Canvas和Paint方发,重载它,应该没有问题,如果界面上要绘制的东西多的化,可以使用幕后位图,屏幕绘图时只是将位图拷贝过来。
myy 2002-11-20
  • 打赏
  • 举报
回复
我明白你的意思了。你要的是“局部更新”,那我倒没有深入研究过,Sorry.
wwwwbb78 2002-11-20
  • 打赏
  • 举报
回复
to:myy()
谢谢你的帮助;
我的本意是:做一个VCL元件,它提供一个画布,和OnPaint事件,并且能对他进行局部更新(不闪). <我在外部程序中要用到该元件,并在OnPaint中添加代码,还用InvalidateRect>.
我把原码简化如下:(对它的Handle用Invalidate还是闪)
/////
typedef void __fastcall(__closure *TPaintEvent) (TObject *sender);
class PACKAGE TMyPicture : public TCustomControl
{
private:
TPaintEvent FOnPaint;
protected:
virtual void __fastcall Paint();
public:
__fastcall TMyPicture(TComponent* Owner);
__property Canvas ;
__published:
__property TPaintEvent OnPaint = {read=FOnPaint, write=FOnPaint };
};

//////////////////
static inline void ValidCtrCheck(TMyPicture *)
{
new TMyPicture(NULL);
}
//---------------------------------------------------------------------------
__fastcall TMyPicture::TMyPicture(TComponent* Owner)
: TCustomControl(Owner)
{
Width=100;
Height=100;
}
//---------------------------------------------------------------------------
namespace Untmypicture
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TMyPicture)};
RegisterComponents("WWW", classes, 0);
}
}
//---------------------------------------------------------------------------

void __fastcall TMyPicture::Paint()
{
if(FOnPaint!=NULL)
FOnPaint(this);
}

602

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧