|
I made the changes you suggested, (you were right on track of understanding
what was not working for me). Now when I compile the program and try to
run it there always is a run time error that happens. I get a box that pops
up a with "Unhandled Exception". Hitting OK to this dumps me into the
debugger with the current code pointer positioned at the BEGIN_MESSAGE_MAP(CStringEdit, CEdit)
line of the CStringEdit class code. I have no idea of what casues this
or what to do about it.
Take a look at what I now have and tell me if you can see anything wrong
with it. Here is what I have:
In the customized edit control called CStringEdit header file StringEdit.h there is:
class CStringEdit : public CEdit
{
....
....
protected:
// Generated message map functions
//{{AFX_MSG(CStringEdit)
afx_msg BOOL OnUpdate();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
...
...
}
Then in the implementation, StringEdit.cpp, file I have the following code following
your suggestion.
//////////////////////////////////////////////////
//
// BEGIN_MESSAGE_MAP and END_MESSAGE_MAP macros
//
BEGIN_MESSAGE_MAP(CStringEdit, CEdit)
//{{AFX_MSG_MAP(CStringEdit)
ON_CONTROL_REFLECT_EX(EN_UPDATE, OnUpdate)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
And for the actual update routine itself in the same file there is the
member function as shown below. This function is supposed to validate
the edit box content per the definitions of my CStringEdit class but
the parent dialog may want to further validate the edit box content.
BOOL CStringEdit::OnUpdate()
{
// local code in here to validate edit contents and possibly
// modify and or reject the most recent changes by replacing
// edit content with last know valid content.
...
...
return(FALSE);
}
Now in the parent dialog class the code that I have now in place
to attempt to provide the further validation of the looks as follows.
In the dialog header file there is this code...
class CEditCounters : public CDialog
{
...
...
// Dialog Data
//{{AFX_DATA(CEditCounters)
enum { IDD = IDD_EDIT_COUNTERS };
...
CStringEdit m_CntFormat_Edit;
...
//}}AFX_DATA
...
// Generated message map functions
//{{AFX_MSG(CEditCounters)
...
afx_msg void OnUpdateCntFormatEdit();
...
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
...
...
// function to check a counter format string
BOOL CEditCounters::FormatCheck(CString *pCntFormat);
};
And for completeness (please bear with here) the dialog implementation file
(.cpp file) has the code snippetts as shown below.
...
...
BEGIN_MESSAGE_MAP(CEditCounters, CDialog)
//{{AFX_MSG_MAP(CEditCounters)
...
ON_EN_UPDATE(IDC_CNT_FORMAT_EDIT, OnUpdateCntFormatEdit)
...
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
...
...
void CEditCounters::OnUpdateCntFormatEdit()
{
CString strBuffer;
m_CntFormat_Edit.GetText(strBuffer);
if(FormatCheck(&strBuffer) == FALSE) // validate the string
{
m_CntFormat_Edit.SetText(strBuffer); // replace if changed by validate
}
}
...
...
BOOL CEditCounters::FormatCheck(CString *pCntFormat)
{
// validate string and if ok return TRUE else
// suggest a change in string and return FALSE
...
...
}
|
|
|
|
|
Seems to me everything's fine. Have you tried with "Rebuild All"? Sometimes it helps.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Thanks for looking at all my code!! I tried the ReBuild All again (I had done this before anyway out of normal practice) but it does not help the problem. I have now done some debug investigation. I set two breakpoints. One at the UpDate function in the CStringEdit class and one at the Update handler code in the parent dialog code. What seems to be happening is that the two breakpoints are being hit alternately first the edit control update and then the parent update routine in a never ending loop. I see the ESP register steadily going downard in addresses at each breakpoint. I am guessing that there is an interlock in here that some how that makes the stack grow till it reaches its lower bound and tries to reference memory outside my programs stack area. DOes this seem like this could happen?? And if so how does one fixup to prevent a deadly loop like this from happening?
|
|
|
|
|
Actually I found that my check code in the dialog was never happy with the edit
text and was changing the edit box content...This apparently cases the edit control
to get another update message and so the process went on till some 12 megabytes of
stack get used up!!!!
Thanks again,,,I think I am on track now of how to correct the problem. Your
help with ON_CONTROL_REFLECT_EX is more than appreciated !!
Mike Karas
|
|
|
|
|
In case it is of any help, I suggest you follow the following policy when implement OnUpdate : Have a boolean flag, say m_bInOnUpdate to prevent reentrancy, and do not call SetWindowText till you've parsed the whole string. Sort of like this:
BOOL CStringEdit::OnUpdate()
{
if(m_bInOnUpDate)return TRUE;
m_bInOnUpDate=TRUE;
CString str;
GetWindowText(str);
SetWindowText(str);
m_bInOnUpDate=FALSE;
} (Actually, either of these two techniques would suffice alone.)
As a quality of implementation issue, you can also treat the selection (the highlithed portion) of the edit box and make it consistent with your "purged" string. Use GetSel /SetSel for this.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Hi ,
I have a window ,which it has got lot of images.
If the user clicks anywhere in the window,i need to update some things.If the user keeps on clicking for about 2-3 minutes.Then the dc i receive in the OnPaint() or OnEraseBkGnd() will be null.
Is there any way to solve this problem..
Thanks
Neha
|
|
|
|
|
well.. this sounds for me like a resource leak...
maybe this article helps you any further:
http://www.codeproject.com/gdi/csavedc.asp
hope this helps
bernhard
Sometimes I think the surest sign for intelligent life elsewhere in
the universe is that none of them ever tried to contact us.
|
|
|
|
|
But when i run through Boundscheker.there was no resource or memory leaks..
Thanks
Neha
|
|
|
|
|
well.. i didn't know that..
i've never used boundschecker.. so i don't know anyhting bout i neither..
if you could post some pseudocode here.. maybe this would help.. (just to show the context how're you using your dc functions)
bernhard
Sometimes I think the surest sign for intelligent life elsewhere in
the universe is that none of them ever tried to contact us.
|
|
|
|
|
I have a doubht,Like in my code some parts i had used
HDC hDC=::GetDC(this->m_hWnd);
After my work is done i will say DeleteDC(hDC);
Will that be fine?
Thanks
Neha
|
|
|
|
|
First off:
An application must not delete a device context whose handle was obtained by calling the GetDC function. Instead, it must call the ReleaseDC function to free the device context.
Secondly
You have to restore the HDC when using SDK type DC's
With MFC i don't think you have this problem.
Yes it's a GDI leak, use VC++ stress utility and watch the GDI values drop like mad. I don't think BoundsChecker checks for these kind of memory leaks...I don't have and never used it, only know what i've read.
Cheers
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
If i do ReleaseDC() also , i have the problem.
I have VC++ 6.0.But in tools i didn't find any stress utility.
Thanks
Neha
|
|
|
|
|
Visual C++ tools menu and you didn't find stress...?
Which version of C++ are you using...
Anyways...Windows 98 comes with (if you install it) resource meter, this should do the same trick.
Even if you call Release it'll still leak, yes...I only pointed that out cuz...well MSDN says so...so do it!
You have to restore your original HDC object
I'm tired and i dunno if i can remember correctly, it's been a while since i programmed SDK...
HDC hdc = ::GetDC(this->m_hWnd);
HGDIOBJ oldBrush = SelectObject(hdc, color);
SelectObject(hdc, oldBrush);
DeleteObject(color);
Sorry I had to refer to some old code, you MUST restore the old object back to original state or you will leak.
If this doesn't work...Then i'm gonna need to know more...
Cheers
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
Correction this leakage will ocurr in MFC...so always restore your objects.
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
If you're using pens or brushes, not restoring them results in instant memory leak also. As has been suggested, use the W98 resource meter to see where your GDI resources are going. If you have W2000 or XP, you won't get the problem, the OS plugs the leak for you.
Christian
I have come to clean zee pooollll. - Michael Martin Dec 30, 2001
Picture the daffodil. And while you do that, I'll be over here going through your stuff.
|
|
|
|
|
Thanks all for the replies...
I got the problem fixed ...
Neha
|
|
|
|
|
HockeyDude wrote:
I don't think BoundsChecker checks for these kind of memory leaks
Boundschecker does I think. It reports a list of all resource leaks after the program terminates. It can't do it while the program is running.
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?
Please step to the rear of the car and make room for more victims. - John Simmons the Outlaw programmer, 1st Feb 2002, in the lounge
|
|
|
|
|
Aren't I glad I said i don't think...
I read an article on CodeGuru...basiaclly explaining how BoundsChecker is crap and the same can be accomplished with _CrtDebug memory functions.
I've never used it...so i'm unaware of it's abilities..i was only going on what someone else had said. My mistake..
Cheers!
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
I am new to templates in C++. Say I have declared Vector<int> in first.cpp and also in Second.cpp. Does the compiler generate two Vector<int> implementation ?. If so is there any way I can force the compiler to generate just a single implementation.
Thanks
|
|
|
|
|
It works exactly the same as if you had two instances of a non-templated class.
The template code bloat is that the compiler needs to generate new classes for each DIFFERENT template parameter it is used with.
Christian
I have come to clean zee pooollll. - Michael Martin Dec 30, 2001
Picture the daffodil. And while you do that, I'll be over here going through your stuff.
|
|
|
|
|
|
It is the linker's responsibility to strip off duplicates across compilation units, so in general there'll be only one implementation.
Code bloat can stem from another reasons:- instantiating
vector s (or other template classes) of many different types
- code bloat resulting from massive inlining
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Joaquín M López Muñoz wrote:
code bloat resulting from massive inlining
Although I'll point out that inline is a suggestion to the compiler, not a command. If you inline stupidly, the compiler will ignore you.
Christian
I have come to clean zee pooollll. - Michael Martin Dec 30, 2001
Picture the daffodil. And while you do that, I'll be over here going through your stuff.
|
|
|
|
|
How can I get the WebPage's Last Modified Time.
Following is my code,but it doesn't work properly.
::HttpQueryInfo always return FALSE. Why?
BOOL CChkOlDlg::IsUrlModified(CString strUrl)
{
BOOL bRet = FALSE,bSucc = FALSE;
HINTERNET hSession ;
hSession = ::InternetOpen(_T("CheckOl"),
PRE_CONFIG_INTERNET_ACCESS,
_T(""),
INTERNET_INVALID_PORT_NUMBER,
0 ) ;
if(hSession)
{
HINTERNET hConnect = ::InternetConnect(hSession,
GetServer(strUrl),
INTERNET_INVALID_PORT_NUMBER,
"",
"",
INTERNET_SERVICE_HTTP,
0,
0);
if(hConnect != NULL)
{
HINTERNET hHttpFile = ::HttpOpenRequest(hConnect,
_T("GET"),
strUrl,
HTTP_VERSION,
NULL,
0,
INTERNET_FLAG_DONT_CACHE,
0) ;
if(hHttpFile != NULL)
{
BOOL bSendRequest = ::HttpSendRequest(hHttpFile, NULL, 0, 0, 0);
if(bSendRequest)
{
char bufQuery[32] ;
DWORD dwLengthBufQuery = sizeof (bufQuery);
BOOL bQuery = ::HttpQueryInfo(hHttpFile,
HTTP_QUERY_LAST_MODIFIED,
bufQuery,
&dwLengthBufQuery,
NULL) ;
if(bQuery)
{
bSucc = TRUE;
}
}
VERIFY(::InternetCloseHandle(hHttpFile));
}
VERIFY(::InternetCloseHandle(hConnect)) ;
}
}
if(!bSucc)
{
}
return bRet;
}
|
|
|
|
|
Possibly because web servers rarely send out the last modified information in the header of an HTTP response.
Test this with telnetting to your host on port 80 and issueing your GET (or HEAD) request manually. Is the info there?
Sorry to dissapoint you all with my lack of a witty or poignant signature.
|
|
|
|