如何拖StringGrid->Cells的值到其他空间中?

牧牛人软件 2009-08-08 08:02:42
如题,谢谢!
...全文
165 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
牧牛人软件 2009-08-13
  • 打赏
  • 举报
回复
不好意思,这么点分累了这么多人,现在的贴又不能加分,对不起了!
ccrun.com 2009-08-12
  • 打赏
  • 举报
回复
jjwwang的方法不错,但是有一点,当鼠标处于拖拽状态的时候,是不会触发OnMouseMove事件的。所以,上面的这段代码单独使用有效果,可是在楼主这个问题上,就不行了。
CACACACACA 2009-08-12
  • 打赏
  • 举报
回复
拖放的过程中,随时显示一个闪动的光标并随着鼠标移动而改变位置。
//------------
再补充一下,估计就完美了. :)


procedure TForm1.Memo1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
CharIndex, CharLine, CharPos: integer;
begin
CharIndex := LoWord( Memo1.Perform( EM_CHARFROMPOS,
0,
MAKELPARAM(X, Y)) );

CharLine := Memo1.Perform( EM_LINEFROMCHAR,
CharIndex,
0);

CharPos := CharIndex - Memo1.Perform( EM_LINEINDEX,
CharLine,
-1);

Caption := 'X='+IntToStr(CharPos)+' : Y='+IntToStr(CharLine);

Memo1.CaretPos := Point(CharPos, CharLine);

//粘贴文本
//...
end;
ccrun.com 2009-08-12
  • 打赏
  • 举报
回复
光红的分真难挣啊。

将StringGrid格子中的内容拖放到Memo中当前鼠标位置,最终代码:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
// 往StringGrid添加一些数据
for (int i = 1; i < StringGrid1->RowCount; i++)
{
for (int j = 1; j < StringGrid1->ColCount; j++)
{
StringGrid1->Cells[i][j] = IntToStr(i * 10 + j);
}
}

// StringGrid的DragMode默认属性不要改动
StringGrid1->DragMode = dmManual;

// Memo需要将滚动条显示出来,否则内容显示超过一屏时计算Y坐标有误差
Memo1->ScrollBars = ssBoth;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Memo1DragDrop(TObject *Sender, TObject *Source,
int X, int Y)
{
// 拖放到Edit中时,读取拖动源StringGrid的当前格子内容
TStringGrid *sg = (TStringGrid *)Source;
if (!sg) return;

TMemo *mmo = (TMemo *)Sender;
if (!mmo) return;

int x, y;
SIZE Size;
HFONT hOldFont;
TEXTMETRIC tm;

HDC hDC = GetDC(mmo->Handle);
hOldFont = SelectObject(hDC, mmo->Font->Handle);
GetTextMetrics(hDC, &tm);
y = GetScrollPos(mmo->Handle, SB_VERT) + Y / tm.tmHeight;
if (y < mmo->Lines->Count)
{
AnsiString str = mmo->Lines->Strings[y];
LPCSTR s = str.c_str();
for(LPCSTR t=s; *t!=NULL; s=t)
{
t = CharNext(t);
GetTextExtentPoint(hDC, str.c_str(), t-str.c_str(), &Size);
if(X < Size.cx)
break;
}
x = int(s - str.c_str());
}
SelectObject(hDC, hOldFont);
ReleaseDC(mmo->Handle, hDC);

Caption = AnsiString("X=") + x + " Y=" + y;

String strLine = mmo->Lines->Strings[y];
mmo->Lines->Strings[y] = strLine.SubString(1, x)
+ sg->Cells[sg->Col][sg->Row]
+ strLine.SubString(x + 1, strLine.Length());
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Memo1DragOver(TObject *Sender, TObject *Source,
int X, int Y, TDragState State, bool &Accept)
{
// 鼠标经过Edit时,判断拖动源,接受来自属于TStringGrid的组件的拖放
Accept = Source->InheritsFrom(__classid(TStringGrid));
}
//---------------------------------------------------------------------------

void __fastcall TForm1::StringGrid1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
// 在StringGrid中按下鼠标时判断当前是否在有内容的格子中
int nCol, nRow;
StringGrid1->MouseToCell(X, Y, nCol, nRow);

if (nCol > 0 && nRow > 0)
{
StringGrid1->BeginDrag(true);
}
}
牧牛人软件 2009-08-12
  • 打赏
  • 举报
回复
谢谢两位!很不好意思,怪我之前没有将事情说清楚,其实我是要“拖”到MENO中,请问MENO.Perform怎么用?
按jjwwang的代码只能拖到第一行。
CACACACACA 2009-08-10
  • 打赏
  • 举报
回复
procedure TForm1.Edit1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
//楼主想要这么?
Edit1.SelStart := Edit1.Perform( EM_CHARFROMPOS, 0, MAKELPARAM(X, Y) );
end;
ccrun.com 2009-08-10
  • 打赏
  • 举报
回复
我又来了!!!根据6楼的需求,略加工了一下,大致可以实现将“拖入的字符”加入到Edit->text中间去,不完美的是不能象某些编辑软件一样,拖放的过程中,随时显示一个闪动的光标并随着鼠标移动而改变位置。

void __fastcall TForm1::Edit1DragDrop(TObject *Sender, TObject *Source,
int X, int Y)
{
// 拖放到Edit中时,读取拖动源StringGrid的当前格子内容
TStringGrid *sg = (TStringGrid *)Source;
if (!sg) return;

TEdit *edt = (TEdit *)Sender;
if (!edt) return;

TControlCanvas *cc = new TControlCanvas;
try
{
cc->Control = edt;
String strText = edt->Text;

// 计算Edit中字符串的宽度(注意不是字符串的长度)
int nTextWidth = cc->TextWidth(strText);
// 计算每个字符地宽度
int nCharWidth = nTextWidth / strText.Length();
// 根据当前鼠标所在的X坐标计算大概是第几个字符的位置
int nCharIndex = (X - 2) / nCharWidth;

// 将StringGrid当前格式的内容添加到Edit文本中
edt->Text = strText.SubString(1, nCharIndex)
+ sg->Cells[sg->Col][sg->Row]
+ strText.SubString(nCharIndex + 1, 256);
}
__finally
{
delete cc;
}
}
牧牛人软件 2009-08-10
  • 打赏
  • 举报
回复
我是想将“拖入的字符”加入到Edit->text中间去,不是覆盖。
如何通过Edit1DragDrop中坐标X\Y计算Edit->text的位置?
谢谢!
Edit1DragDrop(*Sender, TObject *Source, int X, int Y)
ccrun.com 2009-08-09
  • 打赏
  • 举报
回复
怎么光红也问问题啊。

针对一楼的代码,首先不建议将StringGrid的DragMode设置为dmAutomatic,因为这样会使得无法用鼠标选中StringGrid的格子
其次ListBox作为拖放的接受方,无需设置DragMode属性,除非需要从ListBox再拖回StringGrid

以下例子实现将StringGrid中选中格子的内容拖放到Edit中,代码很简单,看注释即可:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
// 往StringGrid添加一些数据
for (int i = 1; i < StringGrid1->RowCount; i++)
{
for (int j = 1; j < StringGrid1->ColCount; j++)
{
StringGrid1->Cells[i][j] = IntToStr(i * 10 + j);
}
}
// StringGrid的DragMode默认属性不要改动
StringGrid1->DragMode = dmManual;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1DragDrop(TObject *Sender, TObject *Source,
int X, int Y)
{
// 拖放到Edit中时,读取拖动源StringGrid的当前格子内容
TStringGrid *sg = (TStringGrid *)Source;
if (sg)
{
((TEdit *)Sender)->Text = sg->Cells[sg->Col][sg->Row];
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1DragOver(TObject *Sender, TObject *Source,
int X, int Y, TDragState State, bool &Accept)
{
// 鼠标经过Edit时,判断拖动源,接受来自属于TStringGrid的组件的拖放
Accept = Source->InheritsFrom(__classid(TStringGrid));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
// 在StringGrid中按下鼠标时判断当前是否在有内容的格子中
int nCol, nRow;
StringGrid1->MouseToCell(X, Y, nCol, nRow);

if (nCol > 0 && nRow > 0)
{
StringGrid1->BeginDrag(true);
}
}


刚才忘了加代码格式。
牧牛人软件 2009-08-09
  • 打赏
  • 举报
回复
我怎么不能问题啊,谢谢妖哥和各位弟兄!我明天回单位试试看
明朝2013 2009-08-08
  • 打赏
  • 举报
回复
学习了~`
fairchild811 2009-08-08
  • 打赏
  • 举报
回复

cpp中响应的函数添加: -> cpp中相应的函数添加:

-------------

ListBox1->Items->Add(((TStringGrid*)Source)->Cells[1][2]); // 拖动时将第二行第一列的内容添加到TListBox [这里的注释自动换行了:(]

-> ListBox1->Items->Add(((TStringGrid*)Source)->Cells[1][2]); // 拖动时将第二行第一列的内容添//加到TListBox

------------

fairchild811 2009-08-08
  • 打赏
  • 举报
回复
Form上放置一个TStringGrid和一个TListBox;

两者的DragMode都设置为dmAutomatic。

cpp中响应的函数添加:

void __fastcall TForm1::FormCreate(TObject *Sender)
{
StringGrid1->Cells[1][1] = "11";
StringGrid1->Cells[1][2] = "12";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListBox1DragOver(TObject *Sender, TObject *Source, int X,
int Y, TDragState State, bool &Accept)
{
Accept = Source->ClassNameIs("TStringGrid");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListBox1DragDrop(TObject *Sender, TObject *Source, int X,
int Y)
{
ListBox1->Items->Add(((TStringGrid*)Source)->Cells[1][2]); // 拖动时将第二行第一列的内容添加到TListBox
}

13,826

社区成员

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

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