Access Violation during MFC execution of CFrameWnd::InitialUpdateFrame - c++

I am in the process of trying to upgrade a VC++ 6.0 project to the latest version and am running into an issue. The program starts up fine but in the process of creating two child windows within the main view it crashes with an access violation. When run in debug mode it cannot find the exact location where the error occurs, displaying "Frame not in module" and "The current stack frame was not found in a loaded module. Source cannot be shown for this location" making it difficult to pinpoint the exact issue.
Going through the program step by step reveals that the error lies in the call of
CFrameWnd::InitialUpdateFrame.
From there it goes into the following functions:
Main.cpp:
frame->InitialUpdateFrame(dc, TRUE);
winfrm.cpp:
SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);
afxwin2.inl:
CWnd::SendMessageToDescendants(m_hWnd, message, wParam, lParam, bDeep, bOnlyPerm);
wincore.cpp:
SendMessageToDescendants(hWndChild, message, wParam, lParam, bDeep, bOnlyPerm);
(Recursion to same function, error occurs on second recursion)
wincore.cpp:
AfxCallWndProc(pWnd, pWnd->m_hWnd, message, wParam, lParam);
Error has occurred at 3 of the following locations:
wincore.cpp:
_AfxPreInitDialog(pWnd, &rectOld, &dwStyle);
lResult = pWnd->WindowProc(nMsg, wParam, lParam);
_AfxPostInitDialog(pWnd, rectOld, dwStyle);
It is called from this function (simplified):
CDocument* XApp::OpenDocumentFile(LPCTSTR lpszFileName)
{
doc_x_spc *dc =
static_cast<doc_x_spc *> ( m_spc_template->CreateNewDocument() );
CMDIChildWnd *frame =
static_cast<CMDIChildWnd *> ( m_spc_template->CreateNewFrame(dc, NULL) );
if ( !dc->OnOpenDocument(lpszFileName) )
{
AfxMessageBox( IDS_SPCOPENERROR, MB_OK, NULL );
return NULL;
}
CString raw(lpszFileName);
dc->set_raw_file(raw);
frame->InitialUpdateFrame(dc, TRUE);
if (app_multiplexed == SINGLE)
menu.LoadMenu(IDR_REMPLETYPE_SINGLE);
else
menu.LoadMenu(IDR_REMPLETYPE);
CMainFrame* pMainFrame = (CMainFrame *)m_pMainWnd;
pMainFrame->MDISetMenu(&menu, NULL);
return dc;
}
The access violation produces this exact error:
Exception thrown at 0x01144008 in X.exe: 0xC0000005: Access violation executing location 0x01144008.
Would appreciate any help. Thank you!

Related

I'm getting a "Debug Assertion Failed!" error during runtime of my app. The failure happens in the mfc140d.dll

I suddenly started receiving this failure and I cannot figure out why. In the error message, the program is listed as mfc140d.dll and the specific file as "...\mfc\winctrl1.cpp". It seems only windows references this section of code. Specifically, it is failing at "void CComboBox::MeasureItem(…)" function.
Before, I was running my application just fine. I can't imagine what would have happened to cause this error to suddenly show up. Truth be told, I'm pretty unsure of what this code does as is. I know very little about mfc apps.
void CComboBox::DrawItem(LPDRAWITEMSTRUCT)
{ ASSERT(FALSE); }
void CComboBox::MeasureItem(LPMEASUREITEMSTRUCT)
{ ASSERT(FALSE); }
int CComboBox::CompareItem(LPCOMPAREITEMSTRUCT)
{ ASSERT(FALSE); return 0; }
void CComboBox::DeleteItem(LPDELETEITEMSTRUCT)
{ /* default to nothing */ }
BOOL CComboBox::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,
LRESULT* pResult)
{
switch (message)
{
case WM_DRAWITEM:
ASSERT(pResult == NULL); // no return value expected
DrawItem((LPDRAWITEMSTRUCT)lParam);
break;
…

crash on ShowWindow()

I am developing a Notepad++ plugin.
I have a simple dialog box, which is created using CreateDialogParam(). It is initially hidden.
After a menu click, I call ShowWindow() with SW_SHOW on its handle, which results in this exception:
c000041d
Upon debugging , I found that these two messages are sent to my dialog just before crash
WM_SHOWWINDOW
WM_WINDOWPOSCHANGING
Both of them, I am not handling. Here is my dlgproc code. Any idea why it would happen ?
BOOL CALLBACK StaticDialog::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG :
{
// Get the additional init data
StaticDialog *pStaticDlg = (StaticDialog *)(lParam);
// Store the handle in the object
pStaticDlg->_hSelf = hwnd;
::SetWindowLongPtr(hwnd, GWL_USERDATA, (long)lParam);
// Store the co-ordinates in the object
::GetWindowRect(hwnd, &(pStaticDlg->_rc));
// Forward the message for further processing
pStaticDlg->run_dlgProc(message, wParam, lParam);
// TRUE if it processed the message
return TRUE;
}
default :
{
// Retrieve the user data
StaticDialog *pStaticDlg = (StaticDialog *)(::GetWindowLongPtr(hwnd, GWL_USERDATA));
if (!pStaticDlg)
return FALSE;
// Send the message for further processing
return pStaticDlg->run_dlgProc(message, wParam, lParam);
// return FALSE if it processed the message
}
}
}
BOOL CALLBACK MarkDownViewDialog::run_dlgProc( UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_INITDIALOG:
{
EmbedBrowserObject(this->_hSelf);
DisplayHTMLPage(this->_hSelf,L"http://www.microsoft.com");
DisplayHTMLStr(this->_hSelf, L"<H2><CENTER>HTML string test</CENTER></H2><P><FONT COLOR=RED>This is a <U>HTML string</U> in memory.</FONT>");
break;
}
default:
break;
}
return FALSE;
}
The dialog box is created through plugin mechanism of Notpead++. I am putting the source code from its file StaticDialog.cpp. The control goes through else block in code below.
void StaticDialog::create(int dialogID, bool isRTL, bool isModeles)
{
if (isRTL)
{
DLGTEMPLATE *pMyDlgTemplate = NULL;
HGLOBAL hMyDlgTemplate = makeRTLResource(dialogID, &pMyDlgTemplate);
_hSelf = ::CreateDialogIndirectParam(_hInst, pMyDlgTemplate, _hParent, (DLGPROC)dlgProc, (LPARAM)this);
::GlobalFree(hMyDlgTemplate);
}
else
_hSelf = ::CreateDialogParam(_hInst, MAKEINTRESOURCE(dialogID), _hParent, (DLGPROC)dlgProc, (LPARAM)this);
//int i=GetLastError();
if (!_hSelf)
{
//systemMessage(_T("StaticDialog"));
return;
}
if (isModeles) {
_isModeles = isModeles;
::SendMessage(_hParent, NPPM_MODELESSDIALOG, MODELESSDIALOGADD, (WPARAM)_hSelf);
}
}
My entire solution source code is hosted here:
https://github.com/madhur/Npp-Markdown-Viewer
Issue Resolution
Here is what I have done to troubleshoot the problem:
Created a Win32 project in which I create a dialog box and put exactly same source code to embed browser control in WM_INITDIALOG and it works. This Win32 project links with the same static library, which the original source code is linking with. This is the source of the sample project mail file:
https://github.com/madhur/Npp-Markdown-Viewer/blob/master/dll/example/example.c
The static library I referenced above, is nothing but it contains functions to embed browser control in HWND and to render either an URL or string. I have taken the source from here: http://www.codeguru.com/Cpp/I-N/ieprogram/article.php/c4379
This is the source of static library main file:
https://github.com/madhur/Npp-Markdown-Viewer/blob/master/dll/dll.c
If I comment this single line, the plugin works, basically it loads the dialog box without the Browser control in it:
EmbedBrowserObject(this->_hSelf);
The actual exception in Visual Studio is raised on this line:
return pStaticDlg->run_dlgProc(message, wParam, lParam);

C++ Console app, SetWindowsHookEx, Callback is never called

I have a little console application that has an embedded v8 engine, and I would like to add a hook to register key events. This all worked before when I was using Qt and QtScript, but I am porting it all over to straight C++ in VC++ 2008. The application compiles and runs, but the hook is never called, here is the relevant code:
In main()
HWND hwndC = GetConsoleWindow() ;
HINSTANCE hInst = (HINSTANCE)GetWindowLong( hwndC, GWL_HINSTANCE );
if (SetWindowsHookEx(WH_KEYBOARD_LL, HookProc, hInst, NULL) == 0) {
printf("Failed to set hook\n");
} else {
printf("Hook established\n");
}
g->RunScript(argc,argv);
And the proc:
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
printf("HookProc called\n");
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) (lParam);
if (wParam == WM_KEYDOWN) {
keyDown(p,g);
} else if (wParam == WM_KEYUP) {
keyUp(p,g);
}
fflush(stdout);
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
This is essentially an expansion on shell.cc from the v8 sample code. I wonder if it is somehow blocking? I admit to not really knowing what I am doing here, just playing around and learning but this one has me stumped.
Inside of keyDown say, I have something like this:
v8::Handle<v8::String> callback_name = v8::String::New("onKeyDown");
v8::Handle<v8::Value> callback_val = g->_context->Global()->Get(callback_name);
if (!callback_val->IsFunction()) {
printf("No onKeyDown handler found\n");
return;
}
v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(callback_val);
const int argc = 1;
v8::Handle<v8::Value> argv[argc] = { v8::Int32::New(char(p->vkCode)) };
printf("Calling onKeyDown\n");
v8::Handle<v8::Value> result = callback->Call(g->_context->Global(), argc, argv);
Some of this may actually not work in the end, but it just never gets called, when I run the program, and define: onKeyDown = function(key) {...}; I can see that onKeyDown is working just fine, I can use all of my bound c++ method etc from JS, so this thing is just driving me batty.
Any help, maybe pointers to some educational materials would be much appreciated.
Just to be clear, this function in c: LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) is never getting called, or never seeing a printf, and the output at the start says: Hook established, so windows is reporting the hook is established.
/Jason
A low-level hook, like WH_KEYBOARD_LL requires that your application pumps a message loop. That's the only way that Windows can break into your thread and make the call to the HookProc callback you registered.
A console mode app doesn't pump a message loop like regular Windows GUI apps do. Judging from your snippet, it isn't going to be easy to add one either. You'll need to create a thread.
Maybe this function will be of help to you?
GetAsyncKeyState

How can I set up a CBT hook on a Win32 console window?

I've been trying to set up a CBT hook for my C++ Console application with the following code:
...includes...
typedef struct _HOOKDATA
{
int type;
HOOKPROC hookproc;
HHOOK hhook;
}_HOOKDATA;
_HOOKDATA hookdata;
//CBT
LRESULT CALLBACK CBTProc(int code, WPARAM wParam, LPARAM lParam)
{
//do not proccess message
if(code < 0)
{
cout<<"code less than 0"<<endl;
return CallNextHookEx(hookdata.hhook,code,wParam,lParam);
}
switch(code)
{
case HCBT_ACTIVATE:
break;
case HCBT_CREATEWND:
cout<<"CREATEWND"<<endl;
break;
case HCBT_MINMAX:
cout<<"MINMAX"<<endl;
break;
default: //unknown
cout<<"DEFAULT"<<endl;
break;
}
return CallNextHookEx(hookdata.hhook, code, wParam, lParam);
}
int main()
{
hookdata.type = WH_CBT;
hookdata.hookproc = CBTProc;
hookdata.hhook = ::SetWindowsHookEx(hookdata.type, CBTProc,
GetModuleHandle( 0 ), GetCurrentThreadId());
if(hookdata.hhook == NULL)
{
cout<<"FAIL"<<endl;
system("pause");
}
system("pause");
return 0;
}
The program seems to be working because there is not compile errors nor run time errors. Also I do not get a 'FAIL' message stated in the main() function meaning SetWindowHookEx is working OK. However, I don't get any of the messages stated in the CBTProc function; not even the 'DEFAULT' message. Can anyone pin-point what is the logic error in the code?
Thanks.
The problem is that SetWindowHookEx is based upon the Win32 message handling model. Console windows are children of the Kernel itself and do not create their own message pumps or windows.
AFAIK doing what you want directly is not possible.

C++: Error handling problem across threads

In general I use exceptions to deal with errors, however the problem I have here is that the error applies to a different thread than the one that caused it.
Basicly the window has its own thread, and the direct3d device must be created and reset by the same thread that created the window. However creating the device may fail, so I need to throw an exception in the thread that was trying to create the instance, not the window code
The callback function:
void Callback(HWND hwnd, boost::function<void(HWND,LPARAM)> call, LPARAM lParam)
{
//Make our stack allocated function object into a heap allocated one
boost::function<void(HWND,LPARAM)> *callH = new boost::function<void(HWND,LPARAM)>(call);
//send a message with a pointer to our function object in the WPARAM
PostMessage(hwnd, WM_CALLBACK, (unsigned)callH, lParam);
}
LRESULT CALLBACK HookProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
//check for our custom message
if(msg == WM_CALLBACK)
{
//retreive the function pointer from the WPARAM
boost::function<void(HWND,LPARAM)> *callH = (boost::function<void(HWND,LPARAM)>*)wParam;
//call it
(*callH)(hwnd,lParam);
//delete our heap allocated function object
delete callH;
return 0;
}
else
//if there was nothing relevant to us, call the old message procedure
return CallWindowProc(hooked[hwnd], hwnd, msg, wParam, lParam);
}
//std::map<HWND, WNDPROC> hooked;
The code that requests the window thread to create the device
Graphics::Graphics(IWindow *_window, Size2<unsigned> _size)
:lost(false), reset(false), refCnt(0), backCol(0xFF000000),
started(false), exited(false),
window(_window), size(_size)
{
window->AddRef();
HWND hwnd = *((HWND*)window->GetHandle());
CallbackHook(hwnd);
Callback(hwnd, boost::bind(&Graphics::create, this), 0);
while(!started)Sleep(100);
}
void Graphics::create()
{
...code that may throw various exceptions
started = true;
}
So basically I need the exceptions being thrown by the create() method to be caught by the exception handelers where the Graphics object was created which is another thread.
Perhaps you can wrap the call inside another function, using Boost.Exception.
The following code does not work though, but you'll probably get the idea.
class Context
{
public:
Context(HWND hwnd, const boost::function<void(HWND,LPARAM)>& f, LPARAM lParam)
{
// TODO: reroute call through Wrapper function.
}
void wait()
{
mutex::scoped_lock l(m);
while (!finished)
{
c.wait(l);
}
if (ex)
rethrow_exception(ex);
}
private:
void Wrapper()
{
try
{
f(/*params*/);
}
catch (...)
{
ex = current_exception();
}
mutex::scoped_lock l(m);
finished = true;
c.notify_all();
}
boost::function<void(HWND,LPARAM)> f;
exception_ptr ex;
bool finished;
mutex m;
condition c;
};
void Callback(HWND hwnd, const boost::function<void(HWND,LPARAM)>& f, LPARAM lParam)
{
Context ctx(hwnd, f, lParam);
ctx.wait();
}
I see you call PostMessage from Callback then actively wait using a loop and Sleep. Replace PostMessage by SendMessage, which will wait for the message processing to complete. That way the processor-intensive loop is gone. Moreover, you can use the return code of the SendMessage call (from the WM_CALLBACK arm of HookProc) to pass error information. Either use simple numeric codes (e.g. non-zero means error) or pass exception objects (in this case you'll have to allocate then on the heap from your exception handler, you can't pass the parameter directly as it is stack-allocated).
Last, using the synchronous SendMessage instead of the async PostMessage means you no longer have to build an intermediary callH function object from the HookProc, as you can pass the stack allocated call parameter instead. This results in much simpler code.
For example:
void Callback(HWND hwnd, boost::function<void(HWND,LPARAM)> call, LPARAM lParam)
{
//send a message with a pointer to our function object in the WPARAM
if (SendMessage(hwnd, WM_CALLBACK, &call, lParam))
{
// error handling.
}
}
LRESULT CALLBACK HookProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
//check for our custom message
if(msg == WM_CALLBACK)
{
//retreive the function pointer from the WPARAM
boost::function<void(HWND,LPARAM)> *callH = (boost::function<void(HWND,LPARAM)>*)wParam;
//call it, catching exceptions in the process.
try
{
(*callH)(hwnd,lParam);
return 0;
}
catch (...)
{
return 1;
}
}
else
//if there was nothing relevant to us, call the old message procedure
return CallWindowProc(hooked[hwnd], hwnd, msg, wParam, lParam);
}
//std::map<HWND, WNDPROC> hooked;
And:
Graphics::Graphics(IWindow *_window, Size2<unsigned> _size)
:lost(false), reset(false), refCnt(0), backCol(0xFF000000),
started(false), exited(false),
window(_window), size(_size)
{
window->AddRef();
HWND hwnd = *((HWND*)window->GetHandle());
CallbackHook(hwnd);
Callback(hwnd, boost::bind(&Graphics::create, this), 0);
// No need to wait, as SendMessage is synchronous.
}
void Graphics::create()
{
...code that may throw various exceptions
started = true;
}
A simple solution would be to catch the exception in the thread that thrown it (or check the parameters before calling the function to decide if an exception would be thrown) and then pass the exception via a static variable tot the main thread where the main thread can throw it.
I would add a check after the WaitForSingleObject to discover if an exception is waiting to be thrown and in case it does - throw it.
Well, the answer is that you can't. A viable alternative would be to do only necessary work that can't fail, like extractiong value from the parameters, in your callback function, and call the create() function in your main thread.
Also, you shouldn't busy wait for the creation, use a Semaphore, or a Mutex & Event etc.
Graphics::Graphics(IWindow *_window, Size2<unsigned> _size)
:lost(false), reset(false), refCnt(0), backCol(0xFF000000),
started(false), exited(false),
window(_window), size(_size)
{
window->AddRef();
HWND hwnd = *((HWND*)window->GetHandle());
semaphore = CreateSemaphore(NULL, 0, 1, NULL);
if (semaphore == NULL) throw whatever;
CallbackHook(hwnd);
Callback(hwnd, boost::bind(&Graphics::create, this), 0);
WaitForSingleObject(semaphore);
create();
CloseHandle(semaphore); /* you won't need it */
}
void Graphics::create()
{
...code that may throw various exceptions
}
void Graphics::create_callback()
{
ReleaseSemaphore(semaphore, 1, NULL);
}
See http://www.boost.org/doc/libs/release/libs/exception/doc/tutorial_exception_ptr.html.