请问StringGrid上面有办法用Canvas画上线条吗?!

qoror 2014-08-03 12:08:11
请问StringGrid上面有办法用Canvas画上线条吗?!
下面第一章图我画上去会被StringGrid覆盖,要如何不会被覆盖
想要像第二张图一样画个十字标记点

...全文
118 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
qoror 2014-08-04
  • 打赏
  • 举报
回复
感谢妖哥 OK了 谢谢您 我自己在找时间研究 只是很好奇您都是看什么为什么知道这些用法? 例如    StringGrid1->Invalidate(); 很想知道你们高手是怎么累积这程式的能力 想多多学习
ccrun.com 2014-08-04
  • 打赏
  • 举报
回复
引用 12 楼 qoror 的回复:
妖哥我不懂为何您这样话线不会消失?!为何之前我打得code换位置后就会消失啊?可以教导一下原因吗?
你那个坐标还是计算的有问题。你仔细分析一下我14的最终代码就ok了,如果和你的需求还有差异,自己学着修改吧。
ccrun.com 2014-08-04
  • 打赏
  • 举报
回复
OK了,以选定格子的左上角为中心点绘制十字,此代码为终极代码,我是不再修改了。
int nRow = 0;
int nCol = 0;

// ---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    nRow = Edit1->Text.ToIntDef(0);
    nCol = Edit2->Text.ToIntDef(0);

    StringGrid1->Invalidate();
}
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol,
      int ARow, TRect &Rect, TGridDrawState State)
{
    TStringGrid *sg = dynamic_cast <TStringGrid *> (Sender);
    if (!sg) return;
 
    if (ARow == 0 || ACol == 0) return;
 
    sg->Canvas->Pen->Color = clRed;
    sg->Canvas->Pen->Width = 2;
 
    int nLineLen = 15; // 线条的长度
 
    if (ARow == nRow - 1 && ACol == nCol - 1) // 左上格子绘制右和下的线条
    {
        // 下方线条
        sg->Canvas->MoveTo(Rect.Left + Rect.Width() - nLineLen, Rect.Top + Rect.Height());
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top + Rect.Height());
        // 右侧线条
        sg->Canvas->MoveTo(Rect.Left + Rect.Width(), Rect.Top + Rect.Height() - nLineLen);
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top + Rect.Height());
    }
    else if (ARow == nRow - 1 && ACol == nCol) // 右上格子绘制左和下的线条
    {
        // 下方线条
        sg->Canvas->MoveTo(Rect.Left, Rect.Top + Rect.Height());
        sg->Canvas->LineTo(Rect.Left + nLineLen, Rect.Top + Rect.Height());
        // 左侧线条
        sg->Canvas->MoveTo(Rect.Left, Rect.Top + Rect.Height() - nLineLen);
        sg->Canvas->LineTo(Rect.Left, Rect.Top + Rect.Height());
    }
    else if (ARow == nRow && ACol == nCol - 1) // 左下格子绘制右和上的线条
    {
        // 上方线条
        sg->Canvas->MoveTo(Rect.Left + Rect.Width() - nLineLen, Rect.Top);
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top);
        // 右侧线条
        sg->Canvas->MoveTo(Rect.Left + Rect.Width(), Rect.Top);
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top + nLineLen);
    }
    else if (ARow == nRow && ACol == nCol) // 右下格子绘制左和上的线条
    {
        // 上方线条
        sg->Canvas->MoveTo(Rect.Left, Rect.Top);
        sg->Canvas->LineTo(Rect.Left + nLineLen, Rect.Top);
        // 左侧线条
        sg->Canvas->MoveTo(Rect.Left, Rect.Top);
        sg->Canvas->LineTo(Rect.Left, Rect.Top + nLineLen);
    }
}
qoror 2014-08-04
  • 打赏
  • 举报
回复
小弟非常抱歉 昨天稍微用一下,就出门了,没注意到,非常抱歉 谢谢妖哥大大热心帮忙
qoror 2014-08-04
  • 打赏
  • 举报
回复
妖哥我不懂为何您这样话线不会消失?!为何之前我打得code换位置后就会消失啊?可以教导一下原因吗?
ccrun.com 2014-08-04
  • 打赏
  • 举报
回复
早把需求说清楚嘛,浪费这么长时间。你等我一会。
qoror 2014-08-04
  • 打赏
  • 举报
回复
感谢妖哥有成功! 非常感谢你 只是我有点不懂@ @ 要如何可以简单设定两个编辑就可以让它正确显示在某行某列的左上位置呢?! 例如现在读到第二行第三列的位置时希望在那格的单元格左上角显示十字 因为我发现如果XY是一样的如第二行第二列都没问题 但只要XY行列不一致就跑掉了@ @ 想简单化
ccrun.com 2014-08-04
  • 打赏
  • 举报
回复
你需要用四个数字来定位这个十字的位置。
int nRowStart = 0;
int nRowEnd = 0;
int nColStart = 0;
int nColEnd = 0;

// ---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    nRowStart = Edit1->Text.ToIntDef(0);
    nRowEnd = Edit2->Text.ToIntDef(0);
    nColStart = Edit3->Text.ToIntDef(0);
    nColEnd = Edit4->Text.ToIntDef(0);

    StringGrid1->Invalidate();
}

// ---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol,
      int ARow, TRect &Rect, TGridDrawState State)
{
    TStringGrid *sg = dynamic_cast <TStringGrid *> (Sender);
    if (!sg) return;

    if (ARow == 0 || ACol == 0) return;

    sg->Canvas->Pen->Color = clRed;
    sg->Canvas->Pen->Width = 2;

    int nLineLen = 15; // 线条的长度

    if (ARow == nRowStart && ACol == nColStart) // 左上格子绘制右和下的线条
    {
        // 下方线条
        sg->Canvas->MoveTo(Rect.Left + Rect.Width() - nLineLen, Rect.Top + Rect.Height());
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top + Rect.Height());
        // 右侧线条
        sg->Canvas->MoveTo(Rect.Left + Rect.Width(), Rect.Top + Rect.Height() - nLineLen);
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top + Rect.Height());
    }
    else if (ARow == nRowStart && ACol == nColEnd) // 右上格子绘制左和下的线条
    {
        // 下方线条
        sg->Canvas->MoveTo(Rect.Left, Rect.Top + Rect.Height());
        sg->Canvas->LineTo(Rect.Left + nLineLen, Rect.Top + Rect.Height());
        // 左侧线条
        sg->Canvas->MoveTo(Rect.Left, Rect.Top + Rect.Height() - nLineLen);
        sg->Canvas->LineTo(Rect.Left, Rect.Top + Rect.Height());
    }
    else if (ARow == nRowEnd && ACol == nColStart) // 左下格子绘制右和上的线条
    {
        // 上方线条
        sg->Canvas->MoveTo(Rect.Left + Rect.Width() - nLineLen, Rect.Top);
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top);
        // 右侧线条
        sg->Canvas->MoveTo(Rect.Left + Rect.Width(), Rect.Top);
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top + nLineLen);
    }
    else if (ARow == nRowEnd && ACol == nColEnd) // 右下格子绘制左和上的线条
    {
        // 上方线条
        sg->Canvas->MoveTo(Rect.Left, Rect.Top);
        sg->Canvas->LineTo(Rect.Left + nLineLen, Rect.Top);
        // 左侧线条
        sg->Canvas->MoveTo(Rect.Left, Rect.Top);
        sg->Canvas->LineTo(Rect.Left, Rect.Top + nLineLen);
    }
}
qoror 2014-08-04
  • 打赏
  • 举报
回复
妖哥不好意思昨天纷常感谢妳帮我弄出那个十字点 但是我发现我用Button在设定两个Edit可以改变十字点位置后 去设定时怎有时十字会出现有时会消失有时会产生两个十字?
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int a=0;
int b=0;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol,
      int ARow, TRect &Rect, TGridDrawState State)
{

    TStringGrid *sg =  dynamic_cast  <TStringGrid *> (Sender);
    if  (!sg)  return ;

    sg->Canvas->Pen->Color = clRed;
    sg->Canvas->Pen->Width = 1;
 
    int  nLineLen = 15;  //½u±øªºªø«×
    int  nRowStart = a;  //±q²Ä¤T¦æ¶}©l
    int  nRowEnd = b;    //¨ì²Ä¥|¦æµ²§ô
    int  nColStart = a;  //±q²Ä¤T¦C¶}©l
    int  nColEnd = b;    //¨ì²Ä¥|¦Cµ²§ô
 
    if  (ARow == nRowStart && ACol == nColStart &&a!=0 && b!=0)   //¥ª¤W®æ¤lø»s¥k©M¤Uªº½u±ø
    {
        // ¤U¤è½u±ø
        sg->Canvas->MoveTo(Rect.Left + Rect.Width() - nLineLen, Rect.Top + Rect.Height());
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top + Rect.Height());
        // ¥k°¼½u±ø
        sg->Canvas->MoveTo(Rect.Left + Rect.Width(), Rect.Top + Rect.Height() - nLineLen);
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top + Rect.Height());
    }
    else  if  (ARow == nRowStart && ACol == nColEnd &&a!=0 && b!=0)  //¥k¤W®æ¤lø»s¥ª©M¤Uªº½u±ø
    {
        // ¤U¤è½u±ø
        sg->Canvas->MoveTo(Rect.Left, Rect.Top + Rect.Height());
        sg->Canvas->LineTo(Rect.Left + nLineLen, Rect.Top + Rect.Height());
        // ¥ª°¼½u±ø
        sg->Canvas->MoveTo(Rect.Left, Rect.Top + Rect.Height() - nLineLen);
        sg->Canvas->LineTo(Rect.Left, Rect.Top + Rect.Height());
    }
    else  if  (ARow == nRowEnd && ACol == nColStart &&a!=0 && b!=0)  //¥ª¤U®æ¤lø»s¥k©M¤Wªº½u±ø
    {
        // ¤W¤è½u±ø
        sg->Canvas->MoveTo(Rect.Left + Rect.Width() - nLineLen, Rect.Top);
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top);
        // ¥k°¼½u±ø
        sg->Canvas->MoveTo(Rect.Left + Rect.Width(), Rect.Top);
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top + nLineLen);
    }
    else  if  (ARow == nRowEnd && ACol == nColEnd &&a!=0 && b!=0)  //¥k¤U®æ¤lø»s¥ª©M¤Wªº½u±ø
    {
        // ¤W¤è½u±ø
        sg->Canvas->MoveTo(Rect.Left, Rect.Top);
        sg->Canvas->LineTo(Rect.Left + nLineLen, Rect.Top);
        // ¥ª°¼½u±ø
        sg->Canvas->MoveTo(Rect.Left, Rect.Top);
        sg->Canvas->LineTo(Rect.Left, Rect.Top + nLineLen);
    }

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    if(Edit1->Text!=""&&Edit2->Text!="")
    {
    a=StrToInt(Edit1->Text);
    b=StrToInt(Edit2->Text);
    }

}
//---------------------------------------------------------------------------
qoror 2014-08-03
  • 打赏
  • 举报
回复
刚刚找到这个会显是像第一张图那样
请问要怎么能限制他的范围呢?!
 StringGrid1->Canvas->Pen->Color=clRed;
StringGrid1->Canvas->MoveTo(Rect.Left, Rect.Bottom - 1);
StringGrid1->Canvas->LineTo(Rect.Right - 1, Rect.Bottom - 1);
StringGrid1->Canvas->LineTo(Rect.Right - 1, Rect.Top - 1);

qoror 2014-08-03
  • 打赏
  • 举报
回复
非常感谢妖哥 小弟在自行修改
ccrun.com 2014-08-03
  • 打赏
  • 举报
回复
void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol,
      int ARow, TRect &Rect, TGridDrawState State)
{
    TStringGrid *sg = dynamic_cast <TStringGrid *> (Sender);
    if (!sg) return;

    sg->Canvas->Pen->Color = clRed;
    sg->Canvas->Pen->Width = 2;

    int nLineLen = 15; // 线条的长度
    int nRowStart = 3; // 从第三行开始
    int nRowEnd = 4;   // 到第四行结束
    int nColStart = 3; // 从第三列开始
    int nColEnd = 4;   // 到第四列结束

    if (ARow == nRowStart && ACol == nColStart) // 左上格子绘制右和下的线条
    {
        // 下方线条
        sg->Canvas->MoveTo(Rect.Left + Rect.Width() - nLineLen, Rect.Top + Rect.Height());
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top + Rect.Height());
        // 右侧线条
        sg->Canvas->MoveTo(Rect.Left + Rect.Width(), Rect.Top + Rect.Height() - nLineLen);
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top + Rect.Height());
    }
    else if (ARow == nRowStart && ACol == nColEnd) // 右上格子绘制左和下的线条
    {
        // 下方线条
        sg->Canvas->MoveTo(Rect.Left, Rect.Top + Rect.Height());
        sg->Canvas->LineTo(Rect.Left + nLineLen, Rect.Top + Rect.Height());
        // 左侧线条
        sg->Canvas->MoveTo(Rect.Left, Rect.Top + Rect.Height() - nLineLen);
        sg->Canvas->LineTo(Rect.Left, Rect.Top + Rect.Height());
    }
    else if (ARow == nRowEnd && ACol == nColStart) // 左下格子绘制右和上的线条
    {
        // 上方线条
        sg->Canvas->MoveTo(Rect.Left + Rect.Width() - nLineLen, Rect.Top);
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top);
        // 右侧线条
        sg->Canvas->MoveTo(Rect.Left + Rect.Width(), Rect.Top);
        sg->Canvas->LineTo(Rect.Left + Rect.Width(), Rect.Top + nLineLen);
    }
    else if (ARow == nRowEnd && ACol == nColEnd) // 右下格子绘制左和上的线条
    {
        // 上方线条
        sg->Canvas->MoveTo(Rect.Left, Rect.Top);
        sg->Canvas->LineTo(Rect.Left + nLineLen, Rect.Top);
        // 左侧线条
        sg->Canvas->MoveTo(Rect.Left, Rect.Top);
        sg->Canvas->LineTo(Rect.Left, Rect.Top + nLineLen);
    }
}
qoror 2014-08-03
  • 打赏
  • 举报
回复
为何画出得来现在移动cell时会不见?!
 StringGrid1->Canvas->Pen->Color=clRed;
StringGrid1->Canvas->MoveTo(Rect.Left-1, Rect.Top -1);         //右
StringGrid1->Canvas->LineTo(Rect.Right - 1, Rect.Top - 1);

StringGrid1->Canvas->MoveTo(Rect.Left-1, Rect.Top -1);          //下
StringGrid1->Canvas->LineTo(Rect.Left-1, Rect.Bottom - 1);
qoror 2014-08-03
  • 打赏
  • 举报
回复
小弟我刚刚试着有成功画在StringGrid上面 如圖1
但是要怎样正确抓到每个CELL左上角呢?想要的效果如圖2


void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol,
int ARow, TRect &Rect, TGridDrawState State)
{
StringGrid1->Canvas->Pen->Color=clRed;
StringGrid1->Canvas->MoveTo(50,50);
StringGrid1->Canvas->LineTo(50,80);
StringGrid1->Canvas->MoveTo(50,50);
StringGrid1->Canvas->LineTo(50,20);
StringGrid1->Canvas->MoveTo(50,50);
StringGrid1->Canvas->LineTo(80,50);
StringGrid1->Canvas->MoveTo(50,50);
StringGrid1->Canvas->LineTo(20,50);


}



qoror 2014-08-03
  • 打赏
  • 举报
回复
songhtao大大是否可以教导一下怎么重绘呢? 小弟不才 麻烦大大您
我不懂电脑 2014-08-03
  • 打赏
  • 举报
回复
需要在onpaint事件里重绘一下。

13,826

社区成员

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

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