`
love19820823
  • 浏览: 958359 次
文章分类
社区版块
存档分类
最新评论

MFC中自由使用自定义消息

 
阅读更多

消息映射、循环机制是Windows程序运行的基本方式。VC++ MFC 中有许多现成的消息句柄,可当我们需要完成其它的任务,需要自定义消息,就遇到了一些困难。在MFC ClassWizard中不允许添加用户自定义消息,所以我们必须在程序中添加相应代码,以便可以象处理其它消息一样处理自定义消息。通常的做法是采取以下步骤:

  第一步:定义消息。

  推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用WM_USER消息。

#define WM_MY_MESSAGE (WM_USER+100)


  第二步:实现消息处理函数。该函数使用WPRAM和LPARAM参数并返回LPESULT。

LPESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
// TODO: 处理用户自定义消息
...
return 0;
}


  第三步:在类头文件的AFX_MSG块中说明消息处理函数:

class CMainFrame:public CMDIFrameWnd
{
...
// 一般消息映射函数
protected:
// {{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
}


  第四步:在用户类的消息块中,使用ON_MESSAGE宏指令将消息映射到消息处理函数中。

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_WM_TIMER()
ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

如果用户需要一个定义整个系统唯一的消息,可以调用SDK函数RegisterWindowMessage定义消息:

static UINT WM_MY_MESSAGE=RegisterWindowMessage("User");

  并使用ON_REGISTERED_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步骤同上。

  当需要使用自定义消息时,可以在相应类中的函数中调用函数PostMessage或SendMessage发送消息PoseMessage(WM_MY_MESSAGE,O,O); 如果向其他进程发送消息可通过如下方法发送消息:

DWORD result;
SendMessageTimeout(wnd->m_hWnd, // 目标窗口
WM_MY_MESSAGE, // 消息
0, // WPARAM
0, // LPARAM
SMTO_ABORTIFHUNG |
SMTO_NORMAL,
TIMEOUT_INTERVAL,
&result);

  以避免其它进程如果被阻塞而造成系统死等状态。

  可是如果需要向其它类(如主框架、子窗口、视类、对话框、状态条、工具条或其他控件等)发送消息时,上述方法显得无能为力,而在编程过程中往往需要获取其它类中的某个识别信号,MFC框架给我们造成了种种限制,但是可以通过获取某个类的指针而向这个类发送消息,而自定义消息的各种动作则在这个类中定义,这样就可以自由自在的向其它类发送消息了。

  下面举的例子叙述了向视类和框架类发送消息的方法:

  在主框架类中向视类发送消息:

  视类中定义消息:

ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage) //定义消息映射
视类定义消息处理函数:

// 消息处理函数
LRESULT CMessageView::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
// TODO: 处理用户自定义消息
...
return 0;
}

//发送消息的测试函数
void CMainFrame::OnTest()
{
CView * active = GetActiveView();//获取当前视类指针
if(active != NULL)
active->PostMessage(WM_MY_MESSAGE,0,0);
}

  在其它类中向视类发送消息:

//发送消息的测试函数
void CMainFrame::OnTest()
{
CMDIFrameWnd *pFrame;
CMDIChildWnd *pChild;
CView *pView;
//获取主窗口指针
pFrame =(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
// 获取子窗口指针
pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();
//获取视类指针
pView = pChild->GetActiveView();
if(pView != NULL)
pView->PostMessage(WM_MY_MESSAGE,0,0);//发送消息
}

  其余步骤同上。

在视类中向主框架发送消息:

  首先在主框架中定义相关的消息,方法同上,然后在发送消息的函数中添加代码如下

//发送消息的测试函数
void CMessageView::OnTest()
{
CFrameWnd * active = GetActiveFrame();//获取当前主窗口框架指针
if(active != this)
active->PostMessage(WM_MY_MESSAGE,0,0);
return 0;
}

  在其它类中向不同的类发送消息可依次方法类推,这样我们的程序就可以的不受限制向其它类和进程发送消息,而避免了种种意想不到的风险。

  下面一个例子程序为多文档程序里在一对话框中向视类发送消息,详述了发送自定义消息的具体过程。

实现步骤:

  第一步:在VC++中新建工程Message,所有ClassWizard步骤选项均为缺省,完成。

  第二步:在主菜单中添加测试菜单为调出对话框,在框架类中建立相应函数OnTest()

  第三步:在资源中建立对话框,通过ClassWizard添加新类TestDialog,添加测试按钮,

  在对话框类中建立相应函数OnDialogTest()

//通过对话框按钮发送消息的函数
void TestDialog::OnDialogTest()
{
CMDIFrameWnd *pFrame;
CMDIChildWnd *pChild;
CView *pView;
//获取主窗口指针
pFrame =(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
// 获取子窗口指针
pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();
//获取视类指针
pView = pChild->GetActiveView();
if(active != NULL)
active->PostMessage(WM_MY_MESSAGE,0,0);//发送消息
}

  在Message.h头文件中添加如下语句:

static UINT WM_MY_MESSAGE=RegisterWindowMessage("Message");

  第四步:在视类中添加自定义消息:

  在头文件MessageView.h中添加消息映射

protected:
//{{AFX_MSG(CMessageView)
//}}AFX_MSG
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); //此行为添加代码
DECLARE_MESSAGE_MAP()
在视类文件MessageView.cpp中的消息映射中添加自定义消息映射
BEGIN_MESSAGE_MAP(CMessageView, CView)
//{{AFX_MSG_MAP(CMessageView)
//}}AFX_MSG_MAP
// Standard printing commands
ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage) //此行添加代码定义唯一消息
END_MESSAGE_MAP()

  添加相应的0消息处理函数

LRESULT CMessageView::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
CRect rect;
GetClientRect(&rect);
InvalidateRect(&rect);
test=!test;
return 0;
}

  在MessageView.h中添加布尔变量 public:BOOL test;

  在视类构造函数中初始化 test变量:test=FALSE;

  修改CMessageView::OnDraw()函数

void CMessageView::OnDraw(CDC* pDC)
{
CMessageDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// 以下程序显示消息响应效果
if(test)
pDC->TextOut(0,0,"消息响应!");
}

  第五步:显示测试对话框

  在MainFrame类中包含对话框头文件:

#include "TestDialog.h";
OnTest()函数中添加代码
void CMainFrame::OnTest()
{
TestDialog dialog;
dialog.DoModal();
}

  运行程序,在测试菜单打开对话框,点击测试按钮即可看到结果。
分享到:
评论

相关推荐

    MFC中自由使用自定义消息.doc

    以下是如何在MFC中自由使用自定义消息的详细步骤: 1. **定义消息**: 自定义消息通常定义为`WM_USER`值之上,以避免与系统或已存在的控件消息冲突。例如,可以定义如下: ```cpp #define WM_MY_MESSAGE (WM_...

    MFC CToolBar工具栏自定义图片及文字

    本文将深入探讨如何在MFC框架中利用`CToolBar`类来自定义工具栏,包括设置按钮的图片和文字,以及实现工具栏的自由停靠功能。 `CToolBar`是MFC中用于创建和管理工具栏的类,它包含了多个按钮,每个按钮可以包含图像...

    好用的mfc自定义控件

    首先,标题"好用的mfc自定义控件"暗示我们将讨论如何在MFC环境中创建和使用自定义控件。MFC自定义控件是开发者为了满足特定需求而设计的,它们可以扩展标准的Windows控件,或者完全原创。自定义控件通常涉及到继承...

    串口编程, 适合入门级

    文件"MFC中自由使用自定义消息.doc"可能涉及如何在MFC程序中添加和处理自定义消息。自定义消息可以扩展MFC的内置消息系统,使得开发者能根据需求创建特定的消息,以处理串口通信中的特殊事件。 总的来说,通过MFC...

    MFC自定义按钮

    这篇文章将深入探讨如何在Visual Studio C++环境中使用MFC来创建自定义按钮,以及相关的编程技术和策略。 首先,我们需要理解MFC的基本结构。MFC封装了Windows API,提供了类库来处理窗口、消息、控件等,使得C++...

    MFC 窗口中控件

    3. **自定义消息处理**:除了使用默认的布局管理,还可以在OnSize()函数中添加自定义代码,根据需要调整控件的位置和大小。 4. **控件的最小和最大尺寸**:有时需要限制控件的最小和最大尺寸,以防止它们在窗口大小...

    MFCWindows程序设计

    创建自定义窗口类时,应在BEGIN_MESSAGE_MAP宏中指定CWnd作为基类,并在窗口的构造函数中使用AfxRegisterWndClass来注册WNDCLASS,最后通过CreateEx方法创建窗口。这种方法摆脱了框架窗口的限制,适用于需要更灵活...

    MFC实现自绘ListControl控件

    本篇将详细探讨如何使用MFC来实现自定义绘制ListControl控件,包括选中行颜色变化、行间距调整以及字体大小设置等功能。 ListControl控件,也称为ListView,是Windows GUI中常用的一种控件,用于展示多列数据,并可...

    MFC 点击鼠标自由绘制箭头

    在MFC(Microsoft Foundation Class)库中,开发人员可以利用其强大的图形用户界面(GUI)功能来实现各种自定义的绘图操作。本教程将详细解释如何在MFC应用程序中实现点击鼠标自由绘制箭头的功能。 首先,我们需要...

    mfc中的自己实现的画线算法

    在这个MFC项目中,我们讨论的是如何利用Bresenham算法来实现自定义的画线功能。 Bresenham算法是由Jack E. Bresenham于1965年提出的,它是一种快速且精确的在像素网格上绘制直线的方法。该算法主要适用于离散的、...

    自定义MessageBox

    8. **多线程支持**:如果在多线程环境中使用自定义MessageBox,需要注意线程同步问题,以防止UI线程被阻塞。 9. **代码复用**:为了提高代码的可维护性和重用性,可以将自定义MessageBox封装成一个静态类或实例类,...

    MFC对话框分割条拖动控件

    在MFC中,我们可以使用`CSplitterWnd`类来实现这种功能,这是一个预定义的控件,专用于创建可分割的窗口。然而,对话框中的分隔条控件可能需要一些额外的处理,因为对话框不直接支持`CSplitterWnd`。 步骤1:创建...

    在MFC中实现“高亮边框”的编辑控件

    为了在对话框中使用这个自定义的`CEditEx`控件,我们需要在`EditDemoDlg.cpp`和`EditDemoDlg.h`中进行相应的修改。在`EditDemoDlg.h`中添加`CEditEx`的成员变量,并在`OnInitDialog()`中初始化: ```cpp class ...

    MFC控件动态拖动

    我们可以通过重载CWnd类或自定义控件类的消息映射函数来处理这些消息。 1. **WM_LBUTTONDOWN**:当用户点击控件时,我们需要记录下鼠标点击时的坐标(ptStart),并设置一个标志位表示拖动开始。例如: ```cpp void...

    mfc 自绘控件 static 可改背景颜色字体等

    在MFC(Microsoft Foundation Classes)框架中,`CStatic`控件是最常用的一种控件,通常用于显示静态文本。然而,MFC默认的`CStatic`控件的背景颜色是灰色,这可能不符合某些应用程序的设计需求。为了实现自定义背景...

    MFC自绘TabCtrl类

    6. **性能优化**:为了提高效率,你可以在自绘过程中使用内存位图缓存,先将绘制结果保存在内存中,然后在`WM_PAINT`消息处理中快速复制到屏幕,避免频繁的GDI操作。 在`testMyOwerTab`这个文件中,我们可以找到...

    MFC拆分窗口及它们之间的数据交换

    3. **事件通知**:使用MFC的`ON_NOTIFY`消息映射条目,可以当一个视图中的事件发生时通知其他视图。例如,一个视图可能触发一个通知,另一个视图接收到该通知后更新自身。 4. **数据对象和剪贴板**:通过创建一个...

    MFC 实现按钮形状 三角形

    在MFC中,我们通常使用对话框(Dialog)类和控件(Control)类来构建用户界面,而按钮(Button)是其中最常见的控件之一。本篇文章将深入探讨如何在MFC应用中实现一个形状非传统的按钮,特别是将其形状改变为三角形...

    MFC 鼠标拖动按钮

    本话题聚焦于"MFC鼠标拖动按钮"这一技术,这通常涉及到自定义控件和消息处理,使得用户可以通过鼠标左键在界面上自由拖动一个按钮。 首先,实现鼠标拖动按钮的核心在于重载MFC中的几个关键函数。在MFC中,CButton类...

    MFC自绘进度条——可修改颜色

    当窗口需要重绘时,系统会发送WM_PAINT消息,此时我们可以在这个消息的处理函数中进行自定义的绘制工作。`CProgressCtrl`是MFC中用于处理进度条控件的类,但默认情况下,它不支持颜色的自定义。为了改变这一情况,...

Global site tag (gtag.js) - Google Analytics