Second use of CFileDialog in my program gets the run-time error Debug Assertion failed - c++

I have developed a simple program with MFC. It's responsible for reading and writing geotiff files using GDAL library. For this purpose, I have derived two classes from CFileDialog class named ManageOpenGeoTiffFiles and ManageSaveGeoTiffFiles each have 3 functions to support reading and writing geotiffs.
this is the header of the constructor and destructor for one of them:
ManageOpenGeoTiffFiles::ManageOpenGeoTiffFiles(void):CFileDialog(true,0,0,OFN_ENABLESIZING | OFN_HIDEREADONLY,_T("Tiff Files (*.tif)|*.tif|"),0,0,true)
ManageOpenGeoTiffFiles::~ManageOpenGeoTiffFiles(void)
{
}
and this is how I use it in my code:
void CInitialJobProject2FinalDlg::OnBnClickedBtnopen()
{
// TODO: Add your control notification handler code here
m_oglWindow1.WantToPan = false;
m_oglWindow1.WantToUseZoomTool = false;
CString fullpath;
if ( m_openFiles.DoModal() == IDOK )
{
fullpath = m_openFiles.GetPathName();
try{
m_openFiles.OpenGeoTiffAsReadonly(fullpath);
}
catch(CFileException *e){
MessageBox(_T("the file could not be opened"),_T("error"),MB_OK);
this ->ExitMFCApp();
}
m_openFiles.ReadRasterData();
}
else
MessageBox(_T("you pressed cancel and can not proceed."),_T("error"),MB_ICONERROR);
}
everythings ok when I use the Open or Save button for the first time in my program but when it comes to second use I get the error:
and if I click ignore:
this error occurs in the line:
if ( m_openFiles.DoModal() == IDOK )
of each dialog and even if I click cancel the first time,the error occures in the second use of dialog.
Line 398 of dlgFile.cpp is as follows:
hr = (static_cast<IFileDialog*>(m_pIFileDialog))->SetFileTypes(nFilterCount, pFilter);
ENSURE(SUCCEEDED(hr));
Edited section:
Answering one of the comments and providing information for others too:
When I set a breakpoint there saw these results when the assertion fails:
pFilter 0x00fc3660 {pszName=0x00fc36a8 "Tiff Files (*.tif)" pszSpec=0x00fc3788 "*.tif" }
hr E_UNEXPECTED
and the results for the first time when the assertion does not fail is as follows:
pFilter 0x004cfca0 {pszName=0x004cfce8 "Tiff Files (*.tif)" pszSpec=0x004cfdc8 "*.tif" }
hr S_OK

You are passing a malformed filter string to CFileDialog::CFileDialog. The Remarks sections states the following condition:
The lpszFilter parameter [...] ends with two '|' characters.

Related

Setting Status icon for CFAPI does not work as expected

I try to set the status icon of the placeholder file created with CFAPI to error. (see below)
content of folder T:
I set the error state on the file, but it does not display the error. However the error is displayed on the containing folder.
I use following code to set the error on the file (the complete code is published on github):
void SetTransferStatus(_In_ PCWSTR fullPath, _In_ SYNC_TRANSFER_STATUS status)
{
// Tell the Shell so File Explorer can display the progress bar in its view
try
{
// First, get the Volatile property store for the file. That's where the properties are maintained.
winrt::com_ptr<IShellItem2> shellItem;
winrt::check_hresult(SHCreateItemFromParsingName(fullPath, nullptr, __uuidof(shellItem), shellItem.put_void()));
winrt::com_ptr<IPropertyStore> propStoreVolatile;
winrt::check_hresult(
shellItem->GetPropertyStore(
GETPROPERTYSTOREFLAGS::GPS_READWRITE | GETPROPERTYSTOREFLAGS::GPS_VOLATILEPROPERTIESONLY,
__uuidof(propStoreVolatile),
propStoreVolatile.put_void()));
// Set the sync transfer status accordingly
PROPVARIANT transferStatus;
winrt::check_hresult(
InitPropVariantFromUInt32(
status,
&transferStatus));
winrt::check_hresult(propStoreVolatile->SetValue(PKEY_SyncTransferStatus, transferStatus));
// Without this, all your hard work is wasted.
winrt::check_hresult(propStoreVolatile->Commit());
// Broadcast a notification that something about the file has changed, so that apps
// who subscribe (such as File Explorer) can update their UI to reflect the new progress
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, static_cast<LPCVOID>(fullPath), nullptr);
//wprintf(L"Succesfully Set Transfer Progress on \"%s\" to %llu/%llu\n", fullPath, completed, total);
}
catch (...)
{
// winrt::to_hresult() will eat the exception if it is a result of winrt::check_hresult,
// otherwise the exception will get rethrown and this method will crash out as it should
wprintf(L"Failed to Set Transfer Progress on \"%s\" with %08x\n", fullPath, static_cast<HRESULT>(winrt::to_hresult()));
}
}
In addition, if I delete the file and create a new file the state will still be on error.
Someone pointed me to an pull request in the windows cloud mirror sample that shows how to accomplish this.
This is the code:
void Utilities::UpdateErrorOnItem(PCWSTR path, bool setError)
{
try
{
winrt::com_ptr<IShellItem2> item;
winrt::check_hresult(SHCreateItemFromParsingName(path, nullptr, IID_PPV_ARGS(item.put())));
winrt::com_ptr<IPropertyStore> propertyStore;
winrt::check_hresult(item->GetPropertyStore(GPS_READWRITE | GPS_EXTRINSICPROPERTIESONLY, IID_PPV_ARGS(propertyStore.put())));
PROPVARIANT propVar{};
if (setError)
{
propVar.vt = VT_UI4;
propVar.ulVal = static_cast<unsigned long>(E_FAIL);
winrt::check_hresult(propertyStore->SetValue(PKEY_LastSyncError, propVar));
}
else
{
// Clear by setting to empty
propVar.vt = VT_EMPTY;
winrt::check_hresult(propertyStore->SetValue(PKEY_LastSyncError, propVar));
}
winrt::check_hresult(propertyStore->Commit());
}
catch (...)
{
// winrt::to_hresult() will eat the exception if it is a result of winrt::check_hresult,
// otherwise the exception will get rethrown and this method will crash out as it should
wprintf(L"Failed to set error state with %08x\n", static_cast<HRESULT>(winrt::to_hresult()));
}

Cannot set Scanner Capability because L_TwainStartCapsNeg returns error -84

I'm trying to use the Leadtools API version 21 for automatically scanning some documents and here is a sudo code of what I have done (it runs in a secondary thread and the unlock has been done in the main thread):
void CheckRetCode(int rc)
{
if (SUCCESS != rc)
{
L_TCHAR errMsg[1024];
memset(errMsg, 0, sizeof(errMsg));
L_GetFriendlyErrorMessage(rc, errMsg, 1024, L_FALSE);
throw TLeadException(errMsg, rc);
}
}
void OnThreadExecute(void)
{
HTWAINSESSION hSession = nullptr;
APPLICATIONDATA appData;
L_INT nRet;
L_TCHAR pszTwnSourceName[1024];
LTWAINSOURCE sInfo;
memset(&appData, 0, sizeof(APPLICATIONDATA));
appData.uStructSize = sizeof(APPLICATIONDATA);
appData.hWnd = hWnd;// hWnd is valid handle of my main window
appData.uLanguage = TWLG_ENGLISH_USA;
appData.uCountry = TWCY_USA;
wcscpy(appData.szManufacturerName, L"MyCompanyName");
wcscpy(appData.szAppProductFamily, L"MyProductName");
wcscpy(appData.szAppName, appData.szAppProductFamily);
wcscpy(appData.szVersionInfo, L"Version 0.1.0.1");
nRet = L_TwainInitSession2(&hSession, &appData, LTWAIN_INIT_MULTI_THREADED);
CheckRetCode(nRet);// the exception gets catched elsewhere but no error reported here
memset(pszTwnSourceName, 0, sizeof(pszTwnSourceName));
wcscpy(pszTwnSourceName, L"EPSON Artisan837/PX830"); // the name of the scanner is verifyed
sInfo.uStructSize = sizeof(LTWAINSOURCE);
sInfo.pszTwainSourceName = pszTwnSourceName;
CheckRetCode(L_TwainSelectSource(hSession, &sInfo)); // No error reported here
CheckRetCode(L_TwainStartCapsNeg(hSession)); // in here I get the return value -84 which is reported as "TWAIN DS or DSM reported error, app shouldn't (no need for your app to report the error)."
// the rest of the code but we cannot get there since above code reports error
}
Can anyone tell me what I'm doing wrong? Is there a step that I'm missing here?
EditThe function L_TwainSelectSource() make no effort to make sure the supplied source is valid and does not even return an error. As result, if you set the selected source to a garbage name, it will act as if it accepted it. From that point on if you try to Get/Set anything or try to acquire an image, every function returns -84.
Thank you
Sam
To test your code, I put the main window’s handle in a global variable:
globalhWnd = hWnd;
And modified your function to use that handle like this:
void OnThreadExecute(void *)
{
...
appData.hWnd = globalhWnd; // hWnd is valid handle of my main window
...
}
Then created a thread for it from the main program like this:
globalhWnd = hWnd;
_beginthread(OnThreadExecute, 0, 0);
I tried this with 5 different Twain sources: 2 virtual and 3 physical scanners (one of them an old Epson). All 5 drivers returned SUCCESS when calling L_TwainStartCapsNeg() from within the thread.
Two possibilities come to mind:
The problem might be caused by something else in your code other than the thread function.
Or the problem could be specific to your Twain driver.
To rule out the first possibility, I suggest creating a small test project that only creates a similar thread and does nothing else and trying it with different scanners. If it causes the same problem with all scanners, send that test project (not your full application) to support#leadtools.com and our support engineers with test it for you.
If the problem only happens with a specific Twain driver, try contacting the scanner’s vendor to see if they have an updated driver.

measuring performance of directshow filter

I have built a mp3 decoder directshow filter for win CE , and I want to measure the performance of the decoder. I found two macros from msdn site, https://msdn.microsoft.com/en-IN/library/ms932254.aspx which is declared in the measure.h header file in base classes.
It is explained in the measure.h file that these macros will expand to nothing unless macro PERF is defined. but once I enable the macro, I get link error
"LNK2019: unresolved external symbol Msr_Start() referneced in
function function "public: virtual long_cdecl
CMP3Decoder::Recieve(Struct IMediaSample
*)"(?Recieve#CMP3Decoder##UAAJPAUIMediaSample###Z)
I tried to dump the symbols in strmbase.lib, but I couldn't find any symbol name Msr_Start in it. also I searched the whole base classes folder source code.
where can I find the definition for these functions?
Or is there any other ways to measure the performance of the filter?
CMP3Decoder::recieve() function is as follows
HRESULT CMP3Decoder::Receive(IMediaSample *pSample)
{
HRESULT hr;
ASSERT(pSample);
if(pSample == NULL || m_MP3DecHandle == NULL)
{
return E_FAIL;
}
ASSERT (m_pOutput != NULL) ;
// Start timing the transform (if PERF is defined)
MSR_START(m_idTransform);
// have the derived class transform the data
hr = MP3StartDecode(pSample);//, pOutSample);
// Stop the clock and log it (if PERF is defined)
MSR_STOP(m_idTransform);
if (FAILED(hr)) {
//DbgLog((LOG_TRACE,1,TEXT("Error from transform")));
} else {
// the Transform() function can return S_FALSE to indicate that the
// sample should not be delivered; we only deliver the sample if it's
// really S_OK (same as NOERROR, of course.)
if (hr == NOERROR) {
//hr = m_pOutput->Deliver(pOutSample);
m_bSampleSkipped = FALSE; // last thing no longer dropped
} else {
// S_FALSE returned from Transform is a PRIVATE agreement
// We should return NOERROR from Receive() in this cause because returning S_FALSE
// from Receive() means that this is the end of the stream and no more data should
// be sent.
if (S_FALSE == hr) {
// Release the sample before calling notify to avoid
// deadlocks if the sample holds a lock on the system
// such as DirectDraw buffers do
//pOutSample->Release();
m_bSampleSkipped = TRUE;
if (!m_bQualityChanged) {
NotifyEvent(EC_QUALITY_CHANGE,0,0);
m_bQualityChanged = TRUE;
}
return NOERROR;
}
}
}
// release the output buffer. If the connected pin still needs it,
// it will have addrefed it itself.
//pOutSample->Release();
return hr;
}
According to MSDN, you need to link to Strmiids.lib.
Or is there any other ways to measure the performance of the filter?
To measure performance of a filter, I typically insert a custom trans-in-place filter before and after the filter to be measured. The trans-in-place filter outputs sample times and current time in high resolution to a log file. You can calculate filter processing time by subtracting the before current times from the after and averaging those, etc. Also, the file-io should only be done after stopping the graph as you don't want to interfere with the measurement itself.
Update:
Dumping the symbols in Strmiids.lib seems to confirm that Msr_xxx functions are not defined in Strmiids.lib. Looks like the MSDN article is incorrect.

Visual C++ System::Windows::Forms::SaveFileDialog() throws System.AccessViolationException and quietly kills application if started by drag/drop

In a simple application (a skeleton put together with Visual Studio designer) I recently worked around an error that only manifests if I use drag/drop to execute the program.
Problem: I drag and drop a file onto my program. I later use File->SaveAs to save the contents of a rich text box. If I attempt to type a filename or drop down the hierarchy of directory paths, the application instantly quits. If I select a file displayed in the SaveAs dialog, this works fine (after accepting the overwrite).
Workaround: Add a try/catch block above the ShowDialog call in the saveAsToolStripMenuItem_Click function containing an attempt to open and write to a file. A simple fputs will cause the exception, which I then ignore and delete any file created in the process.
If someone knows a simpler (or cleaner!) solution, thanks in advance. Otherwise, here is my ugly solution:
private: System::Void saveAsToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e)
{
static bool fFirstTime = true;
static char *sBogusFileName = "c:\\__$$TrashFileIMustCreateThenDelete";
SaveFileDialog^ dialog = gcnew SaveFileDialog();
{
System::Windows::Forms::DialogResult DR;
dialog->Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
dialog->FilterIndex = 2;
dialog->RestoreDirectory = true;
// dialog->InitialDirectory = "c:\\";
if (fFirstTime)
{
FILE *fp;
// This is a strange problem that came up on my Windows XP machine.
// The first time through this logic, I would get a System.AccessViolationException
// If I do it with this simple fputs, the error is recoverable.
// If it happens during the dialog->ShowDialog that follows, the application quietly exits.
// No event logs, nothing. This solved it for me.
try {
// The fopen that follows make the MS compiler unhappy. The filename is hard-coded, so I don't care.
#pragma warning( suppress: 4996 )
fp=fopen(sBogusFileName, "w");
fputs("A string that might never be actually written - this causes an exception on some machines\n", fp);
}
catch(Exception ^e)
{
(void)e; // Suppress another compiler error (unused variable)
// Debug code that I later removed. This logging is not required to fix the problem.
// RRCLOGB1("\nError attempting to write to a file:\n%s\n\n", e->ToString());
}
finally
{
fclose(fp);
}
remove(sBogusFileName);
fFirstTime = false; // Only cause the exception once...but why is it necessary?!?
}
DR = dialog->ShowDialog(this);
if ( DR == System::Windows::Forms::DialogResult::OK )
{
o
o
o

wxWidgets debug assertion failed, xtree not deferencable, when modifying wxTextCtrl value

When I enter a wxDialog and I focus one wxTextCtrl nothing bad happens but as soon as I modify something in that text, like deleting one character, the application crashes with this message:
"debug assertion failed: map/set iterator not dereferencable"
The last method I found out is called before crashing is this one:
bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
{
#if wxUSE_CARET
// Deal with caret
if ( m_caret )
{
m_caret->OnKillFocus();
}
#endif // wxUSE_CARET
#if wxUSE_TEXTCTRL
// If it's a wxTextCtrl don't send the event as it will be done
// after the control gets to process it.
wxTextCtrl *ctrl = wxDynamicCastThis(wxTextCtrl);
if ( ctrl )
{
return false;
}
#endif
// Don't send the event when in the process of being deleted. This can
// only cause problems if the event handler tries to access the object.
if ( m_isBeingDeleted )
{
return false;
}
wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
event.SetEventObject(this);
// wxFindWinFromHandle() may return NULL, it is ok
event.SetWindow(wxFindWinFromHandle(hwnd));
return GetEventHandler()->ProcessEvent(event);
}
While running the application, this method is called many times; ctrl having a value of 0x00000000 all the time and therefor not returning false in the first IF clause.
While being inside the dialog and modifying the text, the value of ctrl changes to a real value 0x031194b0; then it enters the IF clause, returns false, and crashes.
The problem came from another code modification that I still do not find how it could have this effect. Internal behaviour of wxWidgets library maybe?