|
|
Hello Manio,
The following is a sample code listing that demonstrates how to call ::ShellExecute() :
HINSTANCE hInstExe = NULL;
hInstExe = ShellExecute
(
(HWND)NULL, // Replace this with your window handle.
(LPCTSTR)"open",
(LPCTSTR)"WordPad.exe",
(LPCTSTR)"c:\\sometext.txt", // Replace this with your specific file.
(LPCTSTR)NULL,
(INT)SW_SHOWNORMAL
);
Looking at your sample code, I think it is an error to specify "Wordpad.exe" together with "myDoc.exe" as in "WordPad.exe myDoc.exe". It is also a little odd that you want WordPad.exe to open an EXE file.
Furthermore, the parameter to Wordpad.exe should be specified in the 4th parameter. In my case, my parameter is "c:\\sometext.txt".
Hope the above will help you, Manio.
Best Regards,
Bio.
|
|
|
|
|
I found that a call to MoveMemory failed for some values of the last parameter dwLen. The call works perfect for all values in 98, but fails for some values in XP. Are there any known issues?
|
|
|
|
|
I bet the memory you are copying is invalid under an NT operating system or the length is too large.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
Hi.
I have a *pointer* to a linked list of objects. I need to write a copy assignment that will allow me to assign a new linked list the same contents as whatever the *pointer* points to.
For example:
MyList *pMList = new MyList;
pMList->insertData() // info.name1 & info.address1;
pMList->insertData() // info.name2 & info.address2;
pMList->insertData() // info.name3 & info.address3;
I would like to write a copy assignment to clone "pMList."
I have tried this:
MyList newList;
newList = *pMList;
------
const CMyList &CMyList:perator=(const CMyList &rCMyList)
{
if (&CMyList == this)
throw exception();
else
{
cloneList(CMyList);
return *this;
}
}
----------
void CMyList::cloneList(const CMyList &rSourceList)
{
cout << "\nCheck0a";
nodeCnt = rSourceList.nodeCnt;
cout << "\nCheck0b";
pOriginNode->info = rSourceList.pOriginNode->info;
CMyListNode *pNewNode = pOriginNode;
cout << "\nCheck 1";
for (CMyListNode *pTraverse = rSourceList.pOriginNode->next; pTraverse != 0; pTraverse = pTraverse->next)
{
try
{
pNewNode->next = new CMyListNode;
}
catch (bad_alloc &dmaError)
{
cerr << "\nError: " << dmaError.what[)
<< "\nPress any key to close program";
cin.ignore(256, '\n');
cin.clear();
exit(1);
}
pNewNode = pNewNode->next;
pNewNode->info = pTraverse->info;
}
cout << "\nCheck2";
pNewNode->next = 0;
}
-----
The code above looks decent. I could not find any logic error. Again, I have a *pointer* to a linked listed of objects. I need to clone that linked list. I could not get the assignment operator to work. Is there something logically incorrect?
Thanks,
Kuphryn
|
|
|
|
|
The first problem that I see with your assignment operator has nothing to do with your problem, but it will cuase a memory leak. You need to delete the existing memory in the current object, before you clone the data from rCMyList.
const CMyList &CMyList:perator=(const CMyList &rCMyList)
{
if (&CMyList == this)
{
throw exception();
}
else
{
cloneList(CMyList);
return *this;
}
}
On to your problem, where does pOriginNode get initialized? It appears that you are just using it.:
void CMyList::cloneList(const CMyList &rSourceList)
{
cout << "\nCheck0a";
nodeCnt = rSourceList.nodeCnt;
cout << "\nCheck0b";
pOriginNode->info = rSourceList.pOriginNode->info;
CMyListNode *pNewNode = pOriginNode;
...
If this pointer is never initialized, then the memory that you assign at this address will be lost. Are you stepping through with the debugger to determine where the problem is, or do you just know at this point that the assignment operator does not work?
|
|
|
|
|
The possible memory leak is not a problem because the program makes certain that "this" is equal to 0 before calling ::cloneList.
pOriginNode gets initialize to CMyListNode in the declaration file (.h).
class CMyList
{
...
private:
CMyListNode = *pOriginNode;
};
As for determination the cause of the crash, I am quite certain that the crash begins here:
void CMyList::cloneList(const CMyList &rSourceList)
{ cout << "\nCheck0a";
nodeCnt = rSourceList.nodeCnt;
cout << "\nCheck0b";
-------Begin crash---------
pOriginNode->info = rSourceList.pOriginNode->info; CMyListNode *pNewNode = pOriginNode;...
---------------------------
For some reason, it does not like anything from "this" assigned to anything from rSourceList.
In other words, it does not want to be assigned, period. I am not sure if the fact that rSourceList is really a pointer to a pointer to a class (pointer->pointer->class object) has anything to do with it.
Kuphryn
|
|
|
|
|
Okay. I got it to work. This is such a "minor" problem. In fact, it is my carelessness.
Here is the new revised working code:
code:
-------------------------------------------------------------------------
void CSList::cloneList(const CSList &rSourceList)
{
cout << "\nCheck0a";
cout << "\nrSourcelist->nodeCnt = " << rSourceList.nodeCnt;
nodeCnt = rSourceList.nodeCnt;
cout << "\nnodeCnt = " << nodeCnt;
cout << "\nCheck0b";
try
{
pOriginNode = new CSListNode;
}
catch (bad_alloc &dmaError)
{
cerr << "\nError: " << dmaError.what()
<< "\nPress any key to close program";
cin.ignore(256, '\n');
cin.clear();
exit(1);
}
pOriginNode->eData = rSourceList.pOriginNode->eData;
CSListNode *pNewNode = pOriginNode;
cout << "\nCheck 1";
for (CSListNode *pTraverse = rSourceList.pOriginNode->next; pTraverse != 0; pTraverse = pTraverse->next)
{
try
{
pNewNode->next = new CSListNode;
}
catch (bad_alloc &dmaError)
{
cerr << "\nError: " << dmaError.what()
<< "\nPress any key to close program";
cin.ignore(256, '\n');
cin.clear();
exit(1);
}
pNewNode = pNewNode->next;
pNewNode->eData = pTraverse->eData;
}
cout << "\nCheck2";
pNewNode->next = 0;
}
------------------------------------------------------------------------
The change was:
------------------------------------------------------------------------
try
{
pOriginNode = new CSListNode;
}
catch (bad_alloc &dmaError)
{
cerr << "\nError: " << dmaError.what()
<< "\nPress any key to close program";
cin.ignore(256, '\n');
cin.clear();
exit(1);
}
------------------------------------------------------------------------
I found out when I looked over the constructor. I found that there were nothing initializing pOriginNode. I then looked at the code for inserting. I saw that if CMyList was empty (pOriginNode == 0), the pOriginNode = new CMyList.
Thanks.
-----------------------
One last related question. Is it good practice to set *all* deleted pointers to right after deleting them?
Kuphryn
|
|
|
|
|
Hi!
I'm having trouble with VC++ 7. My program compiles on VC++ 6 but after i installed VC++ 7 it crashes when I try to: Find("=") in a CString. It says something about Debug Assertion Failed, File: cstringt.h at line 1661, Expression: nCount>=0.
The compiler is also warning me about: '_OLD_IOSTREAMS_ARE_DEPRECATED': name was marked as #pragma deprecated
I have included iostream.h and according to MSDN i should remove the .h to use the new iostream but when I do that the compiler can't find it.
I hope someone can help me!
Regards,
Tobias
|
|
|
|
|
hello. i am not sure what "=" you are trying to do but -
if you are using an if statement you have to use "=="
if you are trying to compare cstring also has a compare and getat functions.
hope this helps.
|
|
|
|
|
Please post some relevant code snippets
Nish
Bow wow wow,
Yippee yo yippee yay,
My miniputt high,
Is now 30 yay.
|
|
|
|
|
Thanks for trying to help but it didn't work... I'm trying to find the position in a CString where a "="-sign is located. Here is the code:
//The next line causes program crash!!!
valuename = readinfo.Left(readinfo.Find("="));
value = readinfo.Right(readinfo.GetLength()-valuename.GetLength()-1);
valuename, value and readinfo are CStrings. This works in VC++ 6 but not in VC++ 7 where it causes the problems I mentioned erlier.
Regards,
Tobias
|
|
|
|
|
Nevermind... I need to add some more errorchecking to my program... I used this code to read a string from a file and find the "="-sign. But i noticed that when the loop found a string where there where no "="-sign the program crashed. This is very strange because it doesn't crash when compiled on VC++ 6...
Well, thanks anyway!
Regards,
Tobias
|
|
|
|
|
Has anyone else noticed some output from TRACE seems to occasionally be dropped before it appears in the debug window?
Am I paranoid? Am I covering my own programming inadequacies by blaming M$?
TIA,
Pete
|
|
|
|
|
donno about that, but i've been bitten already by the size limit of presearved text in the output window; it just won't hold generated C source for a 4MB transparency LUT
Black rooms are calling; To men in leather coats. White labs are cooking up the silver ghost. Smashing Pumpkins, Glass and the Ghost Children
|
|
|
|
|
The input buffer size for the TRACE output window is a limited size (after all its a pipe between the processes). If your debug output TRACE volume is high and the thread reading the buffer in the VC editor does not run often enough, you can lose TRACE information from the window.
So your not paranoid, if this is what is happening to you.
Roger Allen
Sonork 100.10016
If I'm not breathing, I'm either dead or holding my breath.
A fool jabbers, while a wise man listens. But is he so wise to listen to the fool?
|
|
|
|
|
That sounds like what is happening. I'm writing LOADS of memory allocation info to the debug output to try and track down mem leaks. I guess the only solution would be to put a little pause in my AllocHook() after every TRACE().
Thanks Roger.
|
|
|
|
|
No, you are probably getting bitten by a Visual Studio bug. Visual Studio filters the output of the OutPutDebugString() function, which the TRACE macro ultimately calls, before showing it in the output window in order to remove the application name (which otherwise gets added). However, the filtering is not too smart (at least with version 6.0), and it messes up the display of TRACE messages that includes both an open parenthesis "(" and a colon ":" in that order.
When I add the following lines to my code
TRACE (_T("Text before colon: Text after colon\n"));
TRACE (_T("Text with parenthesis() before colon: Text after colon\n"));
TRACE (_T("Text with open parenthesis( before colon: Text after colon\n"));
TRACE (_T("Text with close parenthesis) before colon: Text after colon\n"));
TRACE (_T("Text with (text inside parenthesis) before colon: Text after colon\n"));
the Visual Studio output window displays
Text before colon: Text after colon
Text with parenthesis() before colon
Text with open parenthesis( before colon
Text with close parenthesis) before colon: Text after colon
Text with (text inside parenthesis) before colon
Intrestingly, if I select this text text in the output window and paste it into notepad, I get
Text before colon: Text after colon
Text with parenthesis() before colonText with open parenthesis( before colonText with close parenthesis) before colon: Text after colon
Text with (text inside parenthesis) before colon
Stephen C. Steel
Kerr Vayne Systems Ltd.
|
|
|
|
|
No, you aren't being paranoid - there is a bug in Visual Studio version 6.0. The TRACE macro ultimately uses OutputDebugString(), and along the way the application name gets prepended to the output. Visual studio has a filter that attempts to strip the application name before showing the text in the output window, but it is buggy.
If I add the following code to my application
TRACE (_T("Text before colon: Text after colon\n"));
TRACE (_T("Text with parenthesis() before colon: Text after colon\n"));
TRACE (_T("Text with open parenthesis( before colon: Text after colon\n"));
TRACE (_T("Text with close parenthesis) before colon: Text after colon\n"));
TRACE (_T("Text with (text inside parenthesis) before colon: Text after colon\n"));
then the Visual Studio output window displays
Text before colon: Text after colon
Text with parenthesis() before colon
Text with open parenthesis( before colon
Text with close parenthesis) before colon: Text after colon
Text with (text inside parenthesis) before colon
Interestingly, if I select the text in the output window and paste it to notepad, I get
Text before colon: Text after colon
Text with parenthesis() before colonText with open parenthesis( before colonText with close parenthesis) before colon: Text after colon
Text with (text inside parenthesis) before colon
Stephen C. Steel
Kerr Vayne Systems Ltd.
|
|
|
|
|
I don't think this is the issue in my case, as I'm not using paretheses.
But thanks anyway, it's always useful to know stuff like that!
Pete
|
|
|
|
|
Can sombody tell me why this won't Beep? Cw is derived from CWinThread and Run() is supposed to be executed so what gives?
//////////////////////////////////
class Cw : public CWinThread
{
public:
int Run();
Cw();
virtual ~Cw();
};
Cw::Cw(){}
Cw::~Cw(){}
int Cw::Run()
{
Beep(1000,500);
return 0;
}
///////////////////////
elsewhere in the program:
Cw* w = new Cw();
w->CreateThread();
|
|
|
|
|
You must override CWinThread::InitInstance . This method by default returns FALSE thus preventing the call to CWinThread::Run .
As a sidenote, I assume you're doing this as a simple test and do not plan to base any actual code on this way of overriding CWinThread::Run : this method has to provide some sort of message pump (which is what does by default). To run separate tasks, it is better to use worker threads.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Thank Joaquin, I'll give it a try. Actually, I need a thread with a message pump because i need to send it commands to do things. I can't figure out how to get message queue on a workerthread so I'm using a UI thread. I plan to put my own GetMessage() call into Run(). I will not be using this thread to service an UI elemets though. The only other thing that I know Run() does is call OnIdle(). Can I safly not call OnIdle() - I don't plan to overide it?
|
|
|
|
|
what?
I think you answered the wrong guy.
Bye
|
|
|
|
|
Joaquín,
I tried what you said and overriding CWinThread::InitInstance works. Thanks! Now I have another question. If I declare several instances of this class they all seem to share the same variables. Maybe I am not saying that right so I will show you the code:
class Cw : public CWinThread
{
public:
DWORD delay;
DWORD freq;
BOOL InitInstance();
int Run();
Cw();
virtual ~Cw();
};
Cw::Cw()
{ delay = 0;
freq=1000;
}
Cw::~Cw(){}
int Cw::Run()
{ Sleep(delay);
Beep(freq,500);
return 0;
}
BOOL Cw::InitInstance(){Return TRUE;}
////////////////////////
Then i have four of the instances and i think i should hear 4 tones one after the other but i don't. Are they all sharing the same delay and freq?
w = new Cw();
w->freq=5000;
w->CreateThread();
x = new Cw();
x->delay=500;
x->freq=2000;
x->CreateThread();
y = new Cw();
y->delay=1000;
y->freq=1000;
y->CreateThread();
z = new Cw();
z->delay=1500;
z->freq=500;
z->CreateThread();
///////////////////////////////////////////////
The above code should sound like this:
w = new Cw();
w->freq=5000;
w->CreateThread();
Sleep(500);
x = new Cw();
x->freq=2000;
x->CreateThread();
Sleep(500);
y = new Cw();
y->freq=1000;
y->CreateThread();
Sleep(500);
z = new Cw();
z->freq=500;
z->CreateThread();
|
|
|
|