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
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Invalid CWnd* pointer

Invalid CWnd* pointer

Scheduled Pinned Locked Moved C / C++ / MFC
data-structuresquestion
7 Posts 4 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.
  • A Offline
    A Offline
    AnTri
    wrote on last edited by
    #1

    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?

    D 1 Reply Last reply
    0
    • A AnTri

      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?

      D Offline
      D Offline
      David Crow
      wrote on last edited by
      #2

      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

      A 1 Reply Last reply
      0
      • D David Crow

        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

        A Offline
        A Offline
        AnTri
        wrote on last edited by
        #3

        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()

        D 1 Reply Last reply
        0
        • A AnTri

          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()

          D Offline
          D Offline
          David Crow
          wrote on last edited by
          #4

          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

          A 1 Reply Last reply
          0
          • D David Crow

            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

            A Offline
            A Offline
            AnTri
            wrote on last edited by
            #5

            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.

            PJ ArendsP 1 Reply Last reply
            0
            • A AnTri

              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.

              PJ ArendsP Offline
              PJ ArendsP Offline
              PJ Arends
              wrote on last edited by
              #6

              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.

              Within you lies the power for good; Use it!

              J 1 Reply Last reply
              0
              • PJ ArendsP PJ Arends

                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.

                J Offline
                J Offline
                James R Twine
                wrote on last edited by
                #7

                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(...) or CWnd::Attach(...) to associate a CWnd-based object with an HWND and then call CWnd::GetDlgItem(...) for that particular HWND's control ID, you will get a pointer to that particular CWnd object, and not a temporary CTempWnd 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!)

                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