|
You mean like this[^]?
CPUA 0x5041
Sonork 100.11743 Chicken Little
"So it can now be written in stone as a testament to humanities achievments "PJ did Pi at CP"." Colin Davies
Within you lies the power for good - Use it!
|
|
|
|
|
I am a little confused about the DrawItem member function. I have tried to create a button class derived from CButton that displays a bitmap but basically acts like a checkbox control with the pushbutton style. i.e when the button is raised, pushing on the button will cause the button to remain depressed until the next button push.
Since, I couldn't find a class for checkbox yet alone one that would support a bitmap, I decided to create my own class from CButton and set the BS_CHECKBOX style.
Here's the problem which I'm sure is just my lack of understanding. I got the class working except in order to remain depressed I kept track of my own state from the button's OnClick event and combined with the state passed in DrawItem, I drew the button correctly and everything works great...until I put the button in a toolbar. When in a toolbar the button receives the OnClick event but it doesn't pass or reflect the message back to the toolbar and eventually the framewindow.
I'm thinking maybe I shouldn't have used the OnClick event for the button but rather used DrawItem alone but am not sure. I mean, since DrawItem state can be ODS_SELECTED can't I just keep track of whether the button should remain depressed or not in a variable, toggle the state, and draw the button each time ODS_SELECTED is the active state? Not sure if that works the way I think it might.
Or, is there some way to use OnChildNotify or some other event to make sure I handle the OnClick event and pass it to my parent (toolbar or framewindow eventually)??? Maybe I should have derived from CBitmapButton and just added this state info.
Thanks
|
|
|
|
|
JohnnyG wrote:
When in a toolbar the button receives the onclick event but it doesn't pass or reflect the message back to the toolbar and eventually the framewindow.
Actually, it's exactly the opposite. The OnClicked (BN_CLICKED ) notification message is sent to the parent window, or better to the window specified as parent during control creation (the parent window can be changed later).
MFC reflects notification messages (either in the form of WM_NOTIFY or WM_COMMAND ) back to the child control. The message can or can not be processed by the parent then, in dependence to what message macro you use: ON_xxx_REFLECT or ON_xxx_REFLECT_EX (where xxx can be NOTIFY or CONTROL).
If you use the EX extension the message handler function return value is not void, but a BOOL that specifies if the parent can handle the message as well (TRUE) or not (FALSE). Without EX, the parent is called only if the child does not have an handler for the message.
For details see TN062 (Technical Note 62: Message Reflection for Windows Controls) on MSDN.
Paolo
------
"airplane is cool, but space shuttle is even better" (J. Kaczorowski)
|
|
|
|
|
Paolo,
Thanks, for the reply but I'm still confused. I did read TN062 yesterday and here's part of what it says:
If, in your parent window class, you supply a handler for a specific WM_NOTIFY message or a range of WM_NOTIFY messages, your handler will be called only if the child control sending those messages does not have a reflected message handler through ON_NOTIFY_REFLECT(). If you use ON_NOTIFY_REFLECT_EX() in your message map, your message handler may or may not allow the parent window to handle the message. If the handler returns TRUE, the message will be handled by the parent as well, while a call that returns FALSE does not allow the parent to handle it. Note that the reflected message is handled before the notification message.
So, If in my derived button class, I have ON_NOTIFY_REFLECT_EX(BN_CLICKED, OnClicked)and in my OnClicked member function I return TRUE. What do I need in the framewindow class or even the toolbar class? I mean do I need WM_NOTIFY message handler in one or both of these class files? Currently, I have nothing there but in my application class I have: ON_COMMAND(ID_VIEW_FREEZE, OnViewFreeze) because the button, toolbar button, and menu ID is the same. This worked fine when I was using just a plain CBitmapButton.
|
|
|
|
|
JohnnyG wrote:
So, If in my derived button class, I have ON_NOTIFY_REFLECT_EX(BN_CLICKED, onclicked)and in my onclicked member function I return TRUE.
That's correct, but the BN_CLICKED notification is sent as a WM_COMMAND message and so the right macro should be ON_CONTROL_REFLECT_EX.
For the parent window nothing changes, you handle the notification as usual. The different message macro is used by MFC when looking up the message map, so it knows it has to call both handlers.
Paolo
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? (Chris Maunder)
|
|
|
|
|
Actually, I did have ON_CONTROL_REFLECT_EX...but it still doesn't work. I'm pulling hairs here. So, what you're saying is that if I used ON_CONTROL_REFLECT_EX and return TRUE, it should work and there is nothing left to do MFC wise in any of my other source files?
I put a breakpoint in my app class for the ID of the button (message handler) which is the same as the menu selection ID. If I do the menu selection, I go in there but if I push the button I don't. Instead, I am going into the onclick event handler. However, the button's ID is the same as the menu selection yet both aren't being called when I press the button.
If you want, I can post portions of the source code. Thanks for your help!
|
|
|
|
|
JohnnyG wrote:
So, what you're saying is that if I used ON_CONTROL_REFLECT_EX and return TRUE, it should work and there is nothing left to do MFC wise in any of my other source files?
Yes, exactly. Maybe there's something else that's wrong...
JohnnyG wrote:
If I do the menu selection, I go in there but if I push the button I don't.
Are you sure that notification messages are sent to the frame window and not to the toolbar? I remember in some article I read you have to create the control (it was a combo, but should be the same for a button) as child of the frame (or the window you want to get notifications), then change the parent with SetParent() .
A simple try to discover if the frame gets the message is commenting out the ON_CONTROL_REFLECT_EX line in the message map.
Paolo
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)
|
|
|
|
|
if I have a C++ DLL that exports classes and was compiled by VC6 (sp5) can it be linked to (with the .lib file) in VC7 or does the DLL need to be recompiled with the VC7 compiler?
Also can a VC7 C++ DLL be linked to/used in VC6?
I would expect a NO to both questions, but I just want to make sure, as this may affect whether my work has to go and order 1 or more copies of VC7.
Thanks
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
|
|
|
|
|
Jim Crafton wrote:
I would expect a NO to both questions,
And you would be right.
|
|
|
|
|
It depends.
If you export a C++ class, it would be exported according to the compilers name-mangling scheme. VC6 and VC7 have different name mangling. This could make it impossible for code compiled by one compiler to even find the mangled and exported names exported from code compiled with another compiler.
If you'd want debug info your also in for a treat since the debug format again changed (seems Microsoft can never get this right).
Depending on what memory management you use, and what dependencies you have from the DLL, it could also make it impossible.
To sum up; using a VC6 DLL (that exports C++ classes) from a VC7 app would have greater chance of success than the other way around, but I wouldn't expect any of these scenarios to work - there's just too much unspecified (and most certainly undocumented) binary incompatibilities.
The following are the only two ways around this that I'm aware of:
1. Export only a C interface that internally in the DLL uses C++ classes (lots of casting, and cumbersome). Example (modulo proprietary keywords):
For a fictious class "foo", defined as
class foo
{
foo(int n);
~foo();
int do_something(int n);
};
export the C functions
struct foo_t* foo_create(int n)
{
return (foo_t*)new (std::nothrow) foo(n);
}
void foo_destroy(struct foo_t* p)
{
delete (foo*)p;
}
int foo_do_something(struct foo_t* p, int n)
{
foo* pFoo = (foo*)p;
return pFoo->do_something(n);
}
Well, you get the idea.
2. Export factory functions (with C linkage) that returns pointers to interface classes that only have virtual functions. This resembles the way COM works, though you would of course not have to implement the COM deficiencies.
++luck;
|
|
|
|
|
Hello,
I have a console app where I spawn a worker thread to do some work .. I do a wait for single object.. if the object is around for 30 seconds I want to kill the worker thread. Here is my code.. note "delete pStatus" causes a memory leak. How can I kill the thread with out creating a memory leak?
CWinThread* pStatus = (CWinThread*)AfxBeginThread(ThreadStatus,
theApp,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED,
NULL);
pStatus->m_bAutoDelete = TRUE;
pStatus->ResumeThread();
int nWait = WaitForSingleObject(pStatus->m_hThread, 30000);
if(nWait == WAIT_TIMEOUT)
{
printf("Timed Out..\n");
delete pStatus;
}
Thanks,
Rob
|
|
|
|
|
If the worker thread allocates any memory, freeing up this memory will not occur, when you execute your 'delete pStatus;'. What is so special about 30 seconds? It would help if more info could be given about what the worker thread is doing.
Chris Meech
"what makes CP different is the people and sense of community, things people will only discover if they join up and join in." Christian Graus Nov 14, 2002.
"AAAAAAAAAHHHHHH!!!!! Those leaks are driving me crazy! How does one finds a memory leak in a garbage collected environment ??! Daniel Turini Nov. 2, 2002.
|
|
|
|
|
We use third party software that runs on clients across the world with in the enterprise. The software is kind of like SMS or LANDesk, it reports inventory allows us to do remote software deployment etc..
The application has a html type service that allows us to connect to the node through the browser and look at the nodes status.. I wrote a console tool that pulls the HTML information then parses it for the required info... (this is done in the worker thread) I have found that some of the nodes hang forever when going to the url (even through the browser). So I have to limit the amount of time the thread is trying to pull the info to 30 seconds because we use this tool in a batch file agains thousands of machines... If one hangs the whole process stops.
My problem is that if I need to kill the worker thread it will create a memory leak..
Any ideas?
|
|
|
|
|
RobJones wrote:
I wrote a console tool that pulls the HTML information then parses it for ....
I think the thirty second timeout recognition needs to occur within the thread when you try to pull the HTML. If it's some synchronous call, there should be some kind of timeout config/recognition available, I would think.
Chris Meech
"what makes CP different is the people and sense of community, things people will only discover if they join up and join in." Christian Graus Nov 14, 2002.
"AAAAAAAAAHHHHHH!!!!! Those leaks are driving me crazy! How does one finds a memory leak in a garbage collected environment ??! Daniel Turini Nov. 2, 2002.
|
|
|
|
|
Here is the code for the worker thread.. I have no idea how I could wait on anything in this.. any ideas on how I could re-write it so I could wait??
UINT ThreadStatus(LPVOID lParam)
{
char httpbuff[1024];
TCHAR szCause[2048];
int numbytes;
strError.Format("SUCCESS");
TRY
{
CInternetSession mysession;
CStdioFile *remotefile = mysession.OpenURL(strUrl,1,INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_RELOAD);
while (numbytes = remotefile->Read(httpbuff, sizeof(httpbuff)-1))
{
httpbuff[numbytes];
strBuff += (CString)httpbuff;
}
remotefile->Close();
delete remotefile;
.... SNIP....
}
CATCH_ALL(error)
{
error->GetErrorMessage(szCause,2048,NULL);
strError.Format("%s",szCause);
}
END_CATCH_ALL;
if(!strError.CompareNoCase("SUCCESS"))
{
.... SNIP ....
}
else
printf("ERROR GETTING STATUS - %s\n",strError);
return 0;
}
|
|
|
|
|
You can safely avoid memory leaks if you spawn the thread in a separate process --when the process terminates, all memory resources are claimed back by the OS. This approach is considerably slower than launching a thread, so maybe it doesn't suit your needs.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Joaquín M López Muñoz wrote:
You can safely avoid memory leaks if you spawn the thread in a separate process
Does this mean another executable? If not how do I spawn another process inside my console app? If you have an example I would greatly appreciate it..
Thanks,
Rob
|
|
|
|
|
This is only intended as a last resort, if you cannot modify the code for the worker thread. Since you seemingly can, I'd suggest you try and convert the thread into responsive code: you can avoid locking by specifying INTERNET_FLAG_ASYNC in the construction of your CInternetSession object.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Hello,
INTRODUCTION:
1. I have a dialog that is used to monitor the backup of some files.
2. This dialog has a thread that makes the backup (in order to avoid the hung effect that creates not repainting the window...).
3. My problems appear when while I'm saving data to the floppy disk I remove it: when this happens an exception gets fired.
QUESTION:
I wanted to handle that in order to prevent my app to get hung if a user does this.
The strange fact is that after reading a little of Jeff Richter's book (advanced programming in windows) I've thought that I had understood how the SEH worked, but now this message is appearing and I don't understand why.
this is my code:
__try
{
iRet = CopyFile(csFullSourcePath, csFullDestinationPath, FALSE);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
iRet = 0;
}
if (iRet == 0)
{
iNumErrorsFound++;
csAuxiliar += " : ERROR FOUND!";
bErrorFound = true;
}
the thread has some CString, HANDLE, DWORD and WORD variables...
and the error messages that I receive are:
nonstandard extension used: 'ThreadRespatllar' uses SEH and 'csFullSourcePath' has destructor
where 'ThreadRespatllar' is the thread name and 'csFullSourcePath' is one of the CString variables that are declared in the thread.
NOTE: I get one warning message for each CString declared in the thread.
Thank you in advance.
|
|
|
|
|
This is just a guess, but possibly mixing SEH with MFC exception handling in a MT environment is the culprit. Just wondering though, are these error messages you get when compiling, linking, or executing?
Chirs Meech
"what makes CP different is the people and sense of community, things people will only discover if they join up and join in." Christian Graus Nov 14, 2002.
"AAAAAAAAAHHHHHH!!!!! Those leaks are driving me crazy! How does one finds a memory leak in a garbage collected environment ??! Daniel Turini Nov. 2, 2002.
|
|
|
|
|
Those errors appear at compilation time.
Thank you for your interest.
|
|
|
|
|
Chris Meech wrote:
This is just a guess, but possibly mixing SEH with MFC exception handling in a MT environment is the culprit
Actually, MT has nothing to do with it. SEH and C++ EH is inherently incompatible - you simply can't have C++ stack unwinding in a function that uses SEH (among other things because MS C++ EH is implemented in terms of SEH).
If one absolutely needs both, one would have to create separate functions, where one uses one kind of EH, and then calls the other function that uses the other kind of EH.
|
|
|
|
|
You can handle regular C++ exceptions and SEH all in one with a little code like this:
class SEH_exception:public std::runtime_error
{
public:
SEH_exception(unsigned int code,const char* msg):std::runtime_error(msg),code_(code){}
unsigned int code()const{return code_;}
private:
unsigned int code_;
};
static void SEH_translator(unsigned int code,EXCEPTION_POINTERS*)
{
std::string msg;
switch(code){
case EXCEPTION_ACCESS_VIOLATION: msg="access violation";break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: msg="array bounds exceeded";break;
case EXCEPTION_BREAKPOINT: msg="breakpoint exception";break;
case EXCEPTION_DATATYPE_MISALIGNMENT: msg="datatype misalignment";break;
case EXCEPTION_FLT_DENORMAL_OPERAND: msg="flt denormal operand";break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO: msg="flt divide by zero";break;
case EXCEPTION_FLT_INEXACT_RESULT: msg="flt inexact result";break;
case EXCEPTION_FLT_INVALID_OPERATION: msg="flt invalid operation";break;
case EXCEPTION_FLT_OVERFLOW: msg="flt overflow";break;
case EXCEPTION_FLT_STACK_CHECK: msg="flt stack check";break;
case EXCEPTION_FLT_UNDERFLOW: msg="flt underflow";break;
case EXCEPTION_ILLEGAL_INSTRUCTION: msg="illegal instruction";
case EXCEPTION_IN_PAGE_ERROR: msg="in page error";break;
case EXCEPTION_INT_DIVIDE_BY_ZERO: msg="divide by zero";break;
case EXCEPTION_INT_OVERFLOW: msg="overflow"; break;
case EXCEPTION_INVALID_DISPOSITION: msg="invalid disposition";break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION: msg="noncontinuable exception";break;
case EXCEPTION_PRIV_INSTRUCTION: msg="priv instruction";break;
case EXCEPTION_SINGLE_STEP: msg="single step trap";break;
case EXCEPTION_STACK_OVERFLOW: msg="stack overflow";break;
default:{
char buf[1024];
sprintf(buf,"SEH exception (%x)",code);
msg=buf;
}
break;
}
throw SEH_exception(code,msg.c_str());
}
_set_se_translator(SEH_translator); Now use C++ good old try and catch (no leading underscores). Good luck.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Hello,
Excuse me for having not said anything till now, I've been out of my office some days...
I've tried it, but the compiler tells me:
error C2653: 'std' : is not a class or namespace name Also I've tried to write down (just before the class definition)
using namespace std; but then the message is:
error C2871: 'std' : does not exist or is not a namespace Moreover, after all of this has been done I've tried to get it work using the normal try/catch exception handlers, but if I place them there it seems that the thread gets locked somewhere/somehow...
the code that I've used is:
try
{
hArxiuLog = CreateFile (csFullPathArxiuRegistreCS,GENERIC_WRITE,FILE_SHARE_WRITE | FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL);
}
catch(CException *e)
{
hArxiuLog = INVALID_HANDLE_VALUE;
e->Delete();
}
<code> What I've understood (reading to the MSDN) is that if I place a try statement the exceptions that are in the catch clause are handled by the contents of the catch clause. Then, the code that I've implemented should catch all the exceptions (I think that all the CExceptions are derived from CException class) and then as I delete the exception e->Delete() the code should continue executing normally after the catch clause without hanging the thread.
Am I right?
Thank you in advance.
|
|
|
|
|
As for the std problem, include the definition of std:runtime_error with
#include <stdexcept> Now, replace
catch(CException *e) with
catch(std::exception& e) and don't delete anything. If you like the MFC exceptions more, change the definition of SEH_exception to derive from CException instead of std:runtime_error .
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|