返回首页

前简介
我用嵌入式VC + + 3.0,和2002年掌上电脑​​编写代码,因为它是在康柏iPAQ实施。您的里程可能会有所不同。简介
您知道它是如何。你screamin"以来,像一个疯狂的疯子(好了,所以这种情况很少发生与CE)编码,并与世界所有。然后,它发生。一个销售纳粹(或者更糟,否则联合国参与管理型)坚持在门头,说的东西,不仅会影响您的一天,但日程安排以及。在我的情况又是这样的:问题
"嘿约翰,对等,如对话框,当我打电话的键盘,它掩盖了现场我输入的数据。你能做些什么?quot;
的灵魂,我的好脾气,甚​​至脾气,我愉快地答复"是的,你刻着'白痴。我可以放弃我在做什么,现在和权利上it.quot;因此,我坐在。几番思索。经过一个星期的试验和错误,我终于想出了的东西。它仍然是一个有点古怪的(在这篇文章的末尾中描述的怪癖),但它几乎工程,我想它的方式,我以为我共享的财富,比如它。如何做到这一点
如果您尚未创建的CPropertyPage派生一个类。这isnbsp;必不可少的,如果你希望得到在一个合理的时间内做了什么。之后,在这里我们会做简而言之的:创建动态的滚动条。这可防止身体上放置所需的属性页模板,NBSP实际滚动;它让我们的scrollbarnbsp;比应用程序的工作室薄允许。覆盖的OnInitDialog。覆盖OnVScroll。检测时显示的SIP和解雇,并作出适当的反应。
我们先从基类的头文件的修改。首先,我们需要定义一个滚动的资源ID。在资源编辑器,我已经习惯在1000-10000范围内分配控件ID,当我需要的东西手动定义(像现在),我把它在64000-64100范围内。这就避免了与其他资源ID冲突。

#define CE_DLGSCROLLBAR 64000

接下来,我们需要确保,我们的类的定义包括以下几行:{C}
接下来,我们需要添加一些代码基类的CPP文件。首先,我们要告诉基类,我们不需要一个滚动条,并不会自动滚屏设置一些默认值。顺便说一下,如果m_bAutoScroll是TRUE,propertypage将自动滚动到页面底部。我用这种方式是在文章的结尾附近。
因为我们将要使用Create()函数来构建的滚动,我们需要调用propertypage的析构函数的滚动的DestroyWindow()方法。
CMyBasePropertyPage:: CMyBasePropertyPage()

{

   if (IsWindow(m_ctrlScrollBar))

   {

      m_ctrlScrollBar.DestroyWindow();

   }

}

现在,我们正在做的准备,这里的肉的代码。你应该有以下消息处理程序实施。对于WM_SETTINGCHANGE消息处理程序,你必须手动添加到您的代码,因为类向导不知道如何为你添加。还要注意,它liesnbsp;外AFX_MSG_MAP组。
BEGIN_MESSAGE_MAP(CPtcPropertyPage, CPropertyPage)

 //{{AFX_MSG_MAP(CPtcPropertyPage)

 ON_WM_VSCROLL()

 //}}AFX_MSG_MAP

   ON_MESSAGE(WM_SETTINGCHANGE, OnSettingChange)

END_MESSAGE_MAP()

现在,让我们添加初始化滚动条的功能。在这里,我们简单地创建滚动条,设置滚动范围和其他的滚动条的东西,然后隐藏它。
如果你想在SIP走时,他们改变到一个不同的属性页,使用类向导包括OnKillActive处理程序,像这样:
BOOL CPtcPropertyPage::OnKillActive() 

{

   SHSipPreference(m_hWnd, SIP_FORCEDOWN); 

   return CPropertyPage::OnKillActive();

}

接下来,我们必须要能够自行处理滚动,当用户点击滚动条控制。由于我们采取这样一个小的滚动范围,我决定结合上一页(上下)的阵容(和下降。注意的项目之一是,为了获得新的滚动位置,你还必须处理的SB_ENDSCROLL消息(MSDN上的任何地方都没有提及这个小珍闻,我发现)。
另外一个有趣的项目是,尽管信息MSDN上的相反,调用SW_SCROLLCHILDREN标志设置ScrollWindowEx出现在2002年的PocketPC工作。诚然,MSDN说,它不工作在CE,这是,大家都知道, 不完全的PocketPC 2002年相同。
//-------------------------------------------------------------------------

// Handle the WM_VSCROLL message

//-------------------------------------------------------------------------

void CMyBasePropertyPage::OnVScroll(UINT nSBCode, 

                 UINT nPos, CScrollBar* pScrollBar) 

{

   if (pScrollBar == &m_ctrlScrollBar)

   {

    int nDelta  = 0;

    int nMaxPos = m_DlgClientRect.Height() - m_nCurHeight;



    switch (nSBCode)

    {

         case SB_LINEDOWN:

         case SB_PAGEDOWN:

      if (m_nScrollPos >= nMaxPos)

            {

               return;

            }

      nDelta = min(max(nMaxPos / 2, 30), nMaxPos - m_nScrollPos);

      break;



         case SB_LINEUP:

         case SB_PAGEUP:

      if (m_nScrollPos <= 0)

            {

               return;

            }

      nDelta = -min(max(nMaxPos / 2, 30), m_nScrollPos);

      break;

       

         case SB_THUMBTRACK:

         case SB_THUMBPOSITION:

      nDelta = (int)nPos - m_nScrollPos;

      break;



         case SB_BOTTOM:

            nDelta = 50;

            break;

         case SB_TOP:

            if (m_nScrollPos <= 0)

            {

               return;

            }

            nDelta = -m_nScrollPos;

            break;;

         case SB_ENDSCROLL:

            return;

         default:

        return;

    }

      m_nScrollPos += nDelta;

      pScrollBar->SetScrollPos(m_nScrollPos, TRUE);

      ScrollWindowEx(0, -nDelta, NULL, &m_DlgClientRect, 

              NULL, NULL, SW_SCROLLCHILDREN);

      pScrollBar->MoveWindow(m_DlgClientRect.Width()-m_ScrollBarRect.Width(),

              0, m_ScrollBarRect.Width(), m_ScrollBarRect.Height());

   }

}

最后,我们必须处理WM_SETTINGCHANGE消息。 SIP状态变化时,此消息是发送到系统中。这个函数只是调用和投入的SIP的反应。当SIP显示,滚动条也显示,如有必要,propertypage是滚动的底部。当SIP被驳回,滚动条是隐藏的。
//------------------------------------------------------------------------

// We have to set up a custom handler for the

// WM_SETTINGCHANGE message because 

// the CDialog class doesn't handle it by default.

//------------------------------------------------------------------------

LRESULT CMyBasePropertyPage::OnSettingChange(WPARAM wParam, LPARAM lParam)

{

 if (m_bNeedScrollBar)

 {

  SIPINFO si;

  memset(&si, 0, sizeof(si));

  si.cbSize = sizeof(si);

  if (SHSipInfo(SPI_GETSIPINFO, 0, &si, 0)) 

  {

   BOOL bShowScrollBar = ((si.fdwFlags & SIPF_ON) == SIPF_ON);

   if (!bShowScrollBar)

   {

     if (m_nScrollPos > 0)

     {

       OnVScroll(SB_TOP, 0, &m_ctrlScrollBar);

     }

     m_ctrlScrollBar.ShowWindow(SW_HIDE);

   }

   else

   {

   // During testing, I discovered that the

   // standard CE SIP is always the same 

   // height, no matter which SIP mode you're using.

   // This means that if you're

   // truly interested in performance

   // (albeit a negligible gain), you can comment 

   // out this code so that the height of the

   // scrollbar is always 142 pixels (as 

   // originally set when you called Create on the scrollbar).

    CRect sipRect(si.rcSipRect);

    CRect clientRect;

    GetClientRect(&clientRect);

    m_ctrlScrollBar.GetWindowRect(&m_ScrollBarRect);

    m_ScrollBarRect.bottom = 

    m_ScrollBarRect.top + clientRect.Height(); 

    m_ctrlScrollBar.MoveWindow(m_DlgClientRect.Width()-m_ScrollBarRect.Width(),

               0, m_ScrollBarRect.Width(), m_ScrollBarRect.Height());



    // show the scrollbar

    m_ctrlScrollBar.ShowWindow(SW_SHOW);

    if (m_bAutoScroll)

    {

      OnVScroll(SB_BOTTOM, 0, &m_ctrlScrollBar);

    }

   }

  }

 }

 return 1L;

}
从派生类使用
现在,我们有我们的基类,我们可以在派生类中使用滚动条。下面的代码是需要激活在基类中的滚动条的处理代码:
CMyDerivedPage::OnInitDialog()

{

 CMyBasePropertyPage::OnInitDialog(); 

 initScrollBarSupport();

}

我的需要,我想有滚动条自动滚动,当一个特定组的控制的重点。要实现这个功能,我需要能够探测到任何页面上的控件获得焦点时,所以我的派生类中添加以下代码:
在头文件:
在CPP文件:
BEGIN_MESSAGE_MAP(CMyDerivedPage, CMyBasePropertyPage)

 //{{AFX_MSG_MAP(CMyDerivedPage)

 ...

 ...

 //}}AFX_MSG_MAP

   ON_CONTROL_RANGE(EN_SETFOCUS, 0, 65535, OnEnSetFocus)

END_MESSAGE_MAP()



void CMyDerivedPage::OnEnSetFocus(UINT nID)

{

   switch (nID)

   {

      case IDC_CONTROL1 :

      case IDC_CONTROL2 :

      case IDC_CONTROL3 :

         m_bAutoScroll = TRUE;

         break;

      default : 

         m_bAutoScroll = FALSE;

         break;

   }

}
怪癖
唯一古怪,我还没有想出是滚动到页面底部时。如果我使用的标签滚动,相当不走所有页面底部的方式。如果我点击向下箭头滚动按钮,滚动页面剩下的路。如果你想找出为什么发生这种情况,采取一捅,有一球,但让我知道。 :)|约翰西蒙斯/取缔程序员

回答

评论会员:[消息删除] 时间:2011/11/30
rockone
评论会员:1111 时间:2011/11/30
majoob
评论会员:游客 时间:2011/11/30
嗨,约翰: 首先,感谢你为你的代码我做的一切如你所说,期望OnEnSetFocus()函数,但我看不到滚动条。你能给我一些帮助吗?谢谢advaned!仅仅是一个代码一个代码
。濒危
评论会员:游客 时间:2011/11/30
您好,我总是fdwFlags==2,是否SIP是向上或向下。我用的是EVC3.0。任何想法?不要让我的用户名欺骗了你,我是一个充满活力的美国。LRESULTCTableDlg:OnSettingChange(WPARAMWPARAM,LPARAM的lParam){#IFDEFWIN32_PLATFORM_PSPCSHSipInfo(SPI_GETSIPINFO,0,m_SIPinfo,0);(m_SIPinfo.fdwFlags==SIPF_ON){m_grid1.MoveWindow(m_rectShort);}ELSE{m_grid1.MoveWindow(m_rectFull);}#ENDIF返回1L;}
哈迪Rezaee
评论会员:游客 时间:2011/11/30
你如何从MFC的CPropertyPage派生不指定对话框资源我相信在您创建这无论是从它派生的基类,对话框种源必须手动设置。威尼斯
哈迪Rezaee
评论会员:游客 时间:2011/11/30
正确的。在派生类从基类指定对话框资源的CPropertyPage---CMyBaseClass----CMyPropertyPage(在这里获取资源枚举)-------签名开始"......在发言中淫秽惊人层做出这么多层次的艺术工作。"贾森-Jystad,2001年10月26日"你会不喜欢我,当我生气......"-博士布鲁斯班纳请仔细阅读法律声明我的生物。-------签名结束
windrzej
评论会员:游客 时间:2011/11/30
喜约翰​​imgsrc=http://www.orcode.com/upimg/2011_11_30_19_17_43_0.gif我要感谢你为这个漂亮的文章!我的生活受到攻击,我的老板会杀了我imgsrc=http://www.orcode.com/upimg/2011_11_30_19_17_43_1.gif所以,我觉得我很幸运,找到你的文章......好了,我的问题是这样的...我想我你的答案,但我只是donno如何实现它。我的意思是如何,我可以给派生类的对话框ID?请尽快答复。的问候,imgsrc=http://www.orcode.com/upimg/2011_11_30_19_17_43_2.gif哈迪
Youssif穆罕默德
评论会员:游客 时间:2011/11/30
基类中的头文件而不是把资源枚举,把它在派生类的头文件。-------SIG开始"我听说过一些司机说,"我们走得太快...'.如果你不能在这里比赛,去地狱回家-不来这里抱怨走得太快,为什么不"T你挂在你的脚踝煤油抹布,所以蚂蚁不会爬上,吃你的糖果屁股......"-山谷Earnhardt"......在发言中淫秽惊人层做出这么多层次的艺术工作。"贾森-Jystad,2001年10月26日
Youssif穆罕默德
评论会员:游客 时间:2011/11/30
为答复感谢imgsrc=http://www.orcode.com/upimg/2011_11_30_19_17_43_0.gif我只是写了一些代码来做到这一点,但每次我得到了一些错误imgsrc=http://www.orcode.com/upimg/2011_11_30_19_17_43_4.gif下面的代码:#定义CE_DLGSCROLLBAR64000/////////////////////////////////////////////////////////////////////////////{BR}//CScrollPropertyPage对话框类CScrollPropertyPage:公众的CPropertyPage{DECLARE_DYNCREATE(CScrollPropertyPage)//建筑市民:CScrollPropertyPage()〜CScrollPropertyPage()//对话框数据//{{AFX_DATA(CScrollPropertyPage)//注意-ClassWizard将添加数据成员在这里。//不编辑你看到在生成的代码,这些块!//}}AFX_DATA//重写//类向导生成虚函数覆盖//{{AFX_VIRTUAL(CScrollPropertyPage)保护:虚拟无效的DoDataExchange(CDataExchange*PDX);//DDX/DDV支持//}}AFX_VIRTUAL//执行保护://生成的消息映射功能//{{AFX_MSG(CScrollPropertyPage)虚拟布尔的OnInitDialog()AFX_MSG无效OnVScroll(UINT,UINT的非营利组织,nSBCodeCScrollBar*pScrollBar);//}}AFX_MSGAFX_MSGLRESULTOnSettingChange(WPARAMWPARAM,LPARAM的lParam)DECLARE_MESSAGE_MAP()保护:CScrollBarm_ctrlScrollBar;//我们的英雄CRECTm_DlgClientRect;//propertypage客户端矩形CRECTm_ScrollBarRect;//滚动条的矩形INTm_nScrollPos;//当前的滚动条位置INTm_nCurHeight;//滚动区域的高度BOOLm_bNeedScrollBar;//默认=FALSE-派生类//告诉这个基类//我们需要一个滚动BOOLm_bAutoScroll;//默认=FALSE-派生类//根据什么标准//可能发生的指定。无效initScrollBarSupport();//调用此派生功能//类来设置滚动条。}好吧,我不写CScrollPropertyPageimplemention,因为它喜欢你CScrollPropertyPage定义类,它是在您的文章已经在您的文章中写道的。这里是我的派生类(定义):类CMainPage:公共CScrollPropertyPage{DECLARE_DYNCREATE(CMainPage)//建筑市民:CMainPage()〜CMainPage()//对话框数据//{{AFX_DATA(CMainPage)枚举{IDD=IDD_MAIN_PROPPAGE}这里的派生类implemention:IMPLEMENT_DYNCREATE(CMainPage,CScrollPropertyPage)CMainPage:CMainPage()的CPropertyPage(CMainPage::IDD){//{{AFX_DATA_INIT(CMainPage)m_Date=_T("");{BR}m_CustomerName=_T("");{BR}m_nOrderNum=0;m_nCenterCode=0;m_nVisitorCode=0;m_CustomerNum=_T("");{BR}//}}AFX_DATA_INITCMainPage:〜CMainPage(){}当我编译的代码,编译器将得到一个错误:从构造"错误C2614:"CMainPage":非法的成员初始化:"的CPropertyPage"不是基或成员"所以,我如何可以通过对话ID来constrcuture?!imgsrc=http://www.orcode.com/upimg/2011_11_30_19_17_43_4.gif的请帮我...imgsrc=http://www.orcode.com/upimg/2011_11_30_19_17_43_6.gif
naveed
评论会员:游客 时间:2011/11/30
H//类CScrollPropPageDECLARE_DYNCREATE(CScrollPropPage)CScrollPropPage(){m_bNeedScrollBar=FALSE;m_bAutoScroll=FALSE;}CScrollPropPage(UINTnIDTemplate);CPP//类CScrollPropPageIMPLEMENT_DYNCREATE(CScrollPropPage的CPropertyPage)CScrollPropPage:CScrollPropPage(UINTnIDTemplate)的CPropertyPage(nIDTemplate){m_bNeedScrollBar=FALSE;m_bAutoScroll=FALSE;}//类CMainPageIMPLEMENT_DYNCREATE(CMainPage,CScrollPropPage)CMainPage:CMainPage():CScrollPropPage(CMainPage::IDD)