|
Thanks for answering my question.
This helps me a lot.
So consequently, in UNICODE circumstance, the complier automatically casts PCXSTR to LPCWSTR, or LPCTSTR?
Also, that is why CSimpleStringT only needs operator PCXSTR()?
Thank you.
|
|
|
|
|
Yes, Dean. You're correct. Excerpt from the header atlsimpstr.h
template< typename BaseType = char >
class ChTraitsBase
{
public:
typedef char XCHAR;
typedef LPSTR PXSTR;
typedef LPCSTR PCXSTR;
typedef wchar_t YCHAR;
typedef LPWSTR PYSTR;
typedef LPCWSTR PCYSTR;
};
template<>
class ChTraitsBase< wchar_t >
{
public:
typedef wchar_t XCHAR;
typedef LPWSTR PXSTR;
typedef LPCWSTR PCXSTR;
typedef char YCHAR;
typedef LPSTR PYSTR;
typedef LPCSTR PCYSTR;
};
"Real men drive manual transmission" - Rajesh.
|
|
|
|
|
Thanks.
This helps me a lot and I now feel that I understand MFC more than before.
|
|
|
|
|
Is AfxGetMainWnd a function pointer to method "AfxGetMainWnd"?
I use "(CMainFrame*)AfxGetMainWnd;" to get CMainFrame pointer, but no Exception show.
|
|
|
|
|
yu-jian wrote: Is AfxGetMainWnd a function pointer to method "AfxGetMainWnd"?
No. Why would you think that and why do you expect an exception?
By the way, you have the source code - you can look at the function
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Because I use the AfxGetMainWnd but AfxGetMainWnd() to get CMainFrame, when compiling no error show. When running, I found that that m_hwnd of (CMainFrame*)AfxGetMainWnd is 0x00000000, I think that if the compiler can give a exception when compiling, it can save much time for me .
|
|
|
|
|
As you can see here[^] AfxGetMainWnd() returns a CWnd* i.e. a pointer to a CWnd object. In your call you actually want a pointer to your CMainFrame object, so you have to use the cast to let the compiler know that the return value will actually be a pointer to a different object type than described in the function definition. Remember also that you can only cast to an object that derives from the original, and since CMainFrame derives from CWnd this will work OK.
The best things in life are not things.
|
|
|
|
|
You are using a C style typecast here. By doing so you tell the compiler taht YOU know that the variable you're casting is in truth of the type you are casting to. The compiler will therefore ignore any other information and believe you.
The compiler is simply doing what you tell it: ignore the stupidity of the cast.
Maybe you can take one lesson from this: never use C-Style type casts. They are almost always an error!
Check out GotW # 17 to learn more about type casts and how (not) to use them.
|
|
|
|
|
If you want an exception, you should try calling any of the CMainFrame methods using the returned pointer.
|
|
|
|
|
Why would that happen? As far as I recall from MFC CMainFrame derives from CFrameWnd which derives from CWnd , so it should be OK. I must admit I don't use MFC these days so I may well be wrong.
The best things in life are not things.
|
|
|
|
|
Here is what I meant.
This code will work fine -
CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
pFrame->BringWindowToTop(); But this one -
CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd;
pFrame->BringWindowToTop(); Because AfxGetMainWnd without the () is a function pointer and not a CWnd derived class pointer.
|
|
|
|
|
Very true, but I would not expect the second sample to compile.
The best things in life are not things.
|
|
|
|
|
I just did.
|
|
|
|
|
Me too; fascinating, you learn something new every day.
The best things in life are not things.
|
|
|
|
|
yu-jian wrote: I use "(CMainFrame*)AfxGetMainWnd;" to get CMainFrame pointer
Isn't this just getting the address of the AfxGetMainWnd() function rather than actually calling it?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Some people are making such thorough preparation for rainy days that they aren't enjoying today's sunshine." - William Feather
|
|
|
|
|
Exactly and so typecasting it to a CMainFrame* is like taking a roller coaster ride standing up.
|
|
|
|
|
Thanks for every one's replies.
I know that AfxGetMainWnd is the pointer of function AfxGetMainWnd,
the statement, (CMainFrame*)AfxGetMainWnd converts a wrong pointer to CWnd*.
|
|
|
|
|
I would like to create a service or background running program (something that minimizes to system tray).
It would have a path list of external applications, eg.
- C:\App1\Task1.exe
- C:\App2\Task2.exe
- C:\App3\Task3.exe
It would start the first one and monitor the process details (CPU Usage, Mem Usage, and maybe I/O Writes). Each application will do their jobs for a couple of minutes then go idle - hence completed the task. At this point the CPU Usage = 0, Mem Usage, etc. will be idle.
Then I need to close/kill that process and start the next application in the list. And this repeats as above and so on.
Does anyone know how to execute an external program, monitor the process details, then kill it?
|
|
|
|
|
Why can't the program exit by itself once it's done?
When you create a process, you can wait on the process handle, and it will signal when the process closes.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
andwan0 wrote: Does anyone know how to execute an external program
CreateProcess[^]
|
|
|
|
|
That isn't ideal of course.
The reason is that it isn't deterministic. You don't know it is done but rather you are guessing it.
As an example where there could be real problems if one process is relying on an external server and there are network problems it could take a minute for the server to send a response. During which time the process is blocked - and thus not doing anything.
At a minimum you are going to need to wait a significant amount of time to be sure it isn't doing anything.
|
|
|
|
|
You can start an application using CreateProcess .
If you plan to run the process from a service, you may need to use CreateProcessAsUser or CreateProcessWithLogonW or CreateProcessWithTokenW instead.
To monitor a process there are several functions available like GetProcessMemoryInfo , InitializeProcessForWsWatch , GetProcessIoCounters , QueryProcessCycleTime etc.
To kill a process, you can use the TerminateProcess function, but this is not recommended as this is an unconditional termination. Instead you must have some sort of built in mechanism in the process for it to terminate itself. This could be by sending a message or by setting an event if you want to control it from a service.
|
|
|
|
|
INT* pInt = new int ;
LPVOID pVoid = pInt ;
delete pVoid ;
will pVoid(object) be deleted cleanly as "delete pInt" does? I am a little worried since there's no way to indicate the object size.
|
|
|
|
|
With "basic" types it might work.
With doing this with a "real" classes it will not call the class destructor and will lead to memory leaks
Watched code never compiles.
|
|
|
|
|
I'm pretty sure it'll work with standard types, and for classes, it's undefined behavior. So it should be avoided anyway.
|
|
|
|