This one has me stumped. The following code if for a modal dialog box that is supposed to display the data from a tree so the user can edit it. The tree data is stored in a list. It works fine the first time the user clicks Edit, but any subsequent time the loop that runs through the linked list does not execute.
ItemDialog::OnInitDialog(),int
{
SNIPPET_ITEM *pItem;
SNIPPET_ITEM *pNode;
CStatic *pStatic;
CStatic *pHeading = GetControl(ID_LBL_HEADING);
CEdit *pTextEdit = GetControl(ID_TXT_TEXT);
CEdit *pPathEdit = GetControl(ID_TXT_PATH);
int i;
// THIS LOOP EXEXUTES EACH TIME
for(i = ID_LBL_TEXT; i <= ID_LBL_HEADING; i++)
{
msg("for = " + numToStr(i));
pStatic = GetControl(i);
pStatic->SetColor(RGB(151,0,0), RGB(175,175,175));
}
// THIS LOOP ONLY EXECUTES THE *FIRST* TIME
for(pNode = g_SnippetList.GetFirst(); pNode <> 0; pNode = g_SnippetList.GetNext(pNode))
{
pItem = g_SnippetList.GetData(pNode);
Msg("For Loop: " + pItem->sText);
if(pItem->sText == m_ItemText)
{
pTextEdit->SetText(pItem->sText);
pPathEdit->SetText(pItem->sPath);
}
}
pHeading->SetText(m_sHeading);
SetCaption(m_sCaption);
CenterWindow();
return true;
}
Put a #break in there and examine the variables in the debugger. Are you actually destroying the modal dialog when it is closed or just hiding it?
I use CloseDialog().
I'll have to try the debugger later. My cell phone died this AM (Paul, you may be right about all this technology :P ), and I need to get it replaced this PM.
Just athought - change pnode <> 0 to pnode <> NULL
NULL and 0 are the same thing, in fact NULL is a regular constant defined in acommon.inc.
It sounds to me like OnInitDialog isn't being called more than once. I'm not sure exactly how dialogs work, but it's possible that you may need another method that is called whenever you reopen the dialog.
OnInit is being called because one of the For-Loops does execute. (I used a MessageBox to test.)
I'm back now from my adventures in wireless-land and will try the debugger (which I've haven't used yet) this morning.
Actually I have had issues with null and 0.
Null would be '\0' and 0 would be '\060'.
I stuck the #break command right at the beginning of the loop that goes through the linked list. The first time it executes I get a debug window with all of the variables looking normal - all of the pointers have non-null values, for example. The second time through, the #break command is missed. For some reason, that section of code is not executed on subsequent passes.
NULL=0 ??? That goes against everything that i have been taught.. which is NULL means empty, a non value NOT 0. which is why there is NULL, FALSE and TRUE ???
please feel free to point out if i'm wrong.. and if so when where how why ??? in term that a beginner can understand
Thankyou
In all modern compilers NULL, TRUE and FALSE are just a constants.
#define NULL 0
#define TRUE 1
#define FALSE 0
Which works with whatever variable type you are trying to assign it to since the compiler just substitues constants. As in a NULL terminated string, or a NULL pointer, both of which refer to zero.
Simple enough?
We digress. Why is a segment of code, part of a larger segment, not executing the second time it is invoked?
Quote from: peaslee on March 08, 2007, 11:15:17 AM
I stuck the #break command right at the beginning of the loop that goes through the linked list. The first time it executes I get a debug window with all of the variables looking normal - all of the pointers have non-null values, for example. The second time through, the #break command is missed. For some reason, that section of code is not executed on subsequent passes.
The break command is never missed, it inserts an interrupt into the code. What it means is the code isn't being executed. Insert two #break statements now like so:
// THIS LOOP ONLY EXECUTES THE *FIRST* TIME
#break
for(pNode = g_SnippetList.GetFirst(); pNode <> 0; pNode = g_SnippetList.GetNext(pNode))
{
#break
And see if it is just the list that isn't iterating or if OnInitDialog isn't being called for subsequent DoModal's. In either case I would need to see more of your code in order to help.
Paul.
Tomorrow.
I always check my email before going to bed, but I am in no shape to do serious whatever. ;)
Quote from: Rock Ridge Farm (Larry) on March 08, 2007, 09:53:20 AM
Actually I have had issues with null and 0.
Null would be '\0' and 0 would be '\060'.
Nope. 0 is 0, '0' is '\060' which is two different things. We are talking numbers here, not ASCII representations of numbers. Lets not confuse the subject too much here guys. Peaslee's for loop is fine the way it is written and has nothing to do with the difference of an ASCII '0' and a decimal 0.
Paul.
On the second call to DoModal the loop does not iterate.
How much more of the good would you need to look at?
Another thing I have had problems with:
Change <> to != and see if affects stuff.
Had a program where this actually altered the generated code.
I noticed that after I open the edit dialog, another section of code doesn't execute. It's the section that notices the user cllicked on a different item in the tree control and takes action.
case TVN_SELCHANGED:
if(m_bDragging == false) // don't process selection changes if dragging
{
hItem = *(NMTREEVIEW)pnmhdr.itemnew.hitem;
pTreeView->GetItemText(hItem,sItemText,255);
// find item; load file, if any
for(pNode = g_SnippetList.GetFirst(); pNode <> 0; pNode = g_SnippetList.GetNext(pNode))
// THIS LOOP DOES NOT EXECUTE AFTER THE DIALOG IS OPENED
{
pItem = g_SnippetList.GetData(pNode);
if(pItem->sText == sItemText) // item found
{
if(pItem->sPath == "")
{
pRichEdit->LoadFromString("",0);
}
else
{
pRichEdit->LoadFile(pItem->sPath,0);
}
}
}
}
Very strange... ???
Quote from: peaslee on March 09, 2007, 08:59:16 AM
On the second call to DoModal the loop does not iterate.
How much more of the good would you need to look at?
Send me the whole thing. Bits and peices are not helping me much .
Quote from: Paul Turley on March 09, 2007, 01:41:01 PM
Quote from: peaslee on March 09, 2007, 08:59:16 AM
On the second call to DoModal the loop does not iterate.
How much more of the good would you need to look at?
Send me the whole thing. Bits and peices are not helping me much .
I did. But I know that your projects are backed up, so I rewrote the program with great ;) attention to detail. Same problem: things don't work after the first DoModal() call.
I think I found the solution. In my new code, if I include the Constructor/Destructor methods explicitly in the dialog class, the problem seems to go away. I'll keep testing, but does that make any sense?
OK. Finally had a chance to look at your code.
Remember that a couple of times here I mentioned that global classes were not yet supported in Aurora? This is causing all of your problems:
def g_SnippetList as CPointerList;
Rewriting your code to create the list dynamically and all will work fine. I have done that for you and will email you the changes shortly.
Alos OnClose is not used in a modal dialog, it was part of the problem indirectly as it was the first subroutine after the global declaration of a class, and the compiler not knowing that a global class is handled differently inserted code to destruct the CPointerList at the end of that method.
A few other changes as well. When calling the base class of a method be sure you are calling the first base class. In your WndProc override in the itemdialog you were calling CWindow!!WndProc instead of CDialog!!WndProc. In this case it didn't hurt anything but it can cause problems if you don't call the correct one in some cases.
Paul.
Thanks, Paul. I'll give it a test drive.
Quote from: Paul Turley on March 17, 2007, 08:02:01 PM
Also OnClose is not used in a modal dialog, it was part of the problem indirectly as it was the first subroutine after the global declaration of a class, and the compiler not knowing that a global class is handled differently inserted code to destruct the CPointerList at the end of that method.
Paul.
This part of the answer I don't understand. The dialog editor produces code that uses OnClose with a modal dialog.
You have said more than a couple of times [ ;) ] that global classes are not yet supported.
Thanks again for taking the time to look at the code.
For a modal dialog clicking on the close button calls EndDialog with a return value of ID_CANCEL. OnClose never gets called in the derived class. For a non-modal dialog OnClose is called since you have to handle how the dialog is ended, as many programs just hide the dialog when it is closed instead of destroying it.
The dialog editor just outputs generic code and doesn't know how you are going to be using that dialog, either modal or non.
Paul.