1、VC++获得数组长度
sizeof(array)/sizeof(array[0])
2、在VS2005里想要用cout输出,要引进
#include "iostream "
using namespace std;
如果想看清结果,让“黑屏”停一会,在main函数的return语句前,加cin.get();
3、VC中OnPaint()的工作原理
VC程序是基于消息机制的,你所做的任何操作,比如点击鼠标,拖动窗口,首先进入系统的消息队列。这里的系统消息队列包括多个程序的消息,系统再将消息发送给相应的程序。既然是队列,这就有一个先进先出的问题,屏幕上的无效区更新消息出现的频率就会特别高。比如当左上角更新的消息还没有处理,右下角更新的消息已经过来了。为了避免多次处理WM_PAINT消息,系统就将这些窗口更新消息合并到一条,只是将无效区范围变成包括这两次更新无效区范围在内的矩形区域。这样就减少了WM_PAINT消息的处理次数,提高了效率。
那么,在OnPaint消息处理函数中,又是怎样实现更新无效区的呢?
首先,要明白MFC中所有绘图操作都是基于设备描述表(Device Context,简称DC)的,具体信息可参看任何一本VC教材。DC中包含了绘图设备的各种信息,对于屏幕绘图,其实就是有一块内存(显存),专门用来存放要显示到屏幕上的信息,显示器以85HZ的频率(我以前的显示器)将其内容刷新的屏幕上。这里就到了关键点,显示器的刷新是将显存中的内容完全更新到显示器上,不存在无效区处理的问题,那么,无效区的处理一定发生在DC的绘图处理上。事实确实如此,当程序调用OnPaint消息时,首先将无效区范围传递给DC,DC在进行绘图操作时,就只更新无效区范围内的信息,其他地方的不管,这就提高了效率。
现在你明白OnPaint的处理是怎么一回事了吧?这里还想说一下Invalidate和UpdateWindow的区别。Invalidate在消息队列中加入一条WM_PAINT消息,其无效区为整个客户区。而UpdateWindow直接发送一个WM_PAINT消息,其无效区范围就是消息队列中WM_PAINT消息(最多只有一条)的无效区。效果很明显,调用Invalidate之后,屏幕不一定马上更新,因为WM_PAINT消息不一定在队列头部,而调用UpdateWindow会使WM_PAINT消息马上执行的,绕过了消息队列。如果你调用Invalidate之后想马上更新屏幕,那就加上UpdateWindow()这条语句。
4、对话框的背景色与背景图(VC++)
背景色:
在CDialog的派生类比如叫CBkTestDlg里,增加一个刷子变量。
CBrush m_brshBack;
在BOOL CBkTestDlg::OnInitDialog()函数里追加一行设定刷子颜色的语句。
m_brshBack.CreateSolidBrush(RGB(255, 128, 255));
重载WM_CTLCOLOR消息的处理函数
HBRUSH CBkTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if ( nCtlColor == CTLCOLOR_DLG )
{
return (HBRUSH)m_brshBack;
}
return hbr;
}
背景图:
在CDialog的派生类比如叫CBkTestDlg里,增加一个位图变量。
CBitmap m_bitmapBack;
用资源编辑器做一个大图:IDB_BITMAP1
在BOOL CBkTestDlg::OnInitDialog()函数里追加一行装入位图的语句。
m_bitmapBack.LoadBitmap(IDB_BITMAP1);
修改void CBkTestDlg::OnPaint()函数
void CBkTestDlg::OnPaint()
{
if (IsIconic())
{
... ...
... ...
}
else
{
CPaintDC dc(this);
dc.DrawState(CPoint(0,0), CSize(318,256), m_bitmapBack, DST_BITMAP);
CDialog::OnPaint();
}
}
都是摘抄来的,留着备用,以后好找了