Using VTK LinePlot3D in an MFC child window

Hello,
I have an extensive MFC (commercial) application and we need to replace the 3D graph. We were hoping to incorporate the LinePlot3D application, but, after many hours of trying to get a mini-application to work, I am hoping someone can assist me here. I have tried both a small MFC application and a code project example. In the MFC app, I used m_pvtkWnd = new MyVTKWindow(IDD_DIALOG_BLANK, GetDlgItem(IDD_VTKCHART)) to create the window, but that fails at CWnd::Create() within the vtkWindow constructor. We are using VTK 9.4 in MSVS 2022.
I have also attempted to use this example:

and that example works, but I cannot get the LinePlot3D application to display in that one either.
Can anyone guide me towards a solution or tell me where I might be making a mistake?

Are you going to post your code?

Sure, below is an excerpt from my custom dialog class. I attempted more than just this small section of code as well, but this is the minimum to reproduce an error. The if statement was used as a sanity check and it loads either the vtkMFCWindow or a CDialog that uses Direct2D to draw the window. The CDialog loads and draws just fine.

Please let me know if you need to see more of the code so you can reproduce and troubleshoot the error.

BOOL CMFCApplication1Dlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
	BOOL bNameValid;
	CString strAboutMenu;
	bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
	ASSERT(bNameValid);
	if (!strAboutMenu.IsEmpty())
	{
		pSysMenu->AppendMenu(MF_SEPARATOR);
		pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
	}
}

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);			// Set big icon
SetIcon(m_hIcon, FALSE);		// Set small icon


if (true)
{	// Create the vtkMFCWindow and associate it with an MFC control	
	pvtkMFCWindow = new vtkMFCWindow(GetDlgItem(IDC_VTKAREA));
}
else
{
	CRect rc;
	CWnd* pWnd = GetDlgItem(IDC_VTKAREA);
	if (pWnd) pWnd->GetWindowRect(rc);
	ScreenToClient(rc);
	m_d2dChart.Create(rc, this, IDC_VTKAREA);
	if (m_d2dChart.GetSafeHwnd() == NULL) {
		AfxMessageBox(_T("Graph: Failed to create dialog."));
		return FALSE;
	}
	m_d2dChart.ShowWindow(SW_SHOW);
}

return TRUE;  // return TRUE  unless you set the focus to a control

}

What is the declaration for m_d2dChart?

Is IDC_VTKAREA a CView?

IDC_VTKAREA is not a CView, but a drawing area. If it helps, attached is a screenshot.


If needed, I can work with a CView, but a drawing area is more generalizable.

Did you try running the CodeProject example with IPictEditor?

The code project example uses a CView to draw the bitmap. From my screenshot above, my test app used the IPictEditor. To me, these are different ways to draw a scene in an MFC window. Which is preferred?

I will add that when I use CView from the Code Project example the line
m_pvtkMFCWindow = new vtkMFCWindow(this);
does not result in an exception, but this line has an exception:
this->Context->GetDevice()->SetViewportSize(vtkVector2i(size));
vtkContext2D::GetDevicevirtual returned nullptr.
it is in the function vtkContextActor::RenderOverlay(vtkViewport* viewport).

Do I need to set the device or initialize other members in CTestBMPView::OnInitialUpdate()?
The example from code project just does the following:
m_pvtkMFCWindow = new vtkMFCWindow(this);
m_pvtkMFCWindow->GetRenderWindow()->AddRenderer(m_pvtkRenderer);
m_pvtkRenderer->SetBackground(0.0, 0.0, 0.0);
if(NULL != GetDocument()->m_pvtkBMPReader)
{
//setup renderer
m_pvtkImageActor->GetMapper()->SetInputConnection(GetDocument()->m_pvtkBMPReader->GetOutputPort());
m_pvtkRenderer->AddActor(m_pvtkImageActor);
m_pvtkRenderer->ResetCamera();
}

Hi Todd, I was able to find the solution thanks to several posts made by dwventer. Thank you for your assistance with this problem.

If anyone else needs a bread crumb to the solution, see this:

1 Like

I haven’t actually used vtkMFCWindow but I have done something similar with an OpenCascade rendering window, so I supposed that vtkMFCWindow requires a CView host.

I’m glad you got it solved.