I have a CListCtrl object in my C++ MFC app for Windows Mobile 6. When I call listctrl.GetNextItem(0, LVNI_ABOVE) I should therefore get back -1 (no item above first item), but if (and only if) the list has exactly one item, the call returns 0, even though MSDN says "The specified item itself is excluded from the search". Is this a known bug?
You can search for bugs here:
https://connect.microsoft.com/VisualStudio/Feedback
Related
Let's say that I have a group of radio items in a wxMenu. I know that exactly one of these will be checked at any given time.
Does the wxMenu or some other construct hold onto the index of the checked item, or do I need to call the isChecked on each radio item till I find the checked element to find it's index?
I've asked this question about how to do that, but I'd much prefer wxWidgets saved me from doing that everywhere.
No, saving the index of the last selected item (as shown in ravenspoint's answer) or using wxMenuBarBase::IsChecked() until you find the selected radio button is the only way to do it.
For wxWidgets to provide access to the currently selected button it would need not only to store it (which means not forgetting to update not only when the selected changes, but also when items are inserted into/deleted from the menu, so it's already not completely trivial), but to somehow provide access to the radio items group you're interested in, which would require being able to identify it and currently there is no way to do it and adding it isn't going to be particularly simple.
What could be done easily, however, is writing a reusable function int GetIndexOfSelectedRadioItem(int firstItem) that would start at the given item and call IsChecked() on subsequent items until it returns true and return the offset of the item. You should be able to do it in your own code, but if you'd like to include such function in wxWidgets itself (as a static wxMenuBar method, probably), please don't hesitate to send patches/pull requests doing it!
It is easy enough to roll your own.
Bind an event handler to wxEVT_COMMAND_RADIOBUTTON_SELECTED for every button. In the handler, extract the ID of the selected radio button and store it somewhere.
Like this:
ResolMenu = new wxMenu();
ResolMenu->AppendRadioItem(idRcvLoRez,"Low Resolution");
ResolMenu->AppendRadioItem(idRcvMeRez,"Medium Resolution");
ResolMenu->AppendRadioItem(idRcvHiRez,"High Resolution");
ResolMenu->Check( idRcvLoRez, true );
Bind(wxEVT_MENU,&cFrame::onRcvRez,this,idRcvLoRez);
Bind(wxEVT_MENU,&cFrame::onRcvRez,this,idRcvMeRez);
Bind(wxEVT_MENU,&cFrame::onRcvRez,this,idRcvHiRez);
void onRcvRez( wxCommandEvent& event )
{
myRezID = event.GetId();
in this program, items (markers) are added to a QListWidget calles ui->lwMarkers. These items can also be removed again by pressing the "Remove button" which calls the following function
void Form::on_pbRemoveMarker_clicked()
{
if (ui->lwMarkers->currentRow() < 0) return;
delete ui->lwMarkers->takeItem(ui->lwMarkers->currentRow());
}
Inside the function, the first line is to make sure an item (marker) is actually selected.
The second line is (at least, I hope) to delete the selected item.
Adding and removing: all goes well, unless when you want to remove next-to-last item. Then it crashes, unfortunately. I do not see why.
Can anyone shed a light on this issue?
If it can help: the full code is from the qt-google-maps project: https://code.google.com/p/qt-google-maps/ . This project uses the Google Maps API v2, I altered the code to use v3.
The question that I ask, is a particular behaviour of their code, and I simply don't see the reason of the crash. Any help?
The crash always happens just before the delete, I believe it is because of the takeItem and the error I get is as follows:
ASSERT failure in QList::operator[]: "index out of range", file ../../QtSDK/Desktop/Qt/473/gcc/include/QtCore/qlist.h, line 464
Could it be that takeItem is the evildoer? According to the class reference , it removes the item from the QListWidget and returns it. It also mentions:
Items removed from a list widget will not be managed by Qt, and will need to be deleted manually.
This is why, to me, the original code seems correct, you remove the item from the list widget and delete it afterwards. Still, it gives the above mentioned error when trying to remove the next-to-last item.
I suggest to use the item() function instead, and delete it accordingly:
void Form::on_pbRemoveMarker_clicked()
{
if (ui->lwMarkers->currentRow() < 0) return;
delete ui->lwMarkers->item(ui->lwMarkers->currentRow());
}
The frontend of the program is now working as expected, but do I leave memory leaks this way?
Any other problem you might see?
I use wxWidgets 2.9.5 on a Windows 7 machine.
When I select more then one element in my wxlistctrl using shift, GetNextItem() only returns the index of the first element selected.
Even the example from the manual: http://docs.wxwidgets.org/trunk/classwx_list_ctrl.html#ad8372c4619ad5ea55ad16889caa32e78
which I attached doesn't work; Hence it returns the index of the first element selected when the GetNextItem() is called at first, but when it is called the second time it returns -1.
long item = -1;
for ( ;; )
{
item = listctrl->GetNextItem(item,wxLIST_NEXT_ALL,wxLIST_STATE_SELECTED);
if ( item == -1 )
break;
// this item is selected - do whatever is needed with it
wxLogMessage("Item %ld is selected.", item);
}
Does anyone has had to workaround the same problem?
Thank you.
Almost exactly the same code (see MyFrame::OnShowSelInfo()) does work in the listctrl sample included in wxWidgets, so I really don't know why it doesn't work for you. Can you try to reproduce the problem in the sample?
If I try to debug my C++ program in QT Creator the Locals and Expressions window shows me the variables in the program. However all the values show "< not accessible >".
Screenshot:
How do I get the values to show? I can print the values out with cout so I know they are initialized.
Edit: It seems like it only applies to strings
Specs/other:
Windows 8, 64bit
QT 5.2.0
MinGW 32bit, I think 4.8
QT Creator 3.0.0
Try to remove the checkmark at Tools/Options/Debugger/GDB/Load system GDB pretty printers, and see whether this makes a difference.
Solved:
For composite types (std::string and other classes) it doesn’t
automatically convert to some default type (e.g. std::string to
char*); so what you need to do it right-click on a value, then select
the submenu Change local display format-> Raw structure, and then keep
opening the symbol until you get something meaningful (when possible).
E.g. for std::string, after you change to “Raw structure”, you get
your actual string (by clicking the “+” sign to the left of your
symbol) in: _M_dataplus->_M_p
Note that you can “Change local display format” for one symbol (the
one you selected) or for all symbols of that type (e.g. you select a
std::string, then all std::strings change to Raw structure)
From this link: http://qt-project.org/forums/viewthread/36121/
Credit goes to Gyll.
I used a class which derives from CListBox, and create it with following:
style:WS_CHILD|WS_VISIBLE |LBS_OWNERDRAWFIXED | WS_VSCROLL | WS_HSCROLL
I expect the ListBox's item to be have a fixed size, not affected by the size of the list box. So I override the MeasureItem() method, in which I specify the item's size like below:
void CMyListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
{
lpMIS->itemHeight = ALBUM_ITEM_HEIGHT;
lpMIS->itemWidth = ALBUM_ITEM_WIDTH;
}
But the item's size changes according to the List box's size changing. is there anything wrong with my approach?
What's not mentioned in the reference is that WM_MEASUREITEM is called every time the *_OWNERDRAWFIXED control is resized.
I don't know however, how official this behavior is and whether it should be relied on, but it has been verified at CodeGuru and several forum posts found on the Google thing.
If you don't want to process the message, then just set a private flag somewhere in the first OnMeasureItem() call and return from it as soon as you check that it's set next time.
If you look at the MSDN entry for CListBox::MeasureItem you'll see that it's only called once unless the LBS_OWNERDRAWVARIABLE (not LBS_OWNERDRAWFIXED) style is set. If I understand correctly then this would explain the behaviour you're seeing because MeasureItem would need to be called each time the control's size changes.
Also, have you considered the points made in MFC Technical Note 14 : Custom Controls?