• CPropertySheet属性页的一些使用方法 .


    CPropertySheet 继承一个新类 CMyPropSheet.
    接着便可以进行下面的各种操作:
     隐藏属性页默认按钮
    隐藏掉Apply应用按钮:
    propsheet.m_psh.dwFlags |= PSH_NOAPPLYNOW;
    或隐藏掉Cancel取消按钮:
    CWnd *pWnd = GetDlgItem( IDCANCEL );
    pWnd->ShowWindow( FALSE );
     
    移动属性页按钮
    首先,要获取按钮的句柄,然后就可以象对待窗体一样处理它们了. 下面代码先隐藏掉Apply和Help铵钮,再把OK和Cancel按移动到右侧。
    BOOL CMyPropSheet::OnInitDialog ()
    {
        BOOL bResult = CPropertySheet::OnInitDialog();
     
        int ids [] = {IDOK, IDCANCEL};//, ID_APPLY_NOW, IDHELP };
       
        // Hide Apply and Help buttons
        CWnd *pWnd = GetDlgItem (ID_APPLY_NOW);
        pWnd->ShowWindow (FALSE);
        pWnd = GetDlgItem (IDHELP);
        pWnd->ShowWindow (FALSE);
       
        CRect rectBtn;
        int nSpacing = 6;        // space between two buttons...
     
        for( int i =0; i < sizeof(ids)/sizeof(int); i++)
        {
            GetDlgItem (ids [i])->GetWindowRect (rectBtn);
           
            ScreenToClient (&rectBtn);
            int btnWidth = rectBtn.Width();
            rectBtn.left = rectBtn.left + (btnWidth + nSpacing)* 2;
            rectBtn.right = rectBtn.right + (btnWidth + nSpacing)* 2;
     
            GetDlgItem (ids [i])->MoveWindow(rectBtn);
        }
     
       
        return bResult;
    }
    下面代码移动所有按钮到右侧,并且重新置属性页为合适的大小.
    BOOL CMyPropSheet::OnInitDialog ()
    {
        BOOL bResult = CPropertySheet::OnInitDialog();
     
       
        int ids[] = { IDOK, IDCANCEL, ID_APPLY_NOW };
       
        CRect rectWnd;
        CRect rectBtn;
       
        GetWindowRect (rectWnd);
        GetDlgItem (IDOK)->GetWindowRect (rectBtn);
       
        int btnWidth = rectBtn.Width();
        int btnHeight = rectBtn.Height();
        int btnOffset = rectWnd.bottom - rectBtn.bottom;
        int btnLeft = rectWnd.right - rectWnd.left;
     
        rectWnd.bottom = rectBtn.top;
        rectWnd.right = rectWnd.right + btnWidth + btnOffset;
        MoveWindow(rectWnd);
       
        rectBtn.left = btnLeft;
        rectBtn.right = btnLeft + btnWidth;
     
        for (int i = 0; i < sizeof (ids) / sizeof (int); i++)
        {
            rectBtn.top = (i + 1) * btnOffset + btnHeight * i;
            rectBtn.bottom = rectBtn.top + btnHeight;
            GetDlgItem (ids [i])->MoveWindow (rectBtn);
        }
       
        return bResult;
    }
     改变属性页上的标签文字
    首先修改TC_ITEM结构,然后用 SetItem 来修改标签文字,如下代码:
    TC_ITEM item;
    item.mask = TCIF_TEXT;
    item.pszText = "New Label";
     
    //Change the label of the first tab (0 is the index of the first tab)...
    GetTabControl ()->SetItem (0, &item);
     改变属性页标签文字的字体属性
    如下代码:
        m_NewFont.CreateFont (14, 0, 0, 0, 800, TRUE, 0, 0, 1, 0, 0, 0, 0, _T("Arial") );
        GetTabControl()->SetFont (&m_NewFont);
     在属性页标签上显示位图
    可以用 CImageList 建立图像. 用 SetItem 来设置,如下代码所示:
    BOOL CMyPropSheet::OnInitDialog ()
    {
        BOOL bResult = CPropertySheet::OnInitDialog();
     
        m_imageList.Create (IDB_MYIMAGES, 13, 1, RGB(255,255,255));
        CTabCtrl *pTabCtrl = GetTabControl ();
        pTabCtrl->SetImageList (&m_imageList);
       
        TC_ITEM item;
        item.mask = TCIF_IMAGE;
        for (int i = 0; i < NUMBER_OF_TABS; i++)
        {
            item.iImage = i;
            pTabCtrl->SetItem (i, &item );
        }
     
        return bResult;
    }
    在属性页左下角显示位图
    如下代码所示:
    void CMyPropSheet::OnPaint ()
    {
        CPaintDC dc(this); // device context for painting
       
        int nOffset = 6;
        // load IDB_BITMAP1 from our resources
        CBitmap bmp;
        if (bmp.LoadBitmap (IDB_BITMAP1))
        {
            // Get the size of the bitmap
            BITMAP bmpInfo;
            bmp.GetBitmap (&bmpInfo);
           
            // Create an in-memory DC compatible with the
            // display DC we're using to paint
            CDC dcMemory;
            dcMemory.CreateCompatibleDC (&dc);
           
            // Select the bitmap into the in-memory DC
            CBitmap* pOldBitmap = dcMemory.SelectObject (&bmp);
           
            // Find a bottom-left point for the bitmap in the client area
            CRect rect;
            GetClientRect (&rect);
            int nX = rect.left + nOffset;
            int nY = rect.top + (rect.Height () - bmpInfo.bmHeight) - nOffset;
           
            // Copy the bits from the in-memory DC into the on-
            // screen DC to actually do the painting. Use the centerpoint
            // we computed for the target offset.
            dc.BitBlt (nX, nY, bmpInfo.bmWidth, bmpInfo.bmHeight, &dcMemory,
                0, 0, SRCCOPY);
           
            dcMemory.SelectObject (pOldBitmap);
        }
     
        // Do not call CPropertySheet::OnPaint() for painting messages
    }
    在属性页右下角显示3D文字Logo
    如下代码:
    void CMyPropSheet::OnPaint ()
    {
        /////////////////////////////////////////////////////////////////////////
     //在TAB按钮旁边显示3D文字提示,jingzhou xu
     Cstring m_LogoName = “属性页”;
    // if(m_LogoName == "")
    //  return;
     
     GetWindowRect(rect);
     ScreenToClient(rect);
     
     LOGFONT logFont;
     ZeroMemory((void*)&logFont,sizeof(logFont));
     strcpy(logFont.lfFaceName,"宋体");
     logFont.lfHeight = -12;
     logFont.lfWeight = 400;
     logFont.lfCharSet = GB2312_CHARSET;
     logFont.lfOutPrecision = 3;
     logFont.lfClipPrecision = 2;
     logFont.lfQuality = 1;
     logFont.lfPitchAndFamily = 2;
     m_font.CreateFontIndirect(&logFont);
     SetFont(&m_font);
     CFont *pOldFont = pDC->SelectObject(&m_font);
     
      rect.left += 6;
      rect.right -= 6;
      rect.bottom -= 1;
      rect.top = rect.bottom - ITEMBUTTON_HEIGHT + 1;
     
     
     CFont m_LogoFont;
     CString sLogoString;
      
     m_LogoFont.CreateFont(rect.Height()*4/5, 0, 0, 0, FW_BOLD, 1, FALSE, FALSE,
       DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
       FIXED_PITCH | FF_ROMAN, "楷体_GB2312");
      
     sLogoString = m_LogoName;
      
     RECT m_rDataBox;
     CopyRect(&m_rDataBox,&rect);
      
     TEXTMETRIC tm;
     pDC->GetTextMetrics(&tm);
     CFont* oldFont = pDC->SelectObject(&m_LogoFont);
     CSize sz = pDC->GetTextExtent(sLogoString, sLogoString.GetLength());
     //用GetTextExtent来计算字体logo大小,依靠于设备环境,使用logo位于右下角
     m_rDataBox.left = m_rDataBox.right  - sz.cx - tm.tmAveCharWidth/2;
     m_rDataBox.top  = m_rDataBox.bottom - sz.cy - tm.tmHeight/5;
     pDC->SetBkMode(TRANSPARENT);
     //用3D字体显示,先黑后白,最后再用默认色
     COLORREF oldColor = pDC->SetTextColor(GetSysColor(COLOR_3DDKSHADOW));
     pDC->DrawText(sLogoString, sLogoString.GetLength(), &m_rDataBox, DT_VCENTER | DT_SINGLELINE | DT_CENTER);
     m_rDataBox.left -= tm.tmAveCharWidth;
     pDC->SetTextColor(GetSysColor(COLOR_3DHILIGHT));
     pDC->DrawText(sLogoString, sLogoString.GetLength(), &m_rDataBox, DT_VCENTER | DT_SINGLELINE | DT_CENTER);
     m_rDataBox.left += 3*tm.tmAveCharWidth/5;
     pDC->SetTextColor(RGB(0,0,255));
     pDC->DrawText(sLogoString, sLogoString.GetLength(), &m_rDataBox, DT_VCENTER | DT_SINGLELINE | DT_CENTER);
      
     //释放资源
     pDC->SelectObject(oldFont);
     pDC->SetTextColor(oldColor);  
     m_LogoFont.DeleteObject();
     /////////////////////////////////////////////////////////////////////////
    }
     
    在属性页中动态加入其它控件
    下面演示如何在左下角加入一Edit控件:
    In MyPropSheet.h:
    public:
        CEdit m_edit;
    In MyPropSheet.cpp:
    BOOL CMyPropSheet::OnInitDialog ()
    {
        BOOL bResult = CPropertySheet::OnInitDialog ();
     
       
        CRect rect;
       
        int nHeight = 24;
        int nWidth = 120;
        int nOffset = 6;
       
        GetClientRect (&rect);
     
        // Find a bottom-left point for the edit control in the client area
        int nX = rect.left + nOffset;
        int nY = rect.top + (rect.Height() - nHeight) - nOffset;
       
        // finally create the edit control
        m_Edit.CreateEx (WS_EX_CLIENTEDGE, _T("EDIT"), NULL,
                         WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER,
            nX, nY, nWidth, nHeight, m_hWnd, 0, 0 );
     
        return bResult;
    }


    属性页的一些使用技巧
    加入项目

    举例如下:

    1.在项目中加入MFC类CMyMainSheet,选择CPropertySheet作为其基类。

    2.在项目中加入MFC类CMyPage1,CMyPage2,选择CPropertyPage作为基类,它们将作为属性对话框中的属性页。

    弹出属性对话框


    实现:

    void PopupPropertyDlg()

           // 创建PropertySheet和PropertyPage

           CMyMainSheet mms(_T("MainSheet"), this);

           CMyPage1 mp1;

           CMyPage2 mp2;

           // 如果想要去掉“应用”和“帮助”按钮

           mms.m_psh.dwFlags |= PSH_NOAPPLYNOW;

           mms.m_psh.dwFlags &= ~PSH_HASHELP;

           mp1.m_psp.dwFlags &= ~PSP_HASHELP;

           mp2.m_psp.dwFlags &= ~PSP_HASHELP;

           // 设置各个属性页中元素的初值

           mp1.m_xxxx = ;

           mp2.m_xxxx = ;

           // 弹出对话框

           mms.AddPage(&mp1);

           mms.AddPage(&mp2);

           if(mms.DoModal() == IDOK)

           // 如果确定了,采取的操作

           // 注意,当执行到上面的代码时,UpdateData(True)已经被自动执行


    PropertySheet中各种元素之间的交互

    在复杂的对话框中,常常有这样的情况发生:当修改某一个PropertyPage中的控件时,该元素的值会影响属性页中其他控件,甚至是其他属性页中的控件的属性。如果通过直接发消息等方法来处理,这样的处理逻辑会遍布各个属性页,降低代码的可读和可修改性。我们采用PropertySheet作为中介者,这样的消息全部发送给PropertySheet,然后由它对涉及的PropertyPage中的控件进行处理。

    比如,在mp1控件的Edit中是否填入值要影响mp2中Edit控件的Enable/Disable,我们可以这样做:

    CMyPage1中加入消息响应函数,用于接收Edit控件的修改事件

    OnEnChangeEdit()

    调用PropertySheet的处理函数,而不是自己来处理

           CMyMainSheet* pmms = NULL;

           pmms = (CMyMainSheet*)GetParent();

           pmms->EnableSwitch();

    CMyMainSheet中加入处理函数 

    EnableSwitch

    判断mp1中控件的值,来确定mp2中控件的Enable/Disable

           CString str1;

           GetPage(0)->GetDlgItemText(IDC_EDIT1, str1);

           if(_T("") == str1)

                  GetPage(1)->GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE);

           else

                  GetPage(1)->GetDlgItem(IDC_EDIT1)->EnableWindow(TRUE);

  • 相关阅读:
    How far away(DFS+vector存图)
    A Simple Math Problem (矩阵快速幂)
    A Simple Math Problem (矩阵快速幂)
    1060 爱丁顿数 (25 分)(思维)
    1060 爱丁顿数 (25 分)(思维)
    Codeforces Round #527-D1. Great Vova Wall (Version 1)(思维+栈)
    Codeforces Round #527-D1. Great Vova Wall (Version 1)(思维+栈)
    Codeforces Round #527-B. Teams Forming(贪心)
    Codeforces Round #527-B. Teams Forming(贪心)
    Codeforces Round #527 -A. Uniform String(思维)
  • 原文地址:https://www.cnblogs.com/yangxx-1990/p/5051551.html
Copyright © 2020-2023  润新知