MFC 拦截消息(修改Edit控件技术)

1 篇文章 0 订阅

说明:修改现有控件的功能–>“子类化”技术
SetWindowLong()、CallWindowProc()

自定义CDoubleEdit类

头文件

#pragma once
class CDoubleEdit
{
public:
	CDoubleEdit();
	~CDoubleEdit();

BOOL Attach(HWND hWnd);//绑定文本框控件

void DeAttach();//取消绑定

BOOL GetStringValue(LPTSTR lpBuffer,int nLen);//获取输入的文本

BOOL GetDoubleValue(double* dValue);
protected:
	static LRESULT APIENTRY NewEditProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);//新窗口过程
protected:
	HWND m_hWnd;
	long m_lOldProc;
};

实现文件

#include "stdafx.h"
#include "DoubleEdit.h"

#define DOUBLE_EDIT_PROP_NAME _T("Double_Edit_Prop_Name")
CDoubleEdit::CDoubleEdit()
{
}
CDoubleEdit::~CDoubleEdit()
{
	DeAttach();
}
BOOL CDoubleEdit::Attach(HWND hWnd)
{
	if (m_hWnd!=NULL)
	{
		DebugBreak();
		return FALSE;
	}
	m_hWnd = hWnd;
	SetProp(hWnd, DOUBLE_EDIT_PROP_NAME,this);
	m_lOldProc = SetWindowLong(hWnd, GWL_WNDPROC, (long)NewEditProc);
	if (m_lOldProc==0)
	{
		m_lOldProc = NULL;
		return FALSE;
	}
	return TRUE;
}

//窗口过程成员函数
LRESULT APIENTRY CDoubleEdit::NewEditProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)//新窗口过程
{
	CDoubleEdit* pEdit = (CDoubleEdit*)GetProp(hWnd, DOUBLE_EDIT_PROP_NAME);
	if (pEdit == NULL)
	{
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}

	BOOL bCanceled = FALSE;

	//拦截消息 字符消息
	if (uMsg==WM_CHAR)
	{
		TCHAR szBuff[32] = { 0 };
		pEdit->GetStringValue(szBuff, 32);
		switch (wParam)
		{
		case '.':
			if (_tcschr(szBuff,'.'))
			{
				bCanceled = TRUE;
			}
			break;
		case '-':
			if (_tcschr(szBuff, '-'))
			{
				bCanceled = TRUE;
			}
			else if (LOWORD(SendMessage(hWnd,EM_GETSEL,0,0))!=0)
			{
				bCanceled = TRUE;
			}
			break;
		default:
			if ((wParam>'9') || (wParam<'0') && wParam!=VK_BACK)
			{
				bCanceled = TRUE;
			}
			break;
		}

		if (bCanceled)
		{
			MessageBeep(-1);
			return 0;
		}
	}
	return CallWindowProc((WNDPROC)pEdit->m_lOldProc, hWnd, uMsg, wParam,lParam);
}

BOOL CDoubleEdit::GetStringValue(LPTSTR lpBuffer, int nLen){
	return GetWindowText(m_hWnd,lpBuffer,nLen);
}

BOOL CDoubleEdit::GetDoubleValue(double* dValue)
{
	TCHAR szBuf[32];
	if (GetStringValue(szBuf, 32))
	{
		*dValue = _tstof(szBuf);
	}
	else
	{
		return FALSE;
	}
}

void CDoubleEdit::DeAttach(){
	if (m_hWnd==NULL)
	{
		return;
	}
	SetWindowLong(m_hWnd, GWL_WNDPROC, m_lOldProc);
	m_hWnd = NULL;
	m_lOldProc = 0;
}




// 拦截消息Dlg.cpp : 实现文件
//

#include "stdafx.h"
#include "拦截消息.h"
#include "拦截消息Dlg.h"
#include "afxdialogex.h"
#include "DoubleEdit.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// C拦截消息Dlg 对话框
CDoubleEdit g_edit;


C拦截消息Dlg::C拦截消息Dlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(C拦截消息Dlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void C拦截消息Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(C拦截消息Dlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDOK, &C拦截消息Dlg::OnBnClickedOk)
	ON_WM_DESTROY()
END_MESSAGE_MAP()


// C拦截消息Dlg 消息处理程序

BOOL C拦截消息Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO:  在此添加额外的初始化代码
	g_edit.Attach(GetDlgItem(IDC_EDT_TEST)->GetSafeHwnd());
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void C拦截消息Dlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR C拦截消息Dlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void C拦截消息Dlg::OnBnClickedOk()
{
	// TODO:  在此添加控件通知处理程序代码
	//读取
	double dValue = 0.0;
	if (g_edit.GetDoubleValue(&dValue))
	{
		TCHAR szBuf[128] = { 0 };
		_stprintf(szBuf, _T("输入的数值:%.10f"), dValue);
		AfxMessageBox(szBuf);
	}
	else
	{
		AfxMessageBox(_T("没有输入"));
	}
	//CDialogEx::OnOK();
}


void C拦截消息Dlg::OnDestroy()
{
	CDialogEx::OnDestroy();

	// TODO:  在此处添加消息处理程序代码
	g_edit.DeAttach();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值