Mfc调用嵌入wpf控件的onsize事件

ev7lccsx  于 2023-02-16  发布在  其他
关注(0)|答案(1)|浏览(155)

我使用Hwndsource和ccli技术将一个wpf控件嵌入到一个mfc应用程序中。SiteToContent被设置为WidthAndHeight。
在不同的计算机上发生了错误的大小调整。当创建mfc控件时,wpf过大了很多。
c
cli.h

#pragma once

#if _MANAGED

ref class ControlManager
{
public:
  ControlManager() { }
  ~ControlManager() {}
  Sharp::Control^ Current;

  System::Windows::Interop::HwndSource^ HwndSource;
  void Init(LPCREATESTRUCT lp, HANDLE Hwdn);
  void SetSize(int w, int h);
};

#endif

class AFX_EXT_CLASS CXbimWnd final 
{
public:
  int OnCreate(LPCREATESTRUCT lpCreateStruct, HANDLE hwnd);
  void OnSize(UINT nId, int h, int w);
  
private:

#ifdef _MANAGED
  // current 3d view
  gcroot<ControlManager^ > m_ObjHandle;
#else
  intptr_t m_ObjHandle;
  intptr_t HwndSource;
#endif
};

c++cli.cpp

int CXbimWnd::OnCreate(LPCREATESTRUCT lp, HANDLE hwnd)
{
  m_ObjHandle = gcnew ControlManager(m_Log);
  m_ObjHandle->Init(lp, hwnd);

  return 0;
}

void ControlManager::Init(LPCREATESTRUCT lp, HANDLE hwnd)
{
  System::Windows::Interop::HwndSourceParameters sourceParams("XbimXplorer");
  sourceParams.PositionX = lp->x;
  sourceParams.PositionY = lp->y;
  sourceParams.Height = lp->cy;
  sourceParams.Width = lp->cx;
  sourceParams.ParentWindow = (System::IntPtr)hwnd; 
  sourceParams.WindowStyle = WS_VISIBLE | WS_CHILD | WS_MAXIMIZE;

  HwndSource = gcnew System::Windows::Interop::HwndSource(sourceParams);
  HwndSource->SizeToContent = System::Windows::SizeToContent::WidthAndHeight;

  Current = gcnew Sharp::Control();
  HwndSource->RootVisual = Current;
}

void CXbimWnd::OnSize(UINT /*nId*/, int h, int w)
{
  m_ObjHandle->SetSize(h, w);
}

void ControlManager::SetSize(int h, int w)
{
  Current->Height = h;
  Current->Width = w;
}

mfc.h

class CBIMXBimBar : public CBCGPDockingControlBar
{
public:
  CBIMXBimBar();

  void AdjustLayout();
  virtual ~CBIMXBimBar();

  // Generated message map functions
protected:
  afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
  afx_msg void OnSize(UINT nType, int cx, int cy);
  DECLARE_MESSAGE_MAP()
  CXbimWnd xbim;
};

mfc.cpp

BEGIN_MESSAGE_MAP(CBIMXBimBar, CBCGPDockingControlBar)
  ON_WM_CREATE()
  ON_WM_SIZE()
END_MESSAGE_MAP()

int CBIMXBimBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if (CBCGPDockingControlBar::OnCreate(lpCreateStruct) == -1)
    return -1;

  CRect rectDummy;
  rectDummy.SetRectEmpty();
  auto result = xbim.OnCreate(lpCreateStruct, m_hWnd);

  if (result == 0)
    AdjustLayout();

  return result;
}

void CBIMXBimBar::OnSize(UINT nType, int cx, int cy)
{
  AdjustLayout();
}

void CBIMXBimBar::AdjustLayout()
{

  CRect rectClient;
  GetClientRect(rectClient);
  auto scale = globalUtils.GetDPIScale(); 
  xbim.OnSize(0, int(rectClient.Height()/scale), int(rectClient.Width()/scale));  //<<---

}

我用DPI值重新调整了客户端矩形坐标的x,y。它在我的计算机上工作,但在另一台计算机上不工作。在mfc客户端矩形视图中,嵌入控件的大小是两倍大

oxf4rvwz

oxf4rvwz1#

所以。我的调查给了我一些信息。通过HwndSource托管的WPF控件没有获得OnDpiChange事件。这是一个错误或功能。我的MFC应用程序不允许捕获WM_DPICHANGE事件向WPF准确地抛出一个事件。所以我只是设置

var m = new HwndSource.CompositionTarget.TransformToDevice();
 WpfControl.LayoutTransform = new System.Windows.Media.ScaleTransform(1 / m.M11, 1 / m.M22);

相关问题