How to mark a list control item as selected? - c++

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.

Related

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:

Problems with CMenu::ModifyMenu

I'm using CMenu::ModifyMenu in the OnCreate method of my CFrameWnd derived class to change the captions on my menu to match the user language.
I'm using VC++ designer and the menu is declared in a .rc file.
For the MENUITEM elements I use it as follow:
m_wndMenu->ModifyMenu(ID_APP_EXIT, MF_BYCOMMAND, NULL, CString((LPWSTR) ID_APP_EXIT));
For the POPUP elements (that don't have an ID) I use it as follow:
m_wndMenu->ModifyMenu(0, MF_BYPOSITION | MF_STRING, NULL, CString((LPWSTR) ID_MENU_POPUP_FILE));
It works as expected to change the captions, but for the menu items that are initialy disabled when I change the caption they get enabled. How do I fix this?
You may have to explicitly disable the menu item and set tool tip text after a call to ModifyMenu. Using ModifyMenu will effectively destroy the previous menu item and create a new one. You are losing any settings and initialization from the resource file or otherwise that you had on the previous item or menu.
See remarks: http://msdn.microsoft.com/en-us/library/4tbfebs6(v=vs.80).aspx
for such scenario, better to use EnableMenuItem function, like this
m_wndMenu->EnableMenuItem(ID_APP_EXIT, MF_BYCOMMAND| MF_ENABLED);
this will work...

How to create a multicolumn Listbox?

I'm working on a program, which should list all files and it's size(for now...). I created a simple application, which should write the data to a listbox. I'm trying to write the data in two columns(the first should be the name, and next to it, in an other column, it's size), but i can't figure out, how should i do this.
Can someone help me?
Thanks in advance!
kampi
Update:
I try to use ListControl., but unfortunately i can't. I can succesfully compile my App, but i can only see, the empty rectangle. Does someone know what i am doing wrong?
BOOL CGetFileListDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
LVITEM lvItem;
LVCOLUMN lvColumn;
int nCol;
lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
lvColumn.fmt = LVCFMT_CENTER;
lvColumn.cx = 10;
lvColumn.pszText = _T("Filename");
ListView_InsertColumn( m_List, 0, &lvColumn );
ListView_SetItemText( m_List, 0, 0, _T("TEST") );
return TRUE; // return TRUE unless you set the focus to a control
}
The list box control does support multiple columns, but it only supports a single series of entries; the multiple column support just makes the items continue onto the next columns so that vertical scrolling is not necessary.
As Kornel has suggested, a list view control may be more appropriate. After creating a list view control, use ListView_InsertColumn to create the columns. Then use ListView_SetItemText to insert items.
EDIT:
My apoligies; you should use ListView_InsertItem to insert an item (a row) and then use ListView_SetItemText to alter the subitems (columns). If the list view is still just a blank box without any headings, have you initialised common controls? This can be done using InitCommonControlsEx, specifying the ICC_LISTVIEW_CLASSES constant. This should be done before creating the control.
See Microsoft's documentation on list view controls.
Don't use a List Box, use a List Control with LVS_REPORT style.
Maybe to use DataGridView with object as data source.
Three important parameters to be checked are
List Box or the List Control (List Control is to be used)
View parameter must be Report mode
Owner Data must be set to False
The screenshot shows these
The programming flow to add data to list control are Change the list Control to extended list view(ListView_SetExtendedListViewStyle), Create the layout(By adding columns), Add Item data (for each row needed) & add finally add sub-item to each column (for each item data added previously).

How to create controls at runtime?

How to create dynamic MFC controls and handle message maps of the controls at runtime?
It really depends on which controls do you want to create, especially if you want to know which flags should you set. In general it goes down to this:
Normally a CWnd-derived control is created using Create or CreateEx. For a CButton, for instance:
CButton button;
button.Create("Button text", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | DT_CENTER, CRect(5, 5, 55, 19), this, nID);
where the CRect specifies the button position, this is a pointer to the parent window, and nID is the control ID.
If the control doesn't come out as expected, it's probably because some flags are missing. I suggest you draw a sample control in design mode, check out the code for that control in the RC file, and copy the flags to the Create caller.
As for the message maps, they are normally routed to the parent window. The nID value you used in Create is important here, because it will be the number that identifies the control in the message map. If you have a fixed number of controls, you can hard-code the nID numbers for your controls (starting at 10000, for instance); if not, you'll have to provide a way for the parent window to identify them. Then you just add the message map entries.
ON_BN_CLICKED(10000, OnBnClicked)
ON_CONTROL_RANGE(BN_CLICKED, 10010, 10020, OnBtnsClicked)
You can use the ON_CONTROL_RANGE message map to map a range of IDs to the same function.