Invalid CWnd* pointer
-
Hey, I've a Application with a CFromView dervied class with a couple of CEdit controls. I store the Pointer (CWnd*) of the Control (retrieved with GetDlgItem(...)) in an Array on a second TopLevel Dialog. This dialog has a listbox where you can choose the edit controls. If the user select an item on the listbox, i want to set the focus to the control in my CFormview. CWnd *pEditControl = arrayEditControls[2]; But when I call pEditControl->SetFocus() I get an exception...Why?
-
Hey, I've a Application with a CFromView dervied class with a couple of CEdit controls. I store the Pointer (CWnd*) of the Control (retrieved with GetDlgItem(...)) in an Array on a second TopLevel Dialog. This dialog has a listbox where you can choose the edit controls. If the user select an item on the listbox, i want to set the focus to the control in my CFormview. CWnd *pEditControl = arrayEditControls[2]; But when I call pEditControl->SetFocus() I get an exception...Why?
AnTri wrote:
I store the Pointer (CWnd*) of the Control (retrieved with GetDlgItem(...)) in an Array...
GetDlgItem()
returns a temporary pointer that should not be stored. Store the window handle instead.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
-
AnTri wrote:
I store the Pointer (CWnd*) of the Control (retrieved with GetDlgItem(...)) in an Array...
GetDlgItem()
returns a temporary pointer that should not be stored. Store the window handle instead.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
Ok, but when nothing happens with my CFormView (Controls) why is my (stored) pointer invalid. I thought the CWnd* is valid as long as the window exits. Is the a better way to restore my CWnd* as the following:
CWnd test; test.Attach(m_hWnd); //Attach the stored handle ... //do something test.Detach()
-
Ok, but when nothing happens with my CFormView (Controls) why is my (stored) pointer invalid. I thought the CWnd* is valid as long as the window exits. Is the a better way to restore my CWnd* as the following:
CWnd test; test.Attach(m_hWnd); //Attach the stored handle ... //do something test.Detach()
AnTri wrote:
Is the a better way to restore my CWnd* as the following:
Yes, but if you are only talking about a few edit controls, why not just store the
CEdit
object itself?
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
-
AnTri wrote:
Is the a better way to restore my CWnd* as the following:
Yes, but if you are only talking about a few edit controls, why not just store the
CEdit
object itself?
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
Do you mean a pointer to CEdit - Object? (the CEdit Object itself is located in my CFormView class). I thought CEdit is dervied from CWnd and thats why I originally stored the CWnd* pointer... What do you think about my previous question?
Ok, but when nothing happens with my CFormView (Controls) why is my (stored) pointer invalid. I thought the CWnd* is valid as long as the window exits.
-
Do you mean a pointer to CEdit - Object? (the CEdit Object itself is located in my CFormView class). I thought CEdit is dervied from CWnd and thats why I originally stored the CWnd* pointer... What do you think about my previous question?
Ok, but when nothing happens with my CFormView (Controls) why is my (stored) pointer invalid. I thought the CWnd* is valid as long as the window exits.
The problem you are having is that GetDlgItem actually returns a CTempWnd* pointer. MFC keeps a map of all the windows that are created. It maps CWnd objects to HWND handles making it very fast for MFC to find a CWnd given an HWND. When you have a window that is not created via CWnd::Create (your dialog controls in this instance), those windows are not include in the map. If GetDlgItem finds the window you want in the map it will return that CWnd* pointer, if not it will create a CTempWnd* pointer that you can use as a CWnd, but it is not added to the map. When that CTempWnd* pointer goes out of scope the CWnd object (as opposed to the HWND handle it wraps and the window it points to) is destroyed. If you save that pointer for later use it will just point to garbage. That is why the docs for GetDlgItem state:
The returned pointer may be temporary and should not be stored for later use.
-
The problem you are having is that GetDlgItem actually returns a CTempWnd* pointer. MFC keeps a map of all the windows that are created. It maps CWnd objects to HWND handles making it very fast for MFC to find a CWnd given an HWND. When you have a window that is not created via CWnd::Create (your dialog controls in this instance), those windows are not include in the map. If GetDlgItem finds the window you want in the map it will return that CWnd* pointer, if not it will create a CTempWnd* pointer that you can use as a CWnd, but it is not added to the map. When that CTempWnd* pointer goes out of scope the CWnd object (as opposed to the HWND handle it wraps and the window it points to) is destroyed. If you save that pointer for later use it will just point to garbage. That is why the docs for GetDlgItem state:
The returned pointer may be temporary and should not be stored for later use.
PJ Arends wrote:
When you have a window that is not created via CWnd::Create (your dialog controls in this instance), those windows are not include in the map.
Just an FYI, that is not entirely true... I am fairly certain that if you use
CWnd::SubclassWindow(...)
orCWnd::Attach(...)
to associate aCWnd
-based object with anHWND
and then callCWnd::GetDlgItem(...)
for that particularHWND
's control ID, you will get a pointer to that particularCWnd
object, and not a temporaryCTempWnd
pointer. Peace!-=- James
If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong!
Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road!
DeleteFXPFiles & CheckFavorites (Please rate this post!)