CheckForDuplicateEntries': is not a member of 'Microsoft::WRL::Details (C2039) - visual-c++

I am programming a DirectX Game and on Debug mode it's working normally,
but on release mode I get 46 Errors of this:
Severity Code Description Project File Line Suppression State Error C2039 'CheckForDuplicateEntries': is not a member of 'Microsoft::WRL::Details' DirectXGame D:\Windows Kits\10\Include\10.0.17763.0\winrt\wrl\module.h 1427
I looked into the module.h code and saw this code:
void VerifyEntries() throw()
{
// Walk the linker generated list of pointers to CreatorMap for WinRT objects
for (const Details::CreatorMap** entry = GetMidEntryPointer() + 1; entry < GetLastEntryPointer(); entry++)
{
if (*entry == nullptr)
{
continue;
}
const wchar_t* name = ((*entry)->activationId.getRuntimeName)();
(name);
// Make sure that runtime class name is not nullptr and it has no empty string
__WRL_ASSERT__(name != nullptr && ::wcslen(name) != 0);
}
Details::CheckForDuplicateEntries((GetFirstEntryPointer() + 1), GetMidEntryPointer(),
[](const Details::CreatorMap* entry, const Details::CreatorMap* entry2) -> void {
__WRL_ASSERT__(entry->activationId.clsid != entry2->activationId.clsid && "Duplicate CLSID!");
}
);
Details::CheckForDuplicateEntries((GetMidEntryPointer() + 1), GetLastEntryPointer(),
[](const Details::CreatorMap* entry, const Details::CreatorMap* entry2) -> void {
__WRL_ASSERT__(::wcscmp((entry->activationId.getRuntimeName)(), (entry2->activationId.getRuntimeName)()) != 0 && "Duplicate runtime class name!");
}
);
}
But CheckForDuplicateEntries is only allowed on Debug mode:
#ifdef _DEBUG
template<typename T>
inline void CheckForDuplicateEntries(const CreatorMap** firstEntry, const CreatorMap** lastEntry, T validateEntry) throw()
{
__WRL_ASSERT__(firstEntry <= lastEntry);
if (firstEntry == lastEntry)
{
return;
}
for (const CreatorMap** entry = firstEntry; entry < (lastEntry - 1); entry++)
{
if (*entry == nullptr)
{
continue;
}
// Walk the linker generated list of pointers to CreatorMap
for (const CreatorMap** entry2 = (entry + 1); entry2 < lastEntry; entry2++)
{
if (*entry2 != nullptr)
{
(validateEntry)(*entry, *entry2);
}
}
}
}
#endif // _DEBUG
Does anyone know how I can get rid of this error?
I tried to remove the #endif define and of course it worked but only in visual studio and no where else.
I'm using vs2019, iso c++ 17, SDK 10.0.17763.0,
Thank you for helping!
SOLUTION: Updated SDK version from 10.0.17763.0 to 10.0.20348.0

Windows SDK (17763) is not the 'latest' version.
This specific issue is fixed in the Windows SDK (18362) or later, so I suggest installing a newer version and/or making sure your selection of Windows SDK in the build properties points to the newer one.
At this point, I'd recommend not using any build older than Windows SDK (19041).
https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/

Related

Using a mutex to limit instance of application is not respected if one instance if started from Visual Studio

In InitInstance of my dialog application I use this code to detect other running versions:
strOwner.LoadString(IDS_APP_MUTEX);
m_hMutex = ::CreateMutex(nullptr, FALSE, strOwner);
HWND hOtherInstance = nullptr;
if (DetectRunningInstance(hOtherInstance))
{
DetectFileToOpenFromFileExplorer();
TryToOpenFileInOtherInstance(hOtherInstance);
return FALSE; // Terminates the creation
}
The other functions referred to are:
bool CMeetingScheduleAssistantApp::DetectRunningInstance(HWND& rhOtherWnd) noexcept
{
HWND hOther = nullptr;
if (m_hMutex != nullptr) // indicates running instance
{
if (::GetLastError() == ERROR_ALREADY_EXISTS)
{
EnumWindows(searcher, reinterpret_cast<LPARAM>(&hOther));
if (hOther != nullptr)
{
::SetForegroundWindow(::GetLastActivePopup(hOther));
if (IsIconic(hOther))
{
::ShowWindow(hOther, SW_RESTORE);
}
rhOtherWnd = hOther;
return true; // terminates the creation
}
}
}
return false;
}
And:
void CMeetingScheduleAssistantApp::DetectFileToOpenFromFileExplorer()
{
CCommandLineInfo cmdInfo;
m_bOpenFileFromFileExplorer = false;
m_strFileToOpenFromFileExplorerPath;
ParseCommandLine(cmdInfo);
if (PathFileExists(cmdInfo.m_strFileName))
{
m_bOpenFileFromFileExplorer = true;
m_strFileToOpenFromFileExplorerPath = cmdInfo.m_strFileName;
}
}
And:
void CMeetingScheduleAssistantApp::TryToOpenFileInOtherInstance(HWND hOtherInstance)
{
CString strFile = GetFileToOpenFromFileExplorerPath();
S_COPY_PACKET sCopyDataPacket{};
_tcscpy_s(sCopyDataPacket.szFile, strFile);
sCopyDataPacket.guidSignature = CopyData_Signature;
COPYDATASTRUCT cds;
cds.dwData = COPYDATA_TYPE_MSA;
cds.cbData = sizeof(sCopyDataPacket);
cds.lpData = &sCopyDataPacket;
DWORD_PTR dwResult{};
if (SendMessageTimeout(hOtherInstance, WM_COPYDATA,
NULL, reinterpret_cast<LPARAM>(&cds), SMTO_BLOCK, 2000, &dwResult) != 0)
{
// The message was sent and processed
if (dwResult == FALSE)
{
// The other instance returned FALSE. This is probably because it
// has a pop-up window open so can't open the file
::OutputDebugString(_T("InitInstance::SendMessageTimeout [dwResult was FALSE].\n"));
}
}
else
{
const DWORD dwError = ::GetLastError();
if (dwError == ERROR_TIMEOUT)
{
// The message timed out for some reason
::OutputDebugString(_T("InitInstance::SendMessageTimeout [ERROR_TIMEOUT].\n"));
}
else
{
// Another unknown error
}
CString strError;
strError.Format(_T("InitInstance::SendMessageTimeout [%d: %s]\n"), dwError,
(LPCTSTR)GetLastErrorAsStringEx(dwError));
::OutputDebugString(strError);
}
}
And the seracher:
BOOL CALLBACK CMeetingScheduleAssistantApp::searcher(HWND hWnd, LPARAM lParam) noexcept
{
DWORD_PTR result{};
const LRESULT ok = ::SendMessageTimeout(hWnd,
theApp.UWM_ARE_YOU_ME_MSG,
0, 0,
SMTO_BLOCK |
SMTO_ABORTIFHUNG,
200,
&result);
if (ok == 0)
return TRUE; // ignore this and continue
if (result == theApp.UWM_ARE_YOU_ME_MSG)
{
// found it
HWND *target = reinterpret_cast<HWND *>(lParam);
*target = hWnd;
return FALSE; // stop search
}
return TRUE; // continue search
}
Under normal circumstances this is fully functional. But I have a specific scenario where my mutex is not honored. I think this started with Visual Studio 2022 but I no longer have 2019 edition to confirm.
The scenario
My PC has an instance of the software I am developing "installed" and it has a shortcut on the taskbar. This links to the executable in the installed folder. If I simply use this shortcut then no issues, no multiple instances.
But, if I start my application from inside VS2022 instead, and then accidently click my other shortcut on the taskbar, I end up with two instances running. Why does this happen? I appreciate the otherinstance is running inside VS2022 but it is still the same software.
Is this by design or a coding oversight?
Update
If I manually double-click the release build EXE in file explorer, and then try to invoke the application in my VS2022 environment, it will jump to the existing instance. But ...
If I invoke the application in my VS2022 environment first, and then double-click the same release build EXE in file explorer, I end up with a multiple instance.

Problem using TVN_SELCHANGED seems to go in a continuous cycle

I have this event handler in a modelless popup dialog tree control:
void CAssignHistoryDlg::OnTvnSelchangedTreeHistory(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
if (!m_bBuildTreeMode)
{
if ((pNMTreeView->itemOld.hItem == nullptr && !m_bFirstSelChangeEvent) ||
pNMTreeView->itemOld.hItem != nullptr)
{
m_bFirstSelChangeEvent = true;
if (m_treeHistory.GetParentItem(pNMTreeView->itemNew.hItem) == nullptr)
{
// We must update the correct combo
// and associated string (in the SERVMEET_S structure)
if (m_pCombo != nullptr && m_pStrText != nullptr)
{
CString strExtractedName = ExtractName(pNMTreeView->itemNew.hItem);
m_pCombo->SetWindowText(strExtractedName);
*m_pStrText = strExtractedName;
}
GetParent()->PostMessage(UM_SM_EDITOR_SET_MODIFIED, (WPARAM)TRUE);
}
}
}
*pResult = 0;
}
What I don't understand is why once this event is triggered is that it goes in a continuous cycle.
Does anything jump out at you as wrong?
I don't know why the message seemed to be going in a continuous cycle. Maybe it was because I was inserting breakpoints or adding temporary popup message boxes to debug. Either way, I worked out the minor adjustment I needed:
void CAssignHistoryDlg::OnTvnSelchangedTreeHistory(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
if (!m_bBuildTreeMode)
{
if ((pNMTreeView->itemOld.hItem == nullptr && !m_bFirstSelChangeEvent) ||
pNMTreeView->itemOld.hItem != nullptr)
{
m_bFirstSelChangeEvent = true;
if (m_treeHistory.GetParentItem(pNMTreeView->itemNew.hItem) == nullptr)
{
// We must update the correct combo
// and associated string (in the SERVMEET_S structure)
if (m_pCombo != nullptr && m_pStrText != nullptr)
{
CString strExtractedName = ExtractName(pNMTreeView->itemNew.hItem);
m_pCombo->SetWindowText(strExtractedName);
// Bug fix - Only set as modified if the name is different
if(*m_pStrText != strExtractedName)
GetParent()->PostMessage(UM_SM_EDITOR_SET_MODIFIED, (WPARAM)TRUE);
*m_pStrText = strExtractedName;
}
}
}
}
*pResult = 0;
}
As you can see, I have changed how and where I post the UM_SM_EDITOR_SET_MODIFIED message. This causes my application to work correctly. Previously it was always setting it as modified (multiple times). So even if you had just saved the file, it then was marked as modified again. This problem no longer happens.

seriesmarks is not visible for specified valueindex in teechart2017

In VS2013,teechart2017.ocx,
I make a dialog based MFC project.
I add a teechart on the dialog, changed the property of mark to
display value,set drawevery to 1,visible,not autoposition.
I used getserismark event to display only specified marks.
I add 20000 point in series0,
if i used teechart8, it display correctly,but for teechart2017,the
marks disappeared for all.
void CMFCApplication2Dlg::OnGetSeriesMarkTchart1(long SeriesIndex, long ValueIndex, BSTR* MarkText)
{
// TODO:
if (B_Filter)
{
if ((ValueIndex == 1250) || (ValueIndex == 137)|| (ValueIndex == 10000))
{
}
else
{
m_Chart1.Series(SeriesIndex).GetMarks().GetItem(ValueIndex).SetVisible(false);
}
}
I've reproduced the problem (#1986) and I've added the CalcVisiblePoints property for the next maintenance release.
There was an optimization introduced in v2016.0.0.1 that is causing this issue. You have to set TChart1.Series(0).CalcVisiblePoints = False to skip that optimization and make it work as in v8.
With the new v2018.0.2.9 you can do this:
#include "CAspect.h"
#include "CLegend.h"
#include "CSeries.h"
#include "TeeChartDefines.h"
#include "CMarks.h"
#include "CMarksItem.h"
//...
CAspect a = mChart1.get_Aspect();
a.put_View3D(false);
CLegend l = mChart1.get_Legend();
l.put_Visible(false);
mChart1.AddSeries(scFastLine);
CSeries s = mChart1.Series(0);
s.FillSampleValues(20000);
CMarks sm = s.get_Marks();
sm.put_Visible(true);
for (int i = 0; i < s.get_Count(); i++) {
CMarksItem smi = sm.get_Item(i);
smi.put_Visible((i == 1250) || (i == 137) || (i == 10000));
}
s.put_CalcVisiblePoints(false);

Debug assertion error on printing

I have a simple text editor that I created in Visual Studio 2010 Professional Edition. Basically I modified the MFC MDI program automatically generated by the VS2010 wizard. The problem is that when i print, it gives me a debug assertion error in viewrich.cpp line 294. I have not modified anything in the code to do with printing, though it could be something wrong with how i used Rich Edit. This is all the information I have. Thanks in advance.
Viewrich.cpp
BOOL CRichEditView::PaginateTo(CDC* pDC, CPrintInfo* pInfo)
// attempts pagination to pInfo->m_nCurPage, TRUE == success
{
ASSERT_VALID(this);
ASSERT_VALID(pDC);
CRect rectSave = pInfo->m_rectDraw;
UINT nPageSave = pInfo->m_nCurPage;
ASSERT(nPageSave > 1); // LINE 294
ASSERT(nPageSave >= (UINT)m_aPageStart.GetSize());
VERIFY(pDC->SaveDC() != 0);
pDC->IntersectClipRect(0, 0, 0, 0);
pInfo->m_nCurPage = (int)m_aPageStart.GetSize();
while (pInfo->m_nCurPage < nPageSave)
{
ASSERT(pInfo->m_nCurPage == (UINT)m_aPageStart.GetSize());
OnPrepareDC(pDC, pInfo);
ASSERT(pInfo->m_bContinuePrinting);
pInfo->m_rectDraw.SetRect(0, 0,
pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
pDC->DPtoLP(&pInfo->m_rectDraw);
OnPrint(pDC, pInfo);
if (pInfo->m_nCurPage == (UINT)m_aPageStart.GetSize())
break;
++pInfo->m_nCurPage;
}
BOOL bResult = pInfo->m_nCurPage == nPageSave;
pDC->RestoreDC(-1);
pInfo->m_nCurPage = nPageSave;
pInfo->m_rectDraw = rectSave;
ASSERT_VALID(this);
return bResult;
}
EmergenceView.cpp
IMPLEMENT_DYNCREATE(CEmergenceView, CRichEditView)
BEGIN_MESSAGE_MAP(CEmergenceView, CRichEditView)
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, &CRichEditView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, &CRichEditView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CEmergenceView::OnFilePrintPreview)
ON_WM_CONTEXTMENU()
ON_WM_RBUTTONUP()
ON_COMMAND(ID_MUTATE_GROUP, &CEmergenceView::OnMutateGroup)
ON_UPDATE_COMMAND_UI(ID_MUTATE_GROUP, &CEmergenceView::OnUpdateMutateGroup)
ON_COMMAND(ID_MUTATE_RANDOMISE, &CEmergenceView::OnMutateRandomise)
ON_UPDATE_COMMAND_UI(ID_MUTATE_RANDOMISE, &CEmergenceView::OnUpdateMutateRandomise)
ON_COMMAND(ID_HELP_STATISTICS, &CEmergenceView::OnHelpStatistics)
ON_UPDATE_COMMAND_UI(ID_HELP_STATISTICS, &CEmergenceView::OnUpdateHelpStatistics)
ON_COMMAND(ID_MUTATE_POETRIZE, &CEmergenceView::OnMutatePoetrize)
ON_COMMAND(ID_EDIT_SELECTALL, &CEmergenceView::OnEditSelectall)
END_MESSAGE_MAP()
// CEmergenceView construction/destruction
CEmergenceView::CEmergenceView()
{
// TODO: add construction code here
}
CEmergenceView::~CEmergenceView()
{
}
BOOL CEmergenceView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CRichEditView::PreCreateWindow(cs);
}
// CEmergenceView drawing
void CEmergenceView::OnDraw(CDC* /*pDC*/)
{
CEmergenceDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: add draw code for native data here
}
// CEmergenceView printing
void CEmergenceView::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
AFXPrintPreview(this);
#endif
}
BOOL CEmergenceView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CEmergenceView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CEmergenceView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
The ASSERT says it all:
UINT nPageSave = pInfo->m_nCurPage;
ASSERT(nPageSave > 1);
This is a value for the current page to print/paginate. It is set to 1 in CPrintInfo's constructor. But something changed it and made it 0 or negative. Usually this value is completely controlled by the RTF printout. So you must done something that manipulates it.
You have to set the Minimum page and the Maximum page value (SetMinPage and SetMaxPage) in CPrintInfo.

wxDirDialog Returns the Wrong Directory on Vista

I recently ported the following code to wx3.0 under visual studio 2013:
void PanelFileControl::on_retrieve_clicked(wxCommandEvent &event)
{
if(!chosen_files.empty())
{
Csi::ModalCounter counter;
wxDirDialog query(
this,
make_wxString(my_strings[strid_choose_retrieve_dir]),
make_wxString(wxGetApp().get_config()->get_last_prog_dir()));
int rcd;
query.CentreOnParent();
rcd = query.ShowModal();
if(rcd == wxID_OK)
{
// we need to generate an operation for every selected file.
StrAsc path(make_StrAsc(query.GetPath()));
DlgFileControl::operations_type operations;
if(path.last() != Csi::FileSystemObject::dir_separator())
path.append(Csi::FileSystemObject::dir_separator());
for(files_type::iterator fi = chosen_files.begin(); fi != chosen_files.end(); ++fi)
{
file_type const &file(*fi);
StrAsc file_path(path + file.get_file_name());
bool use_file(true);
if(Csi::file_exists(file_path.c_str()))
{
OwxStringStream message;
message << boost::format(my_strings[strid_overwrite_file_confirm].c_str()) %
file_path;
wxMessageDialog overwrite_query(
this,
message.str(),
wxT(""),
wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
int rcd;
overwrite_query.CentreOnParent();
rcd = overwrite_query.ShowModal();
if(rcd != wxID_YES)
use_file = false;
}
if(use_file)
operations.push_back(new ReceiveFileOperation(file, file_path));
}
// we can now display the operation dialogue
if(!operations.empty())
{
DlgFileControl dialogue(this, device_name, operations);
dialogue.show_modal();
}
}
}
} // on_retrieve_clicked
Following this change (which didn't require any changes to the code above), I have received complaints that, if the user selects the desktop and then double clicks on a directory on the desktop, that the file save operation fails. This appears to be a result of the path produced by the wxDirDialog::GetPath() and has only been seen under windows vista. I have followed up some testing and I find that, under Vista, the last path component is mentioned twice in the string returned by GetPath().
Has anyone seen this issue? Are there any work arounds?
I found that I can address the issue by preventing the wxDirDialog from using the IFILEDIALOG interface from being used. My ShowModal() method now looks like this:
int wxDirDialog::ShowModal()
{
WX_HOOK_MODAL_DIALOG();
wxWindow* const parent = GetParent();
WXHWND hWndParent = parent ? GetHwndOf(parent) : NULL;
// Use IFileDialog under new enough Windows, it's more user-friendly.
int rc;
#if wxUSE_IFILEDIALOG
if ( wxGetWinVersion() > wxWinVersion_Vista )
{
rc = ShowIFileDialog(hWndParent);
}
else
{
rc = wxID_NONE;
}
if ( rc == wxID_NONE )
#endif // wxUSE_IFILEDIALOG
{
rc = ShowSHBrowseForFolder(hWndParent);
}
// change current working directory if asked so
if ( rc == wxID_OK && HasFlag(wxDD_CHANGE_DIR) )
wxSetWorkingDirectory(m_path);
return rc;
}

Resources