Problem SetWindowText on edit box closes window

Zatnikitelman

Addon Developer
Addon Developer
Joined
Jan 13, 2008
Messages
2,302
Reaction score
6
Points
38
Location
Atlanta, GA, USA, North America
I hit a strange problem writing a scenario editor page. It seems that a call to SetDialogText for one specific Edit Control I have is causing the window to close, and I'm at a loss as to why. Here's a chunk of my message handler method:
Code:
case WM_NOTIFY:
		if (((NMHDR*)lParam)->code == UDN_DELTAPOS) 
		{
			NMUPDOWN *nmud = (NMUPDOWN*)lParam;
			int val = 1;
			double posval = 0.0;
			int id = ((NMHDR*)lParam)->idFrom;
			char cbuf[256];

			if(id == IDC_SPIN1)
			{
				GetWindowText (GetDlgItem (hTab, IDC_EDIT1), cbuf, 256);
				sscanf (cbuf, "%d", &val);
				val -= nmud->iDelta * 1;
				if(val < 1)
					val = 1;
				sprintf (cbuf, "%d", val);
				SetWindowText (GetDlgItem (hTab, IDC_EDIT1), cbuf);

				OBJHANDLE hVessel;
				SendMessage (hTab, WM_SCNEDITOR, SE_GETVESSEL, (LPARAM)&hVessel);
				PalletCarrier* ves = (PalletCarrier*)oapiGetVesselInterface(hVessel);
				if(ves->getNumSegments() != val)
				{
					bool bTemp = SendDlgItemMessage(hTab, IDC_CHECK1, BM_GETCHECK, 0, 0) == BST_CHECKED;
					ves->changeCarrier(val,bTemp);
				}
			}
			else if(id == IDC_SPIN2 || id == IDC_SPIN2A)
			{
				GetWindowText (GetDlgItem (hTab, IDC_EDIT2), cbuf, 256);
				sscanf (cbuf, "%lf", &posval);
				posval -= nmud->iDelta * (id == IDC_SPIN2 ? 1 : 0.001);
				if(posval > 1000000)
					posval = 1000000;
				else if(posval < -1000000)
					posval = -1000000;
				sprintf (cbuf, "%.3lf", posval);
				[COLOR="Red"]SetWindowText(GetDlgItem(hTab, IDC_EDIT2), cbuf);[/COLOR]
			}
			else if(id == IDC_SPIN3 || id == IDC_SPIN3A)
			{
				GetWindowText (GetDlgItem (hTab, IDC_EDIT3), cbuf, 256);
				sscanf (cbuf, "%lf", &posval);
				posval -= nmud->iDelta * (id == IDC_SPIN3 ? 1 : 0.001);
				if(posval > 1000000)
					posval = 1000000;
				else if(posval < -1000000)
					posval = -1000000;
				sprintf (cbuf, "%.3lf", posval);
				SetWindowText (GetDlgItem (hTab, IDC_EDIT3), cbuf);
			}
			else if(id == IDC_SPIN4 || id == IDC_SPIN4A)
			{
				GetWindowText (GetDlgItem (hTab, IDC_EDIT4), cbuf, 256);
				sscanf (cbuf, "%lf", &posval);
				posval -= nmud->iDelta * (id == IDC_SPIN4 ? 1 : 0.001);
				if(posval > 1000000)
					posval = 1000000;
				else if(posval < -1000000)
					posval = -1000000;
				sprintf (cbuf, "%.3lf", posval);
				SetWindowText (GetDlgItem (hTab, IDC_EDIT4), cbuf);
			}
			VECTOR3 temp = _V(0,0,0);
			GetWindowText (GetDlgItem (hTab, IDC_EDIT2), cbuf, 256);
			sscanf (cbuf, "%lf", &temp.x);

			GetWindowText (GetDlgItem (hTab, IDC_EDIT3), cbuf, 256);
			sscanf (cbuf, "%lf", &temp.y);

			GetWindowText (GetDlgItem (hTab, IDC_EDIT4), cbuf, 256);
			sscanf (cbuf, "%lf", &temp.z);

			OBJHANDLE hVessel;
			SendMessage (hTab, WM_SCNEDITOR, SE_GETVESSEL, (LPARAM)&hVessel);
			VESSEL3* ves = (VESSEL3*)oapiGetVesselInterface(hVessel);
			((PalletCarrier*)ves)->setOfs(temp);

			return TRUE;
		}

The section I've highlighted in red is the problem section. What's really weird, is the other two calls to that method for other edit boxes don't exhibit this behavior. I traced it down to this line by commenting everything else out and adding lines back in. I've double checked the properties on the dialog and on this control and the other controls all match this control

Has anyone else seen this behavior and solved it? I'm at a loss.

Thanks,

Matt

---------- Post added at 20:27 ---------- Previous post was at 19:51 ----------

Also, while I'm on the topic of Scenario Editor dialogs, how do the IDC_BACK buttons get handled? The Deltaglider example includes no explicit handling of those buttons, yet they work.
 
Last edited:

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Run it under the debugger and see what exact value you're sending?
 

dbeachy1

O-F Administrator
Administrator
Orbiter Contributor
Addon Developer
Donator
Beta Tester
Joined
Jan 14, 2008
Messages
9,218
Reaction score
1,566
Points
203
Location
VA
Website
alteaaerospace.com
Preferred Pronouns
he/him
I've seen Windows silently close dialog boxes and continue running the program if an exception occurs anywhere in the dialog handler's processing (e.g., when the stack gets corrupted, trashing the return address of the caller on the stack), and so the problem is likely elsewhere in the dialog handler's code. What I would do to track it down is comment out almost all the code in the dialog handler until the crash does NOT occur (i.e., simplify it until it works!), and then start adding code back in until it closes (crashes) again. It could well be that some other part of the code is overwriting memory used by something in the dialog handler.

For example, since the 'SetWindowText(GetDlgItem(hTab, IDC_EDIT2), cbuf);' appears to cause the issue (either directly or indirectly), as a test, I would simplify that further by replacing "cbuf" with a hard-coded, static string, like "FOOBAR!". That would rule out the cbuf buffer being corrupted as causing the issue. I would also verify that 'GetDlgItem(hTab, IDC_EDIT2)' always returns a valid handle -- you could try switching that to a different IDC_* value, for example, as a test. I would also, as a test, comment out various code blocks *below* that line (while leaving that line in) to narrow it down further.

Also, I would step through the rest of your dialog code using the debugger all the way to the end of the handler to verify that the text is being set successfully and that everything below that looks correct.

As very first thing, I would make sure that:

1. You are running a DEBUG build and not a RELEASE build, and
2. You have enabled the MSVCRT runtime heap checks for debug builds by having this in your DLLCLBK VESSEL *ovcInit (OBJHANDLE vessel, int flightmodel) method:

Code:
#ifdef _DEBUG
    // NOTE: _CRTDBG_CHECK_ALWAYS_DF is too slow
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF |
                   _CRTDBG_CHECK_CRT_DF | 
                   _CRTDBG_LEAK_CHECK_DF); 
#endif

Beyond that, if you are really stuck on finding a memory overrun bug and the above options don't detect it, you can OR in _CRTDBG_CHECK_ALWAYS_DF as well -- but be advised that that will significantly slow down your code to the point that the framerate drop is quite noticeable (at least, it does on the XRs).
 

dbeachy1

O-F Administrator
Administrator
Orbiter Contributor
Addon Developer
Donator
Beta Tester
Joined
Jan 14, 2008
Messages
9,218
Reaction score
1,566
Points
203
Location
VA
Website
alteaaerospace.com
Preferred Pronouns
he/him
In that case, I would comment out code *after* the apparent problem line (i.e., the code at the end of the method) until the problem does not occur. Then add it back in until it does occur.
 

dbeachy1

O-F Administrator
Administrator
Orbiter Contributor
Addon Developer
Donator
Beta Tester
Joined
Jan 14, 2008
Messages
9,218
Reaction score
1,566
Points
203
Location
VA
Website
alteaaerospace.com
Preferred Pronouns
he/him
Even if that is the only line in the dialog handler??
 

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
What numeric value does IDC_EDIT2 constant have? Does assigning a different value and recompiling resources have any effect?

Is there any error returned by GetLastError right after calling that SetWindowText?

Is it exactly the same when using SendMessage/WM_SETTEXT or SetDlgItemText functions?
 

martins

Orbiter Founder
Orbiter Founder
Joined
Mar 31, 2008
Messages
2,448
Reaction score
462
Points
83
Website
orbit.medphys.ucl.ac.uk
Also, while I'm on the topic of Scenario Editor dialogs, how do the IDC_BACK buttons get handled? The Deltaglider example includes no explicit handling of those buttons, yet they work.

Custom pages are handled by the EditorTab_Custom class of the scenario editor code (for implementation see Orbitersdk/samples/ScnEditor/Editor.cpp). The default message handler of this class filters out and processes the IDC_BACK message (among other things) before calling the plugin's message handler. So no need for plugins to process the "Back" button.
 

Zatnikitelman

Addon Developer
Addon Developer
Joined
Jan 13, 2008
Messages
2,302
Reaction score
6
Points
38
Location
Atlanta, GA, USA, North America
Even if that is the only line in the dialog handler??
Yes, I boiled it down to just that line, and the page won't even open as expected. It flashes briefly, but since the first message is WM_INITDIALOG, it promptly closes since it's executing the method causing this issue without any guard conditions. Boiling it down (back up? :p) to just a case statement to respond to the click of the spin control yields the closing behavior.
What numeric value does IDC_EDIT2 constant have? Does assigning a different value and recompiling resources have any effect?
1003 and no. I also tried replacing IDC_EDIT3 in this section. It updated this other edit box exactly as it's "supposed" to.
Is there any error returned by GetLastError right after calling that SetWindowText?
No, returns 0.
Is it exactly the same when using SendMessage/WM_SETTEXT or SetDlgItemText functions?
Yes.
Custom pages are handled by the EditorTab_Custom class of the scenario editor code (for implementation see Orbitersdk/samples/Editor.cpp). The default message handler of this class filters out and processes the IDC_BACK message (among other things) before calling the plugin's message handler. So no need for plugins to process the "Back" button.
It doesn't seem to be working, I double checked all of my return statements in case I wasn't return a FALSE when my method had nothing to do, and made sure I was returning a TRUE when I do do things, but this isn't working either.
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Can you post the definition of the dialog box? Specifically looking for anything that makes IDC_EDIT2 different from the others...
 

Zatnikitelman

Addon Developer
Addon Developer
Joined
Jan 13, 2008
Messages
2,302
Reaction score
6
Points
38
Location
Atlanta, GA, USA, North America
Here's the definition for that editor page:
Code:
IDD_DIALOG1 DIALOGEX 0, 0, 309, 177
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    EDITTEXT        IDC_EDIT1,7,7,40,14,ES_AUTOHSCROLL
    CONTROL         "STS",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,26,28,10
    [COLOR="Red"]EDITTEXT        IDC_EDIT2,7,45,58,14,ES_AUTOHSCROLL[/COLOR]
    EDITTEXT        IDC_EDIT3,7,68,58,14,ES_AUTOHSCROLL
    EDITTEXT        IDC_EDIT4,7,91,57,14,ES_AUTOHSCROLL
    CONTROL         "",IDC_SPIN1,"msctls_updown32",UDS_ARROWKEYS,48,7,10,14
    CONTROL         "",IDC_SPIN2,"msctls_updown32",UDS_ARROWKEYS,66,45,12,14
    CONTROL         "",IDC_SPIN2A,"msctls_updown32",UDS_ARROWKEYS,78,45,11,14
    CONTROL         "",IDC_SPIN3,"msctls_updown32",UDS_ARROWKEYS,66,69,11,14
    CONTROL         "",IDC_SPIN3A,"msctls_updown32",UDS_ARROWKEYS,78,69,11,14
    CONTROL         "",IDC_SPIN4,"msctls_updown32",UDS_ARROWKEYS,66,91,11,14
    CONTROL         "",IDC_SPIN4A,"msctls_updown32",UDS_ARROWKEYS,78,91,11,14
    LTEXT           "Payload Attachment X-Offset",IDC_STATIC,92,48,95,8
    LTEXT           "Payload Attachment Y-Offset",IDC_STATIC,92,72,95,8
    LTEXT           "Payload Attachment Z-Offset",IDC_STATIC,92,94,95,8
    LTEXT           "Number of carrier segments",IDC_STATIC,61,10,90,8
    PUSHBUTTON      "<< Done",IDC_BACK,7,156,50,14
END

If it helps, here's the entire .rc file:
Code:
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (United States) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#include ""winres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_DIALOG1 DIALOGEX 0, 0, 309, 177
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    EDITTEXT        IDC_EDIT1,7,7,40,14,ES_AUTOHSCROLL
    CONTROL         "STS",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,26,28,10
    EDITTEXT        IDC_EDIT2,7,45,58,14,ES_AUTOHSCROLL
    EDITTEXT        IDC_EDIT3,7,68,58,14,ES_AUTOHSCROLL
    EDITTEXT        IDC_EDIT4,7,91,57,14,ES_AUTOHSCROLL
    CONTROL         "",IDC_SPIN1,"msctls_updown32",UDS_ARROWKEYS,48,7,10,14
    CONTROL         "",IDC_SPIN2,"msctls_updown32",UDS_ARROWKEYS,66,45,12,14
    CONTROL         "",IDC_SPIN2A,"msctls_updown32",UDS_ARROWKEYS,78,45,11,14
    CONTROL         "",IDC_SPIN3,"msctls_updown32",UDS_ARROWKEYS,66,69,11,14
    CONTROL         "",IDC_SPIN3A,"msctls_updown32",UDS_ARROWKEYS,78,69,11,14
    CONTROL         "",IDC_SPIN4,"msctls_updown32",UDS_ARROWKEYS,66,91,11,14
    CONTROL         "",IDC_SPIN4A,"msctls_updown32",UDS_ARROWKEYS,78,91,11,14
    LTEXT           "Payload Attachment X-Offset",IDC_STATIC,92,48,95,8
    LTEXT           "Payload Attachment Y-Offset",IDC_STATIC,92,72,95,8
    LTEXT           "Payload Attachment Z-Offset",IDC_STATIC,92,94,95,8
    LTEXT           "Number of carrier segments",IDC_STATIC,61,10,90,8
    PUSHBUTTON      "<< Done",IDC_BACK,7,156,50,14
END

IDD_DIALOG2 DIALOGEX 0, 0, 309, 176
STYLE DS_SETFONT | WS_CHILD
FONT 8, "MS Sans Serif", 400, 0, 0x0
BEGIN
    LISTBOX         IDC_LIST1,7,7,185,79,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
    PUSHBUTTON      "Attach",IDC_BUTTON1,198,72,50,14
    COMBOBOX        IDC_COMBO2,7,92,183,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    COMBOBOX        IDC_COMBO3,7,110,183,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    PUSHBUTTON      "<< Done",IDC_BACK,7,155,50,14
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
    IDD_DIALOG1, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 302
        TOPMARGIN, 7
        BOTTOMMARGIN, 170
    END

    IDD_DIALOG2, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 302
        TOPMARGIN, 7
        BOTTOMMARGIN, 169
    END
END
#endif    // APSTUDIO_INVOKED

#endif    // English (United States) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED
 

Zatnikitelman

Addon Developer
Addon Developer
Joined
Jan 13, 2008
Messages
2,302
Reaction score
6
Points
38
Location
Atlanta, GA, USA, North America
I'll tentatively say that that may be it, for both problems, orb. I manually edited the resource.h to swap the values of IDC_EDIT2 and IDC_BACK and now both issues seem to be working. I've only poked at it a few minutes so I'm not ready to confirm it, but so far so good. Thanks everyone for the help and sticking with me through this!
 

martins

Orbiter Founder
Orbiter Founder
Joined
Mar 31, 2008
Messages
2,448
Reaction score
462
Points
83
Website
orbit.medphys.ucl.ac.uk
I manually edited the resource.h to swap the values of IDC_EDIT2 and IDC_BACK and now both issues seem to be working.

Why does your resource.h even contain IDC_BACK? Are you re-using the resource.h from the ScnEditor project? That isn't a good idea, in particular if you are modifying constants that are used by the main ScnEditor module, like IDC_BACK. At the least it will be very confusing to have constants with the same names but different values in both projects. It could get worse if you recompile the ScnEditor project with modified constants, since you might end up with code that runs for you, but breaks everybody else's ScnEditor.dll.

A better approach is to write your own resource.h (or let the resource editor write it) containing only the constants used by your own editor pages. Just make sure that the values don't overlap with the default scenario editor resource IDs (for example, start from 5000).

Also, instead of generic names like IDC_EDIT2 etc. it might be a better convention to use unique names like IDC_MYPROJECT_EDIT_VESSELNAME or the like, and use that ID and value only for a single control, rather than across multiple editor pages. That should also reduce the chance of conflicts.

Edit: Scrap that, my mistake. I just realised that the back button IS part of the custom pages (and thus IDC_BACK is needed in the custom resource.h). It's just the message handler for that control that is performed in the core ScnEditor code.

However this makes it even more important NOT to change the value of IDC_BACK. Otherwise the signal generated by the back button on your custom page will no longer be recognised by ScnEditor.dll.
 

Zatnikitelman

Addon Developer
Addon Developer
Joined
Jan 13, 2008
Messages
2,302
Reaction score
6
Points
38
Location
Atlanta, GA, USA, North America
Now I'm a little confused, Martin. So I'm definitely not editing anything from ScnEditor itself. But I'm not really sure how to setup a button with its own value other than manually editing it once I've added it in the dialog designer. But now it sounds like IDC_BACK always needs to have an ID of 1003 in any custom page.

[EDIT] Yes, I know, my names are terrible. Most of this originates from years ago before I even knew what coding standards really were and why they're important. I'm learning that lesson the hard way now.
 
Last edited:
Top