关于SubclassWindow

#define SubclassWindow(hwnd, lpfn) \
((WNDPROC)SetWindowLongPtr((hwnd), GWLP_WNDPROC, (LPARAM)(WNDPROC)(lpfn)))

从该宏可以看出是调用SetWindowLongPtr

具体的详解:http://blog.csdn.net/sunliangyuan/article/details/6028425

由于照着上面的链接敲的时候遇到了两个问题:

1、OnChar无法响应

2、当按回车键的时候整个程序直接退出了

一、其实也是看链接里面的介绍,要进行消息映射,而我只是简单的创建一个类,然后继承CEdit

.h

class SuperEdit : public CEdit
{
public:
    SuperEdit(void);
    ~SuperEdit(void);
    void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
};

这样一种无法进入onchar函数,后来觉得CEdit也应该是一个窗体,既然是窗体就应该要有自己的消息映射函数

于是就写如下代码

//.h
class SuperEdit : public CEdit
{
    DECLARE_DYNAMIC(SuperEdit)
public:
    SuperEdit(void);
    ~SuperEdit(void);
    void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
protected:
    DECLARE_MESSAGE_MAP()
};

// .cpp
#include "StdAfx.h"
#include "SuperEdit.h"

SuperEdit::SuperEdit(void)
{
}

SuperEdit::~SuperEdit(void)
{
}
IMPLEMENT_DYNAMIC(SuperEdit, CEdit)
void SuperEdit::OnChar( UINT nChar, UINT nRepCnt, UINT nFlags )
{
    // TODO: Add your message handler code here and/or call default
    TCHAR ch[20];
    GetWindowText(ch,20);
    if (wcslen(ch) == 1 && (nChar <= ‘C‘ && nChar >= ‘A‘))
        return;
    if (nChar != ‘A‘ && nChar != ‘B‘ && nChar != ‘C‘ )
        return;
    CEdit::OnChar(nChar, nRepCnt, nFlags);
}

BEGIN_MESSAGE_MAP(SuperEdit, CEdit)
    ON_WM_CHAR()
END_MESSAGE_MAP()

很幸运的成功了。 那究竟为何这样才能成功呢?

WNDPROC* lplpfn = GetSuperWndProcAddr();
    WNDPROC oldWndProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC,
        (INT_PTR)AfxGetAfxWndProc());

设置自身的回掉函数。具体如样例的描述解释。

二、第二个问题的解释

具体详解:http://tech.163.com/05/0906/09/1SV5EEQF00091589.html

时间: 2024-10-17 12:40:54

关于SubclassWindow的相关文章

CWnd中PreCreateWindow、PreSubclassWindow、SubclassWindow的区别

http://blog.csdn.net/swimmer2000/archive/2007/10/30/1856213.aspx MFC(VC6.0)的CWnd及其子类中,有如下三个函数:     // From VS Install PathVC98MFCIncludeAFXWIN.H    class CWnd : public CCmdTarget    {        ...    public:        ...        virtual BOOL PreCreateWind

SubclassWindow和SubclassDlgItem

通常如果在对话框中将一个控件映射到一个变量,有三种方法: DDX的方法 GetDlgItem的方法,例如CEdit pEdt = (CEdit *)GetDlgItem(IDC_EDIT1); SubclassWindow的方法(或者其扩展SubclassDlgItem),例如CEdit m_edit:m_edit.SubclassDlgItem(IDC_EDIT1); SubclassWindow CWnd::SubclassWindow(HWND hWnd)中调用两个主要操作:Attach(

DDX_Control、SubclassWindow和SubclassDlgItem

文章参考地址:http://blog.sina.com.cn/s/blog_86fe5b440101au88.html:http://www.cnblogs.com/riskyer/p/3424278.html 问题缘起 通常如果在对话框中将一个控件映射到一个变量,有三种方法: 1. DDX的方法 2. GetDlgItem的方法,例如CEdit pEdt = (CEdit *)GetDlgItem(IDC_EDIT1); 3. SubclassWindow的方法(或者其扩展SubclassDl

WTL自定义控件:SubclassWindow的实现

自定义了一个edit类如下: 1 class CCheckEditEx : public CWindowImpl< CCheckEditEx, CEdit > 其SubclassWindow函数实现如下: 1 BOOL CCheckEditEx::SubclassWindow(HWND hwnd) 2 { 3 ATLASSERT(NULL == ::GetWindow(hwnd, GW_CHILD)); 4 if (CWindowImpl< CCheckEditEx, CEdit >

Windows消息拦截技术的应用

Windows消息拦截技术的应用 民航合肥空管中心 周毅 一.前 言 众所周知,Windows程式的运行是依靠发生的事件来驱动.换句话说,程式不断等待一个消息的发生,然后对这个消息的类型进行判断,再做适当的处理.处理完此次消息后又回到等待状态.从上面对Windows程式运行机制的分析不难发现,消息在用户与程式之间进行交流时起了一种中间“语言”的作用.在程式中接收和处理消息的主角是窗口,它通过消息泵接收消息,再通过一个窗口过程对消息进行相应的处理. 消息拦截的实现是在窗口过程处理消息之前拦截到消息

MFC自绘控件学习总结

前言:从这学期开始就一直在学习自绘控件(mfc),目标是做出一款播放器界面,主要是为了打好基础,因为我基础实在是很烂....说说我自己心得体会以及自绘控件的方法吧,算是吐槽吧,说的不对和不全的地方,或者有更好的方法,请不吝赐教.我的机器环境是:Windows7旗舰版 Service Pack 1,Visual studio 20051).重绘某个控件时,强烈推荐使用子类化方法,比如想自绘Button控件, 首先添加自己的类CMYButton 继承自 CButton ,声明一个CMYButton

VC常用小知识

(1) 如何通过代码获得应用程序主窗口的 指针?主窗口的 指针保存在CWinThread::m_pMainWnd中,调用AfxGetMainWnd实现.AfxGetMainWnd() ->ShowWindow(SW_SHOWMAXMIZED)//使程序最大化. (2) 确定应用程序的路径Use GetModuleFileName 获得应用程序的路径,然后去掉可执行文件名.Example:TCHARexeFullPath[MAX_PATH] // MAX_PATH在API中定义了吧,好象是128G

mfc 按钮自绘

MFC  按钮自绘 :songyanwu 如果你是大神就没必要看这个文章了! 说明 源码下载:mfc 按钮自绘 先说说自己的一些想法:我就想把按钮封装成一个类,每次在使用的时候会很方便,当然在自己的类中去重载也可以! 此文章可借鉴学习:MFC基础,MFC自绘控件学习总结. (我也主要研究了自绘控件的子类化方法  ),看完前面推荐的文章,你似乎有何种感觉呢? 先实际操作吧;原理在后面介绍: 1 新建一个对画框 应用程序 2 新添加一个CMyButton继承CButton 3 为你自己添加的类 添加

积累的VC编程小技巧之框架窗口及其他

1.修改主窗口风格 AppWizard生成的应用程序框架的主窗口具有缺省的窗口风格,比如在窗口标题条中自动添加文档名.窗口是叠加型的.可改变窗口大小等.要修改窗口的缺省风格,需要重载CWnd::PreCreateWindow(CREATESTRUCT& cs)函数,并在其中修改CREATESTRUCT型参数cs.CWnd::PreCreateWindow 函数先于窗口创建函数执行.如果该函数被重载,则窗口创建函数将使用CWnd::PreCreateWindow 函数返回的CREATESTRUCT