listview combobox - c++

I have added combobox to my custom listview and I am trying to set the combobox's text to the current listview subitem.
case CBN_SELCHANGE:
{
char txt[200];
ComboBox_GetText(hCombo, txt, 256);
int i = SendMessage(hListView, LVM_GETHOTITEM,0, 0);
ListView_SetItemText(hListView, i, 2, txt);
}
what am I doing wrong?

The listview "hot" item is the item with the cursor hovered over it and only when hot tracking and hot selection is enabled. The SDK docs for LVM_GETHOTITEM do a poor job explaining what a hot item actually is. The CListCtrl::GetHotItem docs give a bit more detail.
At the time you make the selection from the combo box, the cursor is not hovered over any item in the list box so no text will be set.
You likely want to get the selected item instead:
int i = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
This post has a bit more information.

Related

Edit Win32 combo box items

I have a combo box with a list of names that are editable through a text box on the same form. How would I go about editing the items that are sitting in the combo box when the user changes the name in the text box? There doesn't seem to be any message to update the strings sitting inside the combo box.
Thanks,
Edit: this is the code thats called when the text changes
void txtNameChange(HWND hDlg)
{
if(SelectedIndex != -1)
{
wchar_t Name[255];
GetDlgItemText(hDlg, txtName, Name, 255);
//need to set the item text of an item at a certain index here
}
}
You cannot rename an item in place. You need to delete the item you wish to modify with the CB_DELETESTRING message, and then insert the new value with the CB_INSERTSTRING message.

Prevent selected item from going out of view in QListView

I am using a QListView with only single selection and selection changes handled by the up and down arrows. Everything is working as expected with one minor issue. If many items are added to the top of the list then the currently selected item risks moving down and out of view. Is there any way to detect when this happens? Thanks.
I found solution, but first of all I try to do dimilar thing, I run timer and every 2 second I insert new row to the begin of list and try to detect, is selected item still visible?
//somewhere in the constructor, it is not important
ListModel = new QStandardItemModel();
ui->listView->setModel(ListModel);
Now when I want to insert new row , I wrote code, which checks is the item visible
QStandardItem* Items = new QStandardItem(QString::number(qrand()%100));
ListModel->insertRow(0,Items);
// here we get rect of current selected item
QRect rec = ui->listView->visualRect(ui->listView->currentIndex());
//here we get all listView region, convert it to rect and check is our listView
//contain selected item
if(ui->listView->viewport()->visibleRegion().boundingRect().contains(rec))
{
qDebug() << "visible";//all good
}
else
{
qDebug() << "not visible";//not good, we need do something
//you want to detect it, so you get!
//now you know that item "runs away from you"
//and you can do some actions
someAction();
}
I test it on my computer, when I can see item, I get visible word, when item tries "run away from me" I get not visible
I hope it helps.

Scrolling QListView to keep items in view while inserting at start of list

I have a QListView with a model that I am inserting data into. I'm inserting data at the start of the list which causes all the items in the view to scroll down.
What would be the best way to scroll the view automatically to keep the view fixed (i.e the view should move with the visible items as new items are inserted in the model)?
This seems to work. The problem was not actually scrolling to the specific index - it was finding the correct index in the first place.
The following code scrolls the view to keep the same items in the view when inserting at the start of the list. It also checks if the view is at the top of the list and does not scroll in this case.
QScrollBar *pVerticalScrollBar = m_pUi->listView->verticalScrollBar();
bool bScrolledToTop = pVerticalScrollBar->value() == pVerticalScrollBar->minimum();
int iRowIndex = m_pUi->listView->indexAt(QPoint(8, 8)).row();
int iRowCount = m_pInfoListModel->rowCount();
/*
insert text into m_pInfoListModel here
*/
// move scroll bar to keep current items in view (if not scrolled to the top)
if (bScrolledToTop == false)
{
iRowCount = m_pInfoListModel->rowCount() - iRowCount;
m_pUi->listView->scrollTo(m_pInfoListModel->index(iRowIndex + iRowCount, 0), QAbstractItemView::PositionAtTop);
}
This gives me a list of items that scroll by if I am at the top of the list, but when I wan't to look at items lower down the view stays fixed.
I guess you could give setAutoScroll(True) to QListView instance.
I would do the following:
Find the list view item that I want to keep visible and than get its coordinates using
QRect QAbstractItemView::visualRect(const QModelIndex &index)
Than with the item's coordinates I will call QScrollArea::ensureVisible(int, int, int, int) function to keep the item visible after adding each new item to the list.

Qt QComboBox - change current index not as expected

I would like to have a given item in comboBox selected when opening editor, and when loading given data that should update in editor. Combobox is not working as expected!
I have these lines for having given item selected when I open the window:
normBox = new QComboBox(page1);
gridBox->addWidget(normBox, 2, 1, 1, 1);
QStringList normsLst;
normsLst.append(tr("sum"));
normsLst.append(tr("maxF"));
normsLst.append(tr("sumF"));
setComboBoxItems(normsLst, m_normBox);
m_normBox->setCurrentIndex(0);
but first item 'Sum' is not displayed in combobox when I create editor.
Then, I implemented my 'load' function, which should load the saved data in interface ending with a refresher:
normBox->setCurrentIndex(model->getNormIdx());
where model has accurate member normIdx.
How can I achieve the right selection in combo box with Qt?
Maybe you create a combobox and then set the current index of another one?
normBox = new QComboBox(page1);
...
m_normBox->setCurrentIndex(0);
And what is setComboBoxItems(normsLst, m_normBox)? I didn't find this function (with two arguments) in the Qt documentation.
This code should work:
QComboBox* combo = new QComboBox;
QStringList list;
list << "sum" << "maxF" << "sumF";
combo->addItems(list);
combo->setCurrentIndex(0);

How do I put a checkmark on a menu item that has submenu items. (Visual studio 2008 C++/MFC)

I have a menu that contains submenus.
eg:
Item1
Item2
Item3
item A
Item B
Item3 has items under it.
At any given time 1, 2, or the items under 3 should be checked. Since I don't have an ID for Item3 I have to use the MF_BYPOSITION indicator when I try to set a check on Item3 to indicate one of its children has a checkmark. Item3 should have a checkmark if A or B are checked. I am able to check items 1 and 2 and A and B - but can't figure out item3.
I have not been able to successfully use either ::CheckMenuItem() or ModifyMenu() to set the check mark.
Can someone point me to an example that does this successfully? The docs seem to indicate it can be done, but I have been unable to do it.
EDIT
This is for a menu that is set as the menu for a dlg box. The menu bar has three items - one of which drops down to what is shown above.
Note also, it is used as a popup for a right click, but I will take any suggestions to work in either case.
I've done this before for popup menus. You will need to access the submenu by position, instead of ID. Using your example above, Item 3 would be at position 2:
CMenu popupMenu;
popupMenu.LoadMenu(IDR_MYMENU);
popupMenu.GetSubMenu(0)->CheckMenuItem(2,MF_BYPOSITION|MF_CHECKED);
.
.
.
popupMenu.GetSubMenu(0)->TrackPopupMenu(...);
However, I haven't done this with items in the menu bar.
EDIT by Tim the OP:
For completeness
To get it to work with the menu item you have to get the hmenu
// MENU_POSITION is the zero based location of the menu you want to use. (file, edit, view, help... etc)
HMENU mainMenu = ::GetMenu(m_hWnd);
HMENU subMenu = GetSubMenu( mainMenu, MENU_POSITION);
SetMenuState(subMenu);
A few moments ago I had a similar problem - a standard MFC menu bar containing at least one submenu, and the need to be able to add a check mark to the submenu parent item, when any of the submenu child items were checked.
The easiest solution (for me) turned out to be as simple as performing the update in the standard OnUpdateMenuItem(CCmdUI* pCmdUI) call. In my case I used ON_UPDATE_COMMAND_UI_RANGE() to feed a bunch of menu IDs into the same update call, but the principal is the same for a single ON_UPDATE_COMMAND_UI() map.
The code I used (edited to be more easily inserted into other people's work) is:
void CMyApp::OnUpdateMenu(CCmdUI* pCmdUI)
{
// Note, a submenu parent (which has no editable ID in the resource editor) has the SAME ID as the first child item
if (pCmdUI->m_nID == ID_FIRST_CHILD_MENU && pCmdUI->m_pSubMenu != NULL) {
// Get the child menu so we can see if any child items are checked
CMenu* pSubMenu = pCmdUI->m_pSubMenu;
BOOL fChildChecked = FALSE;
for (UINT i = 0; !fChildChecked && i < pSubMenu->GetMenuItemCount(); ++i) {
// Do something to decide if this child item should be checked...
UINT nChildID = pSubMenu->GetMenuItemID(i);
fChildChecked = IsThisChildChecked(nChildID);
}
// The POSITION of the current menu item is stored in pCmdUI->m_nIndex
CMenu* pMenu = pCmdUI->m_pMenu;
UINT flags = MF_BYPOSITION;
if (fActiveChild) flags |= MF_CHECKED;
pMenu->CheckMenuItem(pCmdUI->m_nIndex, flags);
}
// Set the enabled state of the menu item as you see fit...
pCmdUI->Enable(TRUE);
}
Et voilĂ  the submenu item automagically gains a check mark when any of its child menu items has a check mark.
Hope this helps others looking for similar solutions!
John