Solved

CComboBox Fails to Create

Posted on 2006-10-31
18
293 Views
Last Modified: 2013-11-20
I have a CComboBox, which is restricted to a ListBox via its property sheet.  It is part of a much larger and complex dialog, which is part of a much more complex multi-page tab control.  In other words, there is a lot going on.

The dialogs are created by stepping through a loop that creates and attached each dialog to the tab control.  After the creation step, I load a few CComboBoxes with static data such as states in the union, etc.

Everything works fine on the development machines, but fails when the program is loaded on a 98 Home Edition machine.  

The failure seems to be on a call to ResetAll() on one of the combo boxes.  I KNOW, a ResetAll isn't required if the combobox has just been created---somebody got too diligent.  However, it did raise an interesting question of how to avoid the problem.  On a lark, I placed something that resembled

while(!IsWindow(mydialog->mycombobox.m_hWnd));  //I'll clean this up later

Again this works perfectly, or at least reports no failures on any of the development machines.  However when moved to a non-development XP Hmoe Edition machine, it fails with an assertion, a file name and a line number.  When I examine the file in question it indicates that the problem is that m_hWnd is not a Window.

Does anyone have any idea why this is happening.  I'm still working on a work-around, but for the sake of my sanity, I'd like to know the answer.

Thanks in advance, Rick
0
Comment
Question by:rickatseasoft
  • 9
  • 5
  • 4
18 Comments
 
LVL 5

Expert Comment

by:Alkali_Guy
ID: 17843665
The probable cause is that the combo box doesn't exist yet when you call ResetAll.  Where do you call ResetAll?  Try moving the routine to somewhere after DoDataExchange or your loading code runs.  Alternately, you can work around it by making a boolean member of the dialog class, initialising it to false, and setting it to true when you load the controls, then swaddling all early initalisation code in an if statement testing this flag.
0
 

Author Comment

by:rickatseasoft
ID: 17843791
I am certain that the CComboBox doesn't exist when ResetAll is run.  I hope that you can answer a couple of questions so that I can better understand the issue.  Incidentally, I removed the ResetAll() as it was unnecessary, and now the failure occurs on AddString().

1.  Why on XP Home Edition and not on other machines?
2.  Is the loop while(!IsWindow(...)) preemptive?  In other words does that stop the creation of the Dialog and its controls while it is running.  If so, is there a way to make the loop non-preemptive?
3.  Do you think that the problem is realted to the OS, or to the fact that the machine is without the development system installed?

I know that definitive answers are hard in cases like this, but your best guess will be greatly appreciated.

Rick
0
 
LVL 5

Expert Comment

by:Alkali_Guy
ID: 17844011
Which version of the program are you running on the non-development machine?  Debug or release?

I am actually surprised it seems to work at all on the development machine.  The loop is synchronous; nothing else will happen as long as it runs (I think).  Can you just do?:

if (!IsWindow(mydialog->mycombobox.m_hWnd)) AfxMessageBox("Combo box does not exist.");
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 17844081
Are you setting anything going by posting messages ?
eg
PDlg1->PostMessage(_START_PROCESSING, x, y);

If you are it could well be a timing problem.  By chance on your development machine the message is late enough in the queue that the combo has been created but on the test machine it is appearing before the combo is created.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 17844089
Oh - any multi-threading going on? (similar thoughts about timing problem)
0
 

Author Comment

by:rickatseasoft
ID: 17844092
Keep in mind that on the development machine, the combobox has been created by this point evidenced by the fact that the code executes properly.  It is only when I get to the non-development machine that the ccombobox seems to have not been created, and therefore fails.  The loop is in response to that failure.

I am running the debug version.

Rick
0
 
LVL 5

Expert Comment

by:Alkali_Guy
ID: 17844162
We need to know from what message handler ResetAll/AddString is called, or if it's in the creation loop.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 17844191
DEBUG also on test machine?  (RELEASE will run a lot faster - see my earlier comments)
0
 

Author Comment

by:rickatseasoft
ID: 17844311
The pseudocode is something like

OnInitDialog()

if(!m_TabPage[0]){
   Call the Create Function for the appropriate dialog and set it to m_TabPage[0];
   Set the masks for some of the controls, etc.

   Call the Create Function for the appropriate dialog and set it to m_TabPage[1];
   Set the masks for some of the controls, etc.
   Set the text limit for some CEdits
   
   Call the Create Function for the appropriate dialog and set it to m_TabPage[2];
   Set the masks for some of the controls, etc.
   Set the text limit for some CEdits
   
   ...

   Call the Create Function for the appropriate dialog and set it to m_TabPage[8];
   Populate the CComboBox with some relatively static data
   Set the text limit for some CEdits
   Set the masks for some of the controls, etc.
}


Rick
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 5

Accepted Solution

by:
Alkali_Guy earned 250 total points
ID: 17844342
Better would be to populate the combo box in the OnInitDialog of the child tab dialog.
0
 

Author Comment

by:rickatseasoft
ID: 17844455
Let Me add to the above pseudocode.  After the last Create, I do a loop that moves and sizes the windows to fit on the CTabControl.

It goes like this

            for(ii=0;ii<TAB_PAGE_COUNT_11;ii++){
                  m_CtrlTab1.InsertItem(ii,Captions[ii]);
                  if(m_TabPages[ii])m_TabPages[ii]->MoveWindow(l_Rect,TRUE);
            }
Removing ALL of the code that initializes controls, sets textlength, sets mask, etc. then the code runs right to here, and on the last dialog, it fails because the CDialog isself is not a Window in Winocc.cpp.  The line is

void CWnd::MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint)
{
      ASSERT(::IsWindow(m_hWnd));


Rick
0
 

Author Comment

by:rickatseasoft
ID: 17844505
I guess that I can pass the appropriate size to the Create Method for each CDialog, and then within the dialog, set the size, etc. appropriately.

Would it be better to do this in OnInitDialog, or should I use PreSubclassWindow()?

Thanks, Rick
0
 

Author Comment

by:rickatseasoft
ID: 17847564
Placed all of the control initialization code in OnInitDialog of the child dialog.  Then when I go through the pass for ShowWindow() depending on which Tab is selected---initially the 1st is auto selected, and therefore on page[0] it will do a SW_SHOW and for all others it will do a SW_HIDE.  All of the rest work fine, but when it gets to the last page, it blows up again since it thinks that the dialog attached to page[7] has no m_hWnd.

Just for testing purposes, I took the code to a Windows 2000 machine without the DevSys.  It produces a different failure:

All of the dialogs are declared something like

CRun11Dates m_Run11Dates;

Then created during the OnInitDialog of the parent with something like m_CRun11Dates.Create(this, &m_CtrlTab) so that the dialog will know not only its parent dialog, but the tab to which it is attached.  The create code is

BOOL CRun11Dates::CreatePage(CWnd *pParent, CWnd *pTabParent)
{
      m_pTabCtrlParent=pTabParent;
      m_pParent=pParent;
      return CreateDlg(MAKEINTRESOURCE(IDD), pTabParent);
}

On the windows 2000 computer, this returns a false.  On the XP Home this returns a TRUE, but, of course, still fails.  I am uncertain how to proceed since I can't debug on a computer with no devsys.

Any ideas, suggestions, or solutions will be greatly appreciated.

One other thought: could this be some sort of buffer overflow, random pointer, etc. that just happens to aligh correctly/incorrectly when the dev sys is attached and when it is not?

I am thinking that we run on and test on at least two other machines without the devsys, but they are at the office, and I don't know which flavor of Windows.

Rick
0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 250 total points
ID: 17847996
On the XP Home / Win 2000 machine start up the task monitor and have a look at handles in use.  Does it increase wildly as you move from one tab to the next?
0
 

Author Comment

by:rickatseasoft
ID: 17848601
Andy:

Never get to that point as there is a failure before I can provide any user input at all.

Rick
0
 

Author Comment

by:rickatseasoft
ID: 17848724
Andy:

I did start the program with the task manager open, and watched the number of handles grow, and the number did not increase dramatically at all, about a hundred.

Rick
0
 

Author Comment

by:rickatseasoft
ID: 17848806
Andy and Alkali Guy:

Thanks for all of your help.

I started down a different path this morning; what is different about the dialog in question?  It stood out like a sore thumb---this dialog contains the only instance, at this time, of a FlexGrid control.  Sure enough, I removed the control, and all works as specified.

I'll go ahead and award the points, and open a new quesiton since the topic of this one is not actually germaine at all.

Thanks again, Rick  
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 17848836
Guess - Check if you have initialised OLE.  (CoInitialize or similar)
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
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.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

747 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

12 Experts available now in Live!

Get 1:1 Help Now