现在的位置: 首页 > 综合 > 正文

解决scrollbar的npos值超过32767

2013年02月24日 ⁄ 综合 ⁄ 共 2082字 ⁄ 字号 评论关闭

前两天在编程技巧与维护中看到一个解决scrollbar的npos值超过32767就不能正常显示的问题。

又在网上找了找资料现整理如下。以备后用

提问1

希望在CScroolView中连续的输出图形,并且要求能连续查看所有的该次任务的所有历史输出,但是当坐标值超出32767时,绘图便出现问题。对此MDSN的解释是 

 

ote       Under   Windows   95,   all   screen   coordinates   are   limited   to   16   bits.   Therefore,   an   int   passed   to   a   CDC   member   function   must   lie   in   the   range   –32768   to   32767. 

我用的是VC++6,操作系统是XP,不是95啊,怎么也有这个限制!!在StdAfx.h中预定义 

#ifndef     WINVER 

#define     WINVER     0x0500 

#endif 

#ifndef     _WIN32_WINNT 

#define   _WIN32_WINNT   0x0500 

#endif 

 

#ifndef   _WIN32_WINDOWS 

#define   _WIN32_WINDOWS   0x0500 

#endif 

 

答:

这个问题,CScrollView确实存在。   

要解决,我的办法是   生成自己的     CScrollView类,主要代码可以直接拷贝过来,   主要修改: 

 

对滚动条的控制主要用了GetPos/SetPos.   这个函数只支持   16位POS值,要改为: 

GetScrollInfo,   SetScollInfo. 

 

函数主要要修改   UpdateScrollBar   和对滚动条消息的响应。   OnScrollBy     等函数。 

 

通过这样的修改,确实可以将滚动范围扩展到32值,但是CDC好象也不支持32位的坐标,   所以绘图的时候要自己计算偏移量,并在合适的位置绘图。 

 

这样处理后,就能实现32位的坐标了。   

 

 

提问2

消息

void OnHScroll(UINT nSBCode,UINT nPos,CScrollBar* rollBar )

{

    int icruScrollpos = GetScrollPos(SB_HORZ);

    siwtch{

    case SB_THUMBTRACK:

        SetScrollPos(SB_HORZ,nPos,TRUE);

        break;

    case SB_LINERIGHT:

        SetScrollPos(SB_HORZ,iCurScrollPos+1,TRUE);

        break;

    case SB_LINELEFT:

        SetScrollPos(SB_HORZ,iCurScrollPos-1,TRUE);

        break;

    ...    

    }

 

    CDialog::OnScroll(nSBCode,nPos,pScrollBar);

 

}

 

当滚动条超过32767后自动退回到起始位置,

答:

使用了OnHScroll()函数的nPos值,该值最大为32767,因此出现以上情况。

 

用GetScrollInfo(...)函数中的SCROLLLINFO参数中的nTrackPos也为滚动条拖动值,正常运行。

typedef struct tagSCROLLINFO { 

    UINT cbSize; 

    UINT fMask; 

    int  nMin; 

    int  nMax; 

    UINT nPage; 

    int  nPos; 

    int  nTrackPos; 

}   SCROLLINFO, *LPSCROLLINFO; 

typedef SCROLLINFO CONST *LPCSCROLLINFO;

 

如下

void OnHScroll(UINT nSBCode,UINT nPos,CScrollBar* rollBar )

{

    SCROLLINFO lpScrollInfo;

    GetScrollInfo(SB_HORZ,&lpScrollInfo,SIF_ALL);

    iCurScrollPos = GetScrollPos(SB_HORZ);

 

    int icruScrollpos = GetScrollPos(SB_HORZ);

 

    siwtch{

    case SB_THUMBTRACK:

        SetScrollPos(SB_HORZ,lpScrollInfo.nTrackPos,TRUE);

        break;

    case SB_LINERIGHT:

        SetScrollPos(SB_HORZ,iCurScrollPos+1,TRUE);

        break;

    case SB_LINELEFT:

        SetScrollPos(SB_HORZ,iCurScrollPos-1,TRUE);

        break;

    ...    

    }

 

    CDialog::OnScroll(nSBCode,nPos,pScrollBar);

}

 

 

【上篇】
【下篇】

抱歉!评论已关闭.