I'm upgrading my Crystal report runtime for visual studio from SP16 to the latest one, SP 27, but after building my whole application and running it, when I open a crystal report I end up having an error dialog showing:
Debug Assertion Failed!
Program: C:\WINDOWS\SYSTEM32\mfc140d.dll
File: .../mfc/occsite.cpp
Line:1007
and if I click on Ignore it shows me the stack trace which is this one:
************** Exception Text **************
System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception.
at COleControlSite.AttachWindow(COleControlSite* )
at Microsoft.VisualC.MFC.CWinFormsControlSite.OnHandleCreatedHandler(CWinFormsControlSite* )
at Microsoft.VisualC.MFC.CWinFormsControlSite.OnHandleCreated(CWinFormsControlSite* , Object A_0, EventArgs A_1)
at Microsoft.VisualC.MFC.CWinFormsEventsHelper.OnHandleCreated(Object o, EventArgs args)
at System.Windows.Forms.Control.OnHandleCreated(EventArgs e)
at System.Windows.Forms.Control.WmCreate(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.UserControl.WndProc(Message& m)
at CrystalDecisions.Windows.Forms.CrystalReportViewer.WndProc(Message& msg)
at System.Windows.Forms.Control.ActiveXImpl.System.Windows.Forms.IWindowTarget.OnMessage(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
And then my report is being launched as normal, as if nothing happened.
I'm running VS17, VC Redistributable x64 and x86 14.25.28508, .NET Framework 4.8 and SP any from 25 to 27.
If I install any other SP from 16 to 24 they all work fine. Also on the wiki is says that VS17 is supported from SP21 and higher so I was expecting SP27 to be working fine with VS17 as well.. but it doesnt seem the case, since from SP25 it keeps throwing that exception for me
Looking at the occsite.cpp file this is the function throwing the error
void COleControlSite::AttachWindow()
{
ENSURE_ARG(m_pInPlaceObject!=NULL);
HWND hWnd = NULL;
if (SUCCEEDED(m_pInPlaceObject->GetWindow(&hWnd)))
{
ASSERT(hWnd != NULL);
if (m_hWnd != hWnd)
{
m_hWnd = hWnd;
if (m_pWndCtrl != NULL)
{
ASSERT(m_pWndCtrl->m_hWnd == NULL); // Window already attached?
m_pWndCtrl->Attach(m_hWnd);
ASSERT(m_pWndCtrl->m_pCtrlSite == NULL ||
m_pWndCtrl->m_pCtrlSite == this);
m_pWndCtrl->m_pCtrlSite = this;
}
}
}
}
Related
I would like to hook Windows Explorer paste event to copy files from a remote connection.
Description: The goal is remote copy/paste files. Like Team Viewer or Remote Desktop. Ctrl+C file on one computer, and Ctrl+V on another...
Well let's break this problem into 3 parts:
1. Detect for clipboard changes:
This is pretty easy, by registering a hook using SetClipboardViewer, Windows will nicely send us an WM_DRAWCLIPBOARD message:
HWND nextClipboardViewer = nullptr;
void HandleClipboardChanges()
{
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
nextClipboardViewer = SetClipboardViewer(hwnd);
break;
case WM_CHANGECBCHAIN:
if (reinterpret_cast<HWND>(wParam) == nextClipboardViewer)
{
nextClipboardViewer = reinterpret_cast<HWND>(lParam);
}
else if (nextClipboardViewer != nullptr)
{
SendMessage(nextClipboardViewer, msg, wParam, lParam);
}
break;
case WM_DRAWCLIPBOARD:
HandleClipboardChanges();
SendMessage(nextClipboardViewer, msg, wParam, lParam);
break;
}
}
2. Get the active Windows Explorer directory
In the HandleClipboardChanges function above, we should iterate through all the opened Windows Explorer, check if any of them is focused, and get their current directory, thanks to zett42's answer, we could do this fairly easily:
HWND hWndExplorer = nullptr;
HWND hWndFocused = GetActiveWindow();
std::wstring explorerDir;
for (const auto& info : GetCurrentExplorerFolders())
{
if (hWndFocused == info.hwnd)
{
CComHeapPtr<wchar_t> pPath;
if (SUCCEEDED(::SHGetNameFromIDList(info.pidl.get(), SIGDN_FILESYSPATH, &pPath)))
{
hWndExplorer = info.hwnd;
explorerDir = pPath;
}
break;
}
}
3. Handle the copy operation and show a progress dialog
For the progress dialog, we will use IProgressDialog, although IOperationsProgressDialog has more features, but it is also more difficult to use, you can consider switching to it.
The hWndParent passed into IProgressDialog::StartProgressDialog could be nullptr, but we will use the explorer's hWnd for consistency.
The below code doesn't check for errors for readability.
// don't forget the include and CoInitialize
#include <atlbase.h>
#include <shlobj_core.h>
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
CComPtr<IProgressDialog> pDialog;
pDialog.CoCreateInstance(CLSID_ProgressDialog);
pDialog->StartProgressDialog(hWndExplorer, nullptr, PROGDLG_AUTOTIME, nullptr);
pDialog->SetTitle(L"Copying from network");
pDialog->SetLine(1, L"Copying 69 files", false, nullptr);
// Do your copy operation here
for (DWORD i = 0; i < 1'000'000; i++)
{
pDialog->SetProgress(i, 1'000'000);
pDialog->SetLine(2, L"Copying file_a.txt", false, nullptr);
// Check if the user had cancelled the operation
// See also: pDialog->SetCancelMsg()
// BOOL isUserCancelled = pDialog->HasUserCancelled();
}
pDialog->StopProgressDialog();
Related:
Monitoring clipboard
How to get the path of an active file explorer window in c++ winapi
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!
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;
…
I have a piece of MS C++ (unmanaged) code that runs whenever a USB device is inserted or removed into my computer. On Windows 7, this code runs fine. On Windows 10, it throws an error. What happens is that when a USB drive, or any other USB device for that matter, is inserted into my computer, the OnMyDeviceChange routine gets called 3 times; it is only called two (correct) times on Windows 7. Anyways, on Windows 10, the first two times, the routine runs fine. The third time it fails on this line: type.Format("%d",pHdr->dbch_devicetype);. Does anyone know why?
Note: we now know that for the code that fails, pHdr is null.
Here is my code:
ON_MESSAGE(WM_DEVICECHANGE, OnMyDeviceChange)//in BEGIN_MESSAGE_MAP(CMainFrame, CBCGPMDIFrameWnd)
LRESULT CMainFrame::OnMyDeviceChange(WPARAM wParam, LPARAM lParam)
{
//return 0;//essentially comment out everything else
PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
AddLogLine("1");
// AfxMessageBox(pHdr->dbch_devicetype);
PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr;
AddLogLine("2");
CString type;
type.Format("%d",pHdr->dbch_devicetype);
AddLogLine("type = " + type);
if(pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
UpdateDevice(pDevInf, wParam);
}
return 0;
}
//More relevant code:
struct _DEV_BROADCAST_HDR { /* */
DWORD dbch_size;
DWORD dbch_devicetype;
DWORD dbch_reserved;
};
typedef struct _DEV_BROADCAST_HDR DEV_BROADCAST_HDR;
typedef DEV_BROADCAST_HDR DBTFAR* PDEV_BROADCAST_HDR;
Is it possible to get all windows hwnd from a Alt + Tab window - excluding Metro? Maybe there is some alternative for Windows 8?
I was trying to get all windows using EnumWindows function and paste hwnd's to the GetAltTabInfo function and it is not working for me. I get error message: "Invalid window handle" from GetLastError, because this function (GetAltTabInfo) is no longer usable when you've got Aero enabled. This conclusion is from here: GetAltTabInfo usage?.
Using "Which windows appear in the Alt+Tab list?" article by Raymond Chen, I have been able to reproduce the window list.
// See http://blogs.msdn.com/b/oldnewthing/archive/2007/10/08/5351207.aspx
BOOL IsAltTabWindow(HWND hwnd)
{
// Start at the root owner
HWND hwndWalk = GetAncestor(hwnd, GA_ROOTOWNER);
// See if we are the last active visible popup
HWND hwndTry;
while ((hwndTry = GetLastActivePopup(hwndWalk)) != hwndTry) {
if (IsWindowVisible(hwndTry)) break;
hwndWalk = hwndTry;
}
return hwndWalk == hwnd;
}
BOOL CALLBACK CbEnumAltTab(HWND hwnd, LPARAM lParam)
{
// Do not show invisible windows
if (!IsWindowVisible(hwnd))
return TRUE;
// Alt-tab test as described by Raymond Chen
if (!IsAltTabWindow(hwnd))
return TRUE;
const size_t MAX_WINDOW_NAME = 256;
TCHAR windowName[MAX_WINDOW_NAME];
if (hwnd == GetShellWindow())
_tcscpy_s(windowName, MAX_WINDOW_NAME, _T("Desktop")); // Beware of localization
else
GetWindowText(hwnd, windowName, MAX_WINDOW_NAME);
// Do not show windows that has no caption
if (0 == windowName[0])
return TRUE;
// Print found window to debugger's output
const size_t MAX_MESSAGE_NAME = 64 + MAX_WINDOW_NAME;
TCHAR message[MAX_MESSAGE_NAME];
_stprintf_s(message, MAX_MESSAGE_NAME, _T("AltTab: %08X %s\n"), hwnd, windowName);
OutputDebugString(message);
return TRUE;
}
void ListAltTabWindows()
{
EnumWindows(CbEnumAltTab, 0);
}
Notes:
metro seems to be excluded already
Didn't check WS_EX_TOOLWINDOW
Didn't check WS_EX_APPWINDOW.
Didn't test extensively