
CommandBands are those neat little draggable strips that appear at the top of most CE based applications. They have been around since at least CE 2.00, and do give an application a much more professional appearance than the "standard" fixed toolbar that is available in AppWiz.
CommandBands are containers for other controls. Most commonly CommandBands. Each of these bands is a container for menus, buttons and other controls.
The sample code provided here will work with CE 2.0 and greater.
There are a few examples of generating CommandBands on the Net, but most are not designed for MFC applications, and there are a few "gotchas" to be aware of when using commandbands in a MFC app.
If we change CMainFrame
's OnCreate
, we can get CommandBands working.
eg.
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
HWND b=NULL;
HWND hBar=NULL;
#if defined(_WIN32_WCE) && (_WIN32_WCE < 201)
hBar = this->m_poCommandBar->m_hCommandBar;
if (hBar !=NULL)
{
::DestroyWindow(hBar);
delete this->m_poCommandBar;
this->m_poCommandBar = NULL;
}
#endif
HINSTANCE hInst = AfxGetInstanceHandle();
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(icex);
icex.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES;
InitCommonControlsEx(&icex);
HIMAGELIST himl=NULL;
HBITMAP hbmp;
himl = ImageList_Create(16, 16, ILC_COLOR, 1, 0);
hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BANDIMAGES));
ImageList_Add(himl, hbmp, 0);
DeleteObject(hbmp);
b = (HWND)::CommandBands_Create(hInst, this->m_hWnd, ID_BANDS,
RBS_BANDBORDERS|RBS_VARHEIGHT,himl);
if (b==NULL) return -1;
theApp.m_hRebars= b;
REBARBANDINFO rbi[3];
memset(&rbi,0,sizeof(REBARBANDINFO));
rbi[0].cbSize = sizeof(REBARBANDINFO);
rbi[0].fMask = RBBIM_STYLE|RBBIM_ID|RBBIM_SIZE;
rbi[0].fStyle = RBBS_NOGRIPPER;
rbi[0].wID = ID_MENUBAND;
rbi[0].cx = 120;
rbi[1].cbSize = sizeof(REBARBANDINFO);
rbi[1].fMask = RBBIM_STYLE|RBBIM_ID|RBBIM_SIZE |RBBIM_IMAGE;
rbi[1].fStyle = RBBS_GRIPPERALWAYS;
#if defined(_WIN32_WCE_PSPC)
rbi[1].fStyle = rbi[1].fStyle | RBBS_BREAK;
#endif
rbi[1].wID = ID_BAND1;
rbi[1].cx = 155;
rbi[1].iImage=0;
rbi[2].cbSize = sizeof(REBARBANDINFO);
rbi[2].fMask = RBBIM_STYLE|RBBIM_ID|RBBIM_SIZE |RBBIM_IMAGE;
rbi[2].fStyle = RBBS_GRIPPERALWAYS;
#if defined(_WIN32_WCE_PSPC)
rbi[2].fStyle = rbi[2].fStyle | RBBS_BREAK;
#endif
rbi[2].wID = ID_BAND2;
rbi[2].iImage=1;
if(!::CommandBands_AddBands(b, hInst, 3, rbi))
return -1;
hBar = ::CommandBands_GetCommandBar(b,0);
ASSERT(hBar != NULL);
::CommandBar_InsertMenubar(hBar, hInst, IDR_MAINFRAME, 0);
hBar = ::CommandBands_GetCommandBar(b,1);
ASSERT(hBar != NULL);
::CommandBar_AddBitmap(hBar, hInst, IDB_BAND1,
sizeof(Bar1)/sizeof(TBBUTTON), 0, 0);
#if (_WIN32_WCE < 201)
CommandBar_AddButtons(hBar, sizeof(Bar1)/sizeof(TBBUTTON), &Bar1);
#else
::CommandBar_AddButtons(hBar, sizeof(Bar1)/sizeof(TBBUTTON), &Bar1);
#endif
hBar = ::CommandBands_GetCommandBar(b,2);
ASSERT(hBar != NULL);
::CommandBar_AddBitmap(hBar, hInst, IDB_BAND2,
sizeof(Bar2)/sizeof(TBBUTTON), 0, 0);
#if (_WIN32_WCE < 201)
CommandBar_AddButtons(hBar, sizeof(Bar2)/sizeof(TBBUTTON), &Bar2);
#else
::CommandBar_AddButtons(hBar, sizeof(Bar2)/sizeof(TBBUTTON), &Bar2);
#endif
#if !defined(_WIN32_WCE_PSPC)
CommandBands_AddAdornments(b, hInst, 0, NULL);
#endif
return 0;
}
We will also have to handle resizing of the View, as CMainFrame does not handle it any more. Simply put the following code in the CMainFrame's OnNotify method.
BOOL CMainFrame::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
if (wParam == ID_BANDS)
{
ResizeView();
return (TRUE);
}
return CFrameWnd::OnNotify(wParam, lParam, pResult);
}
void CMainFrame::ResizeView()
{
HWND rebars = theApp.m_hRebars;
if (rebars==NULL) return;
CView* pWnd = (CView*)GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);
ASSERT (pWnd != NULL && pWnd->IsKindOf(RUNTIME_CLASS(CView)));
CRect rect;
GetClientRect(&rect);
int nHeight =(UINT)::SendMessage(rebars, RB_GETBARHEIGHT, 0, 0);
pWnd->MoveWindow(0,nHeight,rect.Width(),rect.Height()-nHeight,TRUE);
}
One last thing to do, we need to make a change to your CMyApp::InitInitialise method.
Just before the final line where its says
return TRUE;
Insert the following line
((CMainFrame*)AfxGetMainWnd())->ResizeView();
This forces the view to resize properly, so that the view sits in its correct position with respect to CommandBands.
Thats it.. You now have a MFC-CE based application with Commandbands in it.
Special thanks goes to Mario Arruda and Brian Weeres for spotting a bug in the previous version.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.