IFileOpenDialog pointer is null when it calls from CFileDialog - c++

I was trying to wrap CFileDialog and IFileOpenDialog in a class, here is the code:
class ITest
{
public:
virtual ~ITest(){};
virtual INT_PTR DoModal() = 0;
virtual IFileOpenDialog* GetDlg() = 0;
};
class test : public ITest
{
public:
test(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL,
DWORD dwSize = 0,
BOOL bVistaStyle = FALSE)
{
dlg = new CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd, dwSize, bVistaStyle);
};
~test(){};
INT_PTR DoModal(){ return S_OK; };
IFileOpenDialog* GetDlg(){ return dlg->GetIFileOpenDialog(); };
private:
CFileDialog* dlg;
};
Then when I call it like:
ITest* a = new test(TRUE, NULL, 0, OFN_ALLOWMULTISELECT | OFN_NOVALIDATE, LoadResourceString(IDS_MYSTRING), this);
fdlg = a->GetDlg();
fdlg->Show(NULL);//it crashes here since fdlg is NULL
Then I tried to call CFileDialog and IFileOpenDialog directly:
IFileOpenDialog* fdlg = NULL;
CFileDialog* b = new CFileDialog(TRUE, NULL, 0, OFN_ALLOWMULTISELECT | OFN_NOVALIDATE, LoadResourceString(IDS_MYSTRING), this);
fdlg = b->GetIFileOpenDialog();
fdlg->Show(NULL);
This part of code works perfectly.
Anyone knows why the crash happens ?
It confuses me so much since I feel they are so similar.
class test : public ITest
{
public:
test(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL,
DWORD dwSize = 0,
BOOL bVistaStyle = FALSE)
{
dlg = new CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd, dwSize, bVistaStyle);
};
~test(){};
INT_PTR DoModal(){ return S_OK; };
IFileOpenDialog* GetDlg();
private:
CFileDialog* dlg;
};
IFileOpenDialog* test::GetDlg()
{
return dlg->GetIFileOpenDialog();
};
The above code also doesn't work( it defines IFileOpenDialog* GetDlg(); outside of the class declartion)

From the help:
Use this function only under Windows Vista with an object that has
bVistaStyle set to true. This function returns NULL if the CFileDialog
is not an Open dialog box or if bVistaStyle is set to false.
When you construct your test object:
ITest* a = new test(TRUE, NULL, 0, OFN_ALLOWMULTISELECT | OFN_NOVALIDATE, LoadResourceString(IDS_MYSTRING), this);
you are leaving our the last parameter of your constructor, bVistaStyle, which defaults to FALSE. So just add it:
ITest* a = new test(TRUE, NULL, 0, OFN_ALLOWMULTISELECT | OFN_NOVALIDATE, LoadResourceString(IDS_MYSTRING), this, 0,
TRUE); // bVistaStyle

Related

CFileDialog: dynamic modification of m_ofn?

C++/MFC, Windows 11. Visual Studio 2022 17.4.3.
I'm using CFileDialog to allow user to chose a file. By creating a new class derived from CFileDialog, I am being notified whenever the user changes directories (folders).
I implemented this so I could control the filter applied to the list of files in the directory. However, I have been unsuccessful in this. Even if I don't change m_ofn, I get an error.
Here is some sample code:
// Caller
#include "Browsing_test.h"
P brTest(true, NULL, NULL, 0, fileTypes);
brTest.BrowseTest();
// Browsing_test.h
class P : CFileDialog
{
public:
P(BOOL bOpenFileDialog,
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd *pParentWnd = NULL,
DWORD dwSize = 0,
BOOL bVistaStyle = TRUE) : CFileDialog(bOpenFileDialog,
lpszDefExt,
lpszFileName,
dwFlags,
lpszFilter,
pParentWnd,
dwSize,
bVistaStyle) {};
int BrowseTest(void);
#include "stdafx.h"
#include "Browsing_test.h"
int P::BrowseTest(void)
{
int resultDebug = (int)DoModal();
return resultDebug;
}
void P::OnFolderChange()
{
auto s = GetOFN(); // for modifying m_ofn member of the base class,
// but not used in this sample code
// Add modificatons to m_ofn here
ApplyOFNToShellDialog(); // Gets assert on updating flags
}
Running this code gives an error in dlgfile.cpp (Microsoft code) at line:
hr = (static_cast<IFileDialog*>(m_pIFileDialog))->SetOptions(dwFlags);
which returns hr = E_UNEXPECTED Catastrophic failure. The value of dwFlags was hex 40.

AcquireCredentialsHandleA() returns 0x8009030e (No credentials are available in the security package) for PFX file

I'm trying to setup server-side encryption using SSPI. I'm successfully (as far as I can tell) loading a certificate stored as a PFX file, but the call to m_pSSPI->AcquireCredentialsHandleA() returns 0x8009030e.
This method seems to successfully load the file and return a CERT_CONTEXT object.
HRESULT CTLSPackage::LoadCertContextFromFilePFX (PCWSTR pcwzFile, PCWSTR pcwzPassword, __deref_out PCCERT_CONTEXT* ppctxCert)
{
HRESULT hr;
HANDLE hFile, hSection = NULL;
BOOL (WINAPI* pfnPFXIsPFXBlob)(CRYPT_DATA_BLOB*);
HCERTSTORE (WINAPI* pfnPFXImportCertStore)(CRYPT_DATA_BLOB*, LPCWSTR, DWORD);
PCCERT_CONTEXT (WINAPI* pfnCertEnumCertificatesInStore)(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrevCertContext);
CRYPT_DATA_BLOB blob; blob.pbData = NULL;
HCERTSTORE pfxStore = NULL;
hFile = CreateFile(pcwzFile, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
CheckIfGetLastError(INVALID_HANDLE_VALUE == hFile);
blob.cbData = GetFileSize(hFile, NULL);
hSection = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0);
CheckIfGetLastError(NULL == hSection);
blob.pbData = reinterpret_cast<PBYTE>(MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0));
CheckIfGetLastError(NULL == blob.pbData);
Check(TGetFunction(m_hCrypt32, "PFXIsPFXBlob", &pfnPFXIsPFXBlob));
Check(TGetFunction(m_hCrypt32, "PFXImportCertStore", &pfnPFXImportCertStore));
Check(TGetFunction(m_hCrypt32, "CertEnumCertificatesInStore", &pfnCertEnumCertificatesInStore));
CheckIf(!pfnPFXIsPFXBlob(&blob), E_FAIL);
pfxStore = pfnPFXImportCertStore(&blob, pcwzPassword, CRYPT_MACHINE_KEYSET | CRYPT_EXPORTABLE);
CheckIf(NULL == pfxStore, SEC_E_NO_CREDENTIALS);
*ppctxCert = pfnCertEnumCertificatesInStore(pfxStore, NULL);
CheckIf(NULL == *ppctxCert, SEC_E_NO_CREDENTIALS);
Cleanup:
if(pfxStore)
{
BOOL (WINAPI* pfnCertCloseStore)(HCERTSTORE, DWORD);
if(SUCCEEDED(TGetFunction(m_hCrypt32, "CertCloseStore", &pfnCertCloseStore)))
pfnCertCloseStore(pfxStore, 0);
}
if(blob.pbData)
UnmapViewOfFile(blob.pbData);
SafeCloseHandle(hSection);
SafeCloseFileHandle(hFile);
return hr;
}
The result is immediately passed to another class method, which makes the failing AcquireCredentialsHandleA() call.
HRESULT CTLSPackage::AcquireCredentials (__in_opt PCCERT_CONTEXT pCertContext, PCredHandle phCreds)
{
SCHANNEL_CRED SchannelCred;
TimeStamp tsExpiry;
ZeroMemory(&SchannelCred, sizeof(SchannelCred));
SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
if(pCertContext)
{
SchannelCred.cCreds = 1;
SchannelCred.paCred = &pCertContext;
}
SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1 | SP_PROT_TLS1_1 | SP_PROT_TLS1_2;
if(!m_fServer)
SchannelCred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS | SCH_USE_STRONG_CRYPTO;
//
// Create an SSPI credential.
//
return m_pSSPI->AcquireCredentialsHandleA(
NULL, // Name of principal
m_fServer ? NEGOSSP_NAME_A : UNISP_NAME_A, // Name of package
m_fServer ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND,
NULL, // Pointer to logon ID
&SchannelCred, // Package specific data
NULL, // Pointer to GetKey() func
NULL, // Value to pass to GetKey()
phCreds, // (out) Cred Handle
&tsExpiry); // (out) Lifetime (optional)
}
My CTLSPackage::AcquireCredentials() code path is also used for setting up client-side encryption, and that works. For the server-side path, m_fServer is TRUE. The m_hCrypt32 member was loaded from Crypt32.dll.
I've cobbled together this code from samples, but I must be missing something for the server case. I only need to setup SSL/TLS-style encryption, so the "No credentials are available in the security package" error is weird because I have no need for credential authentication.
Does anyone know what might be missing? Thanks!
With a hint from RbMm, I then found this article:
https://www.codeproject.com/articles/125124/how-to-use-certificate-from-disk-with-microsoft-cr
The short answer is that CryptAcquireCertificatePrivateKey() needed to be used when loading a PFX from a file, and UNISP_NAME_A needed to be passed to AcquireCredentialsHandleA().
For reference, here is the revised code:
HRESULT CTLSPackage::LoadCertContextFromFilePFX (PCWSTR pcwzFile, PCWSTR pcwzPassword, __deref_out PCCERT_CONTEXT* ppctxCert)
{
HRESULT hr;
HANDLE hFile, hSection = NULL;
BOOL (WINAPI* pfnPFXIsPFXBlob)(CRYPT_DATA_BLOB*);
HCERTSTORE (WINAPI* pfnPFXImportCertStore)(CRYPT_DATA_BLOB*, LPCWSTR, DWORD);
PCCERT_CONTEXT (WINAPI* pfnCertFindCertificateInStore)(HCERTSTORE hCertStore, DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, const void* pvFindPara, PCCERT_CONTEXT pPrevCertContext);
BOOL (WINAPI* pfnCryptAcquireCertificatePrivateKey)(PCCERT_CONTEXT pCert, DWORD dwFlags, void* pvReserved, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *phCryptProvOrNCryptKey, DWORD* pdwKeySpec, BOOL* pfCallerFreeProvOrNCryptKey);
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hProv;
DWORD dwKeySpec;
BOOL fFreeProv = FALSE;
CRYPT_DATA_BLOB blob; blob.pbData = NULL;
HCERTSTORE hpfxStore = NULL;
hFile = CreateFile(pcwzFile, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
CheckIfGetLastError(INVALID_HANDLE_VALUE == hFile);
blob.cbData = GetFileSize(hFile, NULL);
hSection = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0);
CheckIfGetLastError(NULL == hSection);
blob.pbData = reinterpret_cast<PBYTE>(MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0));
CheckIfGetLastError(NULL == blob.pbData);
Check(TGetFunction(m_hCrypt32, "PFXIsPFXBlob", &pfnPFXIsPFXBlob));
Check(TGetFunction(m_hCrypt32, "PFXImportCertStore", &pfnPFXImportCertStore));
Check(TGetFunction(m_hCrypt32, "CertFindCertificateInStore", &pfnCertFindCertificateInStore));
Check(TGetFunction(m_hCrypt32, "CryptAcquireCertificatePrivateKey", &pfnCryptAcquireCertificatePrivateKey));
CheckIf(!pfnPFXIsPFXBlob(&blob), HRESULT_FROM_WIN32(ERROR_BAD_FORMAT));
hpfxStore = pfnPFXImportCertStore(&blob, pcwzPassword, 0);
if(NULL == hpfxStore && pcwzPassword && L'\0' == *pcwzPassword)
{
hpfxStore = pfnPFXImportCertStore(&blob, NULL, 0);
CheckIf(NULL == hpfxStore, SEC_E_NO_CREDENTIALS);
}
*ppctxCert = pfnCertFindCertificateInStore(hpfxStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL);
CheckIfGetLastError(NULL == *ppctxCert);
// Acquire the private key and make it available for the later AcquireCredentalsHandle() call.
if(!pfnCryptAcquireCertificatePrivateKey(*ppctxCert, 0, NULL, &hProv, &dwKeySpec, &fFreeProv))
{
DWORD dwError = GetLastError();
FreeCertificateContext(*ppctxCert);
*ppctxCert = NULL;
CheckWin32Error(dwError);
}
Cleanup:
if(fFreeProv)
FreeProvOrNCryptKey(hProv, dwKeySpec);
if(hpfxStore)
{
BOOL (WINAPI* pfnCertCloseStore)(HCERTSTORE, DWORD);
if(SUCCEEDED(TGetFunction(m_hCrypt32, "CertCloseStore", &pfnCertCloseStore)))
pfnCertCloseStore(hpfxStore, 0);
}
if(blob.pbData)
UnmapViewOfFile(blob.pbData);
SafeCloseHandle(hSection);
SafeCloseFileHandle(hFile);
return hr;
}
HRESULT CTLSPackage::AcquireCredentials (__in_opt PCCERT_CONTEXT pCertContext, PCredHandle phCreds)
{
SCHANNEL_CRED SchannelCred;
TimeStamp tsExpiry;
ZeroMemory(&SchannelCred, sizeof(SchannelCred));
SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
if(pCertContext)
{
SchannelCred.cCreds = 1;
SchannelCred.paCred = &pCertContext;
}
SchannelCred.grbitEnabledProtocols = SP_PROT_SSL3 | SP_PROT_TLS1 | SP_PROT_TLS1_1 | SP_PROT_TLS1_2;
SchannelCred.dwFlags = SCH_USE_STRONG_CRYPTO;
if(!m_fServer)
SchannelCred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;
//
// Create an SSPI credential.
//
return m_pSSPI->AcquireCredentialsHandleA(
NULL, // Name of principal
UNISP_NAME_A, // Name of package
m_fServer ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND,
NULL, // Pointer to logon ID
&SchannelCred, // Package specific data
NULL, // Pointer to GetKey() func
NULL, // Value to pass to GetKey()
phCreds, // (out) Cred Handle
&tsExpiry); // (out) Lifetime (optional)
}

virtual folder is invisible in the CFileDialog in windows 7

-------------------------update 5th-------------------------------
if (fIsFolder)
{
dwAttribs |= SFGAO_FOLDER;
}
else
{
dwAttribs |= SFGAO_SYSTEM;
dwAttribs |= SFGAO_FILESYSTEM;
}
if (nLevel < g_nMaxLevel)
{
dwAttribs |= SFGAO_HASSUBFOLDER;
dwAttribs |= SFGAO_FILESYSANCESTOR;
}
Now this one works normally in application A, stackoverflow image upload file dialog and in regular folder explorer.
-----------------------------------------------------update 4th-----------------------------------------------------------
After add dwAttribs |= SFGAO_SYSTEM; , now at least for application A, it works as expected in the file dialog. But the folder is still not clickable in the regular folder dialog or for CWFileDialog.
if (fIsFolder)
{
dwAttribs |= SFGAO_FOLDER;
dwAttribs |= SFGAO_FILESYSTEM;
dwAttribs |= SFGAO_FILESYSANCESTOR;
}
else
{
dwAttribs |= SFGAO_SYSTEM;// this line of code works better
dwAttribs |= SFGAO_FILESYSTEM;
}
-----------------------------------update third-----------------------------------------
This is the code in the virtual folder's ISHellFolder:
After I edit the following code to add dwAttribs |= SFGAO_FILESYSTEM;, the folder cannot be browsed when I double click it in the folder view. But it can be opened by left clicking it in the tree view.
HRESULT CFolderViewImplFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, ULONG *rgfInOut)
{
// If SFGAO_FILESYSTEM is returned, GetDisplayNameOf(SHGDN_FORPARSING) on that item MUST
// return a filesystem path.
HRESULT hr = E_INVALIDARG;
DWORD dwAttribs = 0;
dwAttribs |= SFGAO_FILESYSTEM;
if (1 == cidl)
{
int nLevel = 0;
hr = _GetLevel(apidl[0], &nLevel);
if (SUCCEEDED(hr))
{
BOOL fIsFolder = FALSE;
hr = _GetFolderness(apidl[0], &fIsFolder);
if (SUCCEEDED(hr))
{
if (fIsFolder)
{
dwAttribs |= SFGAO_FOLDER;
}
if (nLevel < g_nMaxLevel)
{
dwAttribs |= SFGAO_HASSUBFOLDER;
}
}
}
}
*rgfInOut &= dwAttribs;
return hr;
}`
Or
DWORD dwAttribs = 0;
if (1 == cidl)
{
int nLevel = 0;
hr = _GetLevel(apidl[0], &nLevel);
if (SUCCEEDED(hr))
{
BOOL fIsFolder = FALSE;
hr = _GetFolderness(apidl[0], &fIsFolder);
if (SUCCEEDED(hr))
{
if (fIsFolder)
{
dwAttribs |= SFGAO_FOLDER;
dwAttribs |= SFGAO_FILESYSTEM;
dwAttribs |= SFGAO_FILESYSANCESTOR;
}
else
{
dwAttribs |= SFGAO_SYSTEM;
}
if (nLevel < g_nMaxLevel)
{
dwAttribs |= SFGAO_HASSUBFOLDER;
}
}
}
}
*rgfInOut &= dwAttribs;
Other code are the same as in update 2nd.
The weird stuff is, after I edit these code, application A which uses CFileDialog normally( not wrapping it, not set m_bPickNonFileSysFoldersMode to true) can display all virtual folder normally as I expected.
But in all other applications( including the one uses CWFileDilao which set m_bPickNonFileSysFoldersMode to true is still cannot view the virtual folder.
---------------------------------------update 2nd-------------------------
I code a simple class which derives from CFileDialog:
class CWFileDlg : public CFileDialog
{
public:
CWFileDlg(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL,
DWORD dwSize = 0,
BOOL bVistaStyle = TRUE);
~CWFileDlg();
};
CWFileDlg::CWFileDlg(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
LPCTSTR lpszDefExt,
LPCTSTR lpszFileName,
DWORD dwFlags,
LPCTSTR lpszFilter,
CWnd* pParentWnd,
DWORD dwSize,
BOOL bVistaStyle) : CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd, dwSize, bVistaStyle)
{
m_bPickNonFileSysFoldersMode = TRUE;
}
CWFileDlg::~CWFileDlg()
{
}
Then I call it like:
CWFileDlg dlg(TRUE, NULL, 0, OFN_SHAREAWARE | OFN_ENABLESIZING | OFN_ALLOWMULTISELECT, L"all(*.*)|*.*||", this);
BOOL IsPickNonFileSysFoldersMode = dlg.IsPickNonFileSysFoldersMode();
//the value it gets is 1, which is TRUE
INT_PTR result = dlg.DoModal();
But in the pop up dialog, virtual folder is stil invisible. Tree view for it is also invisible.
------------------------------------------updates----------------------------
protected:
BOOL m_bVistaStyle;
BOOL m_bPickFoldersMode;
BOOL m_bPickNonFileSysFoldersMode;
DWORD m_dwCookie;
void* m_pIFileDialog;
void* m_pIFileDialogCustomize;
The m_bPickNonFileSysFoldersMode is not a public type. How could I set it to TRUE ?
Error 1 error C2248: 'CFileDialog::m_bPickNonFileSysFoldersMode' : cannot access protected member declared in class 'CFileDialog' c:\users\liyuan.liu\documents\dp-dll\testvirtualfolder\browser2\browser2\browser2dlg.cpp 166 1 browser2
By using Microsoft windows sample code, I installed a virtual folder on windows 7 by using shell namespace extension.
The following screenshot is using regular folder browser to open it:
Then I wrote a project which can create a file dialog:
CFileDialog dlg(TRUE, NULL, 0, OFN_SHAREAWARE | OFN_ENABLESIZING | OFN_ALLOWMULTISELECT, L"all(*.*)|*.*||", this);
INT_PTR result = dlg.DoModal();
However, in the file browser, the virtual folder is invisible:
But! When I was trying to upload the screenshot to StackOverflow ( the web browser I am using is chrome), the file dialog which is used to select file can display the tree view ( only the tree view) of the virtual folder:
By googling, it seems that the CFileDialog cannot support to display the virtual folder since it doesn't actually exist in the system. Any solutions to solve that?
I also tried with
bi.pidlRoot = pidlVirtual;
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS | BIF_BROWSEINCLUDEFILES | BIF_BROWSEFILEJUNCTIONS;
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
Also doesn't work.
Unfortunately, what the file dialog shows is function of the app that opens it. Starting with Vista, it's the IFileDialog interface which is used, and it defines a set of options through the IFileDialog::SetOptions method.
The FOS_FORCEFILESYSTEM flag ensures that returned items are file system items (SFGAO_FILESYSTEM), and that depends on how you wrote your extension. SFGAO_FILESYSTEM should ring a bell, it's one of the flags the IShellFolder::GetAttributesOf method can return. If what you do is really virtual (ie: if you don't return this flag), they won't be shown when IFileDialog is configured like this.
If you test your extension with different apps (notepad, word, excel, browsers, etc.), you'll see that you see it sometimes, and sometimes you don't.
Spelunking into MFC's code (dlgfile.cpp), you will find this:
// We only expect and handle file system paths (for compatibility with GetOpenFileName functionality), so set the
// "force file system" flag which enables GetOpenFileName-like download behavior for non file system paths, unless
// the m_bPickNonFileSysFoldersMode is set to allow picking non-file system folders (like libraries in Windows 7).
dwFlags |= FOS_FORCEFILESYSTEM;
if (m_bPickNonFileSysFoldersMode)
{
dwFlags &= ~FOS_FORCEFILESYSTEM;
}
So, you need to set m_bPickNonFileSysFoldersMode to TRUE for CFileDialog to show your extension. in MFC you must derive from CFileDialog since this member is protected (BTW this is a stupid MFC design decision), for example::
class MyFileDialog : public CFileDialog
{
public:
MyFileDialog(LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL);
};
MyFileDialog::MyFileDialog(LPCTSTR lpszDefExt, LPCTSTR lpszFileName, DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) : CFileDialog(TRUE, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd)
{
m_bPickNonFileSysFoldersMode = TRUE;
}
Last thing to remember: make sure your virtual folder (namespace extension, etc.) is registered with the same bitness (x86 vs x64) as the app using the CFileDialog.
But it won't fix other apps you don't own that use this flag...

Error with Win32 Window Wrapper (Incorrect Parameter)

I am writing a window wrapper for win32 to make gui creation easier. I have an abstractdisplay class, a displayclass class, and a displayclass. In the end, the window does not show up. After some debugging, my windowclass is not being registered properly. After GetLastError, I got the error code of INVALID PARAMETER
displayclass.h:
#pragma once
#include <Windows.h>
#include "abstractdisplay.h"
class DisplayClass : protected WNDCLASSEX
{
public:
// Public variables
private:
// Private variables
protected:
// Protected variables
public:
// Public functions
DisplayClass(HINSTANCE hInst, const TCHAR* className);
DisplayClass();
~DisplayClass();
// Registers the class
// Get the class name
virtual const TCHAR* getClassName() const { return lpszClassName; }
virtual bool Register();
private:
// Private functions
protected:
// Protected functions
};
displayclass.cpp:
#include "displayclass.h"
#include "abstractdisplay.h"
#include <string>
#include <cstring>
DisplayClass::DisplayClass(HINSTANCE hInst, const TCHAR* className)
{
hInstance = hInst;
// All messages for windows that belong to this Window Class will be sent to Message Router
lpfnWndProc = AbstractDisplay::MessageRouter;
lpszClassName = className;
// Set values for the rest of the WNDCLASSEX structure
ZeroMemory(this, sizeof(WNDCLASSEX));
lpszMenuName = 0;
cbSize = sizeof(WNDCLASSEX);
cbClsExtra = 0;
cbWndExtra = 0;
hIcon = ::LoadIcon(NULL, IDI_APPLICATION);
hIconSm = ::LoadIcon(NULL, IDI_APPLICATION);
hCursor = ::LoadCursor(NULL, IDC_ARROW);
style = CS_HREDRAW | CS_VREDRAW;
hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
}
DisplayClass::DisplayClass()
{
}
DisplayClass::~DisplayClass()
{
}
// Returns the last Win32 error, in string format. Returns an empty string if there is no error.
std::string GetLastErrorAsString()
{
// Get the error message, if any.
DWORD errorMessageID = ::GetLastError();
if (errorMessageID == 0)
return std::string(); // No error message has been recorded
LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
std::string message(messageBuffer, size);
// Free the buffer.
LocalFree(messageBuffer);
return message;
}
bool DisplayClass::Register()
{
if (::RegisterClassEx(this) != 0)
{
return true;
}
else
{
OutputDebugString("ERROR CODE BE LIKE:");
OutputDebugString(GetLastErrorAsString().c_str());
OutputDebugString("\n");
return false;
}
}
Debug:
ERROR CODE BE LIKE:The parameter is incorrect.
(Somewhat following this source: http://www.infernodevelopment.com/c-win32-api-simple-gui-wrapper)
You're calling ZeroMemory after assigning some of the struct members (i.e. hInstance, lpfnWndProc and lpszClassName will all be null).

Access violation occurs in GetHttpConnection () method

You are creating a program to download files from the specified URL in VC ++ 2012.
Part to be downloaded as a DLL, we're calling from the main program.
In this case, when you run the GetHttpConnection () method, an access violation occurs.
We examined various, but did not know.
Please lend your wisdom.
main.exe
:
:
:
hModule = LoadLibraryW(currentDirectory);
DLL_GetHttp = (FUNC_DLL_GetHttp)GetProcAddress(hModule, "GetHttp");
:
:
:
CHttpConnection* pConnection = NULL;
CInternetSession session;
CHttpFile* pFile = NULL;
BYTE* pRecvBuf;
ULONG pnRecvSize;
ULONG lRet;
lRet = DLL_GetHttp(&pConnection, &session, &pFile, downloadFile, NULL, 0, &pRecvBuf, &pnRecvSize);
:
:
http.dll
ULONG GetHttp(CHttpConnection** pConnection, CInternetSession* session, CHttpFile** pFile, LPCTSTR url, BYTE* pSendBuf, ULONG nSendSize, BYTE** pRecvBuf, ULONG* pnRecvSize)
{
*pRecvBuf = NULL;
*pnRecvSize = 0;
LONG nRet = 0;
DWORD dwServiceType;
CString strServer;
CString strObject;
INTERNET_PORT nPort;
CString strConnectUrl;
strConnectUrl = url;
AFX_MANAGE_STATE( AfxGetStaticModuleState() );
if (!AfxParseURL(url, dwServiceType, strServer, strObject, nPort))
{
// ASSERT(0);
return ERROR_PARAMETOR;
}
try
{
(*pConnection) = (*session).GetHttpConnection( // access error!!!!
strServer,
INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE ,
nPort,
NULL,
NULL
);
DWORD dwFlags = INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE;
BOOL bSecure = strConnectUrl.MakeLower().Find(_T("https")) == 0;
if (bSecure)
{
dwFlags |= INTERNET_FLAG_SECURE;
}
*pFile = (*pConnection)->OpenRequest(
CHttpConnection::HTTP_VERB_POST,
strObject,
NULL,
1,
NULL,
_T("HTTP/1.1"),
dwFlags
);
:
:
: