How to change default gripper Style CToolbar? - c++

I am using MFC c++. I using CToolBar i try to changing the default Gripper Style:
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
I want to change this:
to this:
Any help?

Finally its work.
Thanks to Barmak Shemirani.
Method 1: (docking enable)
SetWindowTheme(m_wndToolBar.m_hWnd,L"",L"")
Method 2: (docking not working)
CReBarCtrl& rbc = m_wndReBar.GetReBarCtrl();
REBARBANDINFO rbbi;
rbbi.cbSize = sizeof(rbbi);
rbbi.fMask = RBBIM_STYLE;
int nCount = rbc.GetBandCount();
for (int i = 0; i < nCount; i++)
{
rbc.GetBandInfo(i, &rbbi);
rbbi.fStyle |= RBBS_NOGRIPPER;
rbbi.fStyle &= ~RBBS_GRIPPERALWAYS;
rbc.SetBandInfo(i, &rbbi);
}

Related

Problem with tooltip for two different docked panes of CMFCToolBar

I made two groups of toolbar:
`
if (!m_wndToolBar1.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | CBRS_TOOLTIPS | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar1.LoadToolBar(IDR_MAINFRAME_256)) return -1;
m_wndToolBar1.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_wndToolBar1);
`
I make it in a DockPane and another one:
`
if (!m_wndToolBar2.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar2.LoadToolBar(IDR_MAINFRAME_256_3D)) return -1;
m_wndToolBar2.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_wndToolBar2);
Put tehe MESSAGE MAP:
ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &CTunnelMainFrame::OnNeedText)
And the function:
BOOL CTunnelMainFrame::OnNeedText(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
{
UINT_PTR nId = pNMHDR->idFrom - 1;
CMFCToolBarButton* pBtnToolBar = m_wndToolBar1.GetButton(nId);
if (pBtnToolBar)
{
TCHAR szBuff[64];
::LoadString(AfxGetResourceHandle(), pBtnToolBar->m_nID, szBuff, sizeof(szBuff) / sizeof(TCHAR));
pTTT->lpszText = szBuff;
pTTT->hinst = AfxGetResourceHandle();
}
return TRUE;
}
`
So, I expect that the tooltip will appear only on m_wndToolBar1's dock pane, but in fact it also appear on m_wndToolBar2's dock pane. But with STRINGTABLE ID (string message) that belongs to m_wndToolBar1. My question is how to disable tooltip on m_wndToolBar2's dock pane? or to make other OnNeedText funtion that only wokrs on m_wndToolBar2's dock pane?
Thanks~
1)
BOOL CMainFrame::OnNeedText(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
{
CPoint point;
GetCursorPos(&point);
CRect rcToolbar1;
m_wndToolBar.GetWindowRect(&rcToolbar1);
if(rcToolbar1.PtInRect(point) == FALSE)
return TRUE;
UINT_PTR nId = pNMHDR->idFrom - 1;
NMTTDISPINFO* pTTT = (NMTTDISPINFO*)pNMHDR;
CMFCToolBarButton *pBtn1 = m_wndToolBar.GetButton(nId);
if (pBtn1)
{
TCHAR szBuff[64];
LoadString(AfxGetResourceHandle(), pBtn1->m_nID, szBuff, sizeof(szBuff) / sizeof(TCHAR));
//_stprintf(szBuff, L"Controle ID:%d", pBtn1->m_nID);
pTTT->lpszText = szBuff;
pTTT->hinst = AfxGetResourceHandle();
}
return TRUE;
}
2)don't using TTN_NEEDTEXT, using the prompt instead, Resource View->Toolbar, set the m_wndToolBar1's prompt with text and set the m_wndToolBar2's prompt with empty text

How To Add A Second Toolbar Into Mainframe?

I would like to add a second toolbar in my main frame window to sit under the existing toolbar.
Reading the following tutorials:
http://forums.codeguru.com/showthread.php?495887-Add-a-toolbar-to-an-MFC-application
http://www.codersource.net/2010/01/30/mfc-tutorial-toolbars/
MFC Toolbar on Dialog?
I have come to a similar conclusion to this unanswered thread:
https://stackoverflow.com/questions/35736580/how-to-add-a-second-toolbar-to-an-mfc-application-so-that-the-toolbar-is-added-o
This is my code:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// create a view to occupy the client area of the frame
if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
{
TRACE0("Failed to create view window\n");
return -1;
}
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
m_wndStatusBar.SetPaneInfo(EWF_PANE_INDEX, ID_SEPARATOR, SBPS_NORMAL, EWF_PANE_WIDTH);
for (int i=0;i<5; i++) {
// Change Status Bar style to make it Owner-drawn
m_wndStatusBar.GetStatusBarCtrl().SetText("", i, SBT_OWNERDRAW);
}
CToolBar myToolBar;
if (!myToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!myToolBar.LoadToolBar(IDR_MAINFRAME_B))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
return 0;
}
I have added:
CToolBar myToolBar;
if (!myToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!myToolBar.LoadToolBar(IDR_MAINFRAME_B))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
At the bottom for my second toolbar but it does not appear when the app is opened and it compiles with no errors.
In comparison to the already supplied toolbar which is called from InitInstance() by pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE , NULL, NULL);
If I call this pFrame->LoadFrame with my second toolbar in the next line the app will not load all together.
How do I need to call my second toolbar?
Have I missed something completely?
You need to add CToolBar myToolBar as a member variable of your CMainFrame class, the same way as m_wndToolBar. Otherwise, it gets destroyed if you define it as a local variable after the OnCreate exits.

Specific docking to the frame

Now my bars located on frame thanks to nDockBarID = AFX_IDW_DOCKBAR_LEFT
ForcesBar* m_forcesBar[3];
for (int i=0; i<3; i++)
{
m_forcesBar[i]->SetBarStyle(m_forcesBar[i]->GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_forcesBar[i]->EnableDocking(CBRS_ALIGN_ANY);
}
pMainFrame->EnableDocking(CBRS_ALIGN_ANY);
pMainFrame->DockControlBar(m_forcesBar[0], AFX_IDW_DOCKBAR_LEFT);
pMainFrame->DockControlBar(m_forcesBar[1], AFX_IDW_DOCKBAR_LEFT);
pMainFrame->DockControlBar(m_forcesBar[2], AFX_IDW_DOCKBAR_LEFT);
While I want to receive such bar combination:
I think that it will be good to use lpRect in
void DockControlBar(
CControlBar* pBar,
UINT nDockBarID = 0,
LPCRECT lpRect = NULL
);
but unfortunately it does not work.
Can you give code example for making such specific doking (secon picture).
(In project I use CSizingControlBar http://www.datamekanix.com/sizecbar/manual.html)
I tested it and using rectangle works fine.
One difference is that in my test app I have declared m_forcesBar in MainFrm.h as
ForcesBar m_forcesBar[3];
Avoiding allocation on the heap and remembering memory release.
The code I used (snippet from OnCreate):
EnableDocking(CBRS_ALIGN_ANY);
m_wndToolBar1.EnableDocking(CBRS_ALIGN_ANY);
m_wndToolBar2.EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar1);
DockControlBar(&m_wndToolBar2);
CRect rectWnd;
GetClientRect(rectWnd);
ClientToScreen(rectWnd);
for(int iIndx = 0; iIndx < 3; iIndx++)
{
if (!m_forcesBar[iIndx].Create(_T(""), this, 120 + iIndx))
{
TRACE0("Failed to create mybar\n");
return -1; // fail to create
}
m_forcesBar[iIndx].SetBarStyle(m_forcesBar[iIndx].GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_forcesBar[iIndx].EnableDocking(CBRS_ALIGN_LEFT);
DockControlBar(&m_forcesBar[iIndx], AFX_IDW_DOCKBAR_LEFT, rectWnd);
}
That is it.

CMFCToolbar layout not restored properly between sessions

I'm having a problem with the CMFCToolbar class where the positions of the toolbars are not being restored properly between sessions.
Here is a screen shot of how the toolbars are arranged before the app is closed:
(source: achavis.net)
Here is a screen shot of how the toolbars are restored when the app is launched again:
(source: achavis.net)
Notice the large gap that appears above the first toolbar and the second toolbar is now to the right of the main toolbar instead of beneath it.
I was having problems with my app, so I generated this test app using the App Wizard, then I added the second toolbar manually.
I would like to know if this is because there is something I am doing wrong, or if it is just due to the buggy nature of the feature pack code.
Here is the code from my CMainFrame class which sets up the toolbars:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWndEx::OnCreate(lpCreateStruct) == -1)
return -1;
BOOL bNameValid;
// set the visual manager used to draw all user interface elements
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2007));
// set the visual style to be used the by the visual manager
CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_LunaBlue);
if (!m_wndMenuBar.Create(this))
{
TRACE0("Failed to create menubar\n");
return -1; // fail to create
}
m_wndMenuBar.SetPaneStyle(m_wndMenuBar.GetPaneStyle() | CBRS_SIZE_DYNAMIC | CBRS_TOOLTIPS | CBRS_FLYBY);
// prevent the menu bar from taking the focus on activation
CMFCPopupMenu::SetForceMenuFocus(FALSE);
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(theApp.m_bHiColorIcons ? IDR_MAINFRAME_256 : IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
CString strToolBarName;
bNameValid = strToolBarName.LoadString(IDS_TOOLBAR_STANDARD);
ASSERT(bNameValid);
m_wndToolBar.SetWindowText(strToolBarName);
m_wndToolBar.EnableTextLabels();
if (!m_wndToolBar2.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar2.LoadToolBar(IDR_TOOLBAR))
{
TRACE0("Failed to create toolbar2\n");
return -1; // fail to create
}
CString strCustomize("Toolbar2");
m_wndToolBar2.EnableCustomizeButton(TRUE, ID_VIEW_CUSTOMIZE, strCustomize);
// Allow user-defined toolbars operations:
InitUserToolbars(NULL, uiFirstUserToolBarId, uiLastUserToolBarId);
if (!m_wndStatusBar.Create(this))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
// TODO: Delete these five lines if you don't want the toolbar and menubar to be dockable
m_wndMenuBar.EnableDocking(CBRS_ALIGN_ANY);
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
m_wndToolBar2.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_wndMenuBar);
DockPane(&m_wndToolBar);
DockPane(&m_wndToolBar2);
// enable Visual Studio 2005 style docking window behavior
CDockingManager::SetDockingMode(DT_SMART);
// enable Visual Studio 2005 style docking window auto-hide behavior
EnableAutoHidePanes(CBRS_ALIGN_ANY);
// Load menu item image (not placed on any standard toolbars):
CMFCToolBar::AddToolBarForImageCollection(IDR_MENU_IMAGES, theApp.m_bHiColorIcons ? IDB_MENU_IMAGES_24 : 0);
// create docking windows
if (!CreateDockingWindows())
{
TRACE0("Failed to create docking windows\n");
return -1;
}
m_wndFileView.EnableDocking(CBRS_ALIGN_ANY);
m_wndClassView.EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_wndFileView);
CDockablePane* pTabbedBar = NULL;
m_wndClassView.AttachToTabWnd(&m_wndFileView, DM_SHOW, TRUE, &pTabbedBar);
m_wndOutput.EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_wndOutput);
// Enable toolbar and docking window menu replacement
EnablePaneMenu(TRUE, ID_VIEW_CUSTOMIZE, strCustomize, ID_VIEW_TOOLBAR);
// enable quick (Alt+drag) toolbar customization
CMFCToolBar::EnableQuickCustomization();
if (CMFCToolBar::GetUserImages() == NULL)
{
// load user-defined toolbar images
if (m_UserImages.Load(_T(".\\UserImages.bmp")))
{
m_UserImages.SetImageSize(CSize(16, 16), FALSE);
CMFCToolBar::SetUserImages(&m_UserImages);
}
}
// enable menu personalization (most-recently used commands)
// TODO: define your own basic commands, ensuring that each pulldown menu has at least one basic command.
CList<UINT, UINT> lstBasicCommands;
lstBasicCommands.AddTail(ID_FILE_NEW);
lstBasicCommands.AddTail(ID_FILE_OPEN);
lstBasicCommands.AddTail(ID_FILE_SAVE);
lstBasicCommands.AddTail(ID_FILE_PRINT);
lstBasicCommands.AddTail(ID_APP_EXIT);
lstBasicCommands.AddTail(ID_EDIT_CUT);
lstBasicCommands.AddTail(ID_EDIT_PASTE);
lstBasicCommands.AddTail(ID_EDIT_UNDO);
lstBasicCommands.AddTail(ID_APP_ABOUT);
lstBasicCommands.AddTail(ID_VIEW_STATUS_BAR);
lstBasicCommands.AddTail(ID_VIEW_TOOLBAR);
lstBasicCommands.AddTail(ID_SORTING_SORTALPHABETIC);
lstBasicCommands.AddTail(ID_SORTING_SORTBYTYPE);
lstBasicCommands.AddTail(ID_SORTING_SORTBYACCESS);
lstBasicCommands.AddTail(ID_SORTING_GROUPBYTYPE);
CMFCToolBar::SetBasicCommands(lstBasicCommands);
return 0;
}
This problem was resolved by creating the toolbars with explicit IDs as opposed to relying on the default parameter as in the above code.
Because the registry key that the toolbar's state is saved to is based on the ID, the second toolbar was saving its state on top of the first toolbar.
Here are the code changes that resolved the problem:
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC, CRect(1,1,1,1), IDR_MAINFRAME) ||
!m_wndToolBar.LoadToolBar(theApp.m_bHiColorIcons ? IDR_MAINFRAME_256 : IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
...
if (!m_wndToolBar2.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC, CRect(1,1,1,1), IDR_TOOLBAR) ||
!m_wndToolBar2.LoadToolBar(IDR_TOOLBAR))
{
TRACE0("Failed to create toolbar2\n");
return -1; // fail to create
}

How to modify the tool rect of a CToolTipCtrl?

This question is related to this one.
In a CDockablePane derived class I have a CTreeCtrl member for which I add a ToolTip in OnCreate():
int CMyPane::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDockablePane::OnCreate(lpCreateStruct) == -1)
return -1;
const DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
TVS_CHECKBOXES | TVS_DISABLEDRAGDROP | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT |
TVS_INFOTIP | TVS_NOHSCROLL | TVS_SHOWSELALWAYS;
if(!m_tree.Create(dwStyle, m_treeRect, this, TREECTRL_ID) ) { return -1; }
m_pToolTip->AddTool(&m_tree, LPSTR_TEXTCALLBACK, &m_treeRect, TREECTRL_ID);
m_tree.SetToolTips(m_pToolTip);
return 0;
}
I have to call AddTool() with all of the optional parameters because the default values won't work with CDockablePane.
m_treeRect is a CRect member set to (0, 0, 10000, 10000) in the CTor. This is really ugly.
I would like to adjust the tool's rectangle whenever m_tree's size changes.
So I tried some stuff in CMyPane::OnSize() but none of it worked:
Calling m_pToolTip->GetToolInfo() then modify the CToolInfo's rect member, then calling SetToolInfo()
Calling m_pToolTip->SetToolRect()
How is it meant to be done?
I know no other way to do this other than calling DelTool then AddTool again in your OnSize handler:
void CMyPane::OnSize(UINT nType, int cx, int cy)
{
CDockablePane::OnSize(nType, cx, cy);
if (m_pToolTip != NULL)
{
m_pToolTip->DelTool(&m_tree, TREECTRL_ID);
CRect treeRect;
m_tree.GetClientRect(treeRect);
m_pToolTip->AddTool(&m_tree, LPSTR_TEXTCALLBACK, &treeRect, TREECTRL_ID);
}
}
int CMyPane::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDockablePane::OnCreate(lpCreateStruct) == -1)
return -1;
const DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
TVS_CHECKBOXES | TVS_DISABLEDRAGDROP | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT |
TVS_INFOTIP | TVS_NOHSCROLL | TVS_SHOWSELALWAYS;
if(!m_tree.Create(dwStyle, m_treeRect, this, TREECTRL_ID) ) { return -1; }
m_pToolTip->AddTool(&m_tree, LPSTR_TEXTCALLBACK, &m_treeRect, TREECTRL_ID);
m_tree.SetToolTips(m_pToolTip);
return 0;
}