• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 220
  • Last Modified:

Really shameless pointer abuse

OK, this one's gonna be difficult to explain, but I'll do my best . . .

My company writes bank software.  The software has a marketing programs feature which will pop up a marketing program eligibility dialog to the teller when they pull up a customer's account.  The teller pitches the program to the customer, and has the option to click accept, decline, or follow-up.  If the teller clicks accept or follow-up, the program creates a sales lead in the system.  Later on, when a branch manager is reviewing the sales leads, he/she can add notes to each one if they wish.

Right now I am working to extend this feature so that the teller can also enter notes while the lead is being generated.  It has to be on the marketing popup, because tellers do not have access to the sales leads screen, and once the teller hits accept or follow-up, the box goes away.

The goal here is to simply recycle the the notes dialog from the sales lead screen.  But since I can't add a note to a sales lead that doesn't exist yet, I have to call the notes dialog, "steal" the info out of it so it can be bent to my own evil desires, and then kill it before the code to add the note to the database gets executed (which is easily accomplished by having the notes dialog end if the sales lead ID is -1).  When the teller hits accept, then the marketing popup is supposed to create the new sales lead, get the ID, and then attach the note to it all in one shot.

So here's what I've attempted to do:
I added an "Add Note..." button and gave the marketing popup a CEdit *noteTextBox member.  Then, I call the notes dialog and pass it the address of the noteTextBox member (&noteTextBox) to its Init() function (which I extended to accept a pointer to a CEdit box as one of its arguments).

Now, when the Init() function of the notes dialog runs, it takes the address of its own CEdit box (which is already defined), and assigns it to the reference it got from the marketing popup.  The function looks like this:

... in the marketing popup,
CEdit noteTextBox
NotesDialog notesDlg;

.. in the notes dialog,
NotesDialog::Init(CEdit *pNotesTextBox)
   pNotesTextBox = &m_notesEdit; //m_notesEdit is a private CEdit object

By my reasoning, the marketing popup's edit box should now be pointing to the same place as the notes dialog's edit box, right?  Furthermore, changes in the notes dialog's edit box should be automatically visible from the marketing popup, right??

Well, as soon as the marketing popup does a notesTextBox.GetWindowText(string), the program pukes with a debug assertion error.  I'm not sure why, but I have a few theories:

- The note dialog's m_notesEdit member is private and I am violating encapsulation (this means the compiler is smarter than I am, yet still not smart enough to warn me about it).
- The pointer is getting mangled somehow between the two objects (one's a CEdit, and the other's a CEdit*)
- At some point before I do the GetWindowText(), the notes dialog is being destroyed (along with all its members), making the pointer no longer valid.  Does EndDialog() call the destructor?
- My thinking is totally wrong.  It's completely insane to have two members from different objects pointing to the same place and I should try doing this some other way.
- A fifth option which I haven't considered

Anyone have any ideas as to what's going wrong here and how to fix it?  It would be very much appreciated.  If you can help me out with this, then me luv u long time!
  • 2
1 Solution
NotesDialog notesDlg;

I suspect the window object has not been created when you are calling GetWindowText
CEdit noteTextBox;
With that you get a MFC edit control object but not a window

>>>> NotesDialog notesDlg;
With that you get a MFC dialog object but not a window.

>>>> notesDlg.Init(&noteTextBox)
With that you passing the address of a - not created - edit control object to a function.

>>>> pNotesTextBox = &m_notesEdit;
That assigns a different address value to the local pointer. As the pointer wasn't returned the assignment ... makes nothing.

Regards, Alex
>>>> By my reasoning, the marketing popup's
>>>> edit box should now be pointing to the same
>>>> place as the notes dialog's edit box, right?
No, you passed a pointer (value) to a function but overwrites the value locally with a different pointer value.

If you want get the address of a edit control you need to pass the pointer by reference:

   void NotesDialog::Init(CEdit*& pNotesTextBox)  // see the &

That means the address assigned in NotesDialog::Init was passed back to the caller. if doing so

    CEdit noteTextBox;
    NotesDialog notesDlg;

the last statement wouldn't compile cause you can't pass the address of a locally defined object as a (writeable) reference to another function. And of course, you don't need the local 'noteTextBox' object. You want the address to the edit control defined in the NotesDialog, right? Then, you need:

    CEdit* pnoteTextBox = NULL;   // define a pointer not an object
    NotesDialog notesDlg;
    notesDlg.Init(pnoteTextBox);  // now you get the pointer filled
                                                    // with the address of the notesDlg.m_edit

But still we have

- a not-created NotesDialog
- therefore a pointer to an edit control which was not created either

So, you would need to 'create' the notesDlg. The easiest to do so, is


but unfortunately that means you are passing modal control to the notesDlg and your current dialog was blocked until the NotesDlg was finished (Cancel or OK). I don't think that is what you want. I neither think that you are supposed to create a 'new' NotesDialog but 'hook' into an existing NotesDialog which was invoked by another App. Am I right or is there any other scenario?

Regards, Alex

cuziyqAuthor Commented:
Thanx, Alex.  I appreciate your knowledgeable reply.  Unfortunately, after I went the rest of the afternoon with no response, I decided to change tactics a little.  I made the add notes button a check box instead.  That way, the marketing popup can just look at the checkbox after it has already added the sales lead to the database, allowing the notes dialog to process normally.  This approach has a couple of slight drawbacks (none of which I can really explain without writing another book on the subject), but they were deemed to not be a big deal by the powers that be.

I will give you the points anyway because your response was informative.  I would love to explore it further, because I still believe the concept is valid (just my implementation was off).  But to tell you the truth, the feature is finished now and I'm just not that motivated to mull it over anymore.  LOL.  The idea seems useful, however, and I will probably give it another attempt in the future when working on something else.  Maybe we can hash it over when that time comes.

Thanks again.

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now