Infragistics controls occasionally don't render - infragistics

Got a strange problem with Infragistics controls.
For the most part they work fine, but every now and again, one will fail to render at runtime and I'll see the control on the form with a Red Cross through it. The latest example is where the constructor of the UltraGridExcelExporter tries to grab a handle to the Device Context in the System.Drawning Graphics class (Call stack below - minus the company-proprietary call).
Any ideas what causes this and how I can handle it, given that the error is being thrown in the Infragistics controls?
Type : System.ArgumentException
Message : Parameter is not valid.
Source : System.Drawing
Help link :
ParamName :
Data : System.Collections.ListDictionaryInternal
TargetSite : IntPtr GetHdc()
HResult : -2147024809
Stack Trace: at System.Drawing.Graphics.GetHdc()
at Infragistics.Win.UltraWinGrid.ExcelExport.UltraGridExcelExporter..ctor()
at Infragistics.Win.UltraWinGrid.ExcelExport.UltraGridExcelExporter..ctor(IContainer container)

Related

WinUI3 : Handle network change event in WinUI3 desktop with c++

I'm working on the WinUI3 desktop application in C++. I was checking how we can get an event when the network to which system is connected to changes. I came across NetworkInformation.NetworkStatusChanged event. But I was not able to find any example of its implementation in C++.
NetworkStatusChangedEventHandler says it has one parameter which is IInspectable object.
i tried
static void NetworkStatusChange(winrt::Windows::Foundation::IInspectable const& sender);
But it gave this error
*\Generated Files\winrt\Windows.Networking.Connectivity.h(2213,81): error C2297: '.*': not valid as right operand has type 'const M'
Can you please help me with help me with how to implement NetworkStatusChanged event in WinUI3 C++ desktop application correctly.
Thank you.
This is how you can do it with C++/WinRT:
add this into the pch.h:
#include <winrt/Windows.Networking.Connectivity.h>
add this somewhere in your code:
// you can instead add a "using namespace Windows::Networking::Connectivity;"
// and use NetworkInformation directly if you prefer
Windows::Networking::Connectivity::NetworkInformation info{};
info.NetworkStatusChanged([=](auto&&...) // sender is not super interesting in this type of event so I've not declared it
{
// do your stuff here
MessageBox(nullptr, L"Something Changed!", L"Network", 0);
});
If you prefer the "raw" C/C++ way, there's an example here: How to detect network change events asynchronously using c++ WinRT

"There is no default printer selected" error when Windows default printer is not set up

I need to open the Printer Dialog box when there is no Windows default printer setup. It works fine with the below code when a Windows default printer is set up.
TPrintDialog *dlgPrint = new TPrintDialog(frmDisplayDetail);
if( dlgPrint->Execute()) { //code here }
But if there is no default printer setup in Windows, dlgPrint->Execute() throws an exception:
There is no default printer selected
To check the default printer index, I used Printer()->PrinterIndex. This value becomes inaccessible when there is no Windows printer setup:
error E2122 Function call terminated by unhandled exception XXX at address XXX
Am I doing something wrong? Please suggest a solution.
The exception "There is no default printer currently selected" is thrown only by the TPrinter::SetToDefaultPrinter() method, when either:
the Win32 API EnumPrinters() function fails with an ERROR_INVALID_NAME error code when enumerating with the (undocumented) PRINTER_ENUM_DEFAULT flag.
the TPrinter::Printers list does not contain the default printer. If EnumPrinters() above does not report a default device, the default is then queried from the Win32 API GetDefaultPrinter() function (Delphi/C++Builder 2009 and later), or the device value of the [windows] section of %windir%\win.ini (Delphi/C++Builder 2007 and earlier).
TPrinter::SetToDefaultPrinter() is called only by:
the TPrinter::PrinterIndex getter if the FPrinterIndex member is currently -1.
the TPrinter::PrinterIndex setter if the FPrinterIndex member is currently -1, or the property is being set to -1.
TPrintDialog::Execute() (which uses the Win32 API PrintDlg() function) first calls TPrinter::GetPrinter() to get a handle to the DEVMODE of the currently selected printer, which it then uses to initialize the dialog (via the PRINTDLG::hDevMode field). TPrinter::GetPrinter() reads the TPrinter::PrinterIndex property, so if there is no currently selected printer and no default printer, the exception is thrown.
If there is no default printer configured, you are basically out of luck, as you can't even set the TPrinter::PrinterIndex property to a value >= 0 since it will first call SetToDefaultPrinter() before checking if the new value matches the current value.
TPrinter has a long history of failing/crashing when there is no default printer configured in Windows. To work around this, you should call the Win32 API PrintDlg() function directly instead. At least then, you can manually call TPrinter::GetPrinter() (to get the initial DEVMODE) and wrap it in a try/catch block to discard any exceptions that it may throw.
If the dialog result indicates success, you can manually call TPrinter::SetPrinter() to assign the selected printer options to TPrinter for subsequent printing.
I am checking existence of printers before the dialog usage:
// check printer interface
TPrinter *prn = Printer();
int pxs,pys,i=0;
if (prn==NULL)i=1;
if (prn->Printers==NULL) i=1;
if (prn->Printers->Count<=0) i=1;
if (i) return;
// use dialog
dlg_print->Options.Clear();
dlg_print->Options<<poPrintToFile;
if (!dlg_print->Execute()) return;
// print
prn = Printer();
pxs=prn->PageWidth;
pys=prn->PageHeight;
prn->BeginDoc();
for (i=0;i<dlg_print->Copies;i++)
{
if (i) prn->NewPage();
// here render page into prn->Canvas as image in resolution pxs,pys
}
prn->EndDoc();
where dlg_print is my dialog placed on the form.

CWinApp OpenDocumentFile "unsupported operation" error

Problem
I'm trying to open an MFC program that reads a Microsoft Access database (.mdb) and allows the user to view or modify the data. This is an existing program (and source code) given to me by a group in another lab where the program opens and works just fine.
In our lab, I have yet to see it load properly. When run, it pops up a dialog box that says, "Attempted an unsupported operation". Windows then offers me a chance to debug and such before it crashes.
Environment
In the other lab, they use Windows 7 and Microsoft Office 2010, and it works.
In our lab, I've tried Windows 7 with Office 2013 and Windows XP with Office 2010. The latter crashes without giving me the dialog box. I don't know if we have a Win7/MSO2010 machine.
The Function
I have the source code for the program. The solution file implies it was last developed in VS2010, which the computers I tested on had installed as well. Running it out of Visual Studio 2010 or straight from the executable yields the same results.
I have added additional debug dialog boxes to the code that narrow down the problem to this function call, which the code never gets past:
CwinApp:OpenDocumentFile(LPCTSTR lpszPathName)
The single string passed into the function is a path and filename for the MS Access database to be opened. It exists in a temporary directory created by another program. This is on a drive other than C, though I've tested some there, as well. Problems with programs related to this one often stem from files with "read only" status, but I continually check the temporary files created, and they are write-able.
Documentation
I found this information titled "Breaking Changes in Visual C++" for VS2010 through another SO question:
A new virtual function was added to the CDocTemplate class. This new virtual function is CDocTemplate::OpenDocumentFile. The previous version of OpenDocumentFile had two parameters. The new version has three parameters. To support the restart manager, any class derived from CDocTemplate must implement the version that has three parameters. For more information about the function, see CDocTemplate::OpenDocumentFile. The new parameter is bAddToMRU.
Code
I feel this might be the answer! But I don't have a strong idea of exactly what to change to get this to work. Here's where I stopped:
Program.cpp
CDocument* ProgramApp::OpenDocumentFile(LPCTSTR lpszFileName, BOOL bAddToLRU, BOOL bMakeVisible)
{
// Add specialized code here and/or call base class
// Debug messages added
CDocument* tempDoc;
AfxMessageBox(lpszFileName);
tempDoc = CWinApp::OpenDocumentFile(lpszFileName, bAddToMRU);
AfxMessageBox("Opened database!");
return tempDoc;
}
Program.h
class ProgramApp : public CWinApp
{
public:
...
virtual CDocument* OpenDocumentFile(LPCTSTR lpszFileName, BOOL bAddToMRU, BOOL bMakeVisible);
afxwin.h
class CWinApp : public CWinThread
{
...
virtual CDocument* OpenDocumentFile(LPCTSTR lpszFileName);
virtual CDocument* OpenDocumentFile(LPCTSTR lpszFileName, BOOL bAddToMRU);
Changing the Program.cpp call to be from a "Template" class caused errors, but I wouldn't be surprised if that's towards the answer. This solution looks similar, but I'm not sure exactly what to do.
My hope is that this problem has a simple solution that someone more knowledgeable can give me. I would be much appreciative, and additional context would help a lot.
Edit: Debugging
I drilled down into the Windows code to see what was precisely going wrong. It seemed too dense to understand, but a coworker and I may have clues based on it. The failure message happens here:
dlgdata.cpp
// Could be a windowless OCX
pSite = m_pDlgWnd->GetOldControlSite(nIDC);
if (pSite == NULL)
{
TRACE(traceAppMsg, 0, "Error: no data exchange control with ID 0x%04x.\n", nIDC);
ASSERT(FALSE);
AfxThrowNotSupportedException();
}
...Although we are seeing debugger issues here:
occcont.cpp
COleControlSiteOrWnd *pemp = new COleControlSiteOrWnd(hwndCtrl, pOccDlgInfo->m_pItemInfo[i].bAutoRadioButton);
ASSERT(IsWindow(pTemp->m_hWnd));
if (IsWindow(pTemp->m_hWnd))
{
hwndStart = pTemp->m_hWnd;
...
My coworker believes this could have little to do with the opening of this document as I suspected and more to do with objects/controls we don't have on our lab computers trying to be used for the program.
I have faced the same problem in opendocumentfile(), there was a control in CFormView class which i was not using so i commented it out but forget to delete from .rc file. Once i remove the control entry from .rc file the problem disappear.
there should be no control variable uninitialize , please check that also

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

What is the difference between ON_WM_CTLCOLOR_REFLECT() and ON_WM_CTLCOLOR() in VS2008?

The question is like this:
I write a windows application in VS2005, building success. Then I transfer it to VS2008, when I build the program, there will be an error messsage shows:
error C4867: 'CGroupBox::CtlColor': function call missing argument list; use '&CGroupBox::CtlColor' to create a pointer to member
the message map is as follows:
BEGIN_MESSAGE_MAP(CGroupBox, CButton)
//{{AFX_MSG_MAP(CGroupBox)
ON_WM_PAINT()
ON_WM_CTLCOLOR_REFLECT()
//ON_WM_CTLCOLOR()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
the function is is as follows:
HBRUSH CGroupBox::CtlColor(CDC* pDC, UINT nCtlColor)
{
GetParent()->Invalidate();
return NULL;
}
but if I change to the ON_WM_CTLCOLOR() ,I can get a successful build.
The error message is because the signature of the message handler doesn't match the signature you're using. Look up the signatures for ON_WM_CTLCOLOR_REFLECT() and ON_WM_CTLCOLOR() on MSDN to get the correct ones.
As to the question in your title, some controls normally send their notification messages to their parent. Which is inconvenient, because every time you re-use that control, you need to change its parent window. Therefore MFC has 'reflection' support, which is basically a way of saying 'when you receive a notification from a child control, first try bouncing it back to that control to see if that control knows how to deal with it itself.'
Read the details on https://web.archive.org/web/20101229015404/http://msdn.microsoft.com/en-us/library/eeah46xd(v=vs.80).aspx .
I just had the same problem, and as you can see from the link Roel provided, the original poster DID have the correct signature.
Turns out this is a bug in MFC itself. Find ON_WM_CTLCOLOR_REFLECT in afxmsg_.h and you'll notice that CtlColor is missing the "&" before it. I guess the older compilers didn't mind. Add the "&" to make it "&CtlColor" and the error is fixed.
Alternatively, if you don't like changing the official headers, you could #under ON_WM_CTLCOLOR_REFLECT in your own code and define it again properly.
I notice many other (maybe all?) reflected messages in that file have the same problem too.