Specific docking to the frame - c++

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.

Related

MFC Application don't display toolbar outside Visual Studio

I have a strange Problem with my MFC Application which i create with visual Studio 2015.
If i run the Application inside Visual Studio via Local Windows Debugger everything works as expected.
If i start the generated .exe File outside of Visual Studio the Toolbar and the Statusbar are not displayed in the Mainframe. I couldn't activate them via View Menu. So my application crashs when I use a Menu Point which writes text to the statusbar.
Did someone now whats the Problem??
Perhaps I didn't know which code i should display in the question feel free to ask for specific code sections in the comments. I will edit the question and provide the code.
This is the code in which the Tool- and Statusbar are created.
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
//TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
m_wndToolBar.LoadTCToolBar(16, IDB_TOOLICONS, IDB_TOOLICONS_HOT, IDB_TOOLICONS_DISABLED, RGB(255, 0, 255));
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));
return 0;
}
I have solved the Problem with a simple Code rearranging in the OnCreate Method.
The Method now looks like this:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
//TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
m_wndToolBar.LoadTCToolBar(16, IDB_TOOLICONS, IDB_TOOLICONS_HOT, IDB_TOOLICONS_DISABLED, RGB(255, 0, 255));
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));
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
I had to move the Lines
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
to the end of the Method. After that the Bars are displayed.

C++ win32 ListView columns

I have a problem with my code.
First,the essence of this code is to create a ListView with some columns, using win32.
The problem is when I try to add columns to my ListView and try to display it doesn't show me the columns. Here is my code, thanks for any help.
HWND function::CreateListView (HWND hwndParent)
{
INITCOMMONCONTROLSEX icex; // Structure for control initialization.
icex.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&icex);
RECT rcClient;
// The parent window's client area.
GetClientRect (hwndParent, &rcClient);
HWND hWndListView = CreateWindow(WC_LISTVIEW, "ViewList",WS_BORDER| WS_CHILD | LVS_REPORT | LVS_EDITLABELS,500,300,300,300,hwndParent,NULL,hInst,NULL);
return (hWndListView);
}
VOID function::SetView(HWND hWndListView, DWORD dwView)
{
// Retrieve the current window style.
DWORD dwStyle = GetWindowLong(hWndListView, GWL_STYLE);
// Set the window style only if the view bits changed.
if ((dwStyle & LVS_TYPEMASK) != dwView)
{
SetWindowLong(hWndListView,
GWL_STYLE,
(dwStyle & ~LVS_TYPEMASK) | dwView);
} // Logical OR'ing of dwView with the result of
}
BOOL InitListViewColumns(HWND hWndListView)
{
char szText[256] ="test"; // Temporary buffer.
LVCOLUMN lvc;
int iCol;
// Initialize the LVCOLUMN structure.
// The mask specifies that the format, width, text,
// and subitem members of the structure are valid.
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM|LVS_REPORT;
// Add the columns.
for (iCol = 0; iCol < C_COLUMNS; iCol++)
{
lvc.iSubItem = iCol;
lvc.pszText = "LOL";
lvc.cx = 100; // Width of column in pixels.
if ( iCol < 2 )
lvc.fmt = LVCFMT_LEFT; // Left-aligned column.
else
lvc.fmt = LVCFMT_RIGHT; // Right-aligned column.
// Load the names of the column headings from the string resources.
LoadString(hInst,iCol,szText, sizeof(szText)/sizeof(szText[0]));
// Insert the columns into the list view.
if (ListView_InsertColumn(hWndListView, iCol, &lvc) == -1)
return FALSE;
}
return TRUE;
}
You forgot to specify the WS_VISIBLE style when calling CreateWindow to create the listview. The listview and the columns are there, just not visible.
The buffer you pass to LoadString is never used because you never set lvc.pszText = szText so all the columns are named "LOL".
Edit: My answer applies to the code after it had been edited with fixes from the comments. LVS_REPORT is still not a valid LVCF_* flag but because it has the same value as LVCF_FMT it does no harm in this particular code but should still be removed because the code is technically incorrect.

How to change default gripper Style CToolbar?

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);
}

How can i attach userdata to each item in a listview? C++ Win32

I was thinking i could use the LVITEM structures LPARAM to attach a pointer to my class, but i can't seem to get it to work!
Heres the main parts of my code:
Creating the listview:
hlvQuiz = CreateChild(WC_LISTVIEW, "",
WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | LVS_ICON | LVS_AUTOARRANGE,
0, 0, 320, 240, m_hwnd, FontNormal);
Adding items:
if (vQuizes.size() > 0)
{
LVITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.iItem = 0;
lvi.iSubItem = 0;
lvi.cchTextMax = QUIZSTRLEN;
for (unsigned int i = 0; i < vQuizes.size(); i++)
{
lvi.lParam = (LPARAM)&vQuizes[i]; // adding pointer to lparam
lvi.pszText = vQuizes[i].szName;
ListView_InsertItem(hlvQuiz, &lvi);
}
}
Then later when i go to get my class back from the LPARAM:
LVITEM lvi;
lvi.iItem = ListView_GetNextItem(hwnd, -1, LVNI_SELECTED);
lvi.iSubItem = 0;
if (ListView_GetItem(fm->hlvQuiz, &lvi) == TRUE)
{
Quiz* q = (Quiz*)lvi.lParam;
if (q != NULL) // i get stopped here because my pointer is NULL
if (Exists(q->szPath) == IS_FILE)
ShellExecute(NULL, "edit", q->szPath, NULL, NULL, SW_SHOWNORMAL);
}
Is there anything that i'm doing wrong? the listview creates fine, and the items add, but the pointer to my class which i put in the LPARAM value seems to be ignored, or changed by the time i come to dereference it
I haven't worked at this low level before, but I suspect you need to set the mask member of the LVITEM structure to LVIF_PARAM (as well as the appropriate values for anything else you need) for the call to ListView_GetItem.
Your code works fine in Debug mode but not in Release mode because
you missed to specify the name of LPARAM in lvi.mask (and the name of any other field you want back).
Try this:
lvi.iItem = ListView_GetNextItem(hlvQuiz, -1, LVNI_SELECTED);
lvi.mask = LVIF_PARAM;
if (ListView_GetItem(fm->hlvQuiz, &lvi) == TRUE) ...
You'll receive a copy of the LPARAM's value you've setted. I think that this little strange behaviour is due to the Debug mode's help that initalize everything for you. The Release mode instead do not.

Trying to create my own Toolbar inside Mainframe class VS 6.0

I am having issues with creating my own Toolbar inside the Mainframe. I have bitmaps of buttons which I want to use for my own Toolbar but the problem is that the Toolbar displays inside the View of my SDI application. Here is a pic of the incorrectly displayed Toolbar.
http://www.flickr.com/photos/14402427#N02/3409050475/
Here is the code inside the OnCreate function of the Mainframe class : I also have a
// CToolBarCtrl m_wndToolBar; declared inside the MainFrame.h class.
if(m_wndToolBar.Create(WS_CHILD | TBSTYLE_FLAT | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC
,CRect(0,0,250,50),this,0))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
TBBUTTON tbbutton[3] = {0};
CSize button_size(90,90);
CSize bitmap_size(80,80);
//m_wndToolBar.AddStrings("String 1\0String 2\0String 3\0");
tbbutton[0].iBitmap = 0;
tbbutton[0].idCommand = ID_CONNECT;
tbbutton[0].fsState = TBSTATE_ENABLED;
tbbutton[0].fsStyle = TBSTYLE_BUTTON;
tbbutton[0].dwData = 0;
tbbutton[0].iString = 0;
tbbutton[1].iBitmap = 1;
tbbutton[1].idCommand = ID_DISCONNECT;
tbbutton[1].fsState = TBSTATE_ENABLED;
tbbutton[1].fsStyle = TBSTYLE_BUTTON;
tbbutton[1].dwData = 0;
tbbutton[1].iString = 1;
tbbutton[2].iBitmap = 2;
tbbutton[2].idCommand = ID_STOP;
tbbutton[2].fsState = TBSTATE_ENABLED;
tbbutton[2].fsStyle = TBSTYLE_BUTTON ;
tbbutton[2].dwData = 0;
tbbutton[2].iString = 2;
m_wndToolBar.SetButtonSize(button_size);
m_wndToolBar.SetBitmapSize( bitmap_size);
m_wndToolBar.AddButtons(3,tbbutton);
m_wndToolBar.AddBitmap(1,IDB_BITMAP1);
m_wndToolBar.AddBitmap(1,IDB_BITMAP2);
m_wndToolBar.AddBitmap(1,IDB_BITMAP3);
return TRUE;
Add a call to DockControlBar(&m_wndToolBar) just before the return.
From your image it seems that it is not painted or not painted correctly, did you try adding bitmaps first and then adding buttons? or can you call AutoSize on the m_wndToolbarBar.?