Using CMFCToolBarImages in CMFCTaskPane - mfc

In my MFC MDI application I have 10 CMFCToolBar and each has separate imagelist(bitmap images).
I implemented task pane using CMFCTaskPane in which I am grouping same tasks or activities what the CMFCToolbar is doing.
Can I use/assign each CMFCToolbar image list to the tasks coming under each group?
In CMFCTaskPane class I only have these methods:
BOOL SetIconList(HIMAGELIST hIcons)
BOOL SetIconsList(UINT uiImageListResID, int cx, COLORREF clrTransparent = RGB(255, 0, 255))
In CMFCTaskPane class we have an option to assign only one image list to the entire taskpane. There is no option to assign separate imagelist to each group and its tasks.
But I have 10 CMFCToolbar and 10 CImageList. How to use my toolbar images to achieve my requirement?
In this link https://www.codeproject.com/Articles/16529/Simple-Menus-That-Display-Icons-Minimalistic-Appro?msg=1895336
the toolbar images are used in the menu by overriding DrawItem() function similarly can we draw icon for a task by overriding the function
virtual void OnDrawTasks(CDC* pDC, CRect rectWorkArea); in the CMFCTaskPane.
I dont have any idea on how to do it?

When you call LoadToolbar, you create local instance of imagelist for this toolbar.
By default, all toolbars in application shares same imagelist. So, just make something like this:
CMFCToolbar m_toolbar;
...
m_toolbar.Create(this, AFX_DEFAULT_TOOLBAR_STYLE;);
int newIconID = CMFCToolBar::GetImages()->AddIcon(hIcon, TRUE);
m_toolbar.InsertButton(cmd, newIconID, name);

Related

How to Make a Simple GUI with DropDown Menus with C++

I am really struggling how to make a window with three selections of options. I currently have a setup that uses a CFileDialog object and have successfully implemented two dropdown menus and multiple check items.
What I want is to implement a pop up window that has the two drop down menus and the check boxes. If a certain item is selected in one of the dropdown menus then the file dialog is opened.
Currently I am trying to make a CWnd object and try to write code for it there.
CWnd myWindow;
BOOL VALUE = myWindow.Create(_T("DesktopApp"), _T("test"), WS_VISIBLE | WS_BORDER | WS_CAPTION,
RECT{ 100,100,400,400 },
myWindow.GetDesktopWindow(), 12);
myWindow.ShowWindow(SW_SHOWNORMAL);
if (VALUE == FALSE) {
return 0;
}
Every time I run this, it prematurely returns (VALUE == FALSE). Did I do something wrong? Is there a simpler way to create a window?
The first argument to CWnd::Create is the window class name. A class with the requested name must have been registered before it can be created.
It is common to register an application local class for the application's main window. MFC provides a convenient wrapper function (AfxRegisterWndClass) to register a window class.

MFC:Is it possible to customize the CFontDialog box without creating any child class

I am working on a project where I need to create a font dialog box on a button click.
I used below code:
CFontDialog dlg;
if (dlg.DoModal() == IDOK)
{
m_Font = dlg.GetFont();
}
But here problem is..by default it contains various settings like font family, size, style, color and preview. But here I need only Fontfamily and size and preview settings only.
Is there any alternate to create font dialog box only with "font family, size and preview) without creating any child class.
Modify the m_cf.flags member in the dlg object, like CF_EFFECTS etc.
See documentation and change the flags accordingly

Float (or detach) the tabbed CMDIChildWndEx window from CMDIFrameWndEx,any idea?

In visual studio,all opened editor windows are tabbed in the workspace.when you right click one,there is a "float" option in the menu.if you float a window,the window is detached from the tab and you can drag it anywhere and after all you can dock it back to the tab.
i created a test mdi project,it's not a default behavior.
i overrided the ID_FILE_NEW command and followed the OpenDocumentFile routine,never found out where the framework add the newly created child frame window to the tab.
in the OpenDocumentFile routine,i bumped into a CMFCTabCtrl class and there is a AddTab function.
now the AddTab function:
virtual void AddTab(
CWnd* pTabWnd,
LPCTSTR lpszTabLabel,
UINT uiImageId = (UINT)-1,,
BOOL bDetachable = TRUE
);
virtual void AddTab(
CWnd* pTabWnd,
UINT uiResTabLabel,
UINT uiImageId = (UINT)-1,
BOOL bDetachable = TRUE
);
the Remarks:
If pTabWnd points to an object that is not derived from the CDockablePane Class and
if bDetachable is TRUE, the framework automatically creates a wrapper for the pTabWnd object.
The wrapper makes the pTabWnd object detachable.
By default, the wrapper is an instance of the CDockablePaneAdapter Class.
If the functionality offered by the default wrapper is unacceptable,
use the CMFCBaseTabCtrl::SetDockingBarWrapperRTC method to specify a different wrapper.
still no luck.
i did try to on the fly create a CView and attach it to the CDocument and put that CView in a CDockablePane.so i could switch the old tabbed one to the new dockable one. it's not working yet.
So any thoughts about floating the tabbed CMDIChildWndEx window from CMDIFrameWndEx?

MFC: How to custom draw a dynamically created CListCtrl

I need to customize the head/row height of a CListCtrl. After some googling, I know that I need to subclass CListCtrl, so I wrote my own list class, with the outline as follows:
class CListCtrlCl : public CListCtrl
{
DECLARE_DYNAMIC(CListCtrlCl)
public:
...
BEGIN_MESSAGE_MAP(CListCtrlCl, CListCtrl)
ON_WM_MEASUREITEM()
ON_WM_MEASUREITEM_REFLECT()
END_MESSAGE_MAP()
void CListCtrlCl::PreSubclassWindow()
{
ModifyStyle(0,LVS_OWNERDRAWFIXED);
CListCtrl::PreSubclassWindow();
CHeaderCtrl *pHeader = GetHeaderCtrl();
m_Header.SubclassWindow(pHeader->GetSafeHwnd());
}
void CListCtrlCl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
if (m_nRowHeight>0)
{
lpMeasureItemStruct->itemHeight = 100;
}
}
The problem is that this method worked if I drag a CListCtrl control in dialog template, but if I create this listctrl dynamically, like:
BOOL CListCtrlTestDlg::OnInitDialog()
{
CRect rect(7,7,300,300);
this->m_ListCtrl.Create(WS_CHILD|WS_VISIBLE|WS_VSCROLL|LVS_REPORT|LVS_ALIGNLEFT|WS_BORDER | WS_TABSTOP, rect, this,IDC_LIST1 + 1);
SetWindowLong(m_ListCtrl.m_hWnd ,GWL_EXSTYLE,WS_EX_CLIENTEDGE);
m_ListCtrl.SetExtendedStyle(LVS_EX_GRIDLINES);
::SendMessage(m_ListCtrl.m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
...
Then the customization code just doesn't take effect. Whatever I did, the result listctrl is the standard one without any customization. But I need to create this listctrl dynamically, so could anyone tell me what I need to do to make dynamically created clistctrl customizable?
Thanks.
You've left off the necessary style for custom drawing when you create the control. Add LVS_OWNERDRAWFIXED. That should fix your problem.
The reason is that, PreSubclassWindow is only called when you subclass a control. When you createthe control you have also control over the style.
Simply overwrite the virtual Create function and just add the style like you are doing it in the PreSubclassWindow function. Than call the base class. You can also overwrite PreCreateWindow.
But much simpler than using the ownerdraw feature is cusum draw.

TaskDialog with no buttons

Is it possible to show the TaskDialog with no buttons? I would like to be able to show just a progress bar (with a message), and then close the TaskDialog window when when my processing is complete (from the Timer event). Right now, I can show a disabled button and then call ButtonClick to close the window, but showing no buttons and having a CloseDialog method would be ideal.
Thanks.
Derive your own class from CTaskDialog
class CTaskDlg : public CTaskDialog
{
in CTaskDlg.h declare:
public:
void CloseTaskDlg(void);
protected:
HWND m_TaskDlgHwnd;
virtual HRESULT OnInit();
};
in CTaskDialog.cpp:
void CTaskDlg::CloseTaskDlg(void)
{
::SendMessage(m_TaskDlgHwnd, TDM_CLICK_BUTTON, static_cast<WPARAM>(TDCBF_OK_BUTTON), 0);
}
HRESULT CTaskDlg::OnInit()
{
m_TaskDlgHwnd = ::GetActiveWindow();
return S_OK;
}
CTaskDlg dlg;
dlg.CloseTaskDlg();
Both TaskDialog() and TaskDialogIndirect() force a default button if you do not specify any buttons, but you do have control over what kind of buttons are used, so I would place an Abort button in the dialog to cancel whatever operation you are displaying status of. Or maybe a Hide button if the user does not want to see the progress anymore without stopping the operation that is in progress.
You have to use TaskDialogIndirect() in order to activate the progress bar feature. You can also use its callback feature to obtain the HWND of the dialog so you can close it programmably when needed.
Otherwise, don't use the TaskDialog API. Just create your own window with your own UI, then you can do whatever you want with it.