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

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;
…

Related

MessageBox() returning 0 when called from Win32 button press

I'm barely a week into Win32 GUI programming, so I'm confident/hopeful this is something simple. For your consideration, I've provided a sample of my code below.
As a quick brief, my application watches for another application to be open so that I can modify that application's memory. I've placed this initial check at the top of my UI looper as follows such that it will only run once (in which case the user can only cancel and the app closes, or execution resumes past the if statement with hWndApp having a value assigned):
if (!hWndApp) {
appCheck();
}
If I start my application and the other application isn't running, appCheck(); fires and the waterfall of execution therefrom acts accordingly: a message box appears (and will keep appearing if the user clicks "Retry") until the other application's window is found. If the user clicks "Cancel," the application exits and all is well. If they click "Retry" once the other application is running, then my application will finish painting to the screen and execution is normal.
The funny business starts the next time I call appCheck(); (which happens when one of either two buttons is clicked) if the other application has been opened, then closed.
While debugging (via Visual Studio 2017), the variable I assign the MessageBox() call to equals 0 when the other application has been opened, then closed, then the following:
Push button to call appCheck();
getProcessHandleAndPID(); is then called within the if statement because the window can't be found
AppCheckMessageBox(); is then called within the while loop because the window can't be found
The debugger then points to the first line inside of AppCheckMessageBox();, which is the entire int msgboxID = MessageBox(); bit
Pressing F11 (Step Into), no window shows and the application exists after the default choice in the switch statement is triggered since the value of msgboxID is 0 (indicating the MessageBox() call failed, so I tried calling GetLastError() before exit(EXIT_FAILURE), but to no avail).
I'm not sure where my error lies, but I've sought many solutions--none of which have panned out. Finally, if you see any variables below that look misnamed or undeclared, it's solely due to my modification of the code for this post to try to generalize/ shorten it. I may have left out some global variable declarations, etc.
Thank you for any help/guidance you can provide! I'm at my wit's end with this right now...lol.
//--------------------------------------------------
// Function to get process handle and PID of app /
//------------------------------------------------
void getProcessHandleAndPID()
{
hWndApp = FindWindow(NULL, _T("NameOfApplication"));
while (!hWndApp) {
AppCheckMessageBox();
}
//Much more code here
}
//---------------------------------
// Function to show message box /
//-------------------------------
int AppCheckMessageBox()
{
int msgboxID = MessageBox(
NULL, //I tried making this hWndApp as well, but no difference
(LPCWSTR)L"Cancel to exit or start the app and click Retry.",
(LPCWSTR)L"Application Not Found!",
MB_ICONSTOP | MB_RETRYCANCEL | MB_SYSTEMMODAL | MB_SETFOREGROUND
);
switch (msgboxID)
{
case IDCANCEL:
exit(EXIT_FAILURE);
case IDRETRY:
getProcessHandleAndPID();
break;
default:
//GetLastError();
exit(EXIT_FAILURE);
}
return msgboxID;
}
//------------------------------------------------
// Function to check if application is running /
//----------------------------------------------
void appCheck() {
if (!FindWindow(NULL, _T("NameOfApplication"))) {
getProcessHandleAndPID();
}
}
//--------------------------------------------------
// Function to get process handle and PID of app /
//------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (!hWndApp) {
appCheck();
}
switch (message)
{
case WM_PAINT:
//Code here
break;
case WM_CREATE:
//Code here
break;
case WM_COMMAND:
switch (HIWORD(wParam))
{
case BN_CLICKED:
if (LOWORD(wParam) == BTN_ENABLE) {
appCheck();
//Do stuff with button press
}
if (LOWORD(wParam) == BTN_DISABLE) {
appCheck();
//Do stuff with button press
}
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
Not really an answer, but too long for comments:
This isn't your real code. Many things are missing, there are mismatched braces which would prevent compilation, etc. Always show your real code if you want help.
As David says, calling appCheck() every time you receive a message is the wrong approach. If you want to call it once after your window opens, do that before entering your message loop.
Your code is needlessly recursive (getProcessHandleAndPID() calls AppCheckMessageBox() which calls getProcessHandleAndPID() which calls...) and will potentially lead to a stack overflow.

RDP connection hook called twice for every connection

I want my application to hook remote connect and disconnect events for all sessions on the specified computer.
According to the documentation, I should call WTSRegisterSessionNotification function first:
WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_ALL_SESSIONS);
Then in the messages processor callback I should do the required stuff on WM_WTSSESSION_CHANGE message type:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_WTSSESSION_CHANGE:
{
// do stuff
break;
}
}
}
It works very strange however. Every time I connect or disconnect to/from the computer where my application running, WTS_REMOTE_CONNECT or WTS_REMOTE_DISCONNECT called twice -- in one of these calls I can get user name and in another I can't (it's just an empty string).
case WM_WTSSESSION_CHANGE:
{
const int reason = (int)wParam;
const DWORD sessionId = (DWORD)lParam;
switch (reason)
{
case WTS_REMOTE_CONNECT:
{
DWORD bytesReturned = 0;
LPSTR pData = NULL;
if (WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSUserName, &pData, &bytesReturned) == 0)
{
// Handle error
break;
}
const std::string username = pData;
WTSFreeMemory(pData);
// do other stuff
I found this question but it has very strange accepted answer:
Hmm, the answer appears to be that it's fairly normal for these fields
to be empty on a terminal services/RDP session
I don't understand why it actually works this way.

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.