?
Solved

PreSubclassWindow

Posted on 1997-12-04
7
Medium Priority
?
1,155 Views
Last Modified: 2013-11-20
Realize that we override this function to do the initialization regardless
the window is Created or Subclassed after creation.

However, I found that the following code works only when dealing with
dialog controls (DDX_...).

void CMyCombo::PreSubclassWindow()
  {
    // TODO: Add your specialized code here and/or call the base class
      
    CComboBox::PreSubclassWindow();

    AddString("Default Entry");
  }

It will crash at "AddString"

pCombo = new CMyCombo;
pCombo->Create(....);

Seems like I cannot do a SendMessage to the window inside the
PreSubclassWindow function.

Any Idea ?

0
Comment
Question by:tser
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
7 Comments
 

Expert Comment

by:hariki
ID: 1311652
hi,

maybe only the c++ object is created and the windows window is not created when the call to addstring is called.


0
 
LVL 2

Expert Comment

by:anichini
ID: 1311653
can you post these two things:

code for CMyCombo::CMyCombo()
code for CMyCombo::Create() // if it exists
code for CMyCombo::OnCreate() // if it exists

tracing through the MFC source, I don't see how/where PreSubclassWindow is getting called at all (since this isn't in a dialog box).


0
 
LVL 1

Author Comment

by:tser
ID: 1311654
Regarding hariki,
The window should be created already. The m_hWnd of the base class is valid. Also, if the window is not created, it should have failed the MFC assertion in AddString instead of crash.
I suspect something to do with the WndProc of the window being not ready.

Regarding anichini,
The constructor is empty, no Create() and no OnCreate. PreSubclassWindow is not called directly by Create or OnCreate. Its called by one of the Afx hooks .
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 2

Accepted Solution

by:
anichini earned 600 total points
ID: 1311655
This is my theory:
If you look at the WH_CBT windows hook that MFC uses to hook window creation, you see that it is called before WM_CREATE or WM_NCCREATE. I assume that the default windows combo box class handles WM_CREATE to set up its internal data structures. Herein lies the problem, though, because when you call AddString it sends a message before the combo box has initialized.

The code is no problem in a dialog tho, because by the time subclassing occurs the combo box has already been created (and WM_CREATE has been sent).

Here is my proposed solution:

1) add a BOOL member variable to CMyCombo called m_fInDialog
2) in the constructor, initialize m_fInDialog to TRUE
3) override Create, and set m_fInDialog to FALSE before defering to the base class's create.
4) in PreSubclassWindow, do something like this:
void CMyCombo::PreSubclassWindow()
{
    CComboBox::PreSubclassWindow();

    if(m_fInDialog)
    {
        Initialize();
    }
}

5) handle the WM_CREATE message. In the handler, do this:

void CMyCombo::OnCreate(LPCREATESTRUCT pcs)
{
   CComboBox::OnCreate(pcs); // or whatever the base class is
   if(!m_fInDialog)
   {
       Initialize();
   }
}

6) write a Initialize() routine like this:

void CMyCombo::Initialize()
{
    AddString("Default Entry");
}

This should handle both cases adequately.
 
0
 
LVL 1

Author Comment

by:tser
ID: 1311656
Thanks for your answer. Quite detail.
Couple comments here:

1. Where (filename & line #) can I see WH_CBT called before WM_CREATE ?

2. Doubtful on the fact that WH_CBT called before the window is actually ready. It makes the hook useless.

3. The solution is complete but it defeats the idea of using PreSubclassWindow to handle both cases. Well, if your explanation is correct, there aren't too many choices. But it also mean that PreSubclassWindow is pretty useless.
0
 
LVL 2

Expert Comment

by:anichini
ID: 1311657
1) WINCORE.CPP:583, AfxHookWindowCreate (in VC++ 5.0, other versions might be a different line number) - this sets up the hook.
   AfxHookWindowCreate is called from CWnd::CreateEx(WINCORE.CPP:662), which is eventually called from all Create() statements.

The hook itself is at WINCORE.CPP:474. You can see that the only code it handles for WH_CBT is HCBT_CREATEWND.

2) From the windows SDK: (documentation of CBTProc, the procedure that handles WH_CBT)

"HCBT_CREATEWND: A window is about to be created. The system calls the hook procedure before sending the WM_CREATE or WM_NCCREATE message to the window. If the hook procedure returns a nonzero value, the system destroys the window; the CreateWindow function returns NULL, but the WM_DESTROY message is not sent to the window. If the hook procedure returns zero, the window is created normally.
 At the time of the HCBT_CREATEWND notification, the window has been created, but its final size and position may not have been determined and its parent window may not have been established. It is possible to send messages to the newly created window, although it has not yet received WM_NCCREATE or WM_CREATE messages..."

3) Well, pretty much yeah. Blame the designers of MFC.


0
 
LVL 2

Expert Comment

by:anichini
ID: 1311658
You know, I just had another thought:

If you really are intent on having everything be in PreSubclassWindow, you could use CWnd::PostMessage to send the CB_ADDSTRING to the combo box. This would cause the list box to recieve the message after it receives WM_CREATE. But this is a pain because you'd have to be sure that the pointer to the string is valid until the message is received. Sending a string constant should work fine (since it's in the program's code and won't go anywhere), but I think my original solution is still the best.

0

Featured Post

Learn how to optimize MySQL for your business need

With the increasing importance of apps & networks in both business & personal interconnections, perfor. has become one of the key metrics of successful communication. This ebook is a hands-on business-case-driven guide to understanding MySQL query parameter tuning & database perf

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question