无法获得Dockable Pane C ++的句柄

时间:2015-04-13 02:48:59

标签: c++ mfc

我通过MFC向导创建了一个基于多文档功能区的MFC应用程序。我试图获取m_wndFileView的句柄来更新其视图。我知道有几种方法可以做到,但我不明白为什么我使用的方法不起作用。 Soooo开始

class CMainFrame : public CMDIFrameWndEx
{
    ...
    CFileView         m_wndFileView;
    CPropertiesWnd    m_wndProperties;
    ...
}

class CFileView : public CDockablePane
{
    ...
    protected:
        CViewTree m_wndFileView;
    ...
};

class CPropertiesWnd : public CDockablePane
{
    ...
    protected:
        CMFCPropertyGridCtrl m_wndPropList;
    ...
};

主框架是从MAINAPPLICATION.cpp

创建的
// create main MDI Frame window
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
{
    delete pMainFrame;
    return FALSE;
}
m_pMainWnd = pMainFrame;

// call DragAcceptFiles only if there's a suffix
//  In an MDI app, this should occur immediately after setting m_pMainWnd
// Enable drag/drop open
m_pMainWnd->DragAcceptFiles();

// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);

// Enable DDE Execute open
EnableShellOpen();
RegisterShellFileTypes(TRUE);


// Dispatch commands specified on the command line.  Will return FALSE if
// app was launched with /RegServer, /Register, /Unregserver or /Unregister.
if (!ProcessShellCommand(cmdInfo))
    return FALSE;
// The main window has been initialized, so show and update it
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();

MainFrm.cpp创建这两个窗格:

// Create file view
CString strFileView;
bNameValid = strFileView.LoadString(IDS_FILE_VIEW);
ASSERT(bNameValid);
if (!m_wndFileView.Create(strFileView, this, CRect(0, 0, 200, 200), TRUE, ID_VIEW_FILEVIEW, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT| CBRS_FLOAT_MULTI))
{
    TRACE0("Failed to create File View window\n");
    return FALSE; // failed to create
}


// Create properties window
CString strPropertiesWnd;
bNameValid = strPropertiesWnd.LoadString(IDS_PROPERTIES_WND);
ASSERT(bNameValid);
if (!m_wndProperties.Create(strPropertiesWnd, this, CRect(0, 0, 200, 200), TRUE, ID_VIEW_PROPERTIESWND, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_RIGHT | CBRS_FLOAT_MULTI))
{
    TRACE0("Failed to create Properties window\n");
    return FALSE; // failed to create
}

从MAINAPPLICATION.cpp,我可以通过

访问属性窗格
CWnd * pwnd = ((CWnd*)(AfxGetApp()->m_pMainWnd));
CPropertiesWnd * pPropertiesWnd = (CPropertiesWnd*)pwnd->GetDlgItem(ID_VIEW_PROPERTIESWND);
CMFCPropertyGridCtrl * m_wndPropList = (CMFCPropertyGridCtrl *)pPropertiesWnd->GetDlgItem(2);

但由于某种原因,我无法使用

访问文件视图窗格
CWnd * pwnd = ((CWnd*)(AfxGetApp()->m_pMainWnd));
CFileView * pFileViewWnd = (CFileView*)pwnd->GetDlgItem(ID_VIEW_FILEVIEW);
CViewTree * m_wndFileView= (CViewTree*)pFileViewWnd ->GetDlgItem(4);

(CFileView *)pwnd-> GetDlgItem(ID_VIEW_FILEVIEW);返回NULL

请帮忙。这真让我抓狂。最后我可以修改m_wndPropList而不是m_wndFileView,因为我无法获得pFileViewWnd的句柄。以相同方式创建的两个窗格无法以相同方式访问。为什么?如果需要更多代码,请告诉我。感谢。

2 个答案:

答案 0 :(得分:0)

所以@MarkRansom真的帮助了间谍++的想法。为了得到一个处理,我必须做以下事情:

// get CWnd to main window
CWnd * pwnd = ((CWnd*)(AfxGetApp()->m_pMainWnd));
// from spy++ i found that the tabbed panes were in a window called
// "File View" so i found a child window with that title
HWND h = FindWindowExW(pwnd->GetSafeHwnd(), NULL, NULL, L"File View");
// casted it to a tabbedpane pointer
CTabbedPane * pFileViewWn = (CTabbedPane *)CWnd::FromHandle(h);
// mfc wizard did what seems to me as weird naming. to find the docking 
// panes i did the same as above but there was no title to this window
HWND hh = FindWindowExW(pFileViewWn->GetSafeHwnd(), NULL, NULL, L"");
// casted that
CDockablePane* pTabbedBar = (CDockablePane*)CWnd::FromHandle(hh);
// was able to find my specific docking pane using a resource id
CFileView * pFileViewWnd = (CFileView*)pTabbedBar->GetDlgItem(ID_VIEW_FILEVIEW);
// was able to find the control i wanted to use using a resource id
CViewTree * m_wndFileView = (CViewTree *)pFileViewWnd->GetDlgItem(4);

HTREEITEM hRoot = m_wndFileView->GetRootItem();

m_wndFileView->InsertItem(name, 2, 2, hRoot);

通过代码我会认为逻辑是

tabbed pane
    File View Dockable Pane
        File View controls
    Class View Dockable Pane
        Class View controls

但不知何故,另一个窗口滑入其中

tabbed pane
    MYSTERY DOCKABLE WINDOW
        File View Dockable Pane
            File View controls
        Class View Dockable Pane
            Class View controls

答案 1 :(得分:0)

您应该在CMainFrame类中创建内联getter,如下所示:

CFileView& GetFileViewPane()
{
  return m_wndFileView;
}

CPropertiesWnd& GetPropsPane()
{
  return m_wndProperties;
} 

之后,您可以像这样访问这些窗口:

CMainFrame* pMainFrame = DYNAMIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
if (pMainFrame && pMainFrame->GetSafeHwnd()) // sanity check
{
  pMainFrame->GetFileViewPane().DoStuff();
}