急,请高手进来看看(有关模仿超级链接的问题),今天就要完成。

huang_jihua 2002-10-10 04:14:53
我想在我的DBGRID中模仿超级链接,某一个FIELD记录的是EMAIL,我想实现鼠标移到这一列字上面的时候鼠标变为crHandPoint,鼠标在其他地方的时候鼠标为crDefault,单击文字的时候可以打开email处理软件,单击文字旁边空白的时候不要打开email处理软件。
...全文
74 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
梦回童年001 2002-10-15
  • 打赏
  • 举报
回复
不错
imickey(mickey)
HearMe 2002-10-15
  • 打赏
  • 举报
回复
gz
huang_jihua 2002-10-15
  • 打赏
  • 举报
回复
谢谢duduwolf(嘟嘟狼),问题还是没有解决,再等两天,两天后结帐

duduwolf 2002-10-14
  • 打赏
  • 举报
回复
sorry,给你发迟了!我在StringGrid中实现了你要的这个功能,那是因为StringGrid是我自己画的,cells里的字也是我用textrect画上去的,所以我可以得到每个cells里的textRect;如果换成dbgrid,你也就必须得自己在OnDrawCell里自己画每个cell的字了,不然无法确切的得到Rect,下面是在StringGrid里实现的代码;
void __fastcall TFrmDBIntoList::StringGrid1DrawCell(TObject *Sender,
int ACol, int ARow, TRect &Rect, TGridDrawState State)
{
......
int Left = Rect.Left
+ (Rect.Width() - Canvas->TextWidth(StringGrid1->Cells[ACol][ARow]))/2;
int Top = Rect.Top
+ (Rect.Height() - Canvas->TextHeight(StringGrid1->Cells[ACol][ARow]))/2;
Canvas->TextRect(Rect,Left,Top,StringGrid1->Cells[ACol][ARow]);
......
}
bool TFrmDBIntoList::InText(int X, int Y, const int ACol, const int ARow) //自定义的一个函数,X和Y是鼠标在Grid中的值,ACol和ARow为Grid的列值和行值
{
TRect txtRect;
int txtWidth = StringGrid1->Canvas->TextWidth(StringGrid1->Cells[ACol][ARow]);
int txtHeight = StringGrid1->Canvas->TextHeight(StringGrid1->Cells[ACol][ARow]);
int ColWidth[10]; //假定有10个column;
ColWidth[0] = StringGrid1->ColWidths[0];
for(int i=1;i<StringGrid1->ColCount;i++)
{
ColWidth[i] = ColWidth[i-1]+StringGrid1->ColWidths[i];
if(i<ACol)break;
}
int Left = ColWidth[ACol-1]+ACol;
//ShowMessage(Left);
int Right = ColWidth[ACol]+ACol+1;
int Top = StringGrid1->DefaultRowHeight*ARow+ARow;
int Bottom = StringGrid1->DefaultRowHeight*(ARow+1)+ARow+1;
txtRect.Left = Left+(Right-Left-txtWidth)/2;
txtRect.Top = Top+(StringGrid1->DefaultRowHeight-txtHeight)/2;
txtRect.Right = txtRect.Left+txtWidth;
txtRect.Bottom = txtRect.Top+txtHeight;
Edit1->Text = "X:"+IntToStr(X)+" Y:"+IntToStr(Y)+" Left:"+IntToStr(txtRect.Left)
+" Right:"+IntToStr(txtRect.Right)+" Top:"+IntToStr(txtRect.Top)
+" Bottom:"+IntToStr(txtRect.Bottom);
if(X>=txtRect.Left&&X<=txtRect.Right&&Y>=txtRect.Top&&Y<=txtRect.Bottom)
return true;
else return false;
}
void __fastcall TFrmDBIntoList::StringGrid1MouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
//然后再StringGridMouseMove里调用上面的那个自定义函数
if(InText(X,Y,1,1))StringGrid1->Cursor = crHandPoint;//加定为StringGrid1->Cells[1][1]这一栏实现效果
else StringGrid1->Cursor = crDefault;
}
。。。。。。
写的仓促,比较凌乱,如果哪儿看不懂就在给我发端消息吧!
如果那位高手有其他的办法,望赐教!!!我这个办法太笨了... :(
duduwolf 2002-10-14
  • 打赏
  • 举报
回复
sorry,
huang_jihua 2002-10-14
  • 打赏
  • 举报
回复
还有没有人帮我看看?
imickey 2002-10-14
  • 打赏
  • 举报
回复
Q: 如何打开一个应用程序?
ShellExecute(this->m_hWnd,"open","calc.exe","","", SW_SHOW );

ShellExecute(this->m_hWnd,"open","notepad.exe",
"c:\\MyLog.log","",SW_SHOW );
As you can see, I haven't passed the full path of the programs.

Q: 如何打开一个同系统程序相关连的文档?
ShellExecute(this->m_hWnd,"open",
"c:\\abc.txt","","",SW_SHOW );

Q: 如何打开一个网页?
ShellExecute(this->m_hWnd,"open",
"http://www.google.com","","", SW_SHOW );

Q: 如何激活相关程序,发送EMAIL?
ShellExecute(this->m_hWnd,"open",
"mailto:nishinapp@yahoo.com","","", SW_SHOW );

Q: 如何用系统打印机打印文档?
ShellExecute(this->m_hWnd,"print",
"c:\\abc.txt","","", SW_HIDE);

Q: 如何用系统查找功能来查找指定文件?
ShellExecute(m_hWnd,"find","d:\\nish",
NULL,NULL,SW_SHOW);

Q: 如何启动一个程序,直到它运行结束?
SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = "c:\\MyProgram.exe";
ShExecInfo.lpParameters = "";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
或:
PROCESS_INFORMATION ProcessInfo;
STARTUPINFO StartupInfo; //This is an [in] parameter
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
if(CreateProcess("c:\\winnt\\notepad.exe", NULL,
NULL,NULL,FALSE,0,NULL,
NULL,&StartupInfo,&ProcessInfo))
{
WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
}
else
{
MessageBox("The process could not be started...");
}


Q: 如何显示文件或文件夹的属性?
SHELLEXECUTEINFO ShExecInfo ={0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_INVOKEIDLIST ;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "properties";
ShExecInfo.lpFile = "c:\\"; //can be a file as well
ShExecInfo.lpParameters = "";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
zbc 2002-10-11
  • 打赏
  • 举报
回复
你的要求可能有一点不太好实现,既然这样的话,你还不如把它的列宽固定好,以避免显示出空白区域来
huang_jihua 2002-10-11
  • 打赏
  • 举报
回复
谢谢: zbc(犹豫的强盗)
zbc(犹豫的强盗)的方法已经可以了,但是我是想在单击字符旁边的空白时不要触发,单击文字时触发。这样无法实现,请高人指点。

huang_jihua 2002-10-11
  • 打赏
  • 举报
回复
我测试的是第二列中的,你在运行期改变该列宽度试试,我在改变该列宽度后出现问题更为明显

zbc 2002-10-11
  • 打赏
  • 举报
回复
我帮你看了一下,你只要在某一列中移动的话,它的手形是不会变的,不知道你是怎么测试的.
huang_jihua 2002-10-11
  • 打赏
  • 举报
回复
谢谢: zbc(犹豫的强盗)
我现在用的就是你这个方法,如果这样的话就会出现只要单击那一列就会触发,我是想在单击字符旁边的空白时不要触发,单击文字时触发。
而且鼠标变形的时候定位有问题,我发现当我数据长的时候它定位的时候只能定位到前面一部分,也就是,我的一列为:
111sdfsdf22333asdf
122sdf1312sadfsadfsdf
1231sdf244sdfsdfssd
12413241sadfsadf
这个时候,当我鼠标移上去的时候,在前面几个字符的时候是手型的,而在后面几个字符确是普通的形状。

帮我看看什么毛病,还有没有其他办法?

huang_jihua 2002-10-11
  • 打赏
  • 举报
回复
我看有的软件可以实现的,不知道哪位高人能够指点一二,先谢谢了

zbc 2002-10-10
  • 打赏
  • 举报
回复
报歉,给你留下一个不大不小的bug,修改下面过程中的代码可以做到万无一失:
void __fastcall TForm1::DBGrid1CellClick(TColumn *Column)
{
if (Column->Index == 0)//多加了这句,也就是只有是第1列才可以打开eml的
ShellExecute(this->Handle, "open", ("mailto:" + Query1->FieldByName("gdpjmx_id")->AsString).c_str(), NULL, NULL, SW_SHOWNORMAL);
}
zbc 2002-10-10
  • 打赏
  • 举报
回复
你不要等了,我现在给你一个easy的例子,其实,这很好实现的,呵呵:
void __fastcall TForm1::DBGrid1MouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
TGridCoord p = DBGrid1->MouseCoord(X,Y);
if(p.X == 1)
DBGrid1->Cursor = crHandPoint;
else
DBGrid1->Cursor = crDefault;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DBGrid1CellClick(TColumn *Column)
{
ShellExecute(DBGrid1->Handle, "open", ("mailto:" + Query1->FieldByName("gdpjmx_id")->AsString).c_str(), NULL, NULL, SW_SHOWNORMAL);
}
这样的话,你就可以点击第一列中的值来发送eml了!
duduwolf 2002-10-10
  • 打赏
  • 举报
回复
sorry,要下班了,明早写好了给你贴上来(晚上在家没法上网!)
huang_jihua 2002-10-10
  • 打赏
  • 举报
回复
我等,谢谢


duduwolf 2002-10-10
  • 打赏
  • 举报
回复
mousehook可以解决,不过有点小题大作
你可以得到当前鼠标的point,
然后再dbgrid内得到每一个单元格的rect,然后用textheight和textwidth进行判断
...
说起来好麻烦!你等等,我给你代码先!
huang_jihua 2002-10-10
  • 打赏
  • 举报
回复
我想我还是在说清楚一点:
我现在的问题是怎么才能知道我鼠标所在的位置上面是文字,而不是一块空白。

huang_jihua 2002-10-10
  • 打赏
  • 举报
回复
怎么还是没有人帮我看看
加载更多回复(2)

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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