Simple Custom Control Question
-
I am developing my first custom control, CNewEdit derived from CEdit, which will use a non-system font for display. I want to create the font and then call CWnd::SetFont() after the control's window has been created. I don't want to do this outside the CNewEdit class (by adding code to the dialog class that is containing my CNewEdit control). My instinct is to provide a handler in CNewEdit for WM_CREATE. However, although Class Wizard allows me to define this message handler, I can't get execution to breakpoint inside CNewEdit::OnCreate(). The rest of the class is working as I have customised the background and text colours and these are ok. I find it strange that if I add a handler for WM_DESTROY to CNewEdit I can breakpoint successfully in OnDestroy(). So why not OnCreate()? Mark Jones Software Engineer Hampshire UK
-
I am developing my first custom control, CNewEdit derived from CEdit, which will use a non-system font for display. I want to create the font and then call CWnd::SetFont() after the control's window has been created. I don't want to do this outside the CNewEdit class (by adding code to the dialog class that is containing my CNewEdit control). My instinct is to provide a handler in CNewEdit for WM_CREATE. However, although Class Wizard allows me to define this message handler, I can't get execution to breakpoint inside CNewEdit::OnCreate(). The rest of the class is working as I have customised the background and text colours and these are ok. I find it strange that if I add a handler for WM_DESTROY to CNewEdit I can breakpoint successfully in OnDestroy(). So why not OnCreate()? Mark Jones Software Engineer Hampshire UK
Is your function really CNewEdit::OnCreate()? If so it is probably not being called. The WM_CREATE message calls. CMyEdit::OnCreate(LPCREATESTRUCT lpCreateStruct); I usually override the create function as shown below and add the functionality that I need. But both of the below functions are executed when created by the parent. One other option is are you calling Create or letting teh creation in a dialog initialization call it? IF the last case it may be only calling the base class. Header File class CMyEdit : public CEdit { // Construction public: CMyEdit(); // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMyEdit) public: virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); //}}AFX_VIRTUAL // Implementation public: virtual ~CMyEdit(); // Generated message map functions protected: //{{AFX_MSG(CMyEdit) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; C++ file BEGIN_MESSAGE_MAP(CMyEdit, CEdit) //{{AFX_MSG_MAP(CMyEdit) ON_WM_CREATE() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMyEdit message handlers // Create Message Handler int CMyEdit::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CEdit::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here return 0; } // Virtual Function Override. BOOL CMyEdit::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { // TODO: Add your specialized code here and/or call the base class return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); } Michael A Barnhart mabtech@swbell.net
-
Is your function really CNewEdit::OnCreate()? If so it is probably not being called. The WM_CREATE message calls. CMyEdit::OnCreate(LPCREATESTRUCT lpCreateStruct); I usually override the create function as shown below and add the functionality that I need. But both of the below functions are executed when created by the parent. One other option is are you calling Create or letting teh creation in a dialog initialization call it? IF the last case it may be only calling the base class. Header File class CMyEdit : public CEdit { // Construction public: CMyEdit(); // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMyEdit) public: virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); //}}AFX_VIRTUAL // Implementation public: virtual ~CMyEdit(); // Generated message map functions protected: //{{AFX_MSG(CMyEdit) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; C++ file BEGIN_MESSAGE_MAP(CMyEdit, CEdit) //{{AFX_MSG_MAP(CMyEdit) ON_WM_CREATE() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMyEdit message handlers // Create Message Handler int CMyEdit::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CEdit::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here return 0; } // Virtual Function Override. BOOL CMyEdit::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { // TODO: Add your specialized code here and/or call the base class return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); } Michael A Barnhart mabtech@swbell.net
Thanks for your reply, Michael. In answer to your first question - I am using CNewEdit::OnCreate(LPCREATESTRUCT lpCreateStruct), I was trying to be brief in my post - my mistake. I have now overrided the: virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); function but I still cannot breakpoint in this fn or the WM_CREATE handler. I am using the CNewEdit object in a dialog, whose resource template I have designed in the resource editor. I dragged the standard CEdit control from the resource toolbar onto the dialog. I have looked in the .rc file and have found the resource is identified as a 'EDITTEXT' control - the same as for normal CEdit controls. I have added a CNewEdit member variable to the dialog class using class wizard. I am not calling the Create function in my code. I think the creation of the window for the CNewEdit control occurs somewhere in CDialog::OnInitDialog(). Is there another mechanism brought into play when controls are created inside dialog boxes? Mark Jones Software Engineer Hampshire UK
-
Thanks for your reply, Michael. In answer to your first question - I am using CNewEdit::OnCreate(LPCREATESTRUCT lpCreateStruct), I was trying to be brief in my post - my mistake. I have now overrided the: virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); function but I still cannot breakpoint in this fn or the WM_CREATE handler. I am using the CNewEdit object in a dialog, whose resource template I have designed in the resource editor. I dragged the standard CEdit control from the resource toolbar onto the dialog. I have looked in the .rc file and have found the resource is identified as a 'EDITTEXT' control - the same as for normal CEdit controls. I have added a CNewEdit member variable to the dialog class using class wizard. I am not calling the Create function in my code. I think the creation of the window for the CNewEdit control occurs somewhere in CDialog::OnInitDialog(). Is there another mechanism brought into play when controls are created inside dialog boxes? Mark Jones Software Engineer Hampshire UK
Creation of window (HWND) for your CNewEdit control occurs before CDialog::OnInitDialog. By the time CDialog::OnInitDialog is called, all child windows defined in the dialog template are already created. CDialog::OnInitDialog calls DoDataExchange, and DoDataExchange associates your CNewEdit instance with some HWND. There's no chance for OnCreate in this scenario - the window is already created. The function to override is CWnd::PreSubclassWindow. Tomasz Sowinski http://www.shooltz.com.pl
-
Creation of window (HWND) for your CNewEdit control occurs before CDialog::OnInitDialog. By the time CDialog::OnInitDialog is called, all child windows defined in the dialog template are already created. CDialog::OnInitDialog calls DoDataExchange, and DoDataExchange associates your CNewEdit instance with some HWND. There's no chance for OnCreate in this scenario - the window is already created. The function to override is CWnd::PreSubclassWindow. Tomasz Sowinski http://www.shooltz.com.pl
Thanks Tomasz, that's just what I was looking for. Mark Jones Software Engineer Hampshire UK