Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Problem with Pointers

Problem with Pointers

Scheduled Pinned Locked Moved C / C++ / MFC
helpquestiondebugging
4 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    CoffeeAddict19
    wrote on last edited by
    #1

    This problem cropped up after I converted the dialog from modal to non-modal, so that might have something to do with it. The question: why should I have to call GetDlgItem to get a pointer to a dialog box control in every function instead of just once in OnInitDialog? I've got these pointers in my modeless dialog box header file:

    CListBox* ExpressionsListBoxPtr;
    CListBox* FiltersListBoxPtr;
    CListBox* TargetsListBoxPtr;
    

    All were initialized to null by the constructor. In OnInitDialog() I put this (I checked to make shure OnInitDialog got called, and that the pointers were not null afterwords):

    ExpressionsListBoxPtr = (CListBox*)(GetDlgItem(IDC_DLGS_EXPRESSIONLISTBOX));
    FiltersListBoxPtr = (CListBox*)(GetDlgItem(IDC_DLGS_FILTERLISTBOX));
    TargetsListBoxPtr = (CListBox*)(GetDlgItem(IDC_DLGS_TARGETLISTBOX));
    

    The issue is that when I execute this fuction I get a debug assertation error and I've determined that the class level pointers are the source of the problem. I have worked around it by calling GetDlgItem in the function itself instead of just in OnInitDialog:

    afx_msg void CRatiosNewSearchDialog::OnAddFilter()
    {
    	CListBox* TempListBoxPtr = (CListBox*)(GetDlgItem(IDC_DLGS_EXPRESSIONLISTBOX));
    	//int CurrentSelection = ExpressionsListBoxPtr->GetCurSel();
    	int CurrentSelection = TempListBoxPtr->GetCurSel();
    	
    	int Pos = 0;
    	CString Expression = "";
    
    	if(CurrentSelection == LB_ERR)
    		MessageBox("You must select an expression before you can add a filter. LB_ERR.", "User Error", MB_ICONHAND);
    	else //everything is cool, add the expression to the filter list box
    	{
    		ExpressionsListBoxPtr->GetText(CurrentSelection, Expression);
    		Pos = Expression.Find(" - ", 0);
    		Expression.Delete(0, Pos + 3);
    		Pos = FiltersListBoxPtr->AddString(Expression);
    		ResetListboxScrollbar(FiltersListBoxPtr);
    		FiltersListBoxPtr->SetCurSel(Pos);
    	}
    }
    

    Can anyone tell me why it is not letting me just call GetDlgItem once when the dialog pops up instead of making me call it every time I want to use a control?

    C 1 Reply Last reply
    0
    • C CoffeeAddict19

      This problem cropped up after I converted the dialog from modal to non-modal, so that might have something to do with it. The question: why should I have to call GetDlgItem to get a pointer to a dialog box control in every function instead of just once in OnInitDialog? I've got these pointers in my modeless dialog box header file:

      CListBox* ExpressionsListBoxPtr;
      CListBox* FiltersListBoxPtr;
      CListBox* TargetsListBoxPtr;
      

      All were initialized to null by the constructor. In OnInitDialog() I put this (I checked to make shure OnInitDialog got called, and that the pointers were not null afterwords):

      ExpressionsListBoxPtr = (CListBox*)(GetDlgItem(IDC_DLGS_EXPRESSIONLISTBOX));
      FiltersListBoxPtr = (CListBox*)(GetDlgItem(IDC_DLGS_FILTERLISTBOX));
      TargetsListBoxPtr = (CListBox*)(GetDlgItem(IDC_DLGS_TARGETLISTBOX));
      

      The issue is that when I execute this fuction I get a debug assertation error and I've determined that the class level pointers are the source of the problem. I have worked around it by calling GetDlgItem in the function itself instead of just in OnInitDialog:

      afx_msg void CRatiosNewSearchDialog::OnAddFilter()
      {
      	CListBox* TempListBoxPtr = (CListBox*)(GetDlgItem(IDC_DLGS_EXPRESSIONLISTBOX));
      	//int CurrentSelection = ExpressionsListBoxPtr->GetCurSel();
      	int CurrentSelection = TempListBoxPtr->GetCurSel();
      	
      	int Pos = 0;
      	CString Expression = "";
      
      	if(CurrentSelection == LB_ERR)
      		MessageBox("You must select an expression before you can add a filter. LB_ERR.", "User Error", MB_ICONHAND);
      	else //everything is cool, add the expression to the filter list box
      	{
      		ExpressionsListBoxPtr->GetText(CurrentSelection, Expression);
      		Pos = Expression.Find(" - ", 0);
      		Expression.Delete(0, Pos + 3);
      		Pos = FiltersListBoxPtr->AddString(Expression);
      		ResetListboxScrollbar(FiltersListBoxPtr);
      		FiltersListBoxPtr->SetCurSel(Pos);
      	}
      }
      

      Can anyone tell me why it is not letting me just call GetDlgItem once when the dialog pops up instead of making me call it every time I want to use a control?

      C Offline
      C Offline
      cp9876
      wrote on last edited by
      #2

      from MSDN CWnd::GetDlgItem Return Value A pointer to the given control or child window. If no control with the integer ID given by the nID parameter exists, the value is NULL. The returned pointer may be temporary and should not be stored for later use. Why don't you simply associate control variables with your controls - i.e. associate a CListBox with IDC_DLGS_EXPRESSIONLISTBOX etc. see: http://www.flounder.com/getdlgitem.htm[^]

      Peter "Until the invention of the computer, the machine gun was the device that enabled humans to make the most mistakes in the smallest amount of time."

      C 1 Reply Last reply
      0
      • C cp9876

        from MSDN CWnd::GetDlgItem Return Value A pointer to the given control or child window. If no control with the integer ID given by the nID parameter exists, the value is NULL. The returned pointer may be temporary and should not be stored for later use. Why don't you simply associate control variables with your controls - i.e. associate a CListBox with IDC_DLGS_EXPRESSIONLISTBOX etc. see: http://www.flounder.com/getdlgitem.htm[^]

        Peter "Until the invention of the computer, the machine gun was the device that enabled humans to make the most mistakes in the smallest amount of time."

        C Offline
        C Offline
        CoffeeAddict19
        wrote on last edited by
        #3

        Thanks for the help. I got it working now...I just have to get rid of all of those GetDlgItem calls now. Guess I'll be using find and replace a lot too. X|

        C 1 Reply Last reply
        0
        • C CoffeeAddict19

          Thanks for the help. I got it working now...I just have to get rid of all of those GetDlgItem calls now. Guess I'll be using find and replace a lot too. X|

          C Offline
          C Offline
          cp9876
          wrote on last edited by
          #4

          I should have explained the cause of the problem: Creating a listbox in the dialog creates a windows listbox (identified by a handle) but not any CWnd object. MFC overloads the GetDlgItem() to return a CWnd* so that you can use all the MFC CWnd:: functions, but as there is no CWnd object, it creates a temporary one which is cleaned up later in some idle processing time. I guess that your experience shows that this cleanup doesn't usually happen during DoModal(), but does if the dialog is run modeless. What you could get and save is the HWND of each of your controls, this would stay valid for the lifetime of the dialog window. This is what you are essentially doing when you add a CListBox data member to your class and associate it with the particular windows control in the DoDataExchange() function. The HWND of the control is set in the DDX_Control() function from the ID you provide. Adding these data members is automated (in VC6 use the class wizard, in VS2005 simply right click on the control in the dialog editor and select "Add Variable"). Then you have a CListBox that you can use in any member function once the dialog has been created.

          Peter "Until the invention of the computer, the machine gun was the device that enabled humans to make the most mistakes in the smallest amount of time."

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups