Impossible to delete the last column in a ListView? - c++

I am having a bit of a trouble here. It seems I can't remove all the columns or (reset) a listview. Here is the relevant code:
HWND resultListView = GetDlgItem(hwnd, IDC_RESULTCONTROL);
SendMessage(resultListView, LVM_DELETEALLITEMS, 0, 0); //All items are deleted
//Get numebr of columns
HWND hWndHdr = (HWND)::SendMessage(resultListView, LVM_GETHEADER, 0, 0);
int count = (int)::SendMessage(hWndHdr, HDM_GETITEMCOUNT, 0, 0L);
for (int colIndex = 0; colIndex < count; colIndex++) {
ListView_DeleteColumn(resultListView, colIndex);
}
///... Irrelevant code
HWND listbox = GetDlgItem(hwnd, IDC_SELECTEDLISTBOX);
int numberOfItemsSelected = SendMessage(listbox, LB_GETLISTBOXINFO, 0, 0);
vector<string> selectedItemsStringsVector;
char buf[250];
LVCOLUMN buffer;
//Add Selected Columns
for (int i = 0; i < numberOfItemsSelected; i++) { //In this case always 2 "Date" and "Time" for testing.
SendMessage(listbox, LB_GETTEXT, i, (LPARAM)buf);
selectedItemsStringsVector.push_back(buf);
buffer.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
buffer.fmt = LVCFMT_LEFT;
buffer.cx = 100;
buffer.pszText = buf;
buffer.cchTextMax = lstrlen(buf);
buffer.iSubItem = i;
buffer.iImage = 0;
buffer.iOrder = 0;
ListView_InsertColumn(resultListView, i, &buffer); //Works fine. Maybe I add an extra column here??
}
In debug mode, all my variables have the expected values.
FirstButtonClick column count in debug mode (variable count = 2) all good.
SecondButtonClick Column count = 3. But it does not delete them?
English is not my main language and I am kind of stumped right now...

The indices of columns in a header control are always consecutively numbered, starting at 0. User code does not control the index of a column. When deleting a column, the indices of columns towards higher indices are shifted down by 1. This is the reason, why the call to ListView_DeleteColumn eventually fails.
There are two options to solve this:
Delete columns starting at the final index down to 0. Deleting the last column does not change the index of other columns, so they stable throughout the deletion operation.
Always delete the first column (at index 0).
The second option is both easier to implement as well as read. The following loop will delete all columns:
for (int colIndex = 0; colIndex < count; ++colIndex) {
ListView_DeleteColumn(resultListView, 0);
}

Related

NQueens problem using stacks, code is giving the incorrect output

I have solved the famous NQueens problem with the code below. However, the issue here is that it will only solve boards of size 7 or smaller, and I need to it to work on boards up to size 11x11. Assume that the isPlaceValid() function works correctly, and that the int colIndex parameter is always passed a value of 0. Does anyone have any suggestions? I'm not getting any stack overflow or segmentation fault issues, my code just decides to exit my function.
bool QueensProblem::setQueens(int colIndex)
{
std::stack<class Pair> recurStack; //initialize the stack
Pair init, stacktop, to_push; //we have 3 different Pair objects
init.row = 0; //initial row in set to 0
init.col = colIndex; //initial column is set to 0
recurStack.push(init); // push this pair onto the stack
while((recurStack.top().col) < numOfQueens){ // once the the item at the top of the stack has col = to the number of queens, we are done!
stacktop = recurStack.top(); //stacktop is keeping track of the current colIndex
recurStack.pop(); //we put the object with the incremented col index on the top and get rid of it, theoretically leaving on the correct queen locations
if(stacktop.row == numOfQueens){ //we have run out of inital rows to attempt
return false; //basically we've backtracked numOfQueens times and there are no valid combinations left to try
}
for(int rowIndex = 0; rowIndex < numOfQueens; rowIndex++){ //we want to iterate through each row on the board for the current col index
if(isPlaceValid(rowIndex, stacktop.col)){ //if the queen would not be in danger here
chessTable[rowIndex][stacktop.col] = 1; //set that location = to 1
to_push.row = rowIndex;
to_push.col = stacktop.col;
recurStack.push(to_push); //version of to_push with the location of our set queen is pushed
to_push.col++;
recurStack.push(to_push);//increment col and push to_push again so that stacktop can start at the next column
break;
}
else if(rowIndex == (numOfQueens - 1)){ //this means we've reached the bottom of the board and no place was valid
chessTable[rowIndex][stacktop.col] = 0; //set that spot = to 0 still
to_push = recurStack.top(); //to_push is equal to the most recent valid location
recurStack.pop(); //remove that most recent location because we're backtracking
if(to_push.col == 0) //we are at the bottom of the stack
{
to_push.row += 1;
recurStack.push(to_push); //increment the initial rowIndex of our starting queen, and start from scratch
}
else{
rowIndex = to_push.row + 1;
continue;
}
}
else{
chessTable[rowIndex][stacktop.col] = 0;
}
}
}
return true;
}

FIR filter design in C++ using coefficients from MATLAB, Filter not giving correct results

I am working on a project in OpenCV, as I am new to this field, I am facing a few problems with it. I have to design a 128th order FIR bandpass filter for which I have used the coefficients calculated through MATLAB. I found the following code online.
const int taps = 129;
double buffer[129] = {0.0};
int offset = 0;
double input;
double coefficients[] =
{
0.0005,0.0004,0.0002,0.0000,-0.0001,-0.0000,0.0001,0.0004,0.0007,0.0011,
0.0015,0.0017,0.0018,0.0016,0.0011,0.0006,0.0001,-0.0003,-0.0002,0.0003,
0.0011,0.0022,0.0032,0.0038,0.0038,0.0031,0.0015,-0.0005,-0.0026,-0.0044,
-0.0053,-0.0050,-0.0037,-0.0016,0.0007,0.0023,0.0027,0.0012,-0.0022,-0.0072,
-0.0127,-0.0178,-0.0212,-0.0220,-0.0199,-0.0153,-0.0093,-0.0036,-0.0001,-0.0003,
-0.0053,-0.0147,-0.0274,-0.0408,-0.0519,-0.0573,-0.0545,-0.0419,-0.0197,0.0102,
0.0442,0.0779,0.1064,0.1254,0.1321,0.1254,0.1064,0.0779,0.0442,0.0102,-0.0197,
-0.0419,-0.0545,-0.0573,-0.0519,-0.0408,-0.0274,-0.0147,-0.0053,-0.0003,-0.0001,-0.0036,
-0.0093,-0.0153,-0.0199,-0.0220,-0.0212,-0.0178,-0.0127,-0.0072,-0.0022,0.0012,0.0027,
0.0023,0.0007,-0.0016,-0.0037,-0.0050,-0.0053,-0.0044,-0.0026,-0.0005,0.0015,0.0031,
0.0038,0.0038,0.0032,0.0022,0.0011,0.0003,-0.0002,-0.0003,0.0001,0.0006,0.0011,
0.0016,0.0018,0.0017,0.0015,0.0011,0.0007, 0.0004,0.0001,-0.0000,-0.0001,0.0000,
0.0002,0.0004,0.0005
};
double filter( double input)
{
double output = 0;
for(int i= taps-1; i>0 ; i-- )
{
buffer[i] = buffer[i-1];
}
buffer[0] = input;
for(int j = 0; j<taps; j++ )
{
output += (coefficients[j]*buffer[j]);
}
return output;
}
I try to use the filter as described in the code snippet below.
filteredTrajectory is the vector of vector, where I want to store the filtered values. YCoordinates is a vector of vector containing the data to be filtered. The dimension of YCoordinates is [1000x266]
// Calling FIR filter function filter
// filtering all 266 values across 1000 frames.
const int numFrames = 1000;
//featuresPrevious.size() = 266 (predefined fixed value)
vector<vector<double>> filteredTrajectory;
filteredTrajectory.resize(numFrames-1);
for (int i = 0; i<numFrames-1; i++)
{
filteredTrajectory[i].resize(featuresPrevious.size());
for (int j = 0; j<featuresPrevious.size(); j++)
{
filteredTrajectory[i][j] = filter (Ycoordinates[i][j]);
}
}
When I run this code, the filtered values do not match with those of MATLAB. However if I filter only one value throughout all 1000 frames, I get matching results with MATLAB (see code below).
// Filtering value at index Ycoordinates[i][0] across all frames
filteredTrajectory.resize(numFrames-1);
for (int i = 0; i<numFrames-1; i++)
{
filteredTrajectory[i].resize(1);
filteredTrajectory[i][0] = filter (Ycoordinates[i][0]);
}
What could be the possible flaws in the code which provide wrong results when filtering all trajectories inside the loop but matching results when filtered individually.
Matlab's filter is a one dimensional filter. When provided an input which is a two dimensional matrix, it filters each column independently (the default if the dim parameter is not set, or set to 1; setting dim to 2 would do the same but on each row), essentially resetting the FIR state in between each processed column (or row).
As such, to achieve the correct result you must also reset the filter state which you store in buffer between each set of values to be filtered by setting resetting the buffer to zeros:
void reset_buffer()
{
for(int i=0; i<taps ; i++ )
{
buffer[i] = 0.0;
}
}
Also, the filter must see each values belonging to the same set sequentially (i.e. not interleaving the values to the filtering function), so the order of the loop is important. Depending on whether you want to filter along the column or row dimension of your data, you can use either of the following function:
// Filter along columns, similar to Matlab's filter(coefficients, 1, data, [], 1)
void filterDim1()
{
for (int i = 0; i<numFrames-1; i++)
{
filteredTrajectory[i].resize(featuresPrevious.size());
}
for (int j = 0; j<featuresPrevious.size(); j++)
{
for (int i = 0; i<numFrames-1; i++)
{
filteredTrajectory[i][j] = filter (Ycoordinates[i][j]);
}
reset_buffer();
}
}
// Filter along rows, similar to Matlab's filter(coefficients, 1, data, [], 2)
void filterDim2()
{
for (int i = 0; i<numFrames-1; i++)
{
filteredTrajectory[i].resize(featuresPrevious.size());
for (int j = 0; j<featuresPrevious.size(); j++)
{
filteredTrajectory[i][j] = filter (Ycoordinates[i][j]);
}
reset_buffer();
}
}

How to animate window output from 2D array of x and y screen co-ordinates

I have a set of 2D array(IntMatrix to be exact) that possess values in certain index (if value is 1, it will print to screen).
The following is how I populated the 2D array when i press a button.
case IDC_SOLVE_BUTTON:
trysolve = 1;
solve2D.resize(inRowCount);
for (int i = 0; i < inRowCount; i++){
solve2D[i].resize(inColCount);
}
solve2D[0][3] = 1;
solve2D[1][3] = 1;
solve2D[1][4] = 1;
solve2D[1][5] = 1;
solve2D[2][5] = 1;
Now that I have values in some of the array indices, I know how to print them onto my window as shown below :
for (int rowId = 0; rowId < inRowCount; rowId++){
for (int colId = 0; colId < inColCount; colId++){
check = (colId*inColCount) + (rowId);
if (solve2D[rowId][colId] == 1){
solvecheck = (colId*inColCount) + (rowId);
startCol = colId * 10;
startRow = rowId * 10;
RECT cell = { startCol, startRow, startCol + dCol, startRow + dRow };
FillRect(hdc, &cell, tBrush);
}
}
Now important question is how do i exactly animate the printing ? Such that it will print one RECTANGLE, then print the subsequent RECTANGLE one second later. Any way i can set a timer and update the window at the printing segment of the code ??
Appreiciate some guidiance in this. Please help !
You can use the Sleep function to make the program wait for 1 second before continuing. As follows:
Sleep(1000);
Notice that the parameter is in milli-seconds, so you need 1000 to represent one second.
Place this function call in the suitable place of your code and you'll be done.

Qt setColumnWidth does not work

Have written the following code:
m_selectCategoryTableWidget = new QTableWidget;
m_selectCategoryTableWidget->setRowCount(0);
m_selectCategoryTableWidget->setColumnCount(2);
m_selectCategoryTableWidget->setHorizontalHeaderLabels(QStringList()<<tr("Category")<<tr("Number of items"));
m_selectCategoryTableWidget->verticalHeader()->setVisible(false);
m_selectCategoryTableWidget->horizontalHeader()->setStretchLastSection(true);
//m_selectCategoryTableWidget->setColumnWidth(0,400);
m_selectCategoryTableWidget->resizeColumnsToContents();
m_selectCategoryTableWidget->setColumnWidth(1,100); //this does not take effect
Please help.
Well, Qt's logic is so, that after column resize, scroll bar area checks how columns fit into it. And if the sum of all columns' widths is less than the widget's visible width, then the last column gets resized to fill up the space leading to no visible result of calling setColumnWidth(). Actually two resizes happen - to shrink and reverse to enlarge.
So, the lesson is - get control's visible width, recalculate sizes as you want, and resize all but the last column. For two column case it's really simple:
int secondColumnWidth = 100;
int firstColumnWidth = m_selectCategoryTableWidget->width() - secondColumnWidth;
if (firstColumnWidth > 0)
{
m_selectCategoryTableWidget->setColumnWidth(0, firstColumnWidth);
}
else
{
m_selectCategoryTableWidget->resizeColumnsToContents();
}
Good luck!
It is also possible to specify that you want the first column to fill the remaining space instead of the last column. Unfortunately this does seem to prevent the user from being able to manually resize the columns.
int secondColumnWidth = 100;
m_selectCategoryTableWidget->header()->setStretchLastSection(false);
m_selectCategoryTableWidget->header()->setResizeMode(0, QHeaderView::Stretch);
m_selectCategoryTableWidget->setColumnWidth(1, secondColumnWidth);
This will automatically resize the columns to fit ("view" is an QTableView* and model is a QSqlQueryModel*).
static_cast<QTableView*>(view)->horizontalHeader()
->resizeSections(QHeaderView::ResizeToContents);
QFontMetrics fm(view->font());
for (int i = 0 ; i < model->record().count(); ++i)
{
int maxLength = 0;
for (int j = 0; j < model->rowCount(); ++j)
{
QString cell = model->record(j).value(i).toString();
if (fm.width(cell) > maxLength)
{
maxLength = fm.width(cell);
}
}
QHeaderView& hv = *static_cast<QTableView*>(view)->horizontalHeader();
if (maxLength > hv.sectionSize(i))
{
hv.resizeSection(i, maxLength * 1.5);
}
}

How do I iterate a collection of Excel columns in C++ using Automation?

I want to do the moral equivalent of the following VBA code:
For Each col In Worksheets("Sheet1").Columns
# do stuff
Next col
I have generated MFC wrappers for the Excel type library that get me this far (the generated types all derive from COleDispatchDriver:
CApplication app;
app.CreateDispatch( clsid, e );
CWorkbooks wbks( app.get_Workbooks() );
CWorkbook book( wbks.Open( filename, /* optional args */ ) );
CRange cols( app.get_Columns() );
long numCols = cols.get_Count();
and from there I'm stuck. It looks like I can sort of iterate over cells using Range::get_Item( rowid, colid ), and then get the column from the cell, but I was looking for a more direct translation of the above loop.
(EDIT) Clarification: I don't actually care about the individual cells. My goal is to determine which columns have width 0 (are hidden) and delete them from the worksheet.
I assume that you're trying to traverse all the cells in the spreadsheet. You can get the active worksheet's "all cells" range, and loop through its rows and columns :
CSheets sheets = book.get_WorkSheets();
CWorkSheet sheet = sheets.get_ActiveSheet();
Range cells = sheet.get_Cells();
int nRows = cells.get_Rows().get_Count();
int nCols = cells.get_Columns().get_Count();
for (int i = 0; i <= nRows; i++)
{
for (int j = 0; j <= nCols; j++)
{
Range cell = cells.get_Item(i+1,j+1);
//Do stuff with individual cell
}
}
EDIT: In response to OP clarification:
This will probably do what you're looking for:
CSheets sheets = book.get_WorkSheets();
CWorkSheet sheet = sheets.get_ActiveSheet();
Range cols= sheet.get_Columns();
int nCols = cols.get_Count();
for (int i = nCols; i > 0; i--)
{
Range topCellOfCol = cells.get_Item(1, i);
Range entireCol = topCellOfCol.get_EntireColumn();
if (entireCol.get_Hidden())
entireCol.Delete( xlShiftToLeft );
}
Thanks to Steve, I got most of the way there. It turns out that despite the Excel VBA documentation, Range::Item has different behavior depending on how the range is created; thus:
COleVariant OPTIONAL( (long)DISP_E_PARAMNOTFOUND, VT_ERROR );
Range cols = sheet.get_Columns();
for ( long i = cols.get_Count(); i > 0; --i )
{
Range col = cols.get_Item( COleVariant( i ), OPTIONAL ) ;
// ...
}
will iterate through ranges representing the columns, and
Range rows = sheet.get_Rows();
for ( long i = rows.get_Count(); i > 0; --i )
{
Range row = cols.get_Item( COleVariant( i ), OPTIONAL );
// ...
}
will iterate through ranges representing the rows. This is implicit in the VBA examples, but not actually stated in the documentation.