MFC 攔截消息(修改Edit控件技術)

說明:修改現有控件的功能–>“子類化”技術
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();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章