ActiveX控制項的MFC設計之旅-第12步

來源:互聯網
上載者:User
通常情況下,內製的圖片屬性頁面 CLSID_CPicturePropPage能夠滿足需要,但有時候,也許你想有你自己的屬性頁面來設定你的圖片(IPictureDisp)類型的屬性,本文將講述如何做一個圖片屬性頁面

以上文中的例子為例(和上面的例子基本獨立,可以用新的例子來做,只是懶得弄了)

1.添加Picture屬性(get/set methods,LPPICTUREDISP類型),新增成員變數CPictureHolder m_pic;

LPPICTUREDISP CToppCtrl::GetPicture()
{
    // TODO: Add your property handler here
    return m_pic.GetPictureDispatch();
    return NULL;
}

void CToppCtrl::SetPicture(LPPICTUREDISP newValue)
{
    // TODO: Add your property handler here
    m_pic.SetPictureDispatch(newValue);
    InvalidateControl();
    SetModifiedFlag();
}

2.修改OnDraw

void CToppCtrl::OnDraw(
            CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
    // TODO: Replace the following code with your own drawing code.
    pdc->FillRect(&rcBounds, &CBrush(TranslateColor(m_color)));
    m_pic.Render(pdc, rcBounds, rcBounds);
    int nhei = 18;
    int y = 2;
    for(int i=0; i<m_saItems.GetSize(); i++, y+=nhei){
        CRect rect(rcBounds.left + 4, y+2, rcBounds.right - 4, y + nhei);
        pdc->FillRect(&rect, &CBrush(RGB(255, 255, 255)));
        pdc->TextOut(rcBounds.left + 4, y + 2, m_saItems[i]);
    }
}

3.修改DoPropExchange,添加"Picture"屬性的持久化
void CToppCtrl::DoPropExchange(CPropExchange* pPX)
{
    ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
    COleControl::DoPropExchange(pPX);

    // TODO: Call PX_ functions for each persistent custom property.
    PX_Color(pPX, "Color", m_color, TranslateColor(RGB(0, 0, 0)));
    PX_Picture(pPX, _T("Picture"), m_pic);
    PX_Items(pPX);
}

4.建立一對話方塊資源(OlePropertyPage類型,IDD_PROPPAGE_MYPIC),在上面添加兩按鈕("瀏覽","清除"),用 ClassWizard建立CMyPicPropPage(派生自COlePropertyPage),以後就開始編輯CMyPicPropPage這個 屬性頁面類了。

5.建立字串資源IDS_MYPIC_PPG_CAPTION("圖片"),將之填入以下兩處,作為屬性頁面打進標題(更改屬性頁面的標題,就是簡單的更改相應字串資源的文字就可以了)
CMyPicPropPage::CMyPicPropPage() :
    COlePropertyPage(IDD, IDS_MYPIC_PPG_CAPTION)
{
    //{{AFX_DATA_INIT(CMyPicPropPage)
    // NOTE: ClassWizard will add member initialization here
    //    DO NOT EDIT what you see in these blocks of generated code !
    //}}AFX_DATA_INIT
}

BOOL CMyPicPropPage::CMyPicPropPageFactory::UpdateRegistry(BOOL bRegister)
{
    // TODO: Define string resource for page type; replace '0' below with ID.

    if (bRegister)
        return AfxOleRegisterPropertyPageClass(AfxGetInstanceHandle(),
            m_clsid, IDS_MYPIC_PPG_CAPTION);
    else
        return AfxOleUnregisterClass(m_clsid, NULL);
}

6.為CMyPicPropPage新增成員CPictureHolder m_pic,用來儲存屬性頁面中的圖片(IPictureDisp)對象

7.添加兩個按鈕的響應函數,在OnButtonBrowser建立圖片對象(IPictureDisp),並儲存在m_pic中,在OnButtonClear中則刪除圖片對象。

void CMyPicPropPage::OnButtonBrowser()
{
    // TODO: Add your control notification handler code here
    CFileDialog dlg(TRUE, "所有檔案|*.*||");
    if(dlg.DoModal() == IDOK){
        CFile file;
        if(file.Open(dlg.GetPathName(), CFile::typeBinary | CFile::modeRead)){
            DWORD dwlen = file.GetLength();
            HGLOBAL hMem = GlobalAlloc(GMEM_FIXED, dwlen);
            file.Read((void*)hMem, dwlen);
            file.Close();
            LPSTREAM pstream;
            CreateStreamOnHGlobal(hMem, TRUE, &pstream);
            LPPICTUREDISP ppic = NULL;
            OleLoadPicture(pstream, dwlen, TRUE, IID_IPictureDisp, (LPVOID*)&ppic);
            if(ppic){
                m_pic.SetPictureDispatch(ppic);
            }
            GlobalFree(hMem);
        }
    }
/*    //需要#include "afxpriv2.h"
    CFileDialog dlg(TRUE, "所有檔案|*.*||");
    if(dlg.DoModal() == IDOK){
        CFile file;
        if(file.Open(dlg.GetPathName(), CFile::typeBinary | CFile::modeRead)){
            DWORD dwlen = file.GetLength();
            CArchive ar(&file, CArchive::load);
            CArchiveStream stm(&ar);
            LPSTREAM pstream = (LPSTREAM)&stm;
            LPPICTUREDISP ppic = NULL;
            OleLoadPicture(pstream, dwlen, TRUE, IID_IPictureDisp, (LPVOID*)&ppic);
            if(ppic){
                m_pic.SetPictureDispatch(ppic);
            }
            ar.Close();
            file.Close();
        }
    }*/
}

void CMyPicPropPage::OnButtonClear()
{
    // TODO: Add your control notification handler code here
    m_pic.CreateEmpty();
}

8.添加WM_PAINT訊息響應函數,以在屬性頁面上顯示所選的圖片

void CMyPicPropPage::OnPaint()
{
    CPaintDC dc(this); // device context for painting
   
    // TODO: Add your message handler code here
    CRect rect;
    GetClientRect(&rect);
    rect.DeflateRect(10, 10, 200, 10);
    m_pic.Render(&dc, rect, rect);
    // Do not call COlePropertyPage::OnPaint() for painting messages
}

9.和控制項產生關聯,在適當的時候載入控制項的Picture屬性到m_pic在和儲存m_pic中的圖片到控制項的Picture屬性:

void CMyPicPropPage::DoDataExchange(CDataExchange* pDX)
{
    // NOTE: ClassWizard will add DDP, DDX, and DDV calls here
    //    DO NOT EDIT what you see in these blocks of generated code !
    //{{AFX_DATA_MAP(CMyPicPropPage)
    //}}AFX_DATA_MAP
    if(pDX->m_bSaveAndValidate){
        SetPic();
    }
    else{
        GetPic();
    }
    DDP_PostProcessing(pDX);
}

void CMyPicPropPage::SetPic()
{
    USES_CONVERSION;
    COleDispatchDriver PropDispDriver;
    ULONG nObjects = 0;
    LPDISPATCH* ppDisp = GetObjectArray(&nObjects);

    DISPID dwDispID;
    LPCOLESTR lpOleStr = T2COLE("Picture");
    ppDisp[0]->GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpOleStr, 1, 0, &dwDispID);

    PropDispDriver.AttachDispatch(ppDisp[0]);
    PropDispDriver.SetProperty(dwDispID, VT_DISPATCH, m_pic.GetPictureDispatch());
    PropDispDriver.DetachDispatch();
}

void CMyPicPropPage::GetPic()
{
    USES_CONVERSION;
    COleDispatchDriver PropDispDriver;
    ULONG nObjects = 0;
    LPDISPATCH* ppDisp = GetObjectArray(&nObjects);
    DISPID dwDispID;
    LPCOLESTR lpOleStr = T2COLE("Picture");
    ppDisp[0]->GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpOleStr, 1, 0, &dwDispID);

    LPPICTUREDISP ppic = NULL;
    PropDispDriver.AttachDispatch(ppDisp[0]);
    PropDispDriver.GetProperty(dwDispID, VT_DISPATCH, (void*)&ppic);
    PropDispDriver.DetachDispatch();
    m_pic.SetPictureDispatch(ppic);
}

10.差點忘了一步了,因為是建立了一個屬性頁面,不是用預設的屬性頁面,所以得告訴控制項,你有了哪兩個屬性頁面了。
// TODO: Add more property pages as needed.  Remember to increase the count!
BEGIN_PROPPAGEIDS(CToppCtrl, 2)
    PROPPAGEID(CToppPropPage::guid)
    PROPPAGEID(CMyPicPropPage::guid)
END_PROPPAGEIDS(CToppCtrl)

11.可以編譯運行進行測試了

剛知道可以插入圖片,試試

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.