SubclassWindow() function assert - c++

Its c++ developer want to learn more about vc++. :)
One concept called subclassing is one milestone i have. Basically i go through the following article of codeproject Create your own controls - the art of subclassing its interesting and i understand greatly.
But when i execute same with visual studio 2010 i get assertion at following point.
CWnd* pWnd = GetDlgItem(IDOK); // or use some other method to get
// a pointer to the window you wish
// to subclass
ASSERT( pWnd && pWnd->GetSafeHwnd() );
m_OkButton.SubclassWindow(pWnd->GetSafeHwnd()); //Assertion point.
Please note above code is placed in OnInitDialog() function and

I have some similar experiences.
This code seems causing the error
VERIFY(m_Edit.SubclassWindow(parent->GetSafeHwnd()));
Change to this line,everything would be ok.
m_Edit.SubclassDlgItem(nId,parent);

Related

CMyPrintDialog::OnInitDialog() is not called in IE10

I have a class named CMyPrintDialog derived from CPrintDialog of MFC. It's used as an ActiveX in IE, and the project is linked to MFC statically. It works well in IE8 for many years.
But the same binary of the project doesn't work well on IE10. The print dialog could pop up, but unfortunately its OnInitDialog is never called and causes problems.
The strange thing is that if I attach the VS debugger to IE, OnInitDialog will be called correctly and the customized print dialog works well.
Seems Microsoft has change something and causes the problem.
I found a similar link but it doesn't work.
Thanks a million for any ideas.
The issue is caused by IE's new feature after IE9 - "Hang Resistance". We can avoid the issue by disabling the new feature: Set below value as 0, and close all IE windows. HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\ Type: REG_DWORD Name: HangRecovery Value: 0
I am not getting your point exactly you want to say, Consider CPrintDialog crash your application with IE10.What is you need to do is,
Set up the message hook function, _AfxCommDlgProc(), in the constructor of your
CPrintDialog-derived class as shown below:
// CMyPrintDialog is a CPrintDialog-derived class.
CMyPrintDialog::CMyPrintDialog(DWORD dwFlags)
: CPrintDialog(FALSE,dwFlags)
{
//{{AFX_DATA_INIT(CMyPrintDialog)
//}}AFX_DATA_INIT
// MFCBUG: MFC 6.0 doesn't set the message hook!
m_pd.Flags |= PD_ENABLEPRINTHOOK | PD_ENABLESETUPHOOK;
// _AfxCommDlgProc is exported from static MFC libraries
m_pd.lpfnPrintHook = _AfxCommDlgProc;
m_pd.lpfnSetupHook = _AfxCommDlgProc;
}

C++ Builder 2009 - How to Determine if Control's Window is Visible

I have a TWinControl and am trying to determine if the parent window is visible.
I see TWinControl has a property of ParentWindow. The return type of ParentWindow is void *. So I'm curious if I must cast to a particular type, which would then give me access to check if the window is visible or not.
Does anyone know the type I need to cast to, or another way to accomplish this?
Additional Troubleshooting Notes, Part 1:
I tried to get the ParentWindows class by:
String parentWindowClassName = ((TObject *)(Control->ParentWindow))->ClassName();
But this gave an access violation. I also tried casting to TForm, which also gave an access violation, which makes me believe the parent window may be controlled by windows. If so, does anyone know of any trick to check if it is visible? E.g. Any COM tricks or anything?
Additional Troubleshooting Notes, Part 2:
The answer to this question may help solve my other question: C++ Builder 2009 - Cannot focus a disabled or invisible window
However the other question may be solved without this approach, which is why I posted a different question.
Additional Troubleshooting Notes, Part 3:
Thanks for the extra info Ken. I got my info off code assist:
However I see your HWND return type from: http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Controls_TWinControl_ParentWindow.html
That might be the extra info I need... will post a solution if I get it working. Thx.
#KenWhite, your suggestions gave me what I needed, thanks!
The following is the code that solved my problem:
#include "winuser.h"
...
void SafeSetFocus(TWinControl *Control)
{
HWND hWnd = Control->ParentWindow;
bool parentIsVisible = IsWindowVisible(hWnd);
if(Control->Enabled && Control->Visible && parentIsVisible)
{
Control->SetFocus();
}
}

another win32 problem

Having a problem here with creating a child window with c++ and win32 api.
If i check the getLastError function its returning "87" but i dont know what that means.
For what i know my code does not contain errors, can someone take a look at my code and help me figure out whats wrong with it.
(This is in the WinProc WM_CREATE section.)
HWND hChildWindow = CreateWindowEx(WS_EX_CLIENTEDGE,0,NULL,WS_OVERLAPPEDWINDOW|WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,hwnd,0,GetModuleHandle(0),NULL);
if(!hChildWindow)
{
char text[256];
int errormsg = (int)GetLastError();
sprintf(text,"Error# %i",errormsg);
MessageBox(0,text,"Error",MB_OK|MB_ICONEXCLAMATION);
return false;
}
87 = Invalid Parameter - be aware that you can use FormatMessage to get a string message from an error code.
The 2nd parameter to CreateWindowEx is a window class (either string or ATOM). Obviously NULL is not a valid value.
P.S.
For what i know my code does not
contain errors...
Beware of such a loud phrases. When something doesn't work everything should be checked carefully. Otherwise you may just accuse something/someone without any good for solving the problem. Check everything vs standard/documentation/specifications/etc. before you make any judgement.
A quick look through the System Error Codes reference indicates ERROR_INVALID_PARAMETER. You're most likely passing in an invalid combination of styles/flags to your window.

"Debug Assertion" Runtime Error on VS2008?

I'm writing a C++ MFC program on VS2008 and I'm getting this "Debug Assertion Error" when I first run the program sometimes. When I try to debug it, it takes me to this winhand.cpp file which is not part of the program I wrote so I'm not sure how to debug this.
It takes the error to this place in winhand.cpp
CObject* pTemp = LookupTemporary(h);
if (pTemp != NULL)
{
// temporary objects must have correct handle values
HANDLE* ph = (HANDLE*)((BYTE*)pTemp + m_nOffset); // after CObject
ASSERT(ph[0] == h || ph[0] == NULL);
if (m_nHandles == 2)
ASSERT(ph[1] == h);
}
So why does this error happen? Why does it only happen sometimes (50% of the time)? How would I debug this?
I'll provide some code if is needed.
THANKS!
The code that is asserting is part of MFC's CHandleMap class. MFC deals with windows as CWnd objects, but Windows deals with them as HWND handles. the handle map allows MFC to 'convert' an HWND into a pointer to the MFC object representing that object.
What the assertion seems to be doing is checking that when a lookup of the handle finds an MFC object, that the MFC object also thinks it's wrapping the same handle.
If they're different, then you get the assertion.
So it would appear that something is corrupting the handle map or the MFC object for that handle or you're doing something incorrect that gets these 2 data structures out of sync.
Some things you might do to try to debug the problem is to determine:
what MFC object is being found in the lookup (that's what's being pointed to by pObject)
what the MFC object thinks it's wrapping (that's the handle ph[0] and/or ph[1] - I'm not sure why there can be 2 of them)
what the handle is for (that's h)
Do the handles look like handle values or do they look like garbage? Does pObject point to something that looks like an MFC object, or garbage? Do any of these these things seem related?
The answers to these questions may point to what you need to do next (maybe set a debug write breakpoint on the item that looks like it's trashed).
I got this same assertion few days ago, and after some google search,
I found the solution for my case here:
http://forums.codeguru.com/showthread.php?216770-What-would-cause-this-assertion
In my case, change to misused
CDC* dc = GetDC();
CSize spaceSize = dc->GetTextExtent(" ");
dc->DeleteDC();
to
CDC* dc = GetDC();
CSize spaceSize = dc->GetTextExtent(" ");
ReleaseDC(dc);
would fix it.
Look out for code along those lines (from memory from Stroustrup's book):
c1 = (t2+t3).c_str();
(in spirit, could be other commands and expressions of course).Temporary objects are destroyed after their enclosing full expression has been evaluated, or at least the standard allows them to be. That means that what you would like to allocate to c1 may, or may not, still be in memory where it can be assigned to c1. The compiler may alert you to this issue, and the issue may or may not arise depending on what exactly you assign and other circumstances (I am not compiler writer), which would also explain why you get this error message only sometimes.
So in your shoes, I'd scan my code for similar expressions and clean them up.
When the debugger breaks, head up the call stack to the first bit of your code (if there is any - hopefully there is!). Ideally it's as simple as something in your code calling a library function incorrectly, and the library is catching the error with an assert and alerting you to that. (I don't think anyone will be able to tell what's wrong from the library code, we need to see your code.)
Otherwise, you're in for some tricky debugging: you're doing something wrong with the library that is asserting (looks like MFC) so go back and review all your MFC code and make sure everything is correct and according to the documentation.
This looks suspiciously like an error I had this morning. Is this happening in OnIdle()?
I know this is a very old post, but hoping that someone may get a little help from my answer.
I also faced a similar issue recently because of my simple mistake, then I came across this post and got a hint from "pac"'s post.
What I found is that if I use DeleteDC() to release DC returned from GetWindowDC() or GetDC() I will get the above assertion in MFC frame once CPaintDC object instance goes out of scope.
CDC * pDC = GetWindowDC();
...
ReleaseDC(pDC);
You have to use DeleteDC() only in conjunction with CreateDC() API.
CDC * pDC = new CDC();
pDC->CreateDC();
....
pDC->DeleteDC();
We had this problem when some of our project dlls were linking MFC as static library and some as shared library (check "Use of MFC" in Project settings)

ActiveX plugin causes ASSERT to fail on application exit in VS2008

My MFC application using the "ESRI MapObjects LT2" ActiveX plugin throws an ASSERT at me when closing it.
The error occurs in cmdtarg.cpp:
CCmdTarget::~CCmdTarget()
{
#ifndef _AFX_NO_OLE_SUPPORT
if (m_xDispatch.m_vtbl != 0)
((COleDispatchImpl*)&m_xDispatch)->Disconnect();
ASSERT(m_dwRef <= 1); //<--- Fails because m_dwRef is 3
#endif
m_pModuleState = NULL;
}
I built the (native C++) application with VC9.
When I compile the application with VC6, it behaves nicely.
What could be the reason for this?
That looks like a reference count. Could this "target" be referenced by something else, something that's not releasing it?
You can trace the Addref and Release calls defining _ATL_DEBUG_INTERFACES
from http://msdn.microsoft.com/en-us/library/sycfy8ec(VS.80).aspx
_ATL_DEBUG_INTERFACES
Define this macro before including any ATL header files to trace all AddRef and Release calls on your components' interfaces to the output window.
Using _ATL_DEBUG_INTERFACES did not yield any additional output...
I defined it on the first line of stdafx.h, directly after #pragma once so I guess this is early enough.
Maybe the reason is how I am using the ActiveX control:
I'm not calling AddRef() or Release() by myself.
The MapObjects Installer comes with sample code with lots of wrapper classes which must have been generated by VC6 or something earlier.
I tried to generate wrapper classes myself with VC9 but there occured errors which I wasn't able to fix.
I use the control by letting one of my windows have a member of type CMap1 (derived from CWnd), which is one of those generated wrapper classes. In CMyWnd::OnCreate() I also call CMap1::Create() and that's it, I'm finished: I can add a layer and the control displays a world map.
I have pretty much no idea what the reference-count stuff is about as I have not added or released any references. At least not knowingly...
The control is pretty old: The .OCX file has the year 2000 in its version information.
It's also not officially supported anymore but I don't have any substitue.
The following solved it for me:
In the window that contains the control, add an OnDestroy() handler:
void CMyWnd::OnDestroy()
{
// Apparently we have to disconnect the (ActiveX) Map control manually
// with this undocumented method.
COleControlSite* pSite = GetOleControlSite(MY_DIALOG_CONTROL_ID);
if(NULL != pSite)
{
pSite->ExternalDisconnect();
}
CWnd::OnDestroy();
}