VC++6.0下强大的自定义消息程序的编写(一)
这几天在回答别人
问题的时候明显感觉到自己的水平有限了,刚刚在CSDN闲逛有个朋友问我对VC编程中的自定义消息了解多少,让我写个小例子让他明白,好吧,水平有限的我在这里试讲一下我理解的消息编程。
大二时曾经抱着书看消息这部分的时候,研究了很长时间,但是一直不是很明白,原因是,我不经
常用到这一块,因为,我曾经认为消息机制可以用函数调用来替代,因为触发消息无非也是要在接受消息的时候用函数来处理,但是到了大三,随着写的程序越来越复杂,第一次不得不用到消息是在编写线程的时候用到的。因为我要在一个非MFC线程中控制窗体,但是,在非MFC线程中是不能使用MFC对象,这是不被规范所允许的,所以,我采用了另外一个方法,就是在线程中向窗口发出消息,在窗口中进行处理,这样,就可以在非MFC线程中间接的对窗体进行控制了。
好了说了这么多,现在我来编写一个小例子,即在非MFC线程中向单文档窗口发送消息,以随时改变单文档状态栏中的字符串。这个例子是比较有可用价值的,因为我们在写复杂程序的时候,我们一般会将比较繁重的工作放入线程中执行,以避免给主线程带来太大的负荷,而我们还需要随时将线程执行的状态显示在窗口中。
我们首先打开VC++6.0,新建一个MFC单
文档程序,工程名填写SDIToStatus,然后,新建一个Generic Class,名称填写CThreadToStatus,好了,准备
工作已经完成了,现在我们开始写程序。
第一步:我们先将这个单
文档程序的标题修改一下,至于为什么要修改标题,我们后面会讲到,在CMainFrame类中PreCreateWindow函数中添加代码,如下:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT&; cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.style&;=~FWS_ADDTOTITLE;//将FWS_ADDTOTITLE去掉
cs. lpszName = "SDIToStatus";//改变标题
return TRUE;
}
第二步:我们在ThreadToStatus类中写一个空线程和一个启动函数(类头文件中线程和函数的声明请自行添加,特别注意线程声明前加static),代码如下:
DWORD WINAPI CThreadToStatus::WorkThread(LPVOID lpData){
}
void CThreadToStatus::StartWorkThread()
{
DWORD ThreadID;
CreateThread(NULL,0,WorkThread,NULL,0,&;ThreadID);
}
第三步:在CMainFrame类的OnCreate函数的结尾(即return 0;之前 )加入如下代码(注意加CThreadToStatus类的头文件):
CThreadToStatus ctts;
ctts.StartWorkThread();//开启线程
第四步:在CMainframe类中定义一个函数(类头文件中先不加入声明,原因后面会讲到),代码如下:
void CMainFrame::ToSetStatusBar(WPARAM wParam,LPARAM lParam)//修改任务栏数据
{
int recvint = wParam;
CString recvstr = (LPCTSTR)lParam;
m_wndStatusBar.SetWindowText(recvstr);
}
第五步:从第四步开始才真正进入消息部分的编程。在CThreadToStatus类源文件顶部加入以下代码,用来自定义一个消息:
#define WM_TOSETSTATUS WM_USER+101
第六步:在CThreadToStatus类中我们定义过的线程中加入代码,如下:
DWORD WINAPI CThreadToStatus::WorkThread(LPVOID lpData){
Sleep(1000);//此行目的是延缓1秒,防止线程在状态栏初始化前启动,这样“就绪”会覆盖“线程启动”
HWND hwnd = ::FindWindow(NULL,"SDIToStatus");
CString str1 = "线程启动";
::SendMessage(hwnd,WM_TOSETSTATUS,1,(LPARAM)(LPCTSTR)str1);
Sleep(1000);//中间隔着1秒,目的是方面看清状态栏的变化
CString str2 = "线程结束";
::SendMessage(hwnd,WM_TOSETSTATUS,1,(LPA