I want to do a very simple thing but it's not working. I want to add some CCParticleSystemQuad in an NSMutableArray and delete them. Here is what I do :
int cpt = 0;
NSMutableArray *myArray = [[NSMutableArray alloc] init];
for (cpt = 0; cpt < 10; cpt++) {
part = [CCParticleSystemQuad particleWithFile:#"whiteExplosion.plist"];
[myArray addObject:part];
}
NSLog(#"state of myArray : %#", myArray);
int cont = 0
for (cont = 0; cont < 10; cont++) {
[myArray removeLastObject:cont];
}
NSLog(#"state of myArray : %#", myArray);
When I NSLog the first time I have this :
state of myArray : (
"<CCParticleSystemQuad = 0x91ee380 | Tag = -1>",
"<CCParticleSystemQuad = 0x84aca20 | Tag = -1>",
"<CCParticleSystemQuad = 0x125136c0 | Tag = -1>",
"<CCParticleSystemQuad = 0x125b0fc0 | Tag = -1>",
"<CCParticleSystemQuad = 0x1250d480 | Tag = -1>",
"<CCParticleSystemQuad = 0x1250fa50 | Tag = -1>",
"<CCParticleSystemQuad = 0x9108840 | Tag = -1>",
"<CCParticleSystemQuad = 0x9152b70 | Tag = -1>",
"<CCParticleSystemQuad = 0x914fb80 | Tag = -1>",
"<CCParticleSystemQuad = 0x9135470 | Tag = -1>"
)
The second time I have this :
state of myArray : (
)
So, as you can see my CCParticleSystemQuad have been removed. But, when I check in Instruments (allocations) they are still living (I have 20 still living [CCParticleSystemQuad allocMemory]) and still using memory for nothing. What am I missing ? BTW I use ARC.
I tried with (NSString *) object and it works fine... Thx.
[myArray removeLastObject:cont];
You're trying to delete an int from the array. You wanted to use removeLastObject (no params) or removeObjectAtIndex:
Your problem may be that you're not calling removeChild:particle
You must remove it from its parent not only from array.
[part removeFromParentAndCleanup:YES];
//to remove object from array
for (int i = 0; i < [myArray count]; i++) {
[myArray removeObjectAtIndex:i];
}
//remove only last object
[myArray removeObjectAtIndex:([myArray count]-1)];
Related
I have two functions to init the listview and one to add entries to the list view. I created a struct that holds the column information.
struct LISTVIEW_COLUMN
{
const TCHAR * Title;
int Width;
};
This is how I am creating the column struct
static struct LISTVIEW_COLUMN lvNames[] =
{
{ TEXT("Name"), 150 },
{ TEXT("Last"), 125 }
};
Then I have the functions defined as follows.
void InitListView(HWND hListView, LISTVIEW_COLUMN * lvColumn, int nCols)
{
ListView_SetExtendedListViewStyle(hListView, LVS_EX_FULLROWSELECT);
// Create the columns
for (int col = 0; col < nCols; col++) {
LVCOLUMN lvc;
lvc.pszText = (TCHAR *)lvColumn[col].Title;
lvc.cx = lvColumn[col].Width;
lvc.mask = LVCF_TEXT | LVCF_WIDTH;
ListView_InsertColumn(hListView, col, &lvc);
}
}
void NetPCAddListViewRow(HWND hListView, TCHAR * name, TCHAR * lastName)
{
LVITEM lvItem;
// Add item (name)
lvItem.mask = LVIF_TEXT | LVIF_IMAGE;
lvItem.iItem = 0;
lvItem.iSubItem = 0;
lvItem.iImage = 0;
lvItem.pszText = (TCHAR *)name;
lvItem.iItem = ListView_InsertItem(hListView, &lvItem);
// Just using "testing" right now to see it as a subitem
lvItem.iSubItem += 1;
lvItem.pszText = _T("testing");
ListView_SetItem(hListView, &lvItem);
}
The columns show up just fine and the first column "name" gets added to but I cant get anything to show up as a subitem in that column? Thanks for any help!
If you look at the How to Add List-View Columns example on MSDN you will see that they set the iSubItem member and the LVCF_SUBITEM flag when they insert the columns. This establishes the relationship between sub-items and columns (columns can be re-ordered by the user).
I would also recommend that you reset lvItem.mask before adding sub-items because they only support a subset of the flags.
I used DrawItem() to redraw my CListbox. For some reasons, I want to use custom compare to sort my list item with my own rules, and I use LBS_SORT and no LBS_HASSTRING properties. After using SetItemData() in OnInitDialog(), I get these data in DrawItem(), but it didn't work. Code is like below:
init code :
void OnInitDialog(...)
{
.........
m_List.SetListHeight (40);
for (int i = 0 ; i < 20 ; i ++) {
m_List.AddString ((const char *) i);
m_List.SetItemData (i,(100 + i));
}
....
}
compare code :
int CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct)
{
ASSERT(lpCompareItemStruct->CtlType == ODT_LISTBOX);
int a = lpCompareItemStruct->itemData1;
int b = lpCompareItemStruct->itemData2;
return (a - b);
}
redraw code :
DrawItem (lpDIS)
{
..................
CString str;
int i = (int) GetItemData (lpDIS->itemID); // the i is not what I expect.
str.Format ("%d", (int) i);
dc.DrawText (str,CRect (&lpDIS->rcItem), DT_CENTER | DT_VCENTER | DT_SINGLELINE);
...................
}
when I use
***index = m_List.addstring ((const char *) i) ;
m_List.setitemdata (index,(100 + i));***
it works ,but if I use a struct to addstring ,the index is not right ,code is like this below :
struct test {
int a,b,c,d;
};
init_code :
test *ptest = new test[20]; /* just a test ,we don't delete memory till application ends */
for (int i = 0 ; i < 20 ; i ++) {
ptest [i].a = i;
int index = m_List.AddString ((const char *) (ptest + i));
m_List.SetItemDataPtr (index,(void *) (100 + i));
}
compare code :
int ListEx::CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct)
{
// TODO: Add your code to determine the sorting order of the specified items
// return -1 = item 1 sorts before item 2
// return 0 = item 1 and item 2 sort the same
// return 1 = item 1 sorts after item 2
// ASSERT(lpCompareItemStruct->CtlType == ODT_LISTBOX);
test *pa,*pb;
pa = (test *) lpCompareItemStruct->itemData1; // crashed here
pb = (test *) lpCompareItemStruct->itemData2;
// ASSERT (pa);
// ASSERT (pb);
return (pa->a - pb->a);
}
draw_item code :
CString str;
test *ptest = (test *) (lpDIS->itemData);
str.Format ("%d", (int) ptest->a);
dc.DrawText (str,CRect (&lpDIS->rcItem), DT_CENTER | DT_VCENTER | DT_SINGLELINE);
Is addstring can only use strings ???
if the item is a struct data ,how could I set these struct data to the listbox item ???
In OnInitDialog you should do this:
for (int i = 0 ; i < 20 ; i ++) {
int index = m_List.AddString ((const char *) i);
m_List.SetItemData (index, 100 + i);
}
AddString returns the index where the item has been inserted (which can be anywhere if the list is sorted). m_List.SetItemData (index ,(100 + i)) sets the data for the item you just have inserted.
we can set structure data to list box.
struct _empInfo {
CString strName;
..............
} empInfo = {L"XYZ",...};
m_list.AddString(empinfo.strName);
I tried above code in my app..
I want to read the data from a wxGrid and write it into a XML File.
The wxGrid is like:
Jahr | Monat
------ |-------------
2012 | 03
2009 | 08
What I want to have:
<SQL>
<Datensatz>
<Jahr>2012</Jahr>
<Monat>03</Monat>
</Datensatz>
<Datensatz>
<Jahr>2009</Jahr>
<Monat>08</Monat>
</Datensatz>
</SQL>
What I got:
<SQL>
<Datensatz>
<Jahr>20122009</Jahr>
<Monat>0308</Monat>
</Datensatz>
<Datensatz>
<Jahr>20122009</Jahr>
<Monat>0308</Monat>
</Datensatz>
</SQL>
My Code:
XMLDocument doc;
XMLElement* xesql = doc.NewElement("SQL");
XMLNode * xnsql = doc.InsertFirstChild(xesql);
XMLElement* xejahr = doc.NewElement("Jahr");
XMLElement* xemonat = doc.NewElement("Monat");
XMLText* datensatzJahr = doc.NewText("");
XMLText* datensatzMonat = doc.NewText("");
for(int i=0; i<=1; i++)
{
XMLElement* xedatensatz = doc.NewElement("Datensatz");
datensatzJahr = doc.NewText(m_gd_data->GetCellValue(i,0));
datensatzMonat = doc.NewText(m_gd_data->GetCellValue(i,1));
xejahr->InsertEndChild(datensatzJahr);
xemonat->InsertEndChild(datensatzMonat);
xedatensatz->InsertEndChild(xejahr);
xedatensatz->InsertEndChild(xemonat);
xesql->InsertEndChild(xedatensatz);
}
doc.SaveFile(path);
I really don't know where's the problem. Can anyone help?
You are not resetting the XML elements for each iteration of the loop, hence you are only appending text to an existing element. this should work:
XMLDocument doc;
XMLElement* xesql = doc.NewElement("SQL");
XMLNode * xnsql = doc.InsertFirstChild(xesql);
for(int i=0; i<=1; i++)
{
XMLElement* xejahr = doc.NewElement("Jahr");
XMLElement* xemonat = doc.NewElement("Monat");
XMLText* datensatzJahr = doc.NewText("");
XMLText* datensatzMonat = doc.NewText("");
XMLElement* xedatensatz = doc.NewElement("Datensatz");
datensatzJahr = doc.NewText(m_gd_data->GetCellValue(i,0));
datensatzMonat = doc.NewText(m_gd_data->GetCellValue(i,1));
xejahr->InsertEndChild(datensatzJahr);
xemonat->InsertEndChild(datensatzMonat);
xedatensatz->InsertEndChild(xejahr);
xedatensatz->InsertEndChild(xemonat);
xesql->InsertEndChild(xedatensatz);
}
doc.SaveFile(path);
You have to create new elements for the year and month inside the loop.
I am trying to export to excel using Open XML with simple formatting. Export to Excel is working. The problem is with formatting the data. I am trying to have very basic formatting. i.e. the Column names should be in bold and rest of the content in normal font. This is what I did. Please let me know where am I going wrong.
private Stylesheet GenerateStyleSheet()
{
return new Stylesheet(
new Fonts(
new Font(new DocumentFormat.OpenXml.Spreadsheet.FontSize { Val = 12},
new Bold(),
new Font(new DocumentFormat.OpenXml.Spreadsheet.FontSize { Val = 12}))
)
);
}
protected void ExportExcel(DataTable dtExport)
{
Response.ClearHeaders();
Response.ClearContent();
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
//"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" '"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" '"application/vnd.ms-excel"
Response.AddHeader("content-disposition", "attachment; filename=Test.xlsx");
Response.Charset = "";
this.EnableViewState = false;
MemoryStream ms = new MemoryStream();
SpreadsheetDocument objSpreadsheet = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook);
WorkbookPart objWorkbookPart = objSpreadsheet.AddWorkbookPart();
objWorkbookPart.Workbook = new Workbook();
WorksheetPart objSheetPart = objWorkbookPart.AddNewPart<WorksheetPart>();
objSheetPart.Worksheet = new Worksheet(new SheetData());
Sheets objSheets = objSpreadsheet.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
Sheet objSheet = new Sheet();
objSheet.Id = objSpreadsheet.WorkbookPart.GetIdOfPart(objSheetPart);
objSheet.SheetId = 1;
objSheet.Name = "mySheet";
objSheets.Append(objSheet);
WorkbookStylesPart stylesPart = objSpreadsheet.WorkbookPart.AddNewPart<WorkbookStylesPart>();
stylesPart.Stylesheet = GenerateStyleSheet();
stylesPart.Stylesheet.Save();
objSheetPart.Worksheet.Save();
objSpreadsheet.WorkbookPart.Workbook.Save();
for (int cols = 0; cols < dtExport.Columns.Count; cols++)
{
Cell objCell = InsertCellInWorksheet(GetColumnName(cols), 1, objSheetPart);
objCell.CellValue = new CellValue(dtExport.Columns[cols].ColumnName);
objCell.DataType = new EnumValue<CellValues>(CellValues.String);
objCell.StyleIndex = 0;
}
objSheetPart.Worksheet.Save();
objSpreadsheet.WorkbookPart.Workbook.Save();
for (uint row = 0; row < dtExport.Rows.Count; row++)
{
for (int cols = 0; cols < dtExport.Columns.Count; cols++)
{
//row + 2 as we need to start adding data from second row. First row is left for header
Cell objCell = InsertCellInWorksheet(GetColumnName(cols), row + 2, objSheetPart);
objCell.CellValue = new CellValue(Convert.ToString(dtExport.Rows[Convert.ToInt32(row)][cols]));
objCell.DataType = new EnumValue<CellValues>(CellValues.String);
objCell.StyleIndex = 1;
}
}
objSheetPart.Worksheet.Save();
objSpreadsheet.WorkbookPart.Workbook.Save();
objSpreadsheet.Close();
ms.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
// Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet.
// If the cell already exists, return it.
private Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart)
{
Worksheet worksheet = worksheetPart.Worksheet;
SheetData sheetData = worksheet.GetFirstChild<SheetData>();
string cellReference = (columnName + rowIndex.ToString());
// If the worksheet does not contain a row with the specified row index, insert one.
Row row = default(Row);
if ((sheetData.Elements<Row>().Where(r => r.RowIndex.Value == rowIndex).Count() != 0))
{
row = sheetData.Elements<Row>().Where(r => r.RowIndex.Value == rowIndex).First();
}
else
{
row = new Row();
row.RowIndex = rowIndex;
sheetData.Append(row);
}
// If there is not a cell with the specified column name, insert one.
if ((row.Elements<Cell>().Where(c => c.CellReference.Value == columnName + rowIndex.ToString()).Count() > 0))
{
return row.Elements<Cell>().Where(c => c.CellReference.Value == cellReference).First();
}
else
{
// Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
Cell refCell = null;
foreach (Cell cell in row.Elements<Cell>())
{
if ((string.Compare(cell.CellReference.Value, cellReference, true) > 0))
{
refCell = cell;
break; // TODO: might not be correct. Was : Exit For
}
}
Cell newCell = new Cell();
newCell.CellReference = cellReference;
row.InsertBefore(newCell, refCell);
return newCell;
}
}
It seems like you are missing a ")" after your first font creation. So then you end opp with only one font index (the default one)
Below is the code I use for exactly what you are asking for.
You might remove fills and borders and remove them from cellformat, but I had some syntax problems while writing this so I just left it when it all worked :-)
private Stylesheet GenerateStyleSheet()
{
return new Stylesheet(
new Fonts(
// Index 0 - Default font.
new Font(
new FontSize() { Val = 11 },
new Color() { Rgb = new HexBinaryValue() { Value = "000000" } }
),
new Font(
new Bold(),
new FontSize() { Val = 11 },
new Color() { Rgb = new HexBinaryValue() { Value = "000000" } }
)
),
new Fills(
// Index 0 - Default fill.
new Fill(
new PatternFill() { PatternType = PatternValues.None })
),
new Borders(
// Index 0 - Default border.
new Border(
new LeftBorder(),
new RightBorder(),
new TopBorder(),
new BottomBorder(),
new DiagonalBorder())
),
new CellFormats(
// Index 0 - Default cell style
new CellFormat() { FontId = 0, FillId = 0, BorderId = 0 },
new CellFormat() { FontId = 1, FillId = 0, BorderId = 0, ApplyFont = true }
)
);
}
Here s what I'm doing in a nutshell.
In my class's cpp file I have:
std::vector<std::vector<GLdouble>> ThreadPts[4];
The thread proc looks like this:
unsigned __stdcall BezierThreadProc(void *arg)
{
SHAPETHREADDATA *data = (SHAPETHREADDATA *) arg;
OGLSHAPE *obj = reinterpret_cast<OGLSHAPE*>(data->objectptr);
for(unsigned int i = data->start; i < data->end - 1; ++i)
{
obj->SetCubicBezier(
obj->Contour[data->contournum].UserPoints[i],
obj->Contour[data->contournum].UserPoints[i + 1],
data->whichVector);
}
_endthreadex( 0 );
return 0;
}
SetCubicBezier looks like this:
void OGLSHAPE::SetCubicBezier(USERFPOINT &a,USERFPOINT &b, int ¤tvector )
{
std::vector<GLdouble> temp;
if(a.RightHandle.x == a.UserPoint.x && a.RightHandle.y == a.UserPoint.y
&& b.LeftHandle.x == b.UserPoint.x && b.LeftHandle.y == b.UserPoint.y )
{
temp.clear();
temp.push_back((GLdouble)a.UserPoint.x);
temp.push_back((GLdouble)a.UserPoint.y);
ThreadPts[currentvector].push_back(temp);
temp.clear();
temp.push_back((GLdouble)b.UserPoint.x);
temp.push_back((GLdouble)b.UserPoint.y);
ThreadPts[currentvector].push_back(temp);
}
}
The code that calls the threads looks like this:
for(int i = 0; i < Contour.size(); ++i)
{
Contour[i].DrawingPoints.clear();
if(Contour[i].UserPoints.size() < 2)
{
break;
}
HANDLE hThread[4];
SHAPETHREADDATA dat;
dat.objectptr = (void*)this;
dat.start = 0;
dat.end = floor((Contour[i].UserPoints.size() - 1) * 0.25);
dat.whichVector = 0;
dat.contournum = i;
hThread[0] = (HANDLE)_beginthreadex(NULL,0,&BezierThreadProc,&dat,0,0);
dat.start = dat.end;
dat.end = floor((Contour[i].UserPoints.size() - 1) * 0.5);
dat.whichVector = 1;
hThread[1] = (HANDLE)_beginthreadex(NULL,0,&BezierThreadProc,&dat,0,0);
dat.start = dat.end;
dat.end = floor((Contour[i].UserPoints.size() - 1) * 0.75);
dat.whichVector = 2;
hThread[2] = (HANDLE)_beginthreadex(NULL,0,&BezierThreadProc,&dat,0,0);
dat.start = dat.end;
dat.end = Contour[i].UserPoints.size();
dat.whichVector = 3;
hThread[3] = (HANDLE)_beginthreadex(NULL,0,&BezierThreadProc,&dat,0,0);
WaitForMultipleObjects(4,hThread,true,INFINITE);
}
Is there something wrong with this?
I'd expect it to fill ThreadPts[4]; ... There should never be any conflicts the way I have it set up. I usually get error writing at... on the last thread where dat->whichvector = 3. If I remove:
dat.start = dat.end;
dat.end = Contour[i].UserPoints.size();
dat.whichVector = 3;
hThread[3] = (HANDLE)_beginthreadex(NULL,0,&BezierThreadProc,&dat,0,0);
Then it does not seem to crash, what could be wrong?
Thanks
The problem is that you're passing the same dat structure to each thread as the argument to the threadproc.
For example, When you start thread 1, there's no guarantee that it will have read the information in the dat structure before your main thread starts loading that same dat structure with the information for thread 2 (and so on). In fact, you're constantly directly using that dat structure throughout the thread's loop, so the thread won't be finished with the structure passed to it until the thread is basically done with all its work.
Also note that currentvector in SetCubicBezier() is a reference to data->whichVector, which is referring to the exact same location in a threads. So SetCubicBezier() will be performing push_back() calls on the same object in separate threads because of this.
There's a very simple fix: you should use four separate SHAPETHREADDATA instances - one to initialize each thread.