如何在CWnd中调整WPF控件的大小?
我将WPF UserControl
托管在MFC CWnd
中.它工作得很漂亮,我现在需要弄清楚如何使用其父项调整控件的大小.我已经钩住OnSize
,并且正在调用GetWindowRect
并将结果设置为我的控件,如下所示:
I'm hosting a WPF UserControl
inside an MFC CWnd
. It works beautifully I now need to figure out how to resize the control with its parent. I've hooked the OnSize
and I'm calling GetWindowRect
and setting the result to my control like so:
void CChildFrame::OnSize(UINT nType, int cx, int cy)
{
CRect rect;
this->GetWindowRect(&rect);
m_mainControl->Width = rect.Width();
m_mainControl->Height = rect.Height();
}
尤里卡!解决方法是将HwndSource.SizeToContent
设置为SizeToContent.WidthAndHeight
.这似乎很违反直觉,因为SizeToContent
涉及视口调整其所包含内容的大小的能力,但它确实起作用.我的想法是,它改变了重新绘制控件的方式.整个解决方案(如果有人需要的话)如下:
Eureka! The solution is to set the HwndSource.SizeToContent
to SizeToContent.WidthAndHeight
. This seems counter intuitive as SizeToContent
is involved with a viewport's ability to size to what it contains, but it worked. My thinking is that it changes the way the control is repainted. The solution as a whole, if anyone wants it is as follows:
用于创建并获取WPF用户控件的句柄的函数.在这种情况下称为MyControl
:
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();
}
在主机窗口的OnCreate
中调用GetMyControlHwnd
.该函数通过设置HwndSource.ParentWindow
属性来自己创建父子关系.
Call GetMyControlHwnd
in the OnCreate
of the host window. The function creates the parent child relationship itself 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;
}
ChildFrame
调整大小时,我只是更改控件的宽度和高度.
When ChildFrame
resizes I simply 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;
}
我在头文件中有以下私有字段:
// Fields
private:
gcroot<HwndSource^> m_hwndSource;
gcroot<MyControl^> m_myControl;
HWND m_hMyControl;
它有助于您了解这是如何在MFC C ++/CLI代码文件中包括CLR名称空间的方法:
using namespace System;
using namespace System::Windows;
using namespace System::Windows::Interop;