Как изменить размер элемента управления WPF внутри CWnd?
Я хостинг WPF UserControl
внутри МФЦ CWnd
, Это работает прекрасно, теперь мне нужно выяснить, как изменить размер элемента управления с его родителем. Я подсел OnSize
и я звоню GetWindowRect
и установив результат на мой контроль следующим образом:
void CChildFrame::OnSize(UINT nType, int cx, int cy)
{
CRect rect;
this->GetWindowRect(&rect);
m_mainControl->Width = rect.Width();
m_mainControl->Height = rect.Height();
}
1 ответ
Эврика! Решение состоит в том, чтобы установить HwndSource.SizeToContent
в SizeToContent.WidthAndHeight
, Это кажется противоречивым, поскольку SizeToContent
связан со способностью видового окна измерять то, что он содержит, но это сработало. Я думаю, что это меняет способ перерисовки элемента управления. Решение в целом, если кто-то хочет, заключается в следующем:
Функция для создания и получения дескриптора пользовательского элемента управления 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();
}
Вызов GetMyControlHwnd
в OnCreate
окна хоста. Функция сама создает отношения родитель-потомок, устанавливая HwndSource.ParentWindow
имущество.
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
изменения размеров я просто изменить ширину и высоту элемента управления.
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;
И полезно знать, что именно так вы включаете пространства имен CLR в файлы кода MFC C++/CLI:
using namespace System;
using namespace System::Windows;
using namespace System::Windows::Interop;