CMFCShellTreeCtrl not displaying icons - c++

I am programming with C++ and MFC.
I have a CMFCShellTreeCtrl as one of the child windows in my application. It is created like this:
const DWORD dwViewStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS;
m_wndFileView.Create(dwViewStyle, rectDummy, this, 4))
It displays correctly, but doesn't show any icons for the files. Just blank spaces where icons for folders/files should be. I looked at the function SHGetImageList, it could be my solution to get an appropriate image list and supply it to the Tree control, but I'm having trouble doing the conversion. The image list returned are of type IImageList, but I need CImageList.
Is there a way to convert between these two? Or is there a simple function to make the CMFCShellTreeCtrl show icons that I missed?
Any help would be appreciated.

Related

MFC: How can I initialise CTabbedPane tabs (dialogs) using information from the Document in a SDI?

I'm fairly new to MFC and would like to create an SDI application that has a pane of tabs always embedded on the right of the window with a view left of it. In my app I have a calculation core, with variables that are changed in the tabs with edit boxes. I would like to initialise these variables in the calculation class and then during the initialisation of the dialogs used for tabs set the initial values in the edit boxes to those of the corresponding variable in the calculator.
Currently, I create an instance of the calculator in my document class.
I also create a CTabbedPane in the MainFrame OnCreate Method as follows:
m_TabbedPane.Create(_T(""), this, CRect(0, 0, 290, 200),
TRUE,
(UINT)-1,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
WS_CLIPCHILDREN | CBRS_RIGHT |
CBRS_FLOAT_MULTI))
m_tab = new CParametersDlg();
m_tab->Create(IDD_TAB, this);
m_TabbedPane.AddTab(m_tab);
I would the like to be able in CParameterDlg's OnInitDialog do something like:
BOOL CParameterDlg::OnInitDialog() {
CDialog::OnInitDialog()
float value = pointerToDocument->GetCalculatorVariable();
And use value to initialise an edit box. However I can't access the document from in the main frames OnCreate as it returns null (using GetActiveDocument, AfxGetApp etc).
How can I initialise the tabs then? I have thought about trying to put the Calculator in the App class instead. Or possibly trying to initialise the dialogs somewhere else which is called later when the document is properly initialised and linked? Or should I be doing things entirely differently?
I think that CMainFrame::OnCreate() is too early in the sequence of events to access the document class, it would not normally be created yet.
It would be better to wait until the docuent is created / initialised, the document class could then call a new method in CMainFrame() passing this as a parameter to create the tabs.

How to run command radiobutton inside a container in a window?

How to run command radiobutton inside a container in a window?
I was looking for weeks on the internet but I do not think I conosco forums can help me with a library as sophisticated as windows.h. So I come to this forum for professional help.
I know how to create a radiobutton within the main program window. I also know how to create a radiobutton inside a container of radiobuttons, but I want to run the radiobutton command that is contained within the container.
It turns out that my program requires that when a radiobutton is selected style WM_GRAYED put an EDIT control.
The problem is not how to execute commands from a control contained in a container of controls within a main window.
My code:
hOptEnc = CreateWindowEx (
            0,
            "BUTTON",
            "Type input",
            WS_CHILD | WS_VISIBLE | BS_GROUPBOX,
            264,
            296
            100,
            64,
            hWndParent,
            (HMENU) CM_GROUPS,
            hInstance,
            NULL
            );
hRadioAssci = CreateWindowEx (
            0,
            "BUTTON",
            "Input Assci"
            WS_VISIBLE | WS_CHILDWINDOW | BS_AUTORADIOBUTTON,
            10
            17
            75,
            20
            hOptEnc,
            (HMENU) CM_RADIOASSI,
            hInstance,
            NULL
            );
hRadioHex = CreateWindowEx (
            0,
            "BUTTON",
            "Hex Input"
            WS_VISIBLE | WS_CHILDWINDOW | BS_AUTORADIOBUTTON,
            10
            37,
            75,
            20
            hOptEnc,
            (HMENU) CM_RADIOHEX,
            hInstance,
            NULL
            );
And each time the user dials an option as hex input, edit controls would change the coding. So I need the radiobutton run your command in the main window procedure function.
The container (the group box) has no effect on the radio button. It is for visual clarity only. Pass you main window to the radio buttons as their parent window.

How to insertItem to 2nd colum in CListCtrl

I am new to MFC & BGCControlBar.
Now I plan to use CBCGPListCtrl which is defined as:
class BCGCBPRODLLEXPORT CBCGPListCtrl : public CListCtrl
&
CBCGPListCtrl m_wndWatch;
Now in the demo code I plan to change:
int CWatchBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CBCGPDockingControlBar::OnCreate(lpCreateStruct) == -1)
return -1;
m_Font.CreateStockObject (DEFAULT_GUI_FONT);
CRect rectDummy;
rectDummy.SetRectEmpty ();
// Create output pane:
const DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_VSCROLL | LVS_REPORT | LVS_EDITLABELS ;
m_wndWatch.Create (dwStyle, rectDummy, this, ID_LIST_1);
m_wndWatch.SendMessage (LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
m_wndWatch.InsertColumn (0, _T("Variable"), LVCFMT_LEFT, 100);
m_wndWatch.InsertColumn (1, _T("Value"), LVCFMT_LEFT, 100);
m_wndWatch.InsertItem (0, _T("m_nCount"));
m_wndWatch.SetItemText (0, 1, _T("100"));
m_wndWatch.SetFont (&m_Font);
return 0;
}
What I get is a list(as in pic), I can only edit the 1st colum and the data can not be retained. How can I edit the second column text and make the data retainable?
You need a grid control rather than a CListCtrl (or derived class). Actually, it's possible to add support for edition in other columns but it's a looooooot of work and not the kind of thing I'd recommend to a newcomer.
According to this page of their web site, they have a grid control.
There are a few things you need to do in order to make a MFC CListCtrl editable. This is a very broad overview without going into too many details:
As mentioned above it is quite a bit of work and you need to derive a class from CListCtrl, since CListCtrl by itself does not allow you to explicitly edit all of the columns.
You need a routine that will calculate the row/column number of the particular cell you clicked on, given a cursor position CPoint.
In the derived CListCtrl class you also need a method to edit the selected cell, creating and making visible a CEdit control of the appropriate size.
Create a derived CEdit control, such that it sends the LVN_ENDLABELEDIT message and self-destructs upon completion.
An example Visual Studio 2010 project implementing an editable list control is downloadable from this site:
http://www.technical-recipes.com/2014/making-a-mfc-list-control-editable/
Upon running/debugging the example, you get an example dialog project implementing an editable list control as shown:

Does LVS_EX_FULLROWSELECT have any compatibility issues with other styles?

I am trying to set the LVS_EX_FULLROWSELECT style on my grid list control as I want full row selection. However apparently it doesn't have any effect. Since I am using a number of other styles as well, I am wondering if LVS_EX_FULLROWSELECT has any compatibility issues with other styles. Anyone? Following are the styles I am setting.
Initially following styles are set on base list control class:
WS_CHILD|WS_BORDER|LVS_REPORT|LVS_SHOWSELALWAYS|LVS_SINGLESEL
Then I try to set additional styles in the derived grid list control class:
ListView_SetExtendedListViewStyleEx(sysId(), 0, LVS_EX_GRIDLINES | LVS_OWNERDATA | LVS_EX_FULLROWSELECT);
The second parameter is a mask, so you need:
ListView_SetExtendedListViewStyleEx(m_hWnd, LVS_EX_GRIDLINES | LVS_OWNERDATA | LVS_EX_FULLROWSELECT, LVS_EX_GRIDLINES | LVS_OWNERDATA | LVS_EX_FULLROWSELECT);
You need to send the LVM_SETEXTENDEDLISTVIEWSTYLE message to the control and specify the LVS_EX_FULLROWSELECT extended style (source: MS Support).
Edit:
Check the example. There is
ListView_SetExtendedListViewStyle(m_hWnd, ListView_GetExtendedListViewStyle(m_hWnd), VS_EX_FULLROWSELECT);
Try using ListView_GetExtendedListViewStyle(sysId()) instead of 0. BTW - does this sysId() of yours really retrieve the window handle? The name sounds somewhat different.
Cheers.

How to mark a list control item as selected?

In a Win32 application I have a dialog with a list control which is defined is the dialog template:
CONTROL "",IDC_LIST_Attributes,"SysListView32",LVS_REPORT |
LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,36,246,110
In the runtime I retrieve the handle to that control and perform different operations with it - remove all items, add items, etc. It works fine.
The problem is I can't programmatically mark an item as selected. I use the following code for that:
LVITEM lvItem;
lvItem.stateMask = stateMask;
lvItem.state = state;
SendMessage( windowHandle, LVM_SETITEMSTATE, indexToSelect, (LPARAM)&lvItem);
This code runs and no changes happen to the list control. when I clisk on items with a mouse they are selected allright. What am I missing?
Have you tried ListView_SetItemState Macro?
From the MSDN Link:
Items will only show as selected if
the list-view control has focus or the
LVS_SHOWSELALWAYS style is used.
Another Link that my help.