Regards,
Pooja Katiyar.
Show a few lines of your code. I would guess you are using a CWnd
pointer that is not actually pointing at a CWnd.
--
Scott McPhillips [VC++ MVP]
Here is the piece of code -
BOOL CZedObjectFrame::OnCmdMsg( UINT nID, int nCode, void * pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo)
{
// call up, does menu and toolbar updates
BOOL rc = FALSE;
if (!CanUserModify() && m_pToolBar != NULL)
{
CToolBarCtrl & ctrlFramework = m_pToolBar->GetToolBarCtrl();
if(ctrlFramework.IsButtonEnabled(nID) == 0)
{
return rc;
}
}
rc = CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
access violation here >>>> HWND viewHandle = GetSafeHwnd();
if(viewHandle != NULL && ::IsWindow(viewHandle))
{
Get a breakpoint there. (You may need to add some temporary code so it
breaks on the relevant message.) When it hits the breakpoint examine
the 'this' pointer, and its member variables, to see what you've got. I
don't see any way it could fail unless 'this' is corrupt. Keep in mind
that a lot of stuff is executed when you call CFrameWnd::OnCmdMsg, so
something in there may be causing mayhem. You could move the
troublesome line ahead of the call to see if that changes things.
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
>Hi Scott,
>
>Here is the piece of code -
>
>BOOL CZedObjectFrame::OnCmdMsg( UINT nID, int nCode, void * pExtra,
>AFX_CMDHANDLERINFO* pHandlerInfo)
>{
> // call up, does menu and toolbar updates
> BOOL rc = FALSE;
>
> if (!CanUserModify() && m_pToolBar != NULL)
> {
> CToolBarCtrl & ctrlFramework = m_pToolBar->GetToolBarCtrl();
> if(ctrlFramework.IsButtonEnabled(nID) == 0)
> {
> return rc;
> }
> }
>
> rc = CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
>
>access violation here >>>> HWND viewHandle = GetSafeHwnd();
> if(viewHandle != NULL && ::IsWindow(viewHandle))
> {
If the command message caused the window to be closed, I could (barely) see
this faulting. If this is not the case, then you entered this member
function on an invalid window, or something has caused damage to the object
it was called on or perhaps the thread's stack, e.g. a buffer overrun, or
maybe the register used to hold the "this" pointer wasn't properly saved
and restored across the function call. I don't see any other possibilities,
since GetSafeHwnd amounts to the following in this context:
HWND viewHandle = (this != 0) ? m_hWnd : 0;
I have to say, it's strange you'd get an access violation there and not
earlier. Even if the window were closed and the memory freed, it would have
to be decommitted from your address space to cause an access violation, and
AFAIK, that happens rarely if ever for the C++ heap. What do you observe in
the debugger?
--
Doug Harrison
Visual C++ MVP
>One of the situations I've seen that causes a failure is when there is a CWnd * that is a
>local or member variable that is uninitialized, so it is something like 0xcccccccc or
>0xcdcdcdcd. Of course, if he had gone into the debugger and examined the variable and
>reported it, perhaps there would be a chance to figure out what had gone wrong.
> joe
Unless I'm missing something, his code involves a "this" pointer becoming
corrupted inside a member function. He had:
>>>BOOL CZedObjectFrame::OnCmdMsg( UINT nID, int nCode, void * pExtra,
>>>AFX_CMDHANDLERINFO* pHandlerInfo)
<snip>
>>> rc = CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
>>>
>>>access violation here >>>> HWND viewHandle = GetSafeHwnd();
Apparently, the OnCmdMsg upcall to the base class went all right, but upon
return, he GPF's when he calls GetSafeHwnd, which as I noted, could hardly
be simpler (below I changed m_hWnd to this->m_hWnd to emphasize the
implicit dereference):
>> HWND viewHandle = (this != 0) ? this->m_hWnd : 0;
The "this" pointer is typically kept in a register and is passed in a
register to normal member functions, which follow the __thiscall calling
convention. So how can it get corrupted? I can think of three
possibilities:
1. The base class OnCmdMsg didn't preserve the register
CZedObjectFrame::OnCmdMsg was using to hold "this", or
2. CZedObjectFrame::OnCmdMsg had to dump "this" to the stack, and upon
return from CFrameWnd::OnCmdMsg, it loaded a bad pointer due to stack
corruption, or
3. The memory holding the CZedObjectFrame object was decommitted. (If it
weren't decommitted, he'd load a garbage HWND value and fail later.)
Only (2) seems even somewhat likely. Oh well, enough guessing. I'd actually
be surprised if any of it applies. :)
CMyWnd * something;
something->Whatever();
void CMyWnd::Whatever()
{
HWND h = GetSafeHwnd();
...
}
Note that what this does is pass the uninitialized something pointer (0xccccccccc), which
is harmless until there is an attempt to use it; since GetSafeHwnd() only checks for a
NULL pointer, it will then try to return ((CWnd*)(0xcccccccc))->m_hWnd, which is going to
be fatal.
joe
"Doug Harrison [MVP]" <d...@mvps.org> wrote in message
news:5lifu21bsu9k17s7b...@4ax.com...
>Consider the following situation
>
>CMyWnd * something;
>
>something->Whatever();
>
>void CMyWnd::Whatever()
> {
> HWND h = GetSafeHwnd();
> ...
> }
>
>Note that what this does is pass the uninitialized something pointer (0xccccccccc), which
>is harmless until there is an attempt to use it; since GetSafeHwnd() only checks for a
>NULL pointer, it will then try to return ((CWnd*)(0xcccccccc))->m_hWnd, which is going to
>be fatal.
> joe
Sure, but the OP had done a lot of "this" dereferencing before calling
GetSafeHwnd. If his OnCmdMsg override had been called on an invalid object,
it would have crashed sooner than it did.