mfc滚动条的相关问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mfc滚动条的相关问题相关的知识,希望对你有一定的参考价值。

我现在需要做一个应用软件,需要输入大量的信息,在对话框的左侧是输入区,右边是预览区。
由于要输入大量的信息,需要大量的 Edit 控件 。这样左侧的有限的空间是远远不够的。
哪位高手可以实现类似“滑动条”那样的东西,能够使 这些控件都存在于当前对话框中,然后用“滑动条”来拖动。
如解决必有高分相赠,谢谢

首先你要有一个主Wnd CExtendMainWnd ,里面放一个子Wnd CExtendWnd m_wndExtend和一个CScrollBar m_vScrollBar,Cedit都放在子Wnd中,子Wnd跟主Wnd的高度和Y坐标都是相同的,宽度留一个地方放ScrollBar.拖动滚动条的时候,把子Wnd MoveWindow到相应的位置。你的CEdit每个都有高度的,可以根据N个CEdit高度和与ParentWnd.GetClientRect 的高度进行比较,如果和超过了客户端的高度,
CScrollBar.ShowWindow(SW_SHOW)(之前先把CScrollBar 创建好后 Hide).
后面再来响应ON_WM_VSCROLL()

主要的代码:
void CExtendMainWnd::CreateWnd(CWnd* pParent,int iColorLevel,CRect& rect,int iDefItemHeight )

CWnd::Create(NULL,NULL,WS_CHILD|WS_VISIBLE,rect,pParent,1001);
m_wndExtend.CreateWnd(this,m_iColorlevel,rect,iDefItemHeight);
m_vScrollBar.Create(WS_CHILD|SB_VERT,CRect(0,0,0,0),this,1002);

每次添加完一个CEdit
void CExtendWnd::AddItemWnd(CBaseItemWnd* pBaseItemWnd)

//我这里是动态添加的
ExtendItem* pExtendItem = new ExtendItem;
pExtendItem->m_pBaseWnd = pBaseItemWnd;
pExtendItem->m_pBaseWnd->CreateWnd(CRect(0,0,0,0),m_iColorLevel,this,m_uIDWnd );
m_uIDWnd ++;//

Arrange();
GetParent()->SendMessage(WM_WHETHERNEEDSCROLL,0,0);//加完给父窗口发消息去知道需不需要加滚动条

消息处理
LRESULT CExtendMainWnd::OnWhetherNeedScroll(WPARAM wParam,LPARAM lParam)

UpdataScrollBar();
Arrange();
return 0;


就UpdataScrollBar();
void CExtendMainWnd::UpdataScrollBar()

CRect rtParent;
GetWindowRect(&rtParent);
CRect rtWindow;
m_wndExtend.GetWindowRect(&rtWindow);
if ( m_wndExtend.GetDisplayHeight() > rtParent.Height() )


SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
info.fMask = SIF_ALL;
info.nMin = 0;
info.nMax = m_wndExtend.GetDisplayHeight();
info.nPage = rtParent.Height();
info.nPos = m_iScrollBarPos;
m_vScrollBar.SetScrollInfo(&info);
m_vScrollBar.ShowWindow(SW_SHOW);
m_bNeedScrollBar = TRUE;

else

m_vScrollBar.ShowWindow(SW_HIDE);
m_bNeedScrollBar = FALSE;



拖动滚动条的消息响应
void CExtendMainWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)

// TODO: Add your message handler code here and/or call default
SCROLLINFO si;
m_vScrollBar.GetScrollInfo(&si);
CRect rtParent;
CRect rtChild;
GetClientRect(&rtParent);
m_wndExtend.GetWindowRect(&rtChild);
ScreenToClient(&rtChild);
switch(nSBCode)

case SB_TOP:

si.nPos = si.nMin;

break;
case SB_BOTTOM:

si.nPos = si.nMax;

break;
case SB_LINEUP:

si.nPos -= 1;

break;
case SB_LINEDOWN:

si.nPos += 1;

break;
case SB_PAGEUP:

si.nPos -= si.nPage;

break;
case SB_PAGEDOWN:

si.nPos += si.nPage;

break;
case SB_THUMBTRACK:

si.nPos += nPos;

break;

if(si.nPos > (int)(si.nMax-si.nMin-si.nPage+1))
si.nPos = si.nMax-si.nMin-si.nPage+1;
if(si.nPos < si.nMin)
si.nPos=si.nMin;
m_iScrollBarPos = si.nPos;
m_vScrollBar.SetScrollInfo(&si);
m_wndExtend.MoveWindow(rtParent.left,rtParent.top - si.nPos,rtChild.Width(),rtChild.Height());
//Invalidate(FALSE);
CWnd::OnVScroll(nSBCode, nPos, pScrollBar);


BOOL CExtendMainWnd::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)

CRect rtParent;
CRect rtChild;
GetClientRect(&rtParent);
m_wndExtend.GetWindowRect(&rtChild);
ScreenToClient(&rtChild);
SCROLLINFO si;
m_vScrollBar.GetScrollInfo(&si);
if (zDelta > 0)

zDelta = LINE_COUNT;

else

zDelta = -LINE_COUNT;

si.nPos += -zDelta;
if(si.nPos > (int)(si.nMax-si.nMin-si.nPage+1))
si.nPos = si.nMax-si.nMin-si.nPage+1;
if(si.nPos < si.nMin)
si.nPos=si.nMin;
m_iScrollBarPos = si.nPos;
m_vScrollBar.SetScrollInfo(&si);
m_wndExtend.MoveWindow(rtParent.left,rtParent.top - si.nPos,rtChild.Width(),rtChild.Height());

return CWnd::OnMouseWheel( nFlags, zDelta, pt);
参考技术A 你把左面的输入区用子窗口实现,右边的预览区用一个子窗口实现,那样的话你给左边的子窗口加个滑动条就行了~!之间的通信可以用发消息传递(左边的子窗口发给右边,或者左边的子窗口给父窗口,父窗口再传给右边的窗口)

用MFC画滚动条的小问题

【中文标题】用MFC画滚动条的小问题【英文标题】:Small problem with painting scroll bars with MFC 【发布时间】:2008-10-12 20:54:16 【问题描述】:

在 MFC 应用程序中有一个小的矩形区域,滚动条在此处相遇(窗口的右下角)。似乎该区域仅在调整框架大小时才失效。在其他情况下(例如,如果另一个窗口被拖动到它上面),该区域不会重新绘制。

我已经能够在 VS 6 和 2008 的新创建项目中重现它。我也看到一些商业应用程序有同样的问题。要重新创建它:

    使用 CScrollView 派生视图创建一个新的 SDI 项目。 调整窗口大小以显示两个滚动条。 在该矩形上拖动另一个窗口以查看重绘问题。

任何想法如何摆脱这个?

【问题讨论】:

我相信您的问题演示,尤其是第 3 部分,具有选择“拖动时显示窗口内容”的先决条件。 不一定。您也可以简单地将第一个窗口(MFC 程序)拖离屏幕并返回,矩形不会失效。 【参考方案1】:

一个解决方法是捕获 CScrollViewOnPaint 方法,并在此方法中添加代码以始终绘制底部角客户端窗口。

但是这个绘制代码还需要调用 GetDC 来获得一个新的 CDC,这样它就可以绕过 BeginPaint 的剪切区域> CDCWM_PAINT 消息传入。

【讨论】:

谢谢,我可能最终会这样做。我只是认为有一些“标准”修复,因为这似乎是一个很常见的问题。

以上是关于mfc滚动条的相关问题的主要内容,如果未能解决你的问题,请参考以下文章

用MFC画滚动条的小问题

MFC 控件编程之水平滚动条跟垂直滚动条

求教:关于MFC控件中的滚动条事件........

需要MFC自定义滚动条的建议

CSplitterWnd 的独立滚动条? (MFC)

MFC CCheckListBox 的垂直滚动条没有更新