How to resize a WPF control inside CWnd?

I host the WPF UserControl inside the MFC CWnd . It works great, I now need to figure out how to resize the control with its parent. I hooked OnSize and I call GetWindowRect and set the result for my control as follows:

 void CChildFrame::OnSize(UINT nType, int cx, int cy) { CRect rect; this->GetWindowRect(&rect); m_mainControl->Width = rect.Width(); m_mainControl->Height = rect.Height(); } 
+4
source share
1 answer

Eureka! The solution is to set HwndSource.SizeToContent to SizeToContent.WidthAndHeight . This seems SizeToContent , as SizeToContent is related to being able to view in size up to what it contains, but it worked. My thinking is that it is changing the way the control is repainted. The solution in general, if someone wants it, is as follows:

The function to create and retrieve a WPF user control handle. In this case, MyControl is called:

 HWND CChildFrame::GetMyControlHwnd(HWND a_parent, int a_x, int a_y, int a_width, int a_height) { HWND mainHandle = AfxGetMainWnd()->GetSafeHwnd(); IntPtr testHandle = IntPtr(mainHandle); HwndSource^ test = HwndSource::FromHwnd(testHandle); Global::Bootstrap(IntPtr(mainHandle)); HwndSourceParameters^ sourceParameters = gcnew HwndSourceParameters("MyControl"); sourceParameters->PositionX = a_x; sourceParameters->PositionY = a_y; sourceParameters->Height = a_height; sourceParameters->Width = a_width; sourceParameters->ParentWindow = IntPtr(a_parent); sourceParameters->WindowStyle = WS_VISIBLE | WS_CHILD | WS_MAXIMIZE; m_hwndSource = gcnew HwndSource(*sourceParameters); m_myControl = gcnew MyControl(); // *** This is the line that fixed my problem. m_hwndSource->SizeToContent = SizeToContent::WidthAndHeight; m_hwndSource->RootVisual = m_myControl; return (HWND) m_hwndSource->Handle.ToPointer(); } 

Call GetMyControlHwnd in the OnCreate window of the host. The function creates a parent child relation by setting the HwndSource.ParentWindow property.

 int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1) return -1; m_hMyControl = GetMyControlHwnd(this->GetSafeHwnd(), 0, 0, lpCreateStruct->cx, lpCreateStruct->cy); //// create a view to occupy the client area of the frame //if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, // CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL)) //{ // TRACE0("Failed to create view window\n"); // return -1; //} return 0; } 

When the size of the ChildFrame changes, I just change the width and height of the control.

 void CChildFrame::OnSize(UINT nType, int cx, int cy) { CRect rect; this->GetWindowRect(&rect); m_myControl->Width = cx; m_myControl->Height = cy; } 

I have the following private fields in the header file:

 // Fields private: gcroot<HwndSource^> m_hwndSource; gcroot<MyControl^> m_myControl; HWND m_hMyControl; 

And its useful to know that this is how you include CLR namespaces in MFC C ++ / CLI code files:

 using namespace System; using namespace System::Windows; using namespace System::Windows::Interop; 
+5
source

Source: https://habr.com/ru/post/1501862/


All Articles