`

简单封装的CMyWnd(封装sdk的窗口消息循环)

    博客分类:
  • VC
阅读更多

//CMyWnd.h

#pragma once
#include <Windows.h>
#include <vector>
using namespace std;

class CMyWnd
{
public:
	CMyWnd();
	~CMyWnd(void);

public:
	typedef LRESULT (CMyWnd::*PFNNORMALPROC)(HWND, UINT, WPARAM, LPARAM);
	typedef struct tagMsgInfo
	{
		UINT		m_uMsg;
		PFNNORMALPROC	m_pfunCall;
	}stMsgInfo, *LPMsgInfo;

	typedef LRESULT (CMyWnd::*PFNCOMMPROC)();

	typedef struct tagCommMsgInfo
	{
		UINT		m_uMsg;
		PFNCOMMPROC	m_pfunCall;
	}stCommMsgInfo, *LPCommMsgInfo;


public:
	//注册窗口类
	virtual BOOL RegisterClass(LPCTSTR lpszClassName, UINT style, int cbClsExtra, int cbWndExtra, HINSTANCE hInstance, 
		HICON hIcon, HCURSOR hCursor, HBRUSH hbrBackground, LPCTSTR lpszMenuName = NULL, HICON hIconSm = NULL);
	
	//创建窗口
	virtual BOOL Create(DWORD dwExStyle, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, 
		int nWidth, int nHeight, HWND hWndParent, HMENU nIDorHMenu, HINSTANCE hInst, LPVOID lpParam = NULL);

	//Command消息循环
	virtual LRESULT CmdProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
	
	//消息循环
	static LRESULT WINAPI WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

public:
	BOOL ShowWindow(int nCmdShow);

public:
	BOOL InitMsgFunList();
	BOOL AddCommandMsg(UINT uMsg, PFNNORMALPROC pfunCall);
	BOOL AddNoramlMsg(UINT uMsg, PFNNORMALPROC pfunCall);
	BOOL AddCommonMsg(UINT uMsg, PFNCOMMPROC pfunCall);

public:
	//窗口响应消息
	virtual LRESULT OnCreate();
	virtual LRESULT OnPaint();
	virtual LRESULT OnDestroy();

public:
	//辅助调用的函数
	virtual LRESULT OnDraw(HDC hdc, PAINTSTRUCT& ps);

public:
	HWND			m_hWnd;//保存窗口句柄

private:
	WNDCLASSEX		m_wndClass;//保存注册窗口类
	TCHAR			m_szClassName[MAX_PATH];//保存窗口类的名称

	//消息列表
	vector<stMsgInfo>		m_vtMsgInfo;//消息列表
	vector<stMsgInfo>		m_vtCmdInfo;//Command消息列表
	vector<stCommMsgInfo>	m_vtCommInfo;//常见的消息列表
};
 

 

//CMyWnd.cpp

#include "mywnd.h"
#include <tchar.h>
#include <stdio.h>

#pragma warning(disable: 4311)
#pragma warning(disable: 4312)
#pragma warning(disable: 4018)


CMyWnd::CMyWnd()
{
	m_hWnd = NULL;
	m_vtMsgInfo.clear();
	m_vtMsgInfo.clear();

	//添加常见消息映射
	InitMsgFunList();
}

CMyWnd::~CMyWnd(void)
{
}

BOOL CMyWnd::InitMsgFunList()
{
	AddCommonMsg(WM_CREATE, OnCreate);
	AddCommonMsg(WM_PAINT, OnPaint);
	AddCommonMsg(WM_DESTROY, OnDestroy);

	return TRUE;
}

BOOL CMyWnd::RegisterClass(LPCTSTR lpszClassName, UINT style, int cbClsExtra, int cbWndExtra, HINSTANCE hInstance, 
						   HICON hIcon, HCURSOR hCursor, HBRUSH hbrBackground, LPCTSTR lpszMenuName, HICON hIconSm)
{
	//初始化WNDCLASSEX
	::memset(&m_wndClass, 0, sizeof(m_wndClass));
	m_wndClass.cbSize = sizeof(m_wndClass);
	m_wndClass.style = style;
	m_wndClass.cbClsExtra = sizeof(this);
	m_wndClass.cbWndExtra = sizeof(this);
	m_wndClass.hInstance = hInstance;
	m_wndClass.hIcon = hIcon;
	m_wndClass.hCursor = hCursor;
	m_wndClass.hbrBackground = hbrBackground;

	if (NULL != lpszMenuName)
	{
		_tcsncpy(m_szClassName, lpszClassName, MAX_PATH);
	}
	else
	{
		_stprintf(m_szClassName, "mywnd-%d", rand());
	}

	m_wndClass.lpszClassName = m_szClassName;
	m_wndClass.lpszMenuName = lpszMenuName;
	m_wndClass.hIconSm = hIconSm;
	
	m_wndClass.lpfnWndProc = CMyWnd::WndProc;

	if (!::RegisterClassEx(&m_wndClass))
	{
		return FALSE;
	}

	return TRUE;
}

BOOL CMyWnd::Create(DWORD dwExStyle, LPCTSTR lpszWindowName, DWORD dwStyle,int x, int y, 
					int nWidth, int nHeight, HWND hWndParent, HMENU nIDorHMenu, HINSTANCE hInst, LPVOID lpParam)
{
	m_hWnd = ::CreateWindowEx(dwExStyle, m_szClassName, lpszWindowName, dwStyle, x, y, nWidth, nHeight,
		hWndParent, nIDorHMenu, hInst, lpParam);

	if (NULL == m_hWnd)
	{
		return FALSE;
	}

	//创建完成之后调用OnCreate
    OnCreate();

	SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this);

	::ShowWindow(m_hWnd, SW_NORMAL);
	::UpdateWindow(m_hWnd);

	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return TRUE;
}

BOOL CMyWnd::ShowWindow(int nCmdShow)
{
	if (!::IsWindow(m_hWnd))
	{
		return FALSE;
	}

	return ::ShowWindow(m_hWnd, nCmdShow);
}

LRESULT CMyWnd::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	int		i		= 0;
	LONG	lVal	= 0;
	CMyWnd* pThis	= (CMyWnd*)GetWindowLong(hwnd, GWL_USERDATA);

	if (NULL == pThis)
	{
		return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
	}

	//执行Command消息
	if (uMsg == WM_COMMAND)
	{
		return pThis->CmdProc(hwnd, uMsg, wParam, lParam);
	}

	//执行常见的消息
	for (i = 0; i < pThis->m_vtCommInfo.size(); i++)
	{
		if (uMsg == pThis->m_vtCommInfo[i].m_uMsg)
		{
			return (pThis->*(pThis->m_vtCommInfo[i].m_pfunCall))();
		}
	}

	//执行普通消息
	for (i = 0; i < pThis->m_vtMsgInfo.size(); i++)
	{
		if (uMsg == pThis->m_vtMsgInfo[i].m_uMsg)
		{
			return (pThis->*(pThis->m_vtMsgInfo[i].m_pfunCall))(hwnd, uMsg, wParam, lParam);
		}
	}

	return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
}

LRESULT CMyWnd::CmdProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	int i = 0;

	//执行普通消息
	for (i = 0; i < m_vtCmdInfo.size(); i++)
	{
		if (uMsg == m_vtCmdInfo[i].m_uMsg)
		{
			return ( this->*(m_vtCmdInfo[i].m_pfunCall) )(hwnd, uMsg, wParam, lParam);
		}
	}

	return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
}

BOOL CMyWnd::AddCommandMsg(UINT uMsg, PFNNORMALPROC pfunCall)
{
	stMsgInfo msgInfo = {uMsg, pfunCall};

	m_vtCmdInfo.push_back(msgInfo);

	return TRUE;
}

BOOL CMyWnd::AddNoramlMsg(UINT uMsg, PFNNORMALPROC pfunCall)
{
	stMsgInfo msgInfo = {uMsg, pfunCall};
	m_vtMsgInfo.push_back(msgInfo);

	return TRUE;
}

BOOL CMyWnd::AddCommonMsg(UINT uMsg, PFNCOMMPROC pfunCall)
{
	stCommMsgInfo msgInfo = {uMsg, pfunCall};
	m_vtCommInfo.push_back(msgInfo);

	return TRUE;
}

LRESULT CMyWnd::OnCreate()
{
	return DefWindowProc(m_hWnd, WM_CREATE, 0, 0);
}

LRESULT CMyWnd::OnPaint()
{
	HDC			hdc	= NULL;
	PAINTSTRUCT	ps	= {0};

	hdc = BeginPaint(m_hWnd, &ps);
	OnDraw(hdc, ps);
	EndPaint(m_hWnd, &ps);
	
	return S_OK;
}

LRESULT CMyWnd::OnDestroy()
{
	::PostQuitMessage(0);

	return S_OK;
}

LRESULT CMyWnd::OnDraw(HDC hdc, PAINTSTRUCT& ps)
{
	return S_OK;
}
 
分享到:
评论

相关推荐

    简单源码实现mfc窗口缓动效果

    MFC程序的核心是消息循环,我们需要确保在消息循环中能够接收到并处理定时器消息。这可以通过在消息映射(message map)中添加ON_MESSAGE宏来实现。 5. **结束缓动**: 当缓动动画到达终点时,停止定时器,以防止...

    VC++编程实例,在普通C/C++程序中,可以看到程序从main函数开始到结束的所有代码,但在Visual C++中MFC封装了一部分类,同时也隐藏了一部分代码,因此我们看不到源程序的所有代码,

    通过`DECLARE_MESSAGE_MAP()`和`BEGIN_MESSAGE_MAP()`,`CMyWnd`类将这两个函数与对应的窗口消息关联起来,使得当相应消息发生时,可以自动调用对应的处理函数。 总结来说,MFC在Visual C++中提供了丰富的类库,...

    MFC 动态创建窗口与对话框

    例如,创建一个简单的窗口可能如下所示: ```cpp HWND hWnd = CreateWindow(_T("EDIT"), _T("Hello, MFC!"), WS_VISIBLE | WS_CHILD | ES_LEFT, 10, 10, 200, 50, parentWnd, NULL, NULL, NULL); ``` 这里,`...

    MFC普通窗口重绘

    `BeginPaint()`和`EndPaint()`函数用于初始化和结束绘画过程,它们处理与绘画相关的系统资源,确保正确地处理窗口的paint消息。`BeginPaint()`返回一个`PAINTSTRUCT`结构,包含了关于绘画的信息,而`EndPaint()`则...

    VC获取自身窗口句柄

    在探讨如何通过VC(Visual C++)来获取自身窗口句柄之前,...无论是对窗口大小、位置的调整,还是响应窗口消息,获取窗口句柄都是必不可少的第一步。理解窗口句柄的概念及其获取方法对于Windows应用程序开发至关重要。

    MFC窗口透明

    2. **消息映射与处理**:在CMyWnd类中,我们需要添加消息映射并实现OnHScroll消息处理函数,这个函数会在滚动条的滑块位置改变时被调用。 ```cpp BEGIN_MESSAGE_MAP(CMyWnd, CWnd) ON_WM_HSCROLL() END_MESSAGE_...

    VC最大化和最小化窗口示例代码

    在处理窗口消息时,我们可能还需要响应WM_SIZE消息,这会在窗口大小改变时被触发。在窗口类的`OnSize`方法中,我们可以根据窗口的新尺寸更新内容: ```cpp void CMyWnd::OnSize(UINT nType, int cx, int cy) { ...

    VC++ MFC 定时器函数 刷新窗口

    当设定的时间间隔到达时,系统会发送`WM_TIMER`消息到窗口的消息队列中。窗口可以通过重写`OnTimer`成员函数来处理这些定时器消息。 ##### 函数原型 ```cpp UINT SetTimer( HWND hWnd, // 定时器所属窗口的句柄 ...

    MFC.rar_MFC 销毁窗口_mfc non client_mfc 创建窗口

    MFC封装了Windows API,提供了面向对象的接口,使得开发者能够更高效地构建和管理窗口、对话框、控件等元素。在这个"MFC.rar"压缩包中,我们主要探讨的是MFC如何创建和销毁窗口,以及非客户区域的相关知识。 首先,...

    MFC窗口滚动条

    在`OnSize`消息处理函数中,你需要更新滚动条的范围和页面大小,以适应窗口尺寸的变化。`OnHScroll`和`OnVScroll`函数则用于处理滚动条的操作,如滚动、拖动等。 接下来,我们讨论如何通过GDI+加载图片并设置滚动条...

    1.6 如何设置窗口的大小和位置

    MFC还提供了一个简单的`MoveWindow`函数,可以直接设置窗口的位置和大小: ```cpp MoveWindow(x, y, newWidth, newHeight, TRUE); ``` 7. `Create`函数参数: 当创建窗口时,可以在`Create`函数的`dwStyle`...

    MFC半透明窗口

    **分层窗口(Layered Windows)**是Windows API提供的一种高级窗口特性,它可以实现窗口的透明度、颜色键、以及自定义绘制等效果。分层窗口有两种模式:普通模式和自绘模式。普通模式下,窗口的透明度由系统处理;而...

    构建mfc窗体的简单示例

    在本文中,我们将深入探讨如何使用Microsoft Foundation Classes (MFC) 框架构建一个简单的窗口应用程序。MFC 是微软为 Windows 平台提供的一种 C++ 类库,它封装了 Win32 API,使得开发者可以更高效地编写 Windows ...

    控件的使用、MFC1

    `SendMessage`函数会阻塞调用线程直到消息被处理,而`PostMessage`则将消息放入消息队列,调用线程立即返回,稍后在消息循环中处理。这两种方式各有其应用场景,`SendMessage`常用于需要等待结果的操作,而`Post...

    如何使窗口闪烁

    MFC是VC++(Visual C++)的一部分,它提供了一种方便的方式来处理窗口、消息和系统资源。下面我们将深入探讨如何在MFC应用中实现窗口闪烁。 首先,窗口闪烁功能主要是通过调用Windows API函数来完成的。最常用的API...

    MFC CWnd重写并且加入控件动态创建,VS2005环境编译

    在Microsoft Foundation Classes (MFC)库中,`CWnd`是一个重要的基础类,它封装了Windows API中的`HWND`(窗口句柄)。`CWnd`是所有MFC窗口类(如`CButton`, `CEdit`, `CListBox`等)的基类,用于处理窗口消息和事件...

    VC++MFC编程实例PPT课件.pptx

    - **CwinApp的Run**:AfxWinMain继续调用CwinApp的Run函数,该函数负责应用程序的消息循环,处理用户交互和系统事件。 - **程序结束**:当Run函数返回后,AfxWinMain返回到WinMain,此时程序结束执行。 2. **吹...

    MFC-Draw.rar_MFC 透明窗口_MFC 透明窗口_mfc964

    此外,如果窗口需要响应鼠标和键盘事件,还需要处理相应的消息并进行适当的处理,以确保透明部分能够正确传递事件给底层窗口。 综上所述,通过MFC实现透明窗口并在此基础上进行绘图,需要结合Windows API函数和MFC...

    MFC自定义消息源码附加说明

    MFC是基于Windows消息机制的,它封装了Windows API中的各种消息处理。在MFC中,消息主要通过`ON_MESSAGE`、`ON_COMMAND`和`ON_BN_CLICKED`等宏来处理,但这些宏只能处理系统预定义的消息。为了处理未在标准消息表中...

    MFC编程思路方法及实现

    - `CMyWnd`类的消息映射机制中,`ON_WM_LBUTTONDOWN`和`ON_WM_PAINT`分别处理鼠标左键点击和窗口重绘事件。 - 当用户点击鼠标左键时,`OnLButtonDown`函数生成一个新的泡泡数据,并更新数组,同时触发重绘。 - `...

Global site tag (gtag.js) - Google Analytics