iOS浅谈mfc子类化

释放双眼,带上耳机,听听看~!

一、引入子类化概念的原因:

如果你对CEdit控件有这样的需求:只允许用户输入数字或是字幕!你会怎么做?

1. 你可以二话不说的重写这个类。

2. 在CEdit控件的父窗口中的PreTranslateMessage中拦截这个控件的输入。

两个方法都能实现这个需求,但方法1太过于费时费力。在这里,方法二看似可以完美的解决这个问题。

但是某些情况下,消息不经过消息队列(sendMessage),那方法二就无能为力了。

这时子类化就体现出他的优势了。

二、子类化的概念:创建一个新的窗口函数代替原来的窗口函数。

说了等于没说!仔细想想上面的问题:我们要做的是什么,不就是想过滤用户的输入吗,也就是我们只要能在消息被处理之前拦截到用户的输入就行了!消息被谁处理,当然是窗口函数,所以,我们只要使用我们自定义的窗口函数就可以了!问题又来了,窗口函数是在窗口注册的时候赋值的,而mfc用的消息映射机制,我们不可能去改变框架的代码!又陷入死胡同了?当然不是,SetWindowLong可以改变指定窗口的属性。

LONG SetWindowLong(
HWND hWnd,//handletowindow
int  nlndex,//offsetofvaluetoset
LONG dwNewLong//newvalue
);

当第二个参数赋予GWL_WNDPROC时,第三个参数就可以赋予你自定义的窗口函数了,而此时SetWindowLong的返回值则是旧窗口函数的地址。

三、具体步骤

1. 在该控件(此处为CEdit)的父窗口初始化的时候(比如对话框OnInitDialog)设置新的窗口过程,并保留旧的窗口过程。

m_oldEditProc = (WNDPROC)SetWindowLong(GetDlgItem(hDlg, IDC_EDIT_NUM_CHARETER), GWL_WNDPROC, (LONG)wndProNumBerAndCharater);
(m_oldEditProc是WNDPROC类型的父窗口成员变量)

 

1. 实现新的窗口函数:

LRESULT CALLBACK wndProNumBerAndCharater(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)

{

  if(...) //存在非数字且非字母字符,过滤操作 

  {

    messageBox(_T("不能输入除数字及字幕外的其他字符!"));

    return 0;

  }

  else //是数字或是字母,使用原来的过程处理

  {

    return CallWindowProc(m_oldEditProc, hWnd, Msg, wParam, lParam);
  }

}

 

(CallWindowProc :该函数将消息信息传送给指定的窗口过程, 是window系统api里的一个函数,直接使用即可!).

人已赞赏
iOS文章

ios中改变UIImagePickerController页面的button的文字为中文

2020-2-15 11:45:52

iOS文章

iOS11_适配总结

2020-2-15 12:44:44

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索