Home Up


Visual Studio 2008


MFC Feature Pack

Only online help is available... 
License:    You are supposed to get a free license from M$ to use this in your applications...  This makes it so that you can't create anything that competes with Office Apps.
CMFCRibbonPanel  (This is the main thing I'm interested in).  This gives your app the Ribbon bar interface like Office 2007 apps have.
Get the framework for this going using the AppWizard when creating your project and enable the ribbon.
You need to create a bitmap that has all your buttons on it.  I did this by creating a "dummy" toolbar and then copying the bitmap that this makes in the "..\res" directory. 
In order to automatically create event handlers for buttons, create a "dummy" menu with all the commands you added to the Ribbon.
There's a scribble example around that shows you how to use this.  
In order to create a custom image when the category gets collapsed or added to quick launch, add a new CMFCToolBarImages variable to "MainFrm.h" (e.g. CMFCToolBarImages m_PanelImages_Schematic;) and load it with a toolbar image, like done for the regular buttons.  But, then make the image 16 pixels tall.
Here's how I created a new ribbon category (like the "home" category) (tooltips are nice in case the ribbonbar is too big for the window and gets collapsed):


//adding new CASTLE catagories

// Add "Schematic" category with parts and drawing panels:

//NOTE: Resource Toolbar1 is used as a crutch to create the bitmap required for the ribbon bar

// The bitmap "toolbar1.bmp" generated is manually copied to "Schematic.bmp" for use...

// Same bitmap coped to "bitmap1.bmp" under resource "IDB_Ribbon_Schematic_Catagories" for Quick Access Toolbar

// Load panel images:

m_PanelImages_Schematic.SetImageSize(CSize(16, 16));


CMFCRibbonCategory* pCategorySchematic = m_wndRibbonBar.AddCategory(L"Schematic", IDB_Ribbon_Schematic, NULL);

// Create "Tools" panel:

CMFCRibbonPanel* pPanelTools = pCategorySchematic->AddPanel(L"Tools", m_PanelImages_Schematic.ExtractIcon(7));    //picking icon#7 to represent this group on quick launch...

pPanelTools->Add(new CMFCRibbonButton(ID_Parts_Select, L"Select Tool", 7));

pPanelTools->Add(new CMFCRibbonButton(ID_Parts_Wire, L"Wire Tool", 9));

pPanelTools->Add(new CMFCRibbonButton(ID_Parts_Text, L"Text Tool", 8));

pPanelTools->Add(new CMFCRibbonButton(ID_Parts_Bubble, L"Bubble Connector", 15));

pPanelTools->Add(new CMFCRibbonButton(ID_Parts_Subcircuit, L"Subcircuit", 16));

(pPanelTools->GetElement(0))->SetToolTipText(L"Select Parts Tool"); 

(pPanelTools->GetElement(1))->SetToolTipText(L"Add Wire Tool");

(pPanelTools->GetElement(2))->SetToolTipText(L"Add Text Tool");

(pPanelTools->GetElement(3))->SetToolTipText(L"Add Bubble Connector");

(pPanelTools->GetElement(4))->SetToolTipText(L"Add Subcircuit");




bulletClip Region: 
bulletUse pDC->IntersectClipRect to restrict output to a rectangle by modifying the clip region.  Use pDC->SaveDC() beforehand to save the current clip region and then RestoreDC(-1) after drawing to restore the previous clip region.


bulletAccess MainFrm objects (such as toolbar mentioned below)
bulletuse ((CMainFrame*) AfxGetMainWnd())-> and include "MainFrm.h"
bulletPlace controls on Toolbars
bulletFollow advice at CodeGuru Note that you must replace "IDC_SNAP_COMBO" with your own toolbars ID
bulletClose the default "blank" document:
bulletJust #include "CloseUnusedDocs.h" and add one line of code to OnOpenDocument
bulletThis is harder that it seems to implement!  Fortunately, there is a simple method using a helper class in "undo.h" .  Uses a trick called "Multiple Inheritance".


bulletOnKeyUp/Down: Get state of shift/alt/control keys
bulletI'm upset that the "nFlags" variable is useless...
bulletThis line returns the state of the shift key:
bulletbool bShift = GetKeyState (VK_SHIFT) < 0;
bulletadd #include "memdc.h".  Then, just one line of code in OnDraw makes it work, e.g., CMemDC pdc(pDC);.  Then, just use pdc instead of pDC.


bulletSerialize only works for arrays of usual types.  The actual code for serializing is in the template function "SerializeElements".  To serialize an array of custom types, you need to override the SerializeElements function in the ".cpp" file of the class that declares the array.  Here's an example from a "...doc.cpp" file:
template <> void AFXAPI SerializeElements <CPerson> ( CArchive& ar, CPerson* pNewPersons, int nCount ) { for ( int i = 0; i < nCount; i++, pNewPersons++ ) { // Serialize each CPerson object pNewPersons->Serialize( ar ); } }
bullet<arg1,arg2>:  Arg1 is the actual type of object to be stored.  Arg2 is the argument to be used in some member functions (such as Add()).  For simply types just make arg1=arg2, e.g., CArray<double,double>.  For arrays of objects, make arg2 a reference to arg1, e.g., CArray<CPerson, CPerson&>.  If you want an array of pointers to objects, use CTypedPtrArray instead.
bulletNote that the data is stored in one contiguous place, just like a normal C array.  If you want to pass a CArray off as a normal C array, use the GetData() function, e.g., m_Data.GetData() where m_Data is CArray<double,double> in place of a double *.