文章目录
DECLARE_DYNAMIC/DEClARE_DYNAMIC宏
- IMPLEMENT_DYNAMIC是实现“运行时类型识别”宏
- 在.H文件中必定有DECLARE_DYNAMIC(声明“运行时类型识别”宏)的声明。
- 作用:
- 为了确定运行时对象属于哪一个类而定义的宏
- 为了“动态创建"类的实例而定义的宏。new可以用来创建对象,但不是动态的。比如说,你要在程序中实现根据用户输入的类名来创建类的实例。
BeginWaitCursor() \ EndWaitCursor()
显示沙漏光标,告诉用户 系统正在运行,繁忙。
绘图
Invalidate()
void Invalidate( BOOL bErase = TRUE) 使整个窗口客户区无效,需要重绘。Windows会在应用程序的消息队列中放置WM_PAINT消息。MFC为窗口类提供了WM_PAINT的消息处理函数OnPaint
,OnPaint负责重绘窗口。
调用Invalidate等函数后窗口不会立即重绘,屏幕不一定马上更新,因为WM_PAINT消息不一定在队列头部(WM_PAINT消息的优先级很低,它需要等消息队列中的其它消息发送完后才能被处理)。Invalidate是在消息队列中加入一条WM_PAINT消息,只有当当前函数返回后,进入消息循环,取出WM_PAINT,才执行PAINT。
如果希望在调用Invalidate之后想马上更新屏幕,那就请加上UpdateWindow()这条语句。
InvalidateRect只是增加重绘区域,在下次WM_PAINT的时候才生效。
Invalidate()之后…OnPaint()->OnPrepareDC()->OnDraw(),所以只是刷新在OnPaint()和OnDraw()函数中的绘图语句。其它地方没有影响。
UpdateWindow()
UpdateWindow()窗口立即重绘。在执行的过程中需要先判断客户区是否为空。不为空,UpdateWindow不会执行,只有为空才执行重画。
调用UpdateWindow函数可使WM_PAINT被直接发送到目标窗口,绕过消息队列,从而导致窗口立即重绘。UpdateWindow只向窗体发送WM_PAINT消息,在发送之前判断GetUpdateRect(hWnd,NULL,TRUE)看有无可绘制的客户区域,如果没有,则不发送WM_PAINT。
DWORD 类型:unsigned long
无符号32位整型
链表操作
GetHeadPosition():返回的是链表头元素的位置
遍历迭代:
POSITION pos = pSnapshotList->GetHeadPosition();
int nCount = pSnapshotList->GetCount();
for (int i=0; i<nCount; i++)
{
pos = pSnapshotList->FindIndex(i);
USnapshot *ptmpSnapshot = pSnapshotList->GetAt(pos);
}
GetNext(pos) :返回链表中pos所指的元素,并将pos指向下一个元素
MFC输出
弹窗
CString str;
str.Format( "peak=%g\ndias=%g\nmeam=%g",fPeak,fDIAS,fMean );
AfxMessageBox( str );
打印输出
int a=123;
TRACE("%d+++++++++++++++++++++++++++++++++++++++++++\n",a);
mainCRTStartup 程序入口点
操作系统装载应用程序后,做完初始化工作就转到程序的入口点执行。
程序的默认入口点由连接程序设置,不同的连接器选择的入口函数也不尽相同。在VC++下,连接器对控制台程序设置的入口函数是 mainCRTStartup,mainCRTStartup 再调用main 函数;对图形用户界面(GUI)程序设置的入口函数是 WinMainCRTStartup,WinMainCRTStartup 调用你自己写的 WinMain 函数。
具体设置哪个入口点是由连接器的“/subsystem:”选项确定的,它告诉操作系统如何运行编译生成的.EXE文件。可以指定四种方式:CONSOLE|WINDOWS|NATIVE|POSIX。如果这个选项参数的值为 WINDOWS,则表示该应用程序运行时不需要控制台。
AfxEnableControlContainer() 允许应用程序作为控件容器来使用
CreateSemaphore() 信号量
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // SD
LONG lInitialCount, // initial count
LONG lMaximumCount, // maximum count
LPCTSTR lpName // object name
)
此函数可用来创建或打开一个信号量
消息
SendMessage:执行后系统会一直等待, 直到要发送的消息被处理掉。
PostMessage:将消息放置在与创建指定窗口的线程相关联的消息队列中,并不等待线程处理消息的情况下返回消息。
PostMessage(WM_COMMAND, MAKEWPARAM(ID_BTN_OK, BN_CLICKED), NULL);
WM_COMMAND是要发送的消息,MAKEWPARAM宏是为了组成一个WPARAM,WM_COMMAND消息的WPARAM的低字为控件ID,高字为识别码, 最后一个参数LPARAM可为NULL。
wParam VS lParam
在32位版本的Windows中,WPARAM被定义为UINT,而LPARAM被定义为LONG
(1)字参数(wParam)
(2)长参数(lParam):字参数和长参数都是32位整数,用于提供消息的附带消息,是消息传递过程中参数的载体。附加信息的消息号取决于消息号。
发送点击消息
查找控件
FindWindow(
lpClassName, {窗口的类名}
lpWindowName: PChar {窗口的标题}
): HWND; {返回窗口的句柄; 失败返回 0}
//FindWindowEx 比 FindWindow 多出两个句柄参数:
FindWindowEx(
Parent: HWND; {要查找子窗口的父窗口句柄}
Child: HWND; {子窗口句柄}
ClassName: PChar; {}
WindowName: PChar {}
): HWND;
BM_CLICK VS BN_CLICKED
BM_CLICK是发给按钮控件的消息,通过该消息控制实现按钮点击。
BN_CLICKED是控件发给其父窗口的通知(通过WM_COMMAND消息),告诉其父窗口自己被点击了。
延时执行OnTimer()
- 使用SetTimer函数来设置一个定时器。
#define TIMER_FOCUS 1000
SetTimer(TIMER_FOCUS, 5000, NULL);
- 在对话框的消息映射中添加定时器的消息处理。
BEGIN_MESSAGE_MAP(CYourDialog, CDialogEx)
// ...
ON_WM_TIMER()
// ...
END_MESSAGE_MAP()
- 实现定时器的消息处理函数。
void CYourDialog::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == TIMER_FOCUS) //消息处理
{
// 取消定时器
KillTimer(TIMER_FOCUS);
// 设置焦点到指定控件
CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_NAME);
if (pEdit)
{
pEdit->SetFocus();
pEdit->SetSel(pEdit->GetWindowTextLength(), pEdit->GetWindowTextLength());
}
}
CDialogEx::OnTimer(nIDEvent);
}
常用文件头
#define new DEBUG_NEW
在debug的模式下所有的new都会被替换成DEBUG_NEW。在程序的“Debug”版本中,DEBUG_NEW 将为所分配的每个对象跟踪文件名和行号,帮助定位内存泄漏。
#ifdef _DEBUG // 判断是否定义_DEBUG
#undef THIS_FILE // 取消THIS_FILE的定义
static char THIS_FILE[]=__FILE__; // 定义THIS_FILE指向文件名
#define new DEBUG_NEW
#endif
计算机知识
DPI
96DPI:1英寸由96个像素绘成。