Get the specific child of IShellItem assuming IShellItem is a directory? - c++

Using IKnownFolderManager and IKnownFolder I managed to get the path to C:\Program Files and its corresponding IShellItem. After that I managed to create a directory in that location using IFileOperation. Now, I want to create a file in the new directory. Since IFileOperation needs IShellItem, how do I get the corresponding IShellItem of the new directory?
PS: I'm new to COM and Win32 API.

When using IFileOperation::NewItem(), you can use an IFileOperationProgressSink object, its PostNewItem() event will give you the IShellItem of the new item you create. You can either pass the sink object to NewItem() directly, or pass it to IFileOperation::Advise() before calling IFileOperation::PerformOperations().
Alternatively, you can use SHCreateItemFromRelativeName() instead, after PerformOperations() is successful.

Related

C++ how to get folders and files names from virtual device?

How to get all folders and files names in virtual device plugged to pc?
In C++;
I have problem because the virtual device not have a letter like local disc;
Path started like this "Computer\SUPRA_M727G\Internal storage"
You have to use Shell interfaces, namely IShellFolder and IEnumIDList.
To get an IShellFolder for the "Internal storage" folder, you can either:
Use SHGetDesktopFolder() to get an IShellFolder for the root of the Shell namespace, then pass the "Computer\SUPRA_M727G\Internal storage" string to its IShellFolder::ParseDisplayName() method to get an absolute ITEMIDLIST that you can pass to its IShellFolder::BindToObject() method.
Use SHParseDisplayName() or ILCreateFromPath() to convert the "Computer\SUPRA_M727G\Internal storage" string into an absolute ITEMIDLIST that you can pass to SHBindToObject() with its psf parameter set to NULL.
Either way, once you have an IShellFolder for the storage folder, you can use its IShellFolder::EnumObjects() method to get an IEnumIDList for enumerating its files and subfolders. The enumeration will give you a relative ITEMIDLIST for each item. To retrieve each item's name as a string, pass each ITEMIDLIST to its IShellFolder::GetDisplayNameOf() method, and then pass the returned STRRET to one of the StrRetTo...() functions (StrRetToBSTR(), StrRetToBuf(), or StrRetToStr()).
Refer to MSDN for more details:
Introduction to the Shell Namespace
Navigating the Shell Namespace

WinRT Create File at Customized Path

I am writing some code to create a file from a Windows 8 app in an standard way, the code looks like below:
using namespace Windows::Storage;
StorageFolder^ folder = KnownFolders::DocumentsLibrary;
String ^filename = ref new String(L"file.txt");
auto createFile = folder->CreateFileAsync(filename, CreationCollisionOption::ReplaceExisting);
concurrency::create_task(createFile).wait;
Now instead of using DocumentsLibrary, I want to write thid file to an customized file path, like:
C:\Users\<username>\AppData\Local\ExampleApp\ExampleFolder
How should I change the code to be able to do this? Thanks!
WinRT can only access a few folders. You have a few standard libraries like Pictures, Music, etc (Documents requires elevated rights) and you have the application data folders that you can find under \AppData\Local\Packages\yourpackage.
Inside of this package folder you have two main folders to store data: LocalState and RoamingState. As the names convey: the former is to store data locally while the latter will synchronize its contents whenever possible (according to the rules you define).
You can access these folders using the C++ equivalent of Windows.Storage.ApplicationData.Current.LocalFolder and Windows.Storage.ApplicationData.Current.RoamingFolder.
What you can do though is request explicit access through a FilePicker but this will prompt the user a window where he should target the directory himself.

FindResource Api gives error 1813 for Text file in a DLL

I have develop a dynamic library, in dll I have added a resource text file and other codes for other purpose, then through a executable I am dynamically loading the dll, when the call goes to FindResource API it always returns NULL. while executable is in separate folder, dynamic library folder is separate one. I can't get why it's not working.
code:
>
HRSRC hRes = FindResource(0, MAKEINTRESOURCE(IDR_XYZ_ABC1), "XYZ_ABC");
<
The first parameter of FindResource is the handle to load from. So it could be your dynamic dll handle.
Error code 1813 translates to
The specified resource type cannot be found in the image file.
Passing a NULL as the first argument to FindResource is documented to mean:
If this parameter is NULL, the function searches the module used to create the current process.
If you want to load a resource from an image you load dynamically into a process you have to pass the module's handle to FindResource:
HMODULE hMod = LoadLibrary("MyResources.dll");
HRSRC hRes = FindResource(hMod, MAKEINTRESOURCE(IDR_XYZ_ABC1), "XYZ_ABC");
// ...
If your .dll contains resources only you may want to use LoadLibraryEx instead. It lets you specify additional load options, allowing you to load a library that consists of resources only, without an entry point.

How to Notify a folder using SHChangeNotify

My application will create some folders and it's icon needs to be changed depending on certain activities.
I tried to use the function below and it seems it's not refreshing the folder
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNE_ALLEVENTS | SHCNE_UPDATEIMAGE | SHCNE_UPDATEDIR |SHCNF_PATH | SHCNF_FLUSHNOWAIT, L"C:\\Music\\Test", 0);
If I use
SHChangeNotify(SHCNE_ASSOCCHANGED, 0x1000, 0,0);,
the entire desktop is getting refreshed.
Please let me know the best way to refresh folders.
You're probably using the wrong function. In particular, the documentation for SHCNE_ASSOCCHANGED states that "SHCNF_IDLIST must be specified in the uFlags parameter. dwItem1 and dwItem2 are not used and must be NULL.". You do not pass SHCNF_IDLIST and dwItem1 is a path string, not NULL. Also, the second parameter should be just a combination of SHCNF_* flags; you're adding invalid SHCNE_* flags.
If you're writing files to L"C:\\Music\\Test", and want Explorer to notice that, use SHCNE_CREATE; if you add a folder use SHCNE_MKDIR. In both cases, dwItem1 must be the path to the item created, not the parent folder where it's created in.
Try this
SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH | SHCNF_FLUSHNOWAIT, "Path", NULL);
where "Path" is the folder you want to update.

Save file settings in ini instead of registry

I'm new to MFC, once I create my first app, in myApp::InitInstance() . I have
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
Can I delete this and save settings to my own ini construct ?
Edit: After further testing, the solution below does not work if your app class is derived from CWinAppEx ! It does work if your app is directly derived from CWinApp.
To store values in an .ini file instead of the registry:
Omit the call to SetRegistryKey.
In your app class, set m_pszProfileName to the full path of your .ini file. The filename string must be allocated using malloc, because the framework will call free on it when your app shuts down. First free the existing value, then assign your new string:
free((void*)m_pszProfileName);
m_pszProfileName = ::_tcsdup(_T("C:\\somedir\\myini.ini"));
Call CWinApp::GetProfileInt, CWinApp::WriteProfileInt and similar functions as usual.
I strongly recommend using a path under APPDATA for storing your .ini file.
Yes you can. CWinApp::SetProfileXXX() does this for you, actually - but I wouldn't use these methods anymore in 2010, they were OK when ppl moved from .ini to the registry.
I am not sure if this is possible as a .ini file has only strings for your program. You can create an operating system script (.bat for windows, .sh for unix etc) and call it using system() call.
Use win32 APIs WriteProfileString (write to INI file) and GetProfileString (read from INI file)
For more help
ms-help://MS.MSDNQTR.v90.en/sysinfo/base/writeprofilestring.htm