Mfc 将垂直夹持器添加到对话框
我不确定在这里向您显示什么代码。我的MFC应用程序中有一个Mfc 将垂直夹持器添加到对话框,mfc,Mfc,我不确定在这里向您显示什么代码。我的MFC应用程序中有一个CDialogEx派生资源: 它支持动态调整布局控件,因此用户可以调整窗口大小。但是我想添加一个垂直的抓取器(用红色表示),这样用户就可以使名称列的宽度变大 我对此做了一些研究,所有的文章都有近10年的历史,没有考虑到更新的动态调整控件 经过进一步研究,我发现“调整夹持器大小”一词并不是我的意思。这是右下角的图标。我不是这个意思 不过我相信你知道我的意思。有可能吗?添加自定义夹持器控件相对容易。请参见下面的CMySplittercla
CDialogEx
派生资源:
它支持动态调整布局控件,因此用户可以调整窗口大小。但是我想添加一个垂直的抓取器(用红色表示),这样用户就可以使名称列的宽度变大
我对此做了一些研究,所有的文章都有近10年的历史,没有考虑到更新的动态调整控件
经过进一步研究,我发现“调整夹持器大小”一词并不是我的意思。这是右下角的图标。我不是这个意思
不过我相信你知道我的意思。有可能吗?添加自定义夹持器控件相对容易。请参见下面的
CMySplitter
class
但是,如果所有控件都在一个对话框中,则很难逐个重新定位/调整单个控件的大小
理想情况下,使用两个子对话框。在资源编辑器中为各个控件设置调整大小/重新定位属性。将夹点控件置于两个对话框之间,并相应调整大小
夹持器控制等级:
#include <functional>
class CMySplitter : public CStatic
{
public:
class CPopup : public CWnd
{
public:
CMySplitter *parent;
int offset;
void OnMouseMove(UINT flag, CPoint pt);
void OnLButtonUp(UINT flag, CPoint pt);
DECLARE_MESSAGE_MAP()
};
std::function<void(int)> callback;
CRect boundary;
CPopup popup;
void OnLButtonDown(UINT flag, CPoint point);
void PreSubclassWindow();
void SetRange(int left, int right);
DECLARE_MESSAGE_MAP()
};
//create splitter control from a static control in dialog
void CMySplitter::PreSubclassWindow()
{
CStatic::PreSubclassWindow();
//modify static control's style (must have SS_NOTIFY)
SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_VISIBLE | SS_GRAYRECT | WS_CHILD | SS_NOTIFY);
//create a popup window with transparency
static CString classname =
AfxRegisterWndClass(0, 0, (HBRUSH)GetStockObject(BLACK_BRUSH));
popup.CreateEx(WS_EX_LAYERED | WS_EX_PALETTEWINDOW | WS_EX_NOACTIVATE,
classname, NULL, WS_POPUP, CRect(0, 0, 0, 0), this, 0);
popup.SetLayeredWindowAttributes(0, 128, LWA_ALPHA);
popup.parent = this;
}
//when user click the static control, show a popup window
void CMySplitter::OnLButtonDown(UINT flag, CPoint pt)
{
CStatic::OnLButtonDown(flag, pt);
GetCursorPos(&pt);
CRect rc;
GetWindowRect(&rc);
popup.offset = pt.x - rc.left;
popup.SetWindowPos(NULL, rc.left, rc.top, rc.Width(), rc.Height(), SWP_SHOWWINDOW);
popup.SetCapture();
}
//how far to the left and right the splitter can go
void CMySplitter::SetRange(int left_, int right_)
{
CRect rc;
GetParent()->GetWindowRect(&rc);
boundary.left = rc.left + left_;
boundary.right = rc.right - right_;
}
//move this popup window
void CMySplitter::CPopup::OnMouseMove(UINT flag, CPoint pt)
{
CWnd::OnMouseMove(flag, pt);
GetCursorPos(&pt);
CRect rc;
GetWindowRect(&rc);
int x = pt.x - offset;
if (x > parent->boundary.left && x < parent->boundary.right)
SetWindowPos(NULL, x, rc.top, 0, 0, SWP_NOSIZE);
}
//hide popup window, let the parent dialog know
void CMySplitter::CPopup::OnLButtonUp(UINT flag, CPoint pt)
{
CWnd::OnLButtonUp(flag, pt);
ReleaseCapture();
ShowWindow(SW_HIDE);
CRect rc;
GetWindowRect(&rc);
parent->callback(rc.left);
}
BEGIN_MESSAGE_MAP(CMySplitter::CPopup, CWnd)
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
BEGIN_MESSAGE_MAP(CMySplitter, CWnd)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
您要查找的术语是a,传统上在CFrameWnd应用程序中通过a使用,而不是在CDialog中使用。
CSplitterWnd
是一种方法,但是如果您已经完成了对话框,并且想要添加调整大小/夹持器,则必须创建自己的控件。您需要将对话框分成两个子对话框,夹持器告诉子对话框调整大小。@BarmakShemirani OK。看起来工作太多了。我想我会离开的。好啊谢谢但我不知道如何添加两个子对话框,这可能会破坏我已有的所有代码。拥有子对话框涉及到什么?是的,你必须将对话框分成三部分。一个带有菜单的主对话框和两个子对话框。我更改了CMyDialog
以显示一个示例。大多数对话框没有这种功能,它可能不值得增加复杂性。为了回答,我加了一个答案。
class CMyDialog : public CDialogEx
{
public:
class CChild1 : public CDialogEx
{
};
class CChild2 : public CDialogEx
{
};
CChild1 child1;
CChild1 child2;
//respond to gripper resize
void respond(int position)
{
CRect rs;
m_splitter.GetWindowRect(&rs);
rs.MoveToX(position);
ScreenToClient(&rs);
CRect rc;
GetClientRect(&rc);
CRect r1(0, 0, rs.left, rc.bottom);
CRect r2(rs.right, 0, rc.right, rc.bottom);
child1.MoveWindow(r1, TRUE);
child2.MoveWindow(r2, TRUE);
m_splitter.MoveWindow(rs, TRUE);
m_splitter.Invalidate(TRUE);
}
CMySplitter m_splitter;
BOOL OnInitDialog()
{
CDialogEx::OnInitDialog();
child1.Create(IDD_PAGE1, this);
child2.Create(IDD_PAGE2, this);
m_splitter.SubclassDlgItem(IDC_STATIC1, this);
m_splitter.SetRange(50, 50);
m_splitter.callback = std::bind(&CMyDialog::respond, this, std::placeholders::_1);
//width for splitter
int dx = 10;
CRect rc;
GetClientRect(&rc);
CRect r1(0, 0, 200, rc.bottom);
CRect r2(r1.right + dx, 0, rc.right, rc.bottom);
CRect rs(r1.right, 10, r2.left, rc.bottom - 10);
child1.MoveWindow(r1);
child2.MoveWindow(r2);
m_splitter.MoveWindow(rs);
child1.ShowWindow(SW_SHOW);
child2.ShowWindow(SW_SHOW);
return TRUE;
}
...
};