VC中画出多个矩形

xiaomangmang 2013-03-28 05:08:51
想在对话框的picture(IDC_STATIC_BACK)控件上画出多个矩形,8排12列共96个
我现在只能画出一个
请问各位大侠,怎么画出多个?应该用什么方法,是不是要用循环啊
CWnd * pWnd = GetDlgItem(IDC_STATIC_BACK);
if(pWnd != NULL && ::IsWindow((pWnd->m_hWnd)))
{
CRect rcPic;
pWnd->GetWindowRect(rcPic);
ScreenToClient(rcPic);
CClientDC dc(this);

HBRUSH hBrush=CreateSolidBrush(RGB(122,122,122));
CBrush brush(RGB(122,122,122));
CRect rect(20,20,40,40);
rect.OffsetRect(rcPic.left,rcPic.top);
dc.Rectangle(rect);
dc.FillRect(&rect,&brush);
}
...全文
1012 54 打赏 收藏 转发到动态 举报
写回复
用AI写文章
54 条回复
切换为时间正序
请发表友善的回复…
发表回复
JoeyPLee 2013-04-25
  • 打赏
  • 举报
回复
受教了
xiaomangmang 2013-04-19
  • 打赏
  • 举报
回复
中间的两周忙别的事了,程序我已经弄好了,在参考你代码的基础上,谢谢大牛指点
引用 50 楼 Mackz 的回复:
就少了一句,添加Terminal.h头文件到MyData.cpp或者.h中,放cpp的话要放在MyData.h前面。 我的方法是这样(其实前面都提过):用一个Terminal类包装每个矩形对象,里面有坐标(CRect)、内容(CString)两个属性,而这些对象是通过CMyData类来管理,CMyData类是CCanvasCtrl类的数据上下文实例。 这样窗口……
菜牛 2013-04-19
  • 打赏
  • 举报
回复
引用 52 楼 xiaomangmang 的回复:
中间的两周忙别的事了,程序我已经弄好了,在参考你代码的基础上,谢谢大牛指点引用 50 楼 Mackz 的回复:就少了一句,添加Terminal.h头文件到MyData.cpp或者.h中,放cpp的话要放在MyData.h前面。 我的方法是这样(其实前面都提过):用一个Terminal类包装每个矩形对象,里面有坐标(CRect)、内容(CString)两个属性,而这些……
真客气。
xiaomangmang 2013-03-31
  • 打赏
  • 举报
回复
好的,我再试试,辛苦啦
引用 50 楼 Mackz 的回复:
就少了一句,添加Terminal.h头文件到MyData.cpp或者.h中,放cpp的话要放在MyData.h前面。 我的方法是这样(其实前面都提过):用一个Terminal类包装每个矩形对象,里面有坐标(CRect)、内容(CString)两个属性,而这些对象是通过CMyData类来管理,CMyData类是CCanvasCtrl类的数据上下文实例。 这样窗口……
菜牛 2013-03-31
  • 打赏
  • 举报
回复
就少了一句,添加Terminal.h头文件到MyData.cpp或者.h中,放cpp的话要放在MyData.h前面。 我的方法是这样(其实前面都提过):用一个Terminal类包装每个矩形对象,里面有坐标(CRect)、内容(CString)两个属性,而这些对象是通过CMyData类来管理,CMyData类是CCanvasCtrl类的数据上下文实例。 这样窗口刷新的时候,CCanvasCtrl刷新,调用数据上下文实例(CMyData)的绘图函数(OnDraw),再调用管理的CTerminal对象数组中每个对象的Draw函数去绘制自己。 CCanvasCtrl创建的时候,会触发OnSize消息,同样循上面说的路径去设置每个矩形大小。 CCanvalCtrl上点击鼠标的时候,同样循上面的路径找到每个矩形进行命中判断,在哪个区域内,就记录下那个编号,作为选中标记,所以这个和其他控件焦点一样,每次只能选一个。 在RadioButton点击消息中,把按钮文字设置到激活的那个对象中,因为每个对象都有自己的m_Text属性,所以都可以保存。 对象有自己的属性,负责维护自己的属性(数据),负责绘制自己(表现);界面只管处理消息,把消息转交给合适的对象去处理,逻辑比较清楚。
xiaomangmang 2013-03-31
  • 打赏
  • 举报
回复
而且,第一个矩形是失效的,点击没变化
引用 48 楼 xiaomangmang 的回复:
我在程序里加入CTerminal的时候,在我当前对话框类中添加CArray<CTerminal, CTerminal&> m_Objs;这句,提示没有声明CTerminal类,所以m_Objs都调用不了CTerminal中的函数,这时候我就分析你的程序,把能实现功能的代码试着加入我的对话框类中,可能是我加的不对,还是只能同时显示一个矩形变化,所以想问你是哪句代码实……
xiaomangmang 2013-03-31
  • 打赏
  • 举报
回复
我在程序里加入CTerminal的时候,在我当前对话框类中添加CArray<CTerminal, CTerminal&> m_Objs;这句,提示没有声明CTerminal类,所以m_Objs都调用不了CTerminal中的函数,这时候我就分析你的程序,把能实现功能的代码试着加入我的对话框类中,可能是我加的不对,还是只能同时显示一个矩形变化,所以想问你是哪句代码实现的同时显示?
引用 46 楼 Mackz 的回复:
好了,现在你再想增加功能,就可以在CTerminal和CMyData两个类里面做手脚。CCanvasCtrl绘图的部分是不用动的,这就是界面和实现分离,而CTerminal只管绘制自己(Draw)。
xiaomangmang 2013-03-30
  • 打赏
  • 举报
回复
恩,是在用vc6,我多试试,呵呵,谢谢大侠指点
引用 29 楼 Mackz 的回复:
BaseClass没有CObject也没关系,我是习惯了,就建个基类好了。文件内容不都贴出来了么,你建几个空文件复制进去就是了。估计你还用VC6,就怕有些不兼容的。重在理解。
xiaomangmang 2013-03-30
  • 打赏
  • 举报
回复
恩,好的,这么交流啊下来,自己再动手做,感觉学了好多知识,辛苦啦!
引用 46 楼 Mackz 的回复:
好了,现在你再想增加功能,就可以在CTerminal和CMyData两个类里面做手脚。CCanvasCtrl绘图的部分是不用动的,这就是界面和实现分离,而CTerminal只管绘制自己(Draw)。
菜牛 2013-03-30
  • 打赏
  • 举报
回复
好了,现在你再想增加功能,就可以在CTerminal和CMyData两个类里面做手脚。CCanvasCtrl绘图的部分是不用动的,这就是界面和实现分离,而CTerminal只管绘制自己(Draw)。
xiaomangmang 2013-03-30
  • 打赏
  • 举报
回复
高手就是高手啊这也太神速了,这些代码,我估计还得消化一天
引用 44 楼 Mackz 的回复:
唉,太急,这样更好一些: C/C++ code?12345678910111213141516void CTerminal::Draw(CDC* pDC, CBrush* pBrush){ if (pBrush) { pDC->FillRect(m_Rect, pBrush); } else { pDC->Rec……
菜牛 2013-03-30
  • 打赏
  • 举报
回复
唉,太急,这样更好一些:
void CTerminal::Draw(CDC* pDC, CBrush* pBrush)
{
	if (pBrush)
	{
		pDC->FillRect(m_Rect, pBrush);
	}
	else
	{
		pDC->Rectangle(m_Rect);
	}
	if (m_Text.GetLength() > 0)
	{
		pDC->SetTextColor(RGB(0, 0, 0));
		pDC->DrawText(m_Text, &m_Rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
	}
}
另外原来忘了一点东西,修改CMyData添加一个函数:
	void SetText(LPCTSTR text);// public
protected:
	// 数据,改成保护的,防止外部访问
cpp:
void CMyData::SetText(LPCTSTR text)
{
	m_Text = text;
	if (m_Selected >=0 && m_Selected < m_Objs.GetSize())
	{
		m_Objs[m_Selected].setText(text);
	}
}
void CMyData::OnLButtonDown(UINT nFlags, CPoint point)
{
	for (int i = 0; i < m_Objs.GetSize(); i++)
	{
		if (PtInRect(m_Objs[i].getRect(), point))
		{
			m_Selected = i;
			SetText(m_Text);
			break;
		}
	}
}
以及对话框类:
void CMFCDialogDlg::OnBnClickedRadio(UINT id)
{
	// TODO: 在此添加控件通知处理程序代码
	CString text;
	GetDlgItemText(id, text);
	m_MyData.setText(text);
	if (m_Canvas )
	{
		m_Canvas->Invalidate();
	}
}
搞定! 最后一个功能,点击矩形文字能添加/去除,给CTerminal类添加两个函数: Terminal.h

	BOOL isEmpty(void);
	void Empty(void);
Terminal.cpp:
BOOL CTerminal::isEmpty(void)
{
	return m_Text.IsEmpty();
}

void CTerminal::Empty(void)
{
	m_Text.Empty();
}
MyData.cpp
void CMyData::OnLButtonDown(UINT nFlags, CPoint point)
{
	for (int i = 0; i < m_Objs.GetSize(); i++)
	{
		if (PtInRect(m_Objs[i].getRect(), point))
		{
			if (i == m_Selected && !m_Objs[i].isEmpty())
			{
				m_Objs[i].Empty();
			}
			else
			{
				m_Selected = i;
				m_Objs[i].setText(m_Text);
			}
			break;
		}
	}
}
xiaomangmang 2013-03-30
  • 打赏
  • 举报
回复
我来插一段吧,是不是回复不了了
菜牛 2013-03-30
  • 打赏
  • 举报
回复
更正前面一个错误:
void CTerminal::Draw(CDC* pDC, CBrush* pBrush)
{
	if (pBrush)
	{
		pDC->FillRect(m_Rect, pBrush);
	}
	else
	{
		pDC->Rectangle(m_Rect);
	}
	pDC->SetTextColor(RGB(0, 0, 0));
	if (m_Text.GetLength() > 0)
	{
		pDC->DrawText(m_Text, &m_Rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
	}
}
菜牛 2013-03-30
  • 打赏
  • 举报
回复
修改一下CMyData类: 头文件
	// 放置矩形的数组
	CArray<CTerminal, CTerminal&> m_Objs;
cpp
void CMyData::OnSize(UINT nType, int cx, int cy)
{
	CRect rect;
	float width = (float)(cx - m_LeftSpace) / (float)m_Cols - m_Space;
	float height = (float)(cy - m_TopSpace) / (float)m_Rows - m_Space;
	for (int c = 0; c < m_Cols; c++)
	{
		for (int r = 0; r < m_Rows; r++)
		{
			rect.left = c * (width + m_Space) + m_LeftSpace;
			rect.top = r * (height + m_Space)  + m_TopSpace;
			rect.right = rect.left + width;
			rect.bottom = rect.top + height;
			m_Objs[(r * m_Cols) + c].setRect(rect);
		}
	}
}

void CMyData::OnLButtonDown(UINT nFlags, CPoint point)
{
	for (int i = 0; i < m_Objs.GetSize(); i++)
	{
		if (PtInRect(m_Objs[i].getRect(), point))
		{
			m_Selected = i;
			break;
		}
	}
}

void CMyData::OnDraw(CDC* pDC)
{
	int bkModeOld = pDC->SetBkMode(TRANSPARENT);
	CFont* pFontOld = (CFont*)pDC->SelectStockObject(DEFAULT_GUI_FONT);

	CString str;
	CRect rect;
	COLORREF clrOld = pDC->SetTextColor(RGB(0, 0, 0));
	for (int c = 0; c < m_Cols; c++)
	{
		str.Format(_T("%d"), c + 1);
		rect.SetRect(m_Objs[c].getRect()->left, 0, m_Objs[c].getRect()->right, m_Objs[c].getRect()->top);
		pDC->SetTextColor(RGB(0, 0, 0));
		pDC->DrawText(str, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
		rect.OffsetRect(1, 1);
		pDC->SetTextColor(RGB(255, 255, 255));
		pDC->DrawText(str, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
	}
	for (int r = 0; r < m_Rows; r++)
	{
		str.Format(_T("%C"), _T('A') + r);
		rect.SetRect(0, m_Objs[m_Cols * r].getRect()->top, m_Objs[m_Cols * r].getRect()->left, m_Objs[m_Cols * r].getRect()->bottom);
		pDC->SetTextColor(RGB(0, 0, 0));
		pDC->DrawText(str, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
		rect.OffsetRect(1, 1);
		pDC->SetTextColor(RGB(255, 255, 255));
		pDC->DrawText(str, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
	}
	pDC->SetTextColor(RGB(255, 255, 255));
	for(int i = 0; i < m_Objs.GetSize(); i++)
	{
		m_Objs[i].Draw(pDC, i == m_Selected ? &m_BkgroundBrush : NULL);
	}
	pDC->SetTextColor(clrOld);
	pDC->SetBkMode(bkModeOld);
	pDC->SelectObject(pFontOld);
}
菜牛 2013-03-30
  • 打赏
  • 举报
回复
算了,我建了个CTerminal类:
#pragma once
#include "afx.h"
class CTerminal :
	public CObject
{
public:
	CTerminal(void);
	~CTerminal(void);

	void setRect(LPCRECT lpRect);
	LPCRECT getRect(void);
	void setText(LPCTSTR text);
	LPCTSTR getText(void);
	void Draw(CDC* pDC, CBrush* pBrush = NULL);

protected:
	CRect m_Rect;
	CString m_Text;
};
#include "stdafx.h"
#include "Terminal.h"

CTerminal::CTerminal(void)
{
}

CTerminal::~CTerminal(void)
{
}

void CTerminal::setRect(LPCRECT lpRect)
{
	m_Rect.CopyRect(lpRect);
}

LPCRECT CTerminal::getRect(void)
{
	return m_Rect;
}

void CTerminal::setText(LPCTSTR text)
{
	m_Text = text;
}

LPCTSTR CTerminal::getText(void)
{
	return m_Text;
}

void CTerminal::Draw(CDC* pDC, CBrush* pBrush)
{
	if (pBrush)
	{
		pDC->FillRect(m_Rect, pBrush);
	}
	pDC->SetTextColor(RGB(0, 0, 0));
	pDC->Rectangle(m_Rect);
	if (m_Text.GetLength() > 0)
	{
		pDC->DrawText(m_Text, &m_Rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
	}
}
xiaomangkey 2013-03-30
  • 打赏
  • 举报
回复
咱还是先实现同时显示的功能把,然后再考虑我说的这个
引用 37 楼 xiaomangmang 的回复:
可不可以再加个功能,就是我点击矩形,显示文本,再点击这个矩形,文本消失,矩形还是原来的样子,这样的话是不是要在ONLBUTTONDOWN中加个IF语句判断下呢引用 34 楼 Mackz 的回复:其实呢我前面已经说过了,就是把矩形包装到一个新的类里面。 算了,反正有空,给你再说一下,不过你要自己跟着改: 添加一个类用来作为你的数据类,比如……对了,你给个有意义的……
xiaomangkey 2013-03-30
  • 打赏
  • 举报
回复
我也来学习学习
xiaomangmang 2013-03-30
  • 打赏
  • 举报
回复
可不可以再加个功能,就是我点击矩形,显示文本,再点击这个矩形,文本消失,矩形还是原来的样子,这样的话是不是要在ONLBUTTONDOWN中加个IF语句判断下呢
引用 34 楼 Mackz 的回复:
其实呢我前面已经说过了,就是把矩形包装到一个新的类里面。 算了,反正有空,给你再说一下,不过你要自己跟着改: 添加一个类用来作为你的数据类,比如……对了,你给个有意义的名字,我不喜欢随便命名。也就是说,你的矩形想代表什么?
xiaomangmang 2013-03-30
  • 打赏
  • 举报
回复
恩,是我原来没说清楚,嘿嘿
引用 33 楼 Mackz 的回复:
早知道你有这需求,可是你原来不是这么说滴所以我把变量命名为m_Objs而不是m_Rects
加载更多回复(34)

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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