MFC:OnNcCreate()不被调用;需要为CButton子类设置BS_OWNERDRAW标志

时间:2019-05-19 07:27:59

标签: mfc ownerdrawn cbutton

我不是MFC方面的专家,但是在过去的15多年中,我制作了大约十二种自定义控件。我刚刚使用自定义图形制作了CButton

这是问题所在:当然,我需要设置BS_OWNERDRAW。我有一种OnNcCreate()方法已经粘贴并粘贴了15年以上,该方法在我的自定义控件中一直有效,但是由于某种原因,现在不被调用。

除了{@ {1}}是我第一次尝试编写自定义控件的地方,我最终对OnNcCreate()的设置没有兴趣,甚至没有了解。

问题:什么会阻止BS_OWNERDRAW被调用?或者,还有其他我可以或应该设置OnNcCreate()的地方吗?

工作类定义为:

BS_OWNERDRAW

无效的定义为:

class CGood : public CStatic {

他们俩都以此为方法的原型:

class CBad : public CButton {

方法的编写方式相同(类名除外):

afx_msg int     OnNcCreate( LPCREATESTRUCT lpCreateStruct );

对话框使用Visual Studio 2017对话框编辑器作为CustomControl同时使用好类和坏类。好的和坏的类都具有扩展样式0x0和样式0x50010000。视需要而定,Disabled = False,Help ID = False,Visible = True,Class = Good或Bad。

运行时,应用程序将调用每个类的int CGood::OnNcCreate( LPCREATESTRUCT pcrs ) { wStyleBits = LOWORD( pcrs->style ); DWORD dwStyleSuperclass = MAKELONG( ES_LEFT, HIWORD( pcrs->style ) ); dwStyleSuperclass |= BS_OWNERDRAW; ::SetWindowLong( m_hWnd, GWL_STYLE, dwStyleSuperclass ); pcrs->style = dwStyleSuperclass; return CStatic::OnNcCreate( pcrs ); } 方法:

RegisterControlClass()

(有趣:我在static WNDPROC pfnWndProc = NULL; BOOL CBad::RegisterControlClass() { WNDCLASS wcls; static const TCHAR szClass[] = _T( "CBad" ); if ( ::GetClassInfo( AfxGetInstanceHandle(), szClass, &wcls ) ) return wcls.lpfnWndProc == ( WNDPROC ) CBad::WndProcHook; VERIFY( ::GetClassInfo( NULL, _T( "button" ), &wcls ) ); pfnWndProc = wcls.lpfnWndProc; wcls.lpfnWndProc = CBad::WndProcHook; wcls.hInstance = AfxGetInstanceHandle(); wcls.lpszClassName = szClass; return RegisterClass( &wcls ) != 0; } LRESULT CALLBACK EXPORT CBad::WndProcHook( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { CBad* pthis = new CBad(); pthis->Attach( hWnd ); pthis->m_pfnSuper = pfnWndProc; ::SetWindowLong( hWnd, GWL_WNDPROC, ( DWORD )AfxWndProc ); #ifdef STRICT return ::CallWindowProc( AfxWndProc, hWnd, msg, wParam, lParam ); #else return ::CallWindowProc( ( FARPROC )AfxWndProc, hWnd, msg, wParam, lParam ); #endif } 中注意到,它源自CGood,错误地在其中具有“按钮”并且可以正常工作;如果我更改为“静态”,它将停止工作。我将对此进行研究稍后。错误的类具有“按钮”,的确是CStatic子类。)

我为确认该问题所做的事情:当我从CButton中删除BS_OWNERDRAW时,它会停止调用CGood::OnNcCreate()。因此,我确定这是设置此标志的地方。

根本不会调用在DrawItem()CGood::OnNcCreate()中插入一个CBad断点。

我在互联网上找到了在CBad::OnNcCreate(),BS_OWNERDRAWPreSubclassWindow()中设置OnCreate()的示例,但由于某些原因,我认为这些都不起作用我明白。 (例如,您不能只在OnCreate()中设置标志并调用超类方法,因为它最终不是从您提供的参数中而是从其他来源获得标志。)

我尝试将CBad的超类更改为CStatic,但仍未调用OnNcCreate()。

我尝试在对话框的CreateEx()中设置BS_OWNERDRAW,并且确实可以正确绘制CBad按钮子类。所以我知道我不是偶然地用其他子类等创建它们的。

OnInitDialog()

1 个答案:

答案 0 :(得分:0)

啊!我只是忘了将其添加到消息映射中!

BEGIN_MESSAGE_MAP( CBad, CButton )
    //{{AFX_MSG_MAP( CBad )
    ON_WM_NCCREATE()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()