|
I am working on a project where I need to track information for each row in a listctrl.
I have create a class for the tracking.
Then when I load the listctrl I create a new class and store the pointer in the SetItemData of the row.
Example:
SetItemData( GetItemCount() - 1 , ( DWORD ) new CTrackingObject() );
This works great. The problem I have: "How do I delete the class when the ListCtrl is destroyed.
I have tried overloading the DeleteAllItems() but when I call the GetItemCount() method, I get an error.
Any ideas of how I can call the pointers from the listctrl and delete the classes?
|
|
|
|
|
Cedar Sith wrote:
SetItemData( GetItemCount() - 1 , ( DWORD ) new CTrackingObject() );
This is extremely unsafe code. The first parameter to SetItemData() should be the return value of InsertItem() .
Cedar Sith wrote:
Any ideas of how I can call the pointers from the listctrl and delete the classes?
Whenever the window that owns the list contol is being destroyed, that is the correct time to delete each data item in the control.
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
DavidCrow wrote:
Whenever the window that owns the list contol is being destroyed, that is the correct time to delete each data item in the control.
I assume you mean in the destructor of the listctrl.
I have this code but I still get errors.
for ( int i = 0 ; i < GetItemCount(); i++ ) {
delete ( CShippingObject* ) GetItemData( i );
}
GetItemCount throws an error.
Any new suggestions?
P.s. I have changed my code to be
int nNewId = InsertItem( ...);
SetItemData( nNewId , ( DWORD ) new CTrackingObject() );
|
|
|
|
|
Cedar Sith wrote:
I assume you mean in the destructor of the listctrl.
No, I mean the owner of the list control. That's usually a dialog or a form view.
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
DavidCrow wrote:
No, I mean the owner of the list control. That's usually a dialog or a form view.
I placed the following code in the form view destructor
for ( int i = 0 ; i < GetItemCount(); i++ ) {
delete ( CTrackingObject* ) GetItemData( i );
}
and received the same error.
It is almost as if once the parent window is closed the GetItemCount method no longer works.
Any new ideas? David, Thanks for the information so far.
|
|
|
|
|
Cedar Sith wrote:
placed the following code in the form view destructor
That won't work. You have to do it before the list view is destroyed.
Cedar Sith wrote:
It is almost as if once the parent window is closed the GetItemCount method no longer works.
Of course it doesn't. None of the methods will work; because the list view has already been destroyed. You'll have to put the code in OnDestroy() at the very latest, before you call the base class OnDestroy() handler.
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
Ryan Binns wrote:
OnDestroy()
OnDestroy was the key. Thank you.
I was able to call my overloaded DeleteAllItems that deleted all of the pointers from an overloaded OnDestroy in my Overloades CmyListCtrl Class.
Here are my methods:
BOOL CmyListCtrl::DeleteAllItems( )
{
if ( m_lpszType == "ShippingQuotes" ) {
for ( int i = 0 ; i < GetItemCount(); i++ ) {
delete ( CShippingObject* ) GetItemData( i );
}
}
return CListCtrl::DeleteAllItems();
}
void CmyListCtrl::OnDestroy()
{
DeleteAllItems();
CListCtrl::OnDestroy();
}
Thank you for everyone that helped me out.
|
|
|
|
|
Cedar Sith wrote:
m_lpszType == "ShippingQuotes"
What type is m_lpszType ? LPCTSTR ? If so, this comparison almost definitely won't work. You can't compare two pointers as though they were strings. All it will check is that the pointers point to the same location. Even if they point to the same thing, if they are at different addresses, the comparison will be false. Use _tcscmp() instead.
Of course, if you're using CString this won't be a problem
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
Ryan Binns wrote:
m_lpszType == "ShippingQuotes"
m_lpszType is a CString. I use the overloaded CmyListCtrl in multiple places. Not every ListCtrl has pointers. So I use the type the differentiate the listctrls.
|
|
|
|
|
It seems that the MFC code for GetItemData and GetItemCount calls the following code:
ASSERT(::IsWindow(m_hWnd));
So if the window is being closed, mfc has already destroyed the m_hWnd pointer and mfc throws and error.
If anyone has an ideas on how to delete objects whose pointers have been placed in the itemdata field ... please let me know.
Thank you.
|
|
|
|
|
At the moment I'm trying to make an effort to use std::string and std::ifstream in my work, instead of using "stdio.h" . My main objective is to write elegant code -- performance is not an issue!
I need to read a lot of blocks (of various sizes) from file, and append them to various string buffers. The problem is that functions like ifstream::read are designed to read into char* style buffers, not string s; however there seems to be some kind of relationship between streambuf s and string s that I figured might make my life easier...?
using namespace std;
...
string mystring;
ifstream inputfile;
int length = 20; ...
char* buffer = new char [length];
inputfile.read (buffer, length);
mystring += buffer;
delete[] buffer;
char ch;
for (int i=0; i<length; i++)
{
inputfile >> ch;
mystring += ch;
}
I have the gut feeling that there must be a really elegant way to do this, using some combination of streambuf / ifstream::operator>> / ifstream::read etc. I figured the whole point of using std::string was that it can worry about the allocation side of things behind the scenes. However I'm finding the documentation a little cryptic and generalised.
Any ideas?
It's quite possible I just want the moon on a stick and I should go back to BASIC...
|
|
|
|
|
LiquidEyes wrote:
Any ideas?
getline(inputfile, mystring); will read a string from a file. You can pass a third parameter (a character) that specifies a delimiter to use during the reading if you need to. By default, it stops after a newline character.
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
Thanks for the reply. However I don't see how it will know to stop after (say) 20 characters? Without a delimeter, will it read the whole file into the string?
I want to do the STL equivalent of
fread( mystring, sizeof(char), length, inputfile );
or failing that, use something more elegant than a char[] (which I have to allocate myself) as an intermediate buffer.
|
|
|
|
|
From memory I think you can do getline(infile, mystring, "\n") or something.
Kevin
|
|
|
|
|
I don't want it to stop on 'newline'. I want it to read a fixed number of bytes.
|
|
|
|
|
I couldn't find that getline with no. of bytes that Ray mentioned. I suppose you could use the getline that gets the whole line and then use a substring function. Not as elegant but still avoids char*.
Kevin
|
|
|
|
|
LiquidEyes wrote:
However I don't see how it will know to stop after (say) 20 characters?
It doesn't. You'll have to use the read() method of ifstream to do that.
LiquidEyes wrote:
Without a delimeter, will it read the whole file into the string?
No, as I said, the default delimiter is a newline - it will read a single line.
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
You'll have to use the read() method of ifstream to do that.
Precisely. Which takes us back to my original question ... what structure can I read into instead of an old fashioned char* array?
I just thought there might be an elegant way, using vector s or string s or something, that didn't involve allocating char s manually. As I said, maybe I just want the moon on a stick.
|
|
|
|
|
LiquidEyes wrote:
what structure can I read into instead of an old fashioned char* array?
Just quickly looking at the docs, it appears you can use ifstream::getline(mystring, number_of_chars) . If you pass a size of, say, 10, it reads 9 characters and appends a NULL. Once again, you can add a third parameter which is the delimiter if you need it.
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
Hi all,
I'm running myProg.exe and while it is still process, I killed the process by either going to task manager or right click and close. Then sometime, when I rebuild it again, it failed to rebuild.
<br />
myProg Command line warning D4028 : minimal rebuild failure, reverting to normal build<br />
C:\myProg\myProg\myProg.cpp fatal error C1033: cannot open program database 'c:\myProg\myProg\deug\vc70.idb'<br />
C:\myProg\myProg\myProg.cpp fatal error C1033: cannot open program database 'c:\myProg\myProg\deug\myProg.pdb'<br />
<br />
I have to either delete the myProg.pdb manually or if I can't (sometime get the error message saying, myProg.pdb is still in used), I have to restart the computer in order to rebuild the project..
Is anyone of you have the same experience that I'm facing.. please tell me what is wrong with it?
Thank you.
|
|
|
|
|
pnpfriend wrote:
I killed the process by either going to task manager...sometime get the error message saying, myProg.pdb is still in used...
Are you killing the myprog.exe or msdev.exe process?
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
|
If I create a window in another window in the non-client area then send the WM_PAINT message to the child window if the parent receives a WM_NCPAINT message, the client window doesn't redraw (the non-client area it is on is still garbled with the old pixels that were in those rect). How can I solve this?
|
|
|
|
|
hello
i want to make ActiveX control (VC++6.0) build from other ActiveX controls created in run time. i used MFC ActiveX Wizard to generate the code and now:
1) i have AfxEnableControlContainer() in InitInstance
2) in OnDraw i'm trying to do sth. like:
this->CreateControl("QButton.Button", "", WS_VISIBLE, rc, this, IDR_BATON, NULL, FALSE, NULL);
but it causes run time error (assertion failed with hwnd argument).
can anybody help me?
thanks in advance
--
s3b0
|
|
|
|
|
i have two vectors i am trying to compare the first is a string vector and the other is a char vector. i am trying to find for example the word hello in the grid vector and i can find the fist char but i dont know how to move or set up a loop to check all the possible directions for the next char in the string. here is a bit of my code. Once the first char is found i need to find the next which the next char could be in 9 possible directions.
-String Vector-
01234
0hello 1apple
2car
3me 4men
5ran
6woman
-Grid Vector-
01234
0cenad
1aatps
2rnrpj
3hello
4wmneo
/*------------------- A Word Checker ----------------------*/
for(int i=0; i < GridVector.size(); i++)
{
for(int j=0; j < GridVector.size(); j++)
{
if(StringVector[0][0] == GridVector[i][j])
{
{
}
}
|
|
|
|