Codejock Forums Homepage
Forum Home Forum Home > Codejock Products > Visual C++ MFC > Docking Pane
  New Posts New Posts RSS Feed - Attached pane window being deleted under me
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

Attached pane window being deleted under me

 Post Reply Post Reply
Author
Message
Aaron Koolen View Drop Down
Groupie
Groupie


Joined: 22 July 2009
Status: Offline
Points: 32
Post Options Post Options   Thanks (0) Thanks(0)   Quote Aaron Koolen Quote  Post ReplyReply Direct Link To This Post Topic: Attached pane window being deleted under me
    Posted: 08 March 2010 at 4:32pm
Hi all. Due to the lack of documentation I can't really find out if this is normal behaviour but I've had an issue appear where the CXTPDockingPaneMiniWnd is deleting the window I have attached to a pane from underneath me.

Here is my setup.

- I run my application and create 3 tabbed panes docked together.

- Undock them as a group by double clicking title bar.

- Pull one off from the other two so I now have two pane windows, one with two tabbed panes in it, and one with one in it.

- Double click the single pane title bar, it redocks.

- Double click the dual pane title bar, it redocks.

- Then I double click AGAIN, the title bar of the docked group and they undock back to a set of two and a single pane.

- Double click the single pane title bar to dock it back and BAM!

The application dies in my code because it tries to use was window it created that was deleted from underneath it by the last docking operation.

Stack trace inside CodeJock:


CXTPDockingPaneMiniWnd::OnChildContainerChanged(CXTPDockingPaneBase * 0x0677b858) line 260 + 23 bytes
CXTPDockingPaneSplitterContainer::OnChildContainerChanged(CXTPDockingPaneBase * 0x0677b858) line 478 + 23 bytes
CXTPDockingPaneTabbedContainer::RemovePane(CXTPDockingPaneBase * 0x0677ac00) line 399 + 48 bytes
CXTPDockingPaneManager::_RemovePane(CXTPDockingPaneBase * 0x0677ac00) line 479 + 23 bytes
CXTPDockingPaneManager::_AttachPane(CXTPDockingPaneBase * 0x0677ac00, CXTPDockingPaneBase * 0x0676fd48) line 506
CXTPDockingPaneManager::AttachPane(CXTPDockingPaneBase * 0x0677ac00, CXTPDockingPaneBase * 0x0676fd48) line 485
CXTPDockingPaneManager::_ToggleDocking(CXTPDockingPane * 0x0677abe0 {CXTPDockingPane}, CXTPDockingPaneBase * 0x0676fd48) line 770
CXTPDockingPaneManager::ToggleDocking(CXTPDockingPaneBase * 0x067790f8) line 719 + 60 bytes
CXTPDockingPaneMiniWnd::OnNcLButtonDblClk(unsigned int 2, CPoint {x=957 y=142}) line 585

The offending method is:

void CXTPDockingPaneMiniWnd::OnChildContainerChanged(CXTPDockingPaneBase* /*pContainer*/)
{
     if (!m_hWnd)
          return;

     if (m_pTopContainer == NULL || m_pTopContainer->IsEmpty())
     {
          DestroyWindow();
     }
     else
     {
          m_bDelayInvalidate = TRUE;
          PostMessage(WM_IDLEUPDATECMDUI);
     }
}


DestroyWindow() is called which ends up destroying the window inside that pane.

Is this normal behaviour? If it is, it means I need to track when my windows are deleted and any code the references those or tracks those needs to be notified.

Can someone explain this to me please.

Thanks
Aaron

NOTE: This has happened with 13.2 and 13.3.
Product: Xtreme ToolkitPro v13.3.0 (MFC)
Platform: Windows XP (32bit) - SP 3
Language: Visual C++ 6
Back to Top
mgampi View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14 July 2003
Status: Offline
Points: 1155
Post Options Post Options   Thanks (0) Thanks(0)   Quote mgampi Quote  Post ReplyReply Direct Link To This Post Posted: 08 March 2010 at 4:57pm
Hi;
Could you show me your OnDockingPaneNotify message handler?
Martin

Product: Xtreme Toolkit v 19.0.0, new Projects v 19.1.0
Platform: Windows 10 v 1909 (64bit)
Language: VC++ 2017
Back to Top
Aaron Koolen View Drop Down
Groupie
Groupie


Joined: 22 July 2009
Status: Offline
Points: 32
Post Options Post Options   Thanks (0) Thanks(0)   Quote Aaron Koolen Quote  Post ReplyReply Direct Link To This Post Posted: 08 March 2010 at 5:24pm
Hi there. I can't give you the whole handler but here's a trimmed down version with some stuff obviously replaced but with all the code handling code there. Let me know if you need more.


     if (wParam == XTP_DPN_ACTION)
     {
          XTP_DOCKINGPANE_ACTION* pAction = (XTP_DOCKINGPANE_ACTION*)lParam;
          switch( pAction->action )
          {
               case xtpPaneActionActivated:
               {
                            DO PANEL ACTIVATION INTERNAL STUFF
               }
               break;
          }
          return TRUE;
     }

     if (wParam == XTP_DPN_SHOWWINDOW)
     {
          CXTPDockingPane* pPane = (CXTPDockingPane*)lParam;
          int paneID = pPane->GetID();
          if (!pPane->IsValid() )
          {
               int paneID = pPane->GetID();
               DashboardPanelCollection::iterator pos = m_dashboardPanels.find(paneID);               
                        if ( pos == m_dashboardPanels.end() )
               {
                       DashboardPanel *panel = new DashboardPanel(SOME ID);
                       pPane->Attach(panel);
               }
               else
               {                    
                    pPane->Attach(pos->second);
               }               
          } else {
               DashboardPanel* panel = (DashboardPanel*)pPane->GetChild();
               INTERNAL ACTIVATION CODE FOR panel
          }
          return TRUE; // handled
     }


Thanks
Aaron
Product: Xtreme ToolkitPro v13.3.0 (MFC)
Platform: Windows XP (32bit) - SP 3
Language: Visual C++ 6
Back to Top
adrien View Drop Down
Senior Member
Senior Member


Joined: 30 April 2007
Location: New Zealand
Status: Offline
Points: 449
Post Options Post Options   Thanks (0) Thanks(0)   Quote adrien Quote  Post ReplyReply Direct Link To This Post Posted: 08 March 2010 at 6:10pm
on this note, it would be really useful to be able to store an ID with a pane, so we can match things up on loading layouts.

p.p.s this is on 13.3.0
Back to Top
mgampi View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14 July 2003
Status: Offline
Points: 1155
Post Options Post Options   Thanks (0) Thanks(0)   Quote mgampi Quote  Post ReplyReply Direct Link To This Post Posted: 08 March 2010 at 6:33pm
Hi;

am I right when I assume that below code creates the underlying window too? If this is true then you have to check in the Attach section whether the window handle is still valid or not!
                       DashboardPanel *panel = new DashboardPanel(SOME ID);
                       pPane->Attach(panel);
I do it this way:

                case IDR_TIMESCALE:
                    {
                        if (_timeline.GetSafeHwnd() == 0)
                        {
                            VERIFY(_timeline.Create(WS_CHILD|WS_VISIBLE|XRTLS_HASONLINEBUTTON|XRTLS_HASPRESELECTCOMBO|XRTLS_HASTWOTIMELINES, this, 0)==TRUE);
                        }
                        pPane->Attach(&_timeline);




Martin

Product: Xtreme Toolkit v 19.0.0, new Projects v 19.1.0
Platform: Windows 10 v 1909 (64bit)
Language: VC++ 2017
Back to Top
Aaron Koolen View Drop Down
Groupie
Groupie


Joined: 22 July 2009
Status: Offline
Points: 32
Post Options Post Options   Thanks (0) Thanks(0)   Quote Aaron Koolen Quote  Post ReplyReply Direct Link To This Post Posted: 08 March 2010 at 7:19pm
mgampi, you're sort of right. In order to match up our internal objects with the correct pane we need to save a mapping between pane id and our objects (Dashboard). When we get a XTP_DPN_SHOWWINDOW message, we look to see if we have a mapping for that pane id already. If we do, we just attach the dashboard window to it. If we don't, then we create a new dashboard (Which does create a window, yes) and then attach that.

I understand what you're saying in that the panel should be checked that it's valid, but unfortunately that's not exactly the problem.

When this code is called (During the first time a pane is shown) the panel windows are created fine, and they show up. It's later on, when they are undocked and docked again in some strange manner, that for some reason the CodeJock framework is calling DestroyWindow on it, which inevitably destroys my dashboard window, even though my application doesn't know that it has. From that point on the window handle is invalid.

I'm trying to work out if this is normal. Can CodeJock destroy windows that you've created and put into panes, whenever it feels like? If so, then I will need to trap that and have some sort of observer pattern so things can be told when it's destroyed. If not, then is it a bug?

Thanks for your help

Product: Xtreme ToolkitPro v13.3.0 (MFC)
Platform: Windows XP (32bit) - SP 3
Language: Visual C++ 6
Back to Top
mgampi View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14 July 2003
Status: Offline
Points: 1155
Post Options Post Options   Thanks (0) Thanks(0)   Quote mgampi Quote  Post ReplyReply Direct Link To This Post Posted: 09 March 2010 at 3:38am
Hi;
You attach the created window to the docking pane. So it takes control. I just tried your steps and in my case I catch a ShowWindow message in OnDockingPaneNotify. All I have to do is check the window handle of my control and then recreate it if necessary. It works very well.
If you require information about the window destroyed, just call an appropriate function in your OnDestroy message handler, but perhaps you could change your dashboard window to a singleton...

Martin

Product: Xtreme Toolkit v 19.0.0, new Projects v 19.1.0
Platform: Windows 10 v 1909 (64bit)
Language: VC++ 2017
Back to Top
adrien View Drop Down
Senior Member
Senior Member


Joined: 30 April 2007
Location: New Zealand
Status: Offline
Points: 449
Post Options Post Options   Thanks (0) Thanks(0)   Quote adrien Quote  Post ReplyReply Direct Link To This Post Posted: 09 March 2010 at 4:05am
I think the point is that simply changing the docking of a pane shouldn't call DestroyWindow on it.

Personally I consider this a bug.
Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 12.04
Copyright ©2001-2021 Web Wiz Ltd.

This page was generated in 0.047 seconds.