mfc滚动条的相关问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mfc滚动条的相关问题相关的知识,希望对你有一定的参考价值。
我现在需要做一个应用软件,需要输入大量的信息,在对话框的左侧是输入区,右边是预览区。
由于要输入大量的信息,需要大量的 Edit 控件 。这样左侧的有限的空间是远远不够的。
哪位高手可以实现类似“滑动条”那样的东西,能够使 这些控件都存在于当前对话框中,然后用“滑动条”来拖动。
如解决必有高分相赠,谢谢
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】:一个解决方法是捕获 CScrollView 的 OnPaint 方法,并在此方法中添加代码以始终绘制底部角客户端窗口。
但是这个绘制代码还需要调用 GetDC 来获得一个新的 CDC,这样它就可以绕过 BeginPaint 的剪切区域> CDC 由 WM_PAINT 消息传入。
【讨论】:
谢谢,我可能最终会这样做。我只是认为有一些“标准”修复,因为这似乎是一个很常见的问题。以上是关于mfc滚动条的相关问题的主要内容,如果未能解决你的问题,请参考以下文章