|
Yeah, what he said
-pete
|
|
|
|
|
You were right, That WAS the easy part.
Thanks. At least deciphering is a little clearer. But sheesh! trying to track down why is a whole 'nother issue!
Seems I'm chasing a phantom. Sometimes it dies, other times it will stay running for hours At least I know where to look and it has to do with clearing out memory, so I'm on my way, but sheesh, it keeps changing on me
well, back to the testing ground. I'll see what I can come up with using this new found knowledge
Dan Willis
|
|
|
|
|
OK, I found where it is consistantly dying, but I'm not sure why. Here's the function it is dying in:
void CFileView::OnGetDispInfo(NMHDR* pNMHDR, LRESULT* pResult)
{
CString string;
LV_DISPINFO* pDispInfo = (LV_DISPINFO*) pNMHDR;
if (pDispInfo->item.mask & LVIF_TEXT) {
ITEMINFO* pItem = (ITEMINFO*) pDispInfo->item.lParam;
switch (pDispInfo->item.iSubItem) {
case 0: // File name
::lstrcpy (pDispInfo->item.pszText, pItem->strFileName);
break;
case 1: // File size
string.Format (_T ("%u"), pItem->nFileSizeLow);
::lstrcpy (pDispInfo->item.pszText, string);
break;
case 2: // Date and time
CTime time (pItem->ftLastWriteTime);
BOOL pm = FALSE;
int nHour = time.GetHour ();
if (nHour == 0)
nHour = 12;
else if (nHour == 12)
pm = TRUE;
else if (nHour > 12) {
nHour -= 12;
pm = TRUE;
}
string.Format (_T ("%d/%0.2d/%0.2d (%d:%0.2d%c)"),
time.GetMonth (), time.GetDay (), time.GetYear () % 100,
nHour, time.GetMinute (), pm ? _T ('p') : _T ('a'));
::lstrcpy (pDispInfo->item.pszText, string);
break;
}
}
*pResult = 0;
}
Does anyone see anything wrong it? I'm still pluggin away, but this is the root of my problem I believe. All paths merge in this function. Any comments are greatly appreciated guys Thanks!
Dan Willis
|
|
|
|
|
Are you sure pDispInfo->item.pszText is always initialized and it has sufficient size? Same goes for pItem->strFileName.
|
|
|
|
|
no I'm not sure. I didn't realize I needed to be concerned with here. mmmm..... What should I do to initialize it in this case..
I think you're on to something here.
But I thought if I created a pointer to the LV_DISPINFO and then made that pointer point to the pNMHDR that being passed in, I wouldn't have to initialize the pDispInfo->.... since all I'm doing to making the pointer point to the pNMHDR being passed in. Am I right in this assumption?
Dan Willis
|
|
|
|
|
Do not get it. Run it by me again . Could you publish the structure here?
|
|
|
|
|
Ok Here's the LV_DISPINFO structure and the LVITEM structure that's embedded in it
typedef struct tagLVDISPINFO {
NMHDR hdr;
LVITEM item;
} NMLVDISPINFO, FAR *LPNMLVDISPINFO;
typedef struct _LVITEM {
UINT mask;
int iItem;
int iSubItem;
UINT state;
UINT stateMask;
LPTSTR pszText;
int cchTextMax;
int iImage;
LPARAM lParam;
#if (_WIN32_IE >= 0x0300)
int iIndent;
#endif
} LVITEM, FAR *LPLVITEM;
Ok, looking at the code I posted before referencing this data structure:
LV_DISPINFO* pDispInfo = (LV_DISPINFO*) pNMHDR;
if (pDispInfo->item.mask & LVIF_TEXT) {
ITEMINFO* pItem = (ITEMINFO*) pDispInfo->item.lParam;
switch (pDispInfo->item.iSubItem) {
case 0: // File name
::lstrcpy (pDispInfo->item.pszText, pItem->strFileName);
break;
case 1: // File size
string.Format (_T ("%u"), pItem->nFileSizeLow);
::lstrcpy (pDispInfo->item.pszText, string);
break;
case 2: // Date and time
CTime time (pItem->ftLastWriteTime);
BOOL pm = FALSE;
int nHour = time.GetHour ();
if (nHour == 0)
nHour = 12;
else if (nHour == 12)
pm = TRUE;
else if (nHour > 12) {
nHour -= 12;
pm = TRUE;
}
string.Format (_T ("%d/%0.2d/%0.2d (%d:%0.2d%c)"),
time.GetMonth (), time.GetDay (), time.GetYear () % 100,
nHour, time.GetMinute (), pm ? _T ('p') : _T ('a'));
::lstrcpy (pDispInfo->item.pszText, string);
break;
}
}
*pResult = 0;
I thought I would have enough space in the pDispInfo->item.pszText to put what ever string I needed to in there. I guess what you are saying is that I need to
initialize my structure to ensure the proper size.
Dan Willis
|
|
|
|
|
I think AlexO hit the nail in the head.
According to the docs for LVITEM, pszText is an LPTSTR, which means that it's just a pointer. It's not a character buffer, like your program is treating it. When you copy onto it, you're overwriting whatever memory it's pointing to at the moment, which may be harmless in some cases but not in others.
I'm not sure what your function is used for, but it looks like its intent is to change the text of the list view items. I don't understand why you're doing it this way instead of using SetItemText but whatever.
At any rate, the quick solution to this problem is to stop copying into the pointer and just assign it to a buffer that does not go away. The easiest way to do that is to make your string declaration static:
static CString string;
Then instead of ::lstrcpy (pDispInfo->item.pszText, string), you can do something like this:
pDispInfo->item.pszText = (LPTSTR)(LPCTSTR)string;
This will point it to the string's buffer, which will not go away since it will be static.
That's the quick and dirty solution, without knowing much else.
Regards,
Alvaro
All you need in this life is ignorance and confidence, and then success is sure. -- Mark Twain
|
|
|
|
|
that and ITEMINFO. What is ITEMINFO? I could not find in the standard headers.
|
|
|
|
|
typedef struct {
int iImage;
int iSelectedImage;
int iIndent;
LPTSTR pszText;
} ITEMINFO, *PITEMINFO;
Searched MSDN and found it on an example illustrating the use of ComboBoxEx controls. My guess is that ITEMINFO is his own structure which also happens to have the same name.
Regards,
Alvaro
All you need in this life is ignorance and confidence, and then success is sure. -- Mark Twain
|
|
|
|
|
oh,
Sorry guys, I was on a bug hunt (still).
I totally forgot about the ITEMINFO struct. Here is my ITEMINFO Structure:
typedef struct tagITEMINFO {
CString strFileName;
DWORD nFileSizeLow;
FILETIME ftLastWriteTime;
} ITEMINFO;
The reason I am modifying the displayed file information is that I'm really displaying a single "file" for a group of files, and this required me to associate a different filename/filesize/filedate with the item in the item list.
I suppose there was a different way to do it but this was all that came to mind the first time it was written.
I tried the
pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) string;
and declaring the string as static but I'm still having the same issues. Good ole' Dr. Watson. Same exact spot though. I wish I could figure out how to find the exact line from the Dr. Watson. Then I'd be able to narrow it down even more. Although I suspect you guys are right, it has something to do with the buffer size for the text string.
Dan Willis
|
|
|
|
|
Ok now we are getting somewhere . Show how you instantiate your ITEMINFO and how you assign it to lParam
|
|
|
|
|
Here's where I initialize the ITEMINFO. I do this for every item in the list that is to be shown in my ListView.
//
// Allocate a new ITEMINFO structure and initialize it with information
// about the item.
//
ITEMINFO* pItem;
try {
pItem = new ITEMINFO;
}
catch (CMemoryException* e) {
e->Delete ();
return FALSE;
}
pItem->strFileName = fileName;
pItem->nFileSizeLow = fileSize / 1024; // in KB
pItem->ftLastWriteTime = fileAccessTime;
//
// Add the item to the list view.
//
LV_ITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
lvi.iItem = nIndex;
lvi.iSubItem = 0;
lvi.iImage = 0;
lvi.pszText = LPSTR_TEXTCALLBACK;
lvi.lParam = (LPARAM) pItem;
if (GetListCtrl ().InsertItem (&lvi) == -1)
return FALSE;
// now add the file data text
GetListCtrl().SetItemText(nIndex,3,(LPCSTR) fileDataType);
Dan Willis
|
|
|
|
|
I think I may have found my problem. Gimme a couple of minutes
Dan Willis
|
|
|
|
|
How can I get the temp directory? (The one you get from set in the command prompt)
Dylan
|
|
|
|
|
|
Don't know whether you need a second solution, but here it is:
You can also find the environment variables in the registry, f.i. for the current user under the key HKCU/Environment. It's all env variables defined there, not only TEMP.
|
|
|
|
|
Cheers, I didn't know that
Dylan
|
|
|
|
|
GetEnvironmentVariable
Joel Lucsy
|
|
|
|
|
Hi, everyone!
When compiling a project in VC6.0. I find some errors
that say __FUNCTION__ is undefined. Is it a compiler
defined precompile directive? (I have only noticed __FILE__
and __LINE__ before.)
How to resolve the trouble?
Thanks in advance,
George
|
|
|
|
|
Thanks George2, I just discovered another useful macro. As for you question MSDN states that __FUNCTION__ is invalid when
a. outside of function body
b. /EP (Copy Preprocessor Output to Standard Output) or /P (Create Preprocessor-Output File) are used for compiler
|
|
|
|
|
Thanks, AlexO buddie!
Can you tell me what steps should I do if I
want to use it in VC6.0?
Cheers,
George
|
|
|
|
|
I give up (after 20 min) - could not make it work in VC6, Works great in VC7 though
|
|
|
|
|
Thanks, AlexO buddie!
George
|
|
|
|
|
the problem is simple .
i m tryin to encrypt n decrypt somehthing
to i allready have a pub n priv key .
to encrypt i typed CryptGetUserKey( ...) and i got hold of the priv key to encrypt.
to decrypt ...
i wanted the certificate so that i can get the public key .....
how do i do this ??
p.s : is the ciphertext always larger than the plaintext ?
thank you ,
Dmi3
|
|
|
|