Solved

PreSubclassWindow

Posted on 1997-12-04
7
1,038 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
  • 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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 2

Accepted Solution

by:
anichini earned 200 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

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Adapt this command to show who installed 29 102
Complete beginner needs help making a cron job 9 104
java ^ examples 8 57
withoutTen challenge 14 88
Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
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.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

707 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now