Design of ActiveX Control Using MFC-Step 2

Source: Internet
Author: User
In general, the Internal Image property page CLSID_CPicturePropPageThis article will show you how to create an image property page.

The example above is used as an example (it is basically independent from the above example and can be used as a new example, just too lazy to get it done)

1. Add the Picture attribute (get/set methods, LPPICTUREDISP type) and the member variable 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. Modify 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. Modify DoPropExchange and add "Picture" attribute persistence.
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. create a dialog box resource (OlePropertyPage type, IDD_PROPPAGE_MYPIC), add two buttons ("Browse", "clear") above, and use ClassWizard to create CMyPicPropPage (derived from COlePropertyPage ), edit the attribute page class CMyPicPropPage later.

5. create a string resource IDS_MYPIC_PPG_CAPTION ("image") and enter the following two parts as the title of the property page (change the title of the property page, you can simply change the text of the corresponding string resource)
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. Add CPictureHolder m_pic to CMyPicPropPage to save the IPictureDisp object on the property page.

7. Add the response functions of the two buttons, create an image object (IPictureDisp) in OnButtonBrowser, save it in m_pic, and delete the image object in OnButtonClear.

Void CMyPicPropPage: OnButtonBrowser ()
{
// TODO: Add your control notification handler code here
CFileDialog dlg (TRUE, "All files | *. * | ");
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 );
}
}
/* // Required # include "afxpriv2.h"
CFileDialog dlg (TRUE, "All files | *. * | ");
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. added the WM_PAINT message response function to display the selected image on the properties page.

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. It is associated with the control. When appropriate, the Picture attribute of the control is loaded to the Picture attribute of the control from m_pic to the image of the control after and when m_pic is saved:

Void CMyPicPropPage: DoDataExchange (CDataExchange * pDX)
{
// NOTE: ClassWizard will add DDP, DDX, and DDV cballs 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. I almost forgot one step. Because a property page is created instead of the default property page, I have to tell the control which two property pages you have.
// 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. You can compile and run the test.

I just learned that I can insert images. Try again.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.