求救啊,DBGrid闪烁的问题!

wg961423 2009-06-03 01:50:34
目的:鼠标在DBGrid上移动,不点击鼠标,把鼠标所在的地方的那条记录的某个值(没有在表格中显示出来,但DataSet中有)用Hint的方式显示出来。

Unit1.h

private: // User declarations
int OLDX,OLDY;
THintWindow *fmHint;


Unit1.cpp

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Application->CreateForm(HintWindowClass,&fmHint);
Form1->DoubleBuffered=true;
DBG->DoubleBuffered=true;
DBGrid1->DoubleBuffered=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DBGrid1MouseMove(TObject *Sender, TShiftState Shift,
int X, int Y)
{
AnsiString Str;
TGridCoord p=DBGrid1->MouseCoord(X,Y);
Str="X="+IntToStr(p.X)+" Y="+IntToStr(p.Y);
if(p.X>0&&p.Y>0)
{
if(OLDX!=p.X||OLDY!=p.Y)
{
class TMyGrid:public TCustomDBGrid
{
public:
__property DataLink;
};
TMyGrid *MyGrid=(TMyGrid*)DBGrid1;
MyGrid->DataSource->DataSet->DisableControls();
int i=MyGrid->DataLink->ActiveRecord;
TBookmark BM;
BM=DBG->DataSource->DataSet->GetBookmark();
MyGrid->DataSource->DataSet->MoveBy(OLDY-i-1);
Str+="\n"+MyGrid->DataSource->DataSet->FieldByName("OrderID")->AsString;
if(MyGrid->DataSource->DataSet->FieldByName("Brand")->AsString!="")
Str+="\n"+MyGrid->DataSource->DataSet->FieldByName("Brand")->AsString;
if(MyGrid->DataSource->DataSet->FieldByName("Note")->AsString!="")
Str+="\n"+MyGrid->DataSource->DataSet->FieldByName("Note")->AsString;
MyGrid->DataLink->ActiveRecord=i;
MyGrid->DataSource->DataSet->GotoBookmark(BM);
MyGrid->DataSource->DataSet->FreeBookmark(BM);
MyGrid->DataSource->DataSet->EnableControls();
TRect R = fmHint->CalcHintRect(1000,Str,NULL);
TPoint P = Mouse->CursorPos;
OffsetRect(R,P.x,P.y);
fmHint->ActivateHint(R,Str);
}
OLDX=p.X;
OLDY=p.Y;
}
else
{
OLDX=p.X;
OLDY=p.Y;
fmHint->ReleaseHandle();
}
}
//---------------------------------------------------------------------------



用这个代码可以达到目的,但鼠标在DBGrid上移动的时候,DBGrid会不断的闪烁,请问各位大大,有没有什么好的解决方法?
系统为2003或XP, 在Vista下不闪。
...全文
266 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
mypop2006 2009-06-24
  • 打赏
  • 举报
回复
我模糊记得在delphi里闪烁可以打开什么双缓存的 不知道bcb理有没有
wg961423 2009-06-05
  • 打赏
  • 举报
回复
奇怪,这个方法在用鼠标滚动(DataSet会动)的时候,有时候会出现定位不准的问题,但又不是每次都出现,不过出现问题后,只要在DBGrid上点一下重新设定一下DataSet就又可以了。
wenyongjie 2009-06-05
  • 打赏
  • 举报
回复
帮顶不要分
jaffy 2009-06-05
  • 打赏
  • 举报
回复
DBGRID闪烁是刷新的问题吧。
draculamx 2009-06-04
  • 打赏
  • 举报
回复


class TMyGrid:public TCustomDBGrid //放到头文件去
{
public:
__property DataLink;
};

TMyGrid *MyGrid=(TMyGrid*)DBGrid1; //在头文件中,把 MyGrid 作为 TForm1 的一个类成员,然后把这行代码放在 TForm1 的 Create 事件中

//MouseMove 事件触发的频率很高(鼠标移动时),你每次触发这个事件,都要定义一个类,并且生成它的一个对象(并且这个对象比较复杂),每次事件结束时还要析构,这样效率会非常低下,还不如把这个类生成的对象作为一个全局变量比较快


wg961423 2009-06-04
  • 打赏
  • 举报
回复
对了,忘记说了,经过试验,闪是因为下面的语句造成的:

MyGrid->DataSource->DataSet->DisableControls();
MyGrid->DataLink->ActiveRecord=i;
MyGrid->DataSource->DataSet->EnableControls();

不知道其他的同志们有没有什么好的方法?
wg961423 2009-06-04
  • 打赏
  • 举报
回复
找了一个笨方法,就是再建一个DataSet,和DBGrid的内容一样,鼠标移动时,不动DBGrid的DataSet,而是去动新的DataSet,如下:



void __fastcall TForm1::DBGMouseMove(TObject *Sender, TShiftState Shift, int X,
int Y)
{
if(VT1->RecordCount<1)
{
VT->SaveToStream(ms,true);
VT1->LoadFromStream(ms,true);;
}
TGridCoord p=DBG->MouseCoord(X,Y);
if(p.X>0&&p.Y>0)
{
if(OLDX!=p.X||OLDY!=p.Y)
{
HintStr="X="+IntToStr(p.X)+" Y="+IntToStr(p.Y);
int i=MyGrid->DataLink->ActiveRecord;
TLocateOptions Opts;
Opts.Clear();
Opts << loCaseInsensitive;
VT1->Locate("ID",VT->FieldByName("ID")->AsString,Opts);
int a;
a=OLDY-p.Y;
VT1->MoveBy(OLDY-i-1-a);
HintStr+="\n"+MyGrid->DataSource->DataSet->FieldByName("OrderID")->AsString;
if(VT1->FieldByName("Brand")->AsString!="")
HintStr+="\n"+VT1->FieldByName("Brand")->AsString;
if(VT1->FieldByName("OrderConTentNote")->AsString!="")
HintStr+="\n"+VT1->FieldByName("OrderConTentNote")->AsString;
TRect R = fmHint->CalcHintRect(1000,HintStr,NULL);
TPoint P = Mouse->CursorPos;
OffsetRect(R,P.x,P.y);
fmHint->ActivateHint(R,HintStr);
}
OLDX=p.X;
OLDY=p.Y;
}
else
{
OLDX=p.X;
OLDY=p.Y;
fmHint->ReleaseHandle();
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DBGMouseLeave(TObject *Sender)
{
fmHint->ReleaseHandle();
VT1->Clear();
OLDX=-1;
OLDY=-1;
}
//---------------------------------------------------------------------------



不知道还有没有其他的方法啊!
queshiybb 2009-06-04
  • 打赏
  • 举报
回复
好贴,学习下
wg961423 2009-06-04
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 draculamx 的回复:]
C/C++ code

class TMyGrid:public TCustomDBGrid //放到头文件去
{
public:
__property DataLink;
};

TMyGrid *MyGrid=(TMyGrid*)DBGrid1; //在头文件中,把 MyGrid 作为 TForm1 的一个类成员,然后把这行代码放在 TForm1 的 Create 事件中

//MouseMove 事件触发的频率很高(鼠标移动时),你每次触发这个事件,都要定义一个类,并且生成它的一个对象(并且这个对象比较复杂),
每次事件结束时还要析构,…
[/Quote]

试过了,还是闪。
看了一下,当鼠标动的快的时候,闪的很厉害,慢点就好点!
wg961423 2009-06-04
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 ccrun 的回复:]
我试了试代码,没有发现闪烁?Vista + C++Builder6

不过我看代码中,关于TMyGrid的定义,最好放到DBGrid1MouseMove函数体的外面。
[/Quote]

我的原始的代码,在Vista下是正常的,不闪,但在XP或2003下就闪了。
ccrun.com 2009-06-03
  • 打赏
  • 举报
回复
我试了试代码,没有发现闪烁?Vista + C++Builder6

不过我看代码中,关于TMyGrid的定义,最好放到DBGrid1MouseMove函数体的外面。
wg961423 2009-06-03
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 rouqing 的回复:]
Application->ProcessMessages();

没找了,就她了。加到你的Show Hint 事件里吧。
[/Quote]

似乎也不管用啊!
yangangs 2009-06-03
  • 打赏
  • 举报
回复
没见过,关注
纯冰糖 2009-06-03
  • 打赏
  • 举报
回复
Application->ProcessMessages();

没找了,就她了。加到你的Show Hint 事件里吧。
wg961423 2009-06-03
  • 打赏
  • 举报
回复
不用考虑Vista(我是在Vista下开发的),只要在XP或2003上不闪就行,但现在在XP下还是在闪啊!

继续救命啊!

纯冰糖 2009-06-03
  • 打赏
  • 举报
回复
那就有点特殊了,Vista下我还没做过开发,帮你顶吧。
不过一般的方法这样就可以了。
try
{
LockWindowUpdate(DBGrid->Handle);
....// Your Hint Function
}
__finally
{
LockWindowUpdate(NULL);
}

就是这样啦
总不至于考虑着放到线程里去处理吧。
帮顶,没想法了。
wg961423 2009-06-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 rouqing 的回复:]
LockWindowUpdate(DBGrid->Handle);
....// Your Hint Function
LockWindowUpdate(NULL);
[/Quote]

比之前的好了一点了,但还是在闪啊,而且本来在Vista下不闪的,现在也有点闪了。

纯冰糖 2009-06-03
  • 打赏
  • 举报
回复
LockWindowUpdate(DBGrid->Handle);
....// Your Hint Function
LockWindowUpdate(NULL);

1,178

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 数据库及相关技术
社区管理员
  • 数据库及相关技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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