第十一章、windows消息处理和多线程编程
Windows提供了两种线程:辅助线程和用户界面线程。用户界面线程有窗口,因此它有自己的消息循环,辅助线程没有窗口,没有自己的消息循环。
主线程无法通过消息和辅助线程通信,简单的解决办法是通过全局变量通信。
辅助线程可以通过消息和主线程通信,尽量选择post消息,在模式对话框中使用send消息会出问题。
使用 volatile 修饰符能够确保一个线程检索由另一线程写入的最新值。
MFC库为用户界面线程提供了很好的支持。您可以从CWinApp派生一个类,并使用AfxBeginThread的一个重载版本来启动线程。您从CWinApp派生的类有它自己的InitInstance函数,最重要的是,它有自己的消息循环,你可以根据需要构造窗口并映射一些消息。假如你允许用户运行应用程序的多个实例,但又希望所有的实例共享内存,你可以配置单个进程,让它运行多个用户界面线程。比如:windows explorer就是
第十二章、菜单、加速键、复文本编辑控件和属性表
知识点:
大多数命令消息都来自应用程序的框架窗口,而不是应用程序框架,因此,框架窗口才是放置消息控制函数的地方。借助于命令传递系统,可以在任何地方对消息进行控制,传递顺序为:视图、文档、(MDI子框架窗口在前)SDI主框架窗口、应用程序。
弹出式对话框中的按钮发送命令消息时,应用程序框架会首先把该命令传递给主框架窗口,因为所有的弹出式对话框都属于主框架窗口,之后进行命令传递。
控件的Prompt的属性这样加:添加一个新的条码数据!(状态栏)\n 添加一个新的条码数据!(气泡提示)。
第十三章、工具栏和状态栏
遇到的问题:
一、SelectStockObject();与SelectObject();的区别?
virtual CGdiObject*SelectStockObject( int nIndex );
只能选用系统定义好的对象,且参数为整形。系统仅定义了常用的CFont、CBrush、CPen三种。
CGdiObject*SelectObject(CGdiObject* pObject);
参数为:a pointer to an object of oneof the classes derived from CGdiObject,可用得指针有CFont、CBrush、CPen、CRgn、CBitmap。
二、宽字符串的复制。
宽字符串的复制如:
Strcpy用wcscpy,sprintf用swprintf代替,常数或字符前加L
_T宏会根据情况选择Unicode还是ANSI。_T,TEXT和_TEXT都是一样的。
LPCTSTR并不是一个指向CString对象的指针,而是一个支持Unicode的const char *的替代版本。
例子一、
CStringstrText("test");
wcsncpy(strText.GetBuffer(5),L"T", 1);
strText.ReleaseBuffer();
ASSERT(strText== "Test");
例子二、
wcscpy(cf.szFaceName,_T("宋体")); //有ZeroMemory(&cf, sizeof(cf)); 操作,所以此语句也可实现
wcsncpy(cf.szFaceName,_T("Times New Roman"), 32);
知识点:
控制栏包括工具栏和状态栏,它属于应用程序框架。所以,控制栏对象的构造、析构以及窗口的创建都是由应用程序框架来管理的,代码位于MainFrm中。
状态栏可支持两种类型的文本窗口:信息行窗口和状态指示器窗口。
信息行窗格中显示的是程序动态提供的字符串。可以通过CStatusBar::SetPaneText成员函数来设置信息行的内容,以0为基数从左到右递增。如:
CMainFrame*pFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;
CStatusBar*pStatus = &pFrame->m_wndStatusBar;
pStatus->SetPaneText(0,"message line for first pane");
状态指示器窗格总是被链接到一个字符串资源上,它是否被显示完全取决于相应的更新命令UI消息控制函数。指示器是由一个字符串资源ID来标示的,该ID也被用来传递更新命令UI消息。如:
ON_UPDATE_COMMAND_UI(ID_INDICATOR_CAPS,OnUpdateKeyCapsLock) //消息映射
void CMainFrame::OnUpdateKeyCapsLock(CCmdUI*pCmdUI)
{
pCmdUI->Enable(::GetKyeStatus(VK_CAPITAL)& 1);
}