gpt4 book ai didi

mfc - CPropertySheet 中对话框的垂直滚动条不起作用

转载 作者:行者123 更新时间:2023-12-05 01:30:36 26 4
gpt4 key购买 nike

我是 MFC 的初学者。我在属性表中嵌入了一个对话框。由于对话框比属性表大,因此某些部分被裁剪了。

所以我打算添加一个垂直滚动条。我试过两种方法。

  1. 在对话框本身的工具箱中添加了一个滚动条控件。

创建了一个控制变量。

DDX_Control(pDX, IDC_SCROLLBAR, m_ctlScrollBar);

添加消息映射如下:

ON_WM_VSCROLL(IDC_SCROLLBAR,OnVScroll)

OnInitDialog() 中添加以下代码:

SCROLLINFO ScrollInfo;
ScrollInfo.cbSize = sizeof(ScrollInfo);
ScrollInfo.fMask = SIF_ALL;
ScrollInfo.nMin = 0;
ScrollInfo.nMax = 100;
ScrollInfo.nPage = 40;
ScrollInfo.nPos = 50;
ScrollInfo.nTrackPos = 0;
m_ctlScrollBar.SetScrollInfo(&ScrollInfo,TRUE);

OnVScroll() 函数重写如下:

void CFeesPage::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
SCROLLINFO ScrollInfo;
m_ctlScrollBar.GetScrollInfo(&ScrollInfo);

switch (nSBCode)
{
case SB_BOTTOM: //Scrolls to the lower right.
break;

case SB_ENDSCROLL: //Ends scroll.
break;

case SB_LINEDOWN: //Scrolls one line down.
m_ctlScrollBar.SetScrollPos(m_ctlScrollBar.GetScrollPos() + 1,TRUE);
break;

case SB_LINEUP: //Scrolls one line up.
m_ctlScrollBar.SetScrollPos(m_ctlScrollBar.GetScrollPos() - 1,TRUE);
break;

case SB_PAGEDOWN: //Scrolls one page down.
m_ctlScrollBar.SetScrollPos(m_ctlScrollBar.GetScrollPos() + ScrollInfo.nPage, TRUE);
break;

case SB_PAGEUP: //Scrolls one page up.
m_ctlScrollBar.SetScrollPos(m_ctlScrollBar.GetScrollPos() - ScrollInfo.nPage, TRUE);
break;

case SB_THUMBPOSITION:
break;

case SB_THUMBTRACK:
m_ctlScrollBar.SetScrollPos(nPos, TRUE);
break;

case SB_TOP: //Scrolls to the upper left.
break;
}
}

在这种情况下滚动条移动,但子控件不移动?

  1. 另一方面,我在 OnInitDialog 中为属性表启用了滚动条控件,如下所示:

    CScrollBar* test = this->GetScrollBarCtrl(SB_VERT);

    如上设置SCROLLINFO

OnVScroll的写法如下:

void CSubTranSheet::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
SCROLLINFO ScrollInfo;
GetScrollInfo(SB_VERT, &ScrollInfo);

switch (nSBCode)
{
case SB_BOTTOM: //Scrolls to the lower right.
break;

case SB_ENDSCROLL: //Ends scroll.
break;

case SB_LINEDOWN: //Scrolls one line down.
SetScrollPos(SB_VERT, GetScrollPos(SB_VERT) + 1, TRUE);
break;

case SB_LINEUP: //Scrolls one line up.
SetScrollPos(SB_VERT, GetScrollPos(SB_VERT) - 1, TRUE);
break;

case SB_PAGEDOWN: //Scrolls one page down.
SetScrollPos(SB_VERT, GetScrollPos(SB_VERT) + ScrollInfo.nPage, TRUE);
break;

case SB_PAGEUP: //Scrolls one page up.
SetScrollPos(SB_VERT, GetScrollPos(SB_VERT) - ScrollInfo.nPage, TRUE);
break;

case SB_THUMBPOSITION:
break;

case SB_THUMBTRACK:
SetScrollPos(SB_VERT, nPos, TRUE);
break;

case SB_TOP: //Scrolls to the upper left.
break;
}
}

在这种情况下,滚动条也会移动但子对话框不会移动?

请帮我解决这个问题。我不确定哪种方法是正确的。提前致谢。

最佳答案

PropertySheet 将选择最大的页面对话框并调整自身大小以便显示所有页面对话框。不需要滚动,除非 PropertySheet 的大小被覆盖,或者在 CMyPropertyPage::OnInitDialog

中添加了额外的控件

此外,最终用户的屏幕分辨率可能较低,在这种情况下,部分属性表将被遮挡。您只需制作较小的对话页面,不超过 1000 像素,或大约 300 个对话点。

有问题的代码试图更新滚动条。除了更新滚动条之外,您还必须滚动对话框本身。

link来自@AndrewTruckle 展示了如何使用 ScrollWindow 来实现这一点。

或者,您可以手动移动所有子控件,如下所示。这稍微容易一些,因为您可以调整对话框的大小并调整滚动条范围,而不必担心子控件的对齐方式。

#include <map>

class CMyPropertyPage : public CPropertyPage
{
std::map<CWnd*, CRect> rc_children;
CRect rc_max;
void OnSize(UINT flags, int cx, int cy);
void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
DECLARE_MESSAGE_MAP()
};

void CMyPropertyPage::OnSize(UINT flags, int cx, int cy)
{
CPropertyPage::OnSize(flags, cx, cy);
CRect rc;
if(!rc_max.bottom)
{
//initialize once:
for(CWnd *p = GetWindow(GW_CHILD); p; p = p->GetWindow(GW_HWNDNEXT))
{
//save the rectangles for all child controls
p->GetWindowRect(&rc);
ScreenToClient(&rc);
rc_children[p] = rc;

//find the lowest point in dialog
if(rc.bottom > rc_max.bottom)
rc_max.bottom = rc.bottom;
}
}

GetClientRect(&rc);
SCROLLINFO info = { sizeof(info) };
info.fMask = SIF_ALL;
info.nMin = 0;
info.nMax = (rc_max.bottom + 100); //100 pixels below the lowest control
info.nPage = rc.bottom;
SetScrollInfo(SB_VERT, &info, TRUE);
}

void CMyPropertyPage::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
CPropertyPage::OnVScroll(nSBCode, nPos, pScrollBar);
SCROLLINFO info = { sizeof(SCROLLINFO) };
GetScrollInfo(SB_VERT, &info, SIF_ALL);

//update scroller
switch(nSBCode)
{
case SB_LEFT: info.nPos = info.nMin; break;
case SB_RIGHT: info.nPos = info.nMax; break;
case SB_LINELEFT: info.nPos--; break;
case SB_LINERIGHT: info.nPos++; break;
case SB_PAGELEFT: info.nPos -= info.nPage; break;
case SB_PAGERIGHT: info.nPos += info.nPage; break;
case SB_THUMBPOSITION: info.nPos = info.nTrackPos; break;
case SB_THUMBTRACK: info.nPos = info.nTrackPos; break;
}
SetScrollInfo(SB_VERT, &info, TRUE);

if(info.nPos < 0 || info.nPos > rc_max.bottom)
return;

//find how many child controls we have
int count = 0;
for(CWnd *p = GetWindow(GW_CHILD); p; p = p->GetWindow(GW_HWNDNEXT))
count++;

//go through all child controls and move them:
HDWP hdwp = BeginDeferWindowPos(count);
for(CWnd *p = GetWindow(GW_CHILD); p; p = p->GetWindow(GW_HWNDNEXT))
{
CRect rc;
p->GetWindowRect(&rc);
ScreenToClient(&rc);
if(rc_children.find(p) != rc_children.end())
{
int y = info.nPos - rc_children[p].top;
DeferWindowPos(hdwp, p->m_hWnd, NULL, rc.left, -y, 0, 0,
SWP_NOSIZE | SWP_NOACTIVATE);
}
}
EndDeferWindowPos(hdwp);
}

BEGIN_MESSAGE_MAP(CMyPropertyPage, CPropertyPage)
ON_WM_VSCROLL()
ON_WM_SIZE()
END_MESSAGE_MAP()

关于mfc - CPropertySheet 中对话框的垂直滚动条不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51022094/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com