打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
vc子类化和反子类化
com安装程序:
用 CopyFile 把 Addin 复制到你指定的目录
然后调用 Regsvr32 就可以了,比如

CopyFile(srcFile,"c:\\windows\\system",false);
shellexecute(NULL,"open","regsvr32","c:\\windows\\system",NULL,SW_HIDE);
 
 
 
 
    编译的时候出现dll链接不一致的问题,可能是有些函数声明使用了dllimport,但是实际上本工程并没有使用dll,所以出现声明不一致。此时把dllimport声明去掉即可。
 
一。ATL中使用MFC
 
1。在ATL的接口函数中使用mfc前,需要在函数中包含如下代码调用:
    AFX_MANAGE_STATE(AfxGetStaticModuleState())
注意,这里是使用AfxGetStaticModuleState()而不是AfxGetAppModuleState(),AfxGetAppModuleState()我还没搞清楚怎么使用。
 
二。子类化
通过子类化可以将MFC窗口对象与自己的MFC控件类连接起来,这样,该类的的消息处理函数会替代原来的消息处理函数,窗口消息就能通过自己的类进行消息映射,并首先调用自己的类的消息处理函数,比如可以采用自己的Edit类来处理WM_CHAR消息。子类化可以通过宏DDX_Control宏进行静态关联,以可以通过函数SubclassWindow()或SubclassDlgItem()完成。
 
示例:
 
在对话框类中添加变量 CMyEdit,m_MyEdit,在初始化函数中添加动态子类化函数 : m_MyEdit.SubclassDlgItem(IDC_EDIT,this); 
为了演示一些其他问题,此处添加了两个按钮子类化和反子类化。相关代码如下:
 
子类化:
void CAdEditDlg::OnBtnsub()
m_MyEdit.SubclassWindow(GetDlgItem(IDC_EDIT)->m_hWnd); 
GetDlgItem(IDC_BTNUNSUB)->EnableWindow(true); 
GetDlgItem(IDC_BTNSUB)->EnableWindow(false); 
m_MyEdit.SetFocus(); 
}
 
反子类化:
void CAdEditDlg::OnBtnunsub() 
m_MyEdit.UnsubclassWindow(); 
GetDlgItem(IDC_BTNUNSUB)->EnableWindow(false); 
GetDlgItem(IDC_BTNSUB)->EnableWindow(true); 
GetDlgItem(IDC_EDIT)->SetFocus(); 
}  
 
附加说明:

1、子类化函数的参数说明: 
BOOL SubclassDlgItem( UINT nID, CWnd* pParent); 将一个 Windows 控件与 CWnd 或 CWnd 派生类的对象连接,然后使它通过 CWnd 或 CWnd 派生类的消息映射转发消息。其中nID为该控件的ID,pParent为控件的父窗口。
BOOL SubclassWindow( HWND hWnd ); 作用同SubclassDlgItem,只是该函数通过创后的句柄来完成子类化操作。hWnd为需要子类化的窗口句柄。
HWND UnsubclassWindow(); 反子类化,该函数使窗口与子类化所连接的类脱离,使用该控件窗口默认的消息处理函数WndProc来处理。函数返回取消子类化的窗口句柄。

2、如果使采用ClassWizard将编辑框与CMyEdit变量映射后,ClassWizard已经通过DDX_Control宏完成了子类化的过程,如果此时再在对话框的初始化函数中进行子类化的时候,将会发生错误。

3、反子类化后,m_MyEdit对象已经与窗口分离,此时不能通过m_MyEdit来处理该窗口需要消息类完成的操作,比如SetFocus(),否则,也会发生错误。



1. 子类化 
在一个已经存在的窗口实例基础上产生新的窗口(本质上时改变原窗口的性质:消息护 
理与其他实例属性)。在SDK编程范畴内,子类化就是改变一个窗口实例的窗口函数(通 
过GetWindowLong()和SetWindowLong()),子类化所要做的就是为某窗口实例编写新的 
窗口函数。其操作是在实例级别上进行的。也就是说:子类化影响的是窗口实例的消息 
拦截及其相应处理。 
实际上,所有MFC窗口都是被子类化的窗口(很多体现,如:所有的窗口都共享一个窗口 
函数,所有的窗口包括控件最后都需调用::CreateWindow ()或::CreateWindow Ex 
()。。。。。。)。 
在MFC中子类化的情况有所不同:所有MFC窗口有相同的窗口函数,由该窗口函数根据窗 
口句柄查找窗口实例,在把消息映射到该窗口类(class)得消息处理函数上。为了利用 
MFC的消息映射机制,不宜改变窗口函数(名),MFC也把子类化封装在函数SubclassWi 
ndow()中。但子类化的本质没有变:在实例级别影响窗口的消息及其处理。例: 
Class  B :public A 
  。。。。。。 
A  a; 
B  b; 
HWND ha = a. GetSafeHwnd  (); 
b.SubclassWindow(ha); 
当然A 和B 不一定是继承关系。 
注意:在被子类化的窗口销毁之前,必须执行窗口的反子类化: 
  b.UnSubclassWindow(); 
2 超类化 
与子类化对应,窗口超类化是在窗口类——WNDCLASS或WNDCLASSEX(非MFC类概念)级别 
进行的改变窗口类特征的。一般遵循以下步骤过程:首先,获得一个已存在的窗口类; 
然后设置窗口类;最后注册该窗口类。 
例: 
WNDCLASSEX  wc; 
wc.cbSize = sizeof(wc);//Windows用来进行版本检查的,与窗口特征无关 
GetClassInfoEx(hinst,”XXXXXX”,&wc);// hinst——定义窗口类XXXXXX 
      //的模块的句柄,如为系统定义的窗口类(如:EDIT、BUTTON) 
      //则hinst=NULL.。 
wc.lpszClassName = “YYYYYYY”;//必须改变窗口类的名字 
wc.hbrBackGround = CreateSolidBrush(RGB(0,0.0));//改变背景刷 
wc.lpfnWndProc = NewWndProc;//改变窗口函数 
。。。。。。 
RegisterClassEx(&wc);// 注册新窗口类 
//使用窗口类 
。。。。。。 
::CreateWindow(_T(“YYYYYYYY”,。。。。。); 
显然使用超类化要涉及到SDK中的 CreateWindow(或CreateWindowEx())这就是说:要 
重载MFC中窗口类(class)的Create(或CreateEx())函数,故超类化只能改变自己创建的 
窗口的特征,而不能用于由Windows创建的窗口(如对话框上的按钮就不能进行超类化) 
。而子类化是实例级别上的,只要能获得窗口的实例,就可对其子类化,这是唯一的子 
类化对于超类化的优势,当然,子类化还比较简单。除此,凡是子类化可实现的,超类 
化都可实现,不过超类化用起来较麻烦。 
最后: 
(1) 子类化是在窗口实例级别上的,超类化是在窗口类(WNDCLASS)级别上的。 
(2) 超类化可以完成比子类化更复杂的功能,在SDK范畴上,可以认为子类化是超类化 
的子集。 
(3) 子类化只能改变窗口创建后的性质,对于窗口创建期间无能为力,而超类化可以 
实现 
(4) 超类化不能用于Windows创建的窗口,子类化可以。 


一个窗口类,并在视图类中定义了该类的一个实例对象。我想将视图类中的消息响应函数完全放到该窗口类中实现。可采用窗口子类化技术完成这项工作。我的疑问是,应该在何处添加窗口子类化的代码?请给出示例代码,谢谢!
--------------------------------------------------------------------------------
答:自己顶
--------------------------------------------------------------------------------
答:虽然没太懂,不过是获得父窗口的句柄,然后在子窗口里调用.
--------------------------------------------------------------------------------
答:在VIEW类收到某个你感兴趣的消息时,向那个窗口发送相应的消息。LRESULTC**View:efWindowProc(WPARAMwParam,LPARAMlParam){switch(...)case...:CSubDlg.SendMessage(...);break;}也可以在收到消息后就直接调用它的方法,这也不违背面向对象的方法。
--------------------------------------------------------------------------------
答:谢谢leaf__leaf兄的回答。我可能没说清自己的意图。原意是这样的:自定义一个从CWnd类继承而来的视图类:CCustomView,用于用户界面的显示。在MFC向导生成的视图类(CMyView)中添加一个CCustomView类对象变量。由于CCustomView类里面定义了尺寸改变、鼠标形状设置、鼠标动作和键盘操作等消息响应函数,因此,希望CCustomView类截取CMyView类(严格的讲应是绑定到CMyView类对象的窗口)中的各种消息。一种解决方法就是在CMyView类里添加各种消息的响应函数,然后再分别调用CCustomView类里对应的消息函数;另一种解决方法是在CMyView类的DefWindowProc函数里,调用CCustomView里的消息响应函数。然而,这两种方法,都比较繁琐,而且二者之间耦合过紧,不利于程序的维护。一种较好的方法是,采用窗口子类化(windowsubclassing)技术,将CMyView类的窗口过程(WindowProc)替换为CCustomView类的窗口过程(WindowProc)。这种方法能极大地减少二者之间的耦合,有利于程序的维护。目前,各种介绍窗口子类化的例子,均只限于对话框中控件的子类化。没有我当前这种情形所需的代码。根据MSDN文档,我写出了如下代码:在CCustomView类的PreCreateWindow函数里,启用窗口子类化,将当前窗口过程(WindowProc)绑定到父类窗口,具体代码如下:BOOLCCustomView:reCreateWindow(CREATESTRUCT&cs){ASSERT(cs.hwndParent!=NULL);SubclassWindow(cs.hwndParent);returnCWnd:reCreateWindow(cs);}在CCustomView类的OnDestroy函数里,取消窗口子类化,具体代码如下:voidCCustomView::OnDestroy(){UnsubclassWindow();CView::OnDestroy();}现在的问题是在执行SubclassWindow(cs.hwndParent)语句时,总会出现ASSERT错误,不知是什么原因。请各位兄台赐教,谢谢!
--------------------------------------------------------------------------------
答:请问gofqjyie(誓将天下了然于胸),怎么处理?能否给出具体的示例,谢谢!
--------------------------------------------------------------------------------
答:CToolBar和CToolTipCtrl等控件应该有这方面的需求.你可以看看MFC里面怎么搞的.
--------------------------------------------------------------------------------
答:关于窗口子类化那个SubclassWindow我没用过,可是,如果一个类不是另一个类的子类,这样能成吗?很可能是这个问题,在这个函数里MFC也许加了个IsKindOf的判断。准确来说,那个CCustomView应该是继承自CView的吧?那么你那个CMyView应该也是的吧?为什么不让CMyView不是直接继承CView而直接继承CCustomView呢?我想写这个类的人估计也是会要你做这样的事的吧,就像在生成工程时向导会提醒你要从哪个类继承视图类,这么做……可以是可以,只是不知道合不合LZ的要求^.^
--------------------------------------------------------------------------------
答:我是这样理解的,楼主是想让CMyView子类化为CCustomView的一个子类,这样就可以让CCustomView来优先处理CMyView的消息。但是CCustomView是CMyView的一个成员变量,前者是在后者开始构造之后才被构造,在后者构造完成前首先结束构造的,两者的内存区域有重叠部分,是否是这样导致了子类化时的许多错误?可以试试在CMyView中设置一个CCustomView的指针成员变量pCustomView;而子类化之前,在堆上new一个CCustomView,指针传递给pCustomView,然后再调用SubclassWindow(...);?lz可以把ASSERT错误的语句也贴出来看看啊
--------------------------------------------------------------------------------
答:Toleaf__leaf():“关于窗口子类化那个SubclassWindow我没用过,可是,如果一个类不是另一个类的子类,这样能成吗?很可能是这个问题,在这个函数里MFC也许加了个IsKindOf的判断。”窗口子类化不是C中的继承概念,所以不需要满足“一个类是另一个类的子类”这样的要求。简单地说,就是将一个类中的窗口过程绑定为另一个类的窗口过程。具体的概念,还请参阅MSDN。“准确来说,那个CCustomView应该是继承自CView的吧?那么你那个CMyView应该也是的吧?为什么不让CMyView不是直接继承CView而直接继承CCustomView呢?我想写这个类的人估计也是会要你做这样的事的吧,就像在生成工程时向导会提醒你要从哪个类继承视图类,这么做……可以是可以,只是不知道合不合LZ的要求^.^”CCustomView不从CView继承,它是从CWnd继承得到,是我自己定义的一个窗口类。而CMyView确实从CView继承,实际上它就是用整个程序框架中的视图类。我这所以这样处理,是想要将CCustomView做成一个MFC动态库,然后在CMyView中创建出一个CCustomView对象,让它覆盖原来的CMyView窗口,并处理原来CMyView得到的所有消息。这有点类似于在CMyView中加入一个窗口控件,然后由该窗口控件去处理各种消息。这样做的好处是,程序的模块性比较好,便于维护。
--------------------------------------------------------------------------------
答:Tolifeisdox(isDox):“我是这样理解的,楼主是想让CMyView子类化为CCustomView的一个子类,这样就可以让CCustomView来优先处理CMyView的消息。但是CCustomView是CMyView的一个成员变量,前者是在后者开始构造之后才被构造,在后者构造完成前首先结束构造的,两者的内存区域有重叠部分,是否是这样导致了子类化时的许多错误?可以试试在CMyView中设置一个CCustomView的指针成员变量pCustomView;而子类化之前,在堆上new一个CCustomView,指针传递给pCustomView,然后再调用SubclassWindow(...);?lz可以把ASSERT错误的语句也贴出来看看啊”兄台可能也误解了“窗口子类化”的概念。CMyView不从CCustomView继承,但它却包含一个CMyView的类对象变量。我的意思就是想用CCustomView去处理CMyView内的所有消息。


关于如何换肤、子类化的解决方案(3)
关键词:关于如何换肤、子类化的解决方案,,
SetWindowLong(hWnd, GWL_WNDPROC, (LONG) StaticWindowProc); 

return true; 

void CWndNew::UnsubclassWindow() 
SetWindowLong(m_hWnd, GWL_WNDPROC, (LONG)m_oldProc); 
PostunsubclassWindow(); 
m_map.erase(m_hWnd); 
m_hWnd = NULL; 

LRESULT CALLBACK CWndNew::StaticWindowProc(HWND hWnd, 
UINT uMsg, 
WPARAM wParam, 
LPARAM lParam) 
CWndNew* pWnd = m_map[hWnd]; 
ASSERT(pWnd != NULL); 
return pWnd->WindowProc(uMsg, wParam, lParam); 

LRESULT CWndNew::PrevWindowProc(UINT uMsg, 
WPARAM wParam, 
LPARAM lParam) 
return CallWindowProc(m_oldProc, m_hWnd, uMsg, wParam, lParam); 

LRESULT CWndNew::WindowProc(UINT uMsg, 
WPARAM wParam, 
LPARAM lParam) 
return PrevWindowProc(uMsg, wParam, lParam); 
   关于子类化及其撤销的顺序问题,当用自己的类或者过程子类化窗口时,需要处理好与MFC类子类化的顺序冲突。假设我们自己的类叫CWndNew,那么不管CWnd和CWndNew谁先子类化一个窗口,最终两者协同工作的结果应该是该窗口的窗口过程还原到未子类化之前的状态。首先,不要在HOOK过程中处理WM_NCDESTROY消息。理由:如果CWndNew比CWnd先子类化,由于HOOK的原因,你仍然会先处理WM_NCDESTROY,这时候如果你撤销子类化,那么CWnd类就得不到机会清理。而如果你不撤销子类化,CWnd没有能力把被子类化的窗口还原到最初状态。在HOOK过程中,不能通过调用SendMessage函数让CWnd先行处理,然后你自己再处理,因为SendMessage后,消息又会被HOOK拦截。 
   由于上述原因,在CWndNew的消息过程中处理WM_NCDESTROY是很不错的选择,MFC也是这样做的。参照如下的代码进行解释: case WM_NCDESTROY: 
LRESULT lret; 
WNDPROC wndproc; 
wndproc = (WNDPROC)GetWindowLong(m_hWnd, GWL_WNDPROC); 
if (wndproc == CWndNew::StaticWindowProc) 
HWND hWnd = m_hWnd; 
UnsubclassWindow(); 
lret = CallWindowProc(m_oldProc, 
hWnd, 
uMsg, 
wParam, 
lParam); 
else 
lret = CallWindowProc(m_oldProc, 
m_hWnd, 
uMsg, 
wParam, 
lParam); 

if(wndproc == (WNDPROC)GetWindowLong(m_hWnd, GWL_WNDPROC)) 
UnsubclassWindow(); 
delete this; 
return lret; 
   首先判断该窗口的WNDPROC是否发生过变动,如果没有的话是最好的,赶紧撤销子类化,再把消息传递给之前窗口过程,然后功成身退,不问世事了。 
   如果发生过变动,那么也就是说有别的类在CWndNew子类化以后又进行了子类化,而现在又把WM_NCDESTROY传给了CWndNew。这好办,如法炮制,把消息继续往前传,如果WNDPROC又发生了改变,说明之前的某个窗口过程已经作了处理,就不需要再进行撤销子类化的操作了。这点MFC的CWnd类也是这样做的。 
   另外还有一个问题不解,就是Edit,ListBox,ListCtrl等等控件的内嵌的滚动条是怎么换肤的?网上一般介绍的方法是隐藏原来的,然后换上自己重新实现的。这种在Spy++中一看就能现出原形,可是Skin++ 换肤后的滚动条就不知道是怎么实现的了?我看过coolsb这个文章,他能实现给滚动条换肤的功能,但是对Combobox支持不好

Visual C++中窗口子类化技术的实现及其应用2009年03月19日 星期四 10:16一、引言 
    在Windows编程中,如果我们想在窗口程序执行时改变它所包含的控件(对话框中的按钮、下拉式菜单等)的某些行为,采用窗口子类化技术是一个不错的选择。可以使用对已有控件派生子类的方式定义一个子类,而控件的消息处理则在新定义的子类里定义。适当使用子类化技术创建出容易使用的新窗口类,往往可以使你的程序界面更具人性化。

    二、窗口子类化技术概述

    Windows的窗口类是一个窗口模板,包含一个窗口所具有的部分窗口属性。编写一个Windows程序时首先要做的工作就是注册一个窗口类,然后基于此注册的窗口类创建一个新的窗口。在WIN32平台中,注册窗口类的API函数是RegisterClass和RegisterClassEX,其中RegisterClassEX是推荐使用的函数,使用这个函数注册窗口类时,需要先填写一个WNDCLASSEX结构。这个结构实际上反映了一个窗口类的特征,一个窗口类有本类所有窗口公用的类属性、窗口函数、类图标和小图标、类鼠标、窗口背景刷、类菜单,当然还有类名。除此之外,每个类还有一定大小的类存储区,可以用来存储该类的公共数据。

    每一个创建的窗口都有一个窗口函数,其地址由WNDCLASSEX结构的lpfnWndProc参数设定,该窗口函数处理对应于该窗口类的所有实例的消息。当创建一个窗口时,Windows将分配一个内存块,用来存放与该窗口相关的信息,并将参数lpfnWndProc从窗口类内存块拷贝到该内存块中。当消息被分发到窗口时,Windows检查该窗口中内存块中的lpfnWndProc值,并调用该内存块地址上的窗口函数。

    一个窗口的行为主要取决于它的窗口函数,如果能够改变一个窗口的窗口函数,使它指向自己写的某个函数,那就意味着发给这个窗口的各种消息将由我们自己写的这个函数来处理。

    子类化一个窗口,实际上就是改变窗口内存块中的窗口函数的地址,使其指向用户自定义的新的窗口函数入口,以实现用户希望的窗口特性。

    三、窗口子类化的作用

    窗口子类化技术最大的特点就是能够截取Windows的消息。一旦用户自定义的窗口函数截取了传向原窗口函数的消息,就可以对被截取的消息进行如下处理[2]:

    n         将其传给原来的窗口函数。这是对大多数消息应该采取的措施,因为子类通常只对原来的窗口特性作少量的修改。

    n         截取该消息,阻止其向原窗口函数发送。

    n         修改该消息,修改完毕以后再向原窗口函数发送。

    Windows SDK提供了一些设计好的窗口类,如EDIT、LISTBOX、TREEVIEW等。通过截取这些通用窗口类的消息,用户程序可以为它们添加新的特性,改善其外观,扩充其功能。

    子类化的优点主要体现在以下两个方面:首先,它不需要创建新的窗口类,不需要了解一个窗口的窗口过程。这在原来的窗口函数是由别人编写,而且创建过程不可见的情况下非常有用;其次,子类化比较容易实现,因为所有要做的工作仅仅就是写一个窗口函数。

    四、在VC中实现窗口子类化

    上面介绍的子类化是从Windows本身的窗口函数概念来讲的,实际上属于SDK(Software Development Kit)编程的范畴,在MFC中情况有所不同。下面将分别描述在这两种情况下窗口子类化实现的方法。

    4.1 VC中基于SDK编程的窗口子类化

    VC中基于SDK编程的窗口子类化的基本步骤如下:

    (1)       正常创建原始窗口,得到窗口的句柄。

    (2)       调用GetWindowLong得到原来的窗口函数OldWndProc.

    (3)       调用SetWindowLong设置新的窗口函数NewWndProc.

    新的窗口函数的代码如下所示: LRESULT NewWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)

{

       if(message==WM_IcareIt)

       {

              //截取自己感兴趣的消息,作一些处理,达到改变特性的目的

}

//必要时可以调用原来的窗口函数,使被子类化的窗口仍具有原来的很多特性

return CallWndowProc(OldWndProc,hWnd,message,wParam,lParam);

}
 


    值得注意的是,在调用旧的窗口函数时,不能直接用OldWndProc(…),而必须用函数CallWndProc进行调用,否则会出现堆栈错误。

    4.2 MFC编程中的窗口子类化

    MFC窗口实际上已经是被子类化的窗口。所有的MFC窗口共享同一个窗口函数,由这个窗口函数根据窗口句柄,查找这个窗口对应的CWnd派生类实例,再通过消息映射这个窗口类的消息处理函数。鉴于以上原因,在MFC中要子类化一个窗口就比较容易了,因为你的任务只是编写一个新的MFC窗口类而不需要写一个窗口函数。

    假如我们现在有一个对话框,里面有一个编辑控件,我们只希望在该控件中接受非数字字符输入,我们可以拦截WM_CHAR消息,在它的处理函数中忽略任何数字的输入。MFC编程中窗口子类化的具体实现步骤在下一节笔者将用一个简单的实例来加以说明。

   五、VC中窗口子类化的应用举例

    MFC为广大编程者提供了很多功能丰富的窗口类,如果能在这些通用窗口类的基础上进行子类化的话,将会给编程者带来很多便利。下面举一个例子来说明MFC编程中的子类化是多么的简单易行。该例完成上面提到的在编辑控件只接受非数字字符输入的功能。实现这个子类化的基本步骤和相关代码如下:

    (1)利用AppWziard创建一个基于对话框的程序SubClassing.

    (2)对MFC提供的标准的对话框中的控件进行修改,删除MFC提供的静态文本控件,添加自己的一个编辑控件,设置新控件的ID为IDC_EDIT.合理布置对话框上各控件的位置,使程序界面布局合理、美观。

    (3)用ClassWizard从CEdit类派生一个新的窗口类,新窗口的窗口类叫CNoNumEdit.截取CNoNumEdit类的WM_CHAR消息,在OnChar函中完成忽略任何数字的输入的处理。实现代码如下: void CNoNumEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)

{

TCHAR ch=nChar;

if(ch>=_T('0')&&ch<=_T('9'))

{

         AfxMessageBox(("请不要输入数字!"),MB_OK);

     //当输入数字字符时将被忽略,并显示警告信息

         return;

}

CEdit::OnChar(nChar, nRepCnt, nFlags);//输入为非数字字符时调用原处理函数

}
 


    4)在对话框窗口类CSubClassingDlg的定义中添加变量CNoNumEdit ed.在CSubClassingDlg::OnInitDialog()函数中调用CWnd类的成员函数SubClassWindow进行子类化。

    ed.SubclassWindow(GetDlgItem(IDC_EDIT)->m_hWnd);

    (5) 在对话框窗口类CsubClassing的OnDestroy中调用ed.UnSubClassWindow()执行窗口类的反子类化。

    现在可以编译执行这个程序了,当用户输入数字字符时将会忽略该输入,并显示警告信息。

    六、结束语

    在Windows编程中,适当使用窗口子类化技术,可以很方便地达到改变一个窗口的特性的目的。当然子类化也存在其局限性。实际上,子类化的概念是针对一个已经创建的窗口来谈的,所以修改窗口函数是在窗口创建之后进行的,在窗口创建期间的消息无法捕获,也就无法处理。另外有些窗口的特性与窗口类本身的属性有关。比如如果一个窗口类没有CS_DBLCLKS属性的话,那么要想通过子类化这些窗口达到处理WM_LBUTTONDBLCLK消息的目的是无法实现的。对于子类化的以上局限性,可以通过超类化
 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
MFC窗口销毁过程
走出MFC窗口子类化的迷宫
子类化和超类化区别(转自--眼见为实(2):介绍Windows的窗口、消息、子类化和超类化...
MFC编程中的窗口子类化浅析
(转)走出MFC子类化的迷宫:子类化,SUBCLASSWINDOW ,MFC消息机制
MFC函数—— CWnd::PreCreateWindow
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服