Windows: open a named document - c++

I'm trying to extend an existing app called Drax which edits the metadata of MP4 movie files.. I want to be able to drag-n-drop files onto it, which it does not support. I've gotten far enough to be able to decode the "clipboard" data when it is dropped, and filter to accept only the file (extensions) that I can handle. (Like so but I know next to no winapi/C++ so it's all cargo-culted.)
But now I want to trigger opening the document, whose (file) name I have in a TCHAR. And I'm stuck. How do I trigger the same sort of action the File>Open dialog would, when I know the name of the file from a drag/drop operation?

Normally, the File -> Open dialog does not do anything but allow the user to choose a file name. It then returns this file name to you, the programmer, to do something with.
But, in this case, you're modifying an existing application, so that code has already been written. To find it, you need to search for the method(s) that display the File -> Open dialog. See what they do with the file name(s) returned by the Open dialog.
All the logic for opening the file is very likely to be crammed into the same method as the one that displays the File -> Open dialog. If so, what I would do is refactor the code, so that you have a separate method like
void OpenFile(CString pszFileName, /* other important parameters */)
{
// ...
}
that handles opening the file, specified by a string containing its full path. You will call this method once you get the file name from the File -> Open dialog, and also from elsewhere, like after you get the file name from a drag-drop operation.

Related

How to prevent "How do you want to open this file" dialog?

In my app I open a report using HTML file as such:
//pStrPath is file:///C:/Users/appts/AppData/Local/Temp/Report_View.htm
ShellExecute(hParentWnd, L"", pStrPath, NULL, NULL, SW_SHOW);
On my development machine it opens up in a web browser, but when I just tested it on a new installation of Windows 10, it showed this dialog instead:
So how can I prevent it from being shown and go with "keep using this app" option from the get-go? Otherwise it may be very confusing for my users.
PS. Note that Edge is installed and can open .htm files if I double-click them.
Referring to Launching Applications (ShellExecute, ShellExecuteEx, SHELLEXECUTEINFO) we note the text
Object Verbs
The verbs available for an object are essentially the items that you find on an object's shortcut menu. To find which verbs are available, look in the registry under HKEY_CLASSES_ROOT\CLSID{object_clsid}\Shell\verb
Commonly available verbs include:
edit - Launches an editor and opens the document for editing.
find - Initiates a search starting from the specified directory.
open - Launches an application. If this file is not an executable
file, its associated application is launched.
print - Prints the document file.
properties - Displays the object's properties.
Given that a double-click is the generally equivalent to selecting "open" in the object's shortcut menu, if we supply the function with the open verb, we can expect the behaviour to mirror that of a user's double-click. - Please see Ken's comment below
As such, we can expect the following code to achieve the desired result.
//pStrPath is file:///C:/Users/appts/AppData/Local/Temp/Report_View.htm
ShellExecute(hParentWnd, L"open", pStrPath, NULL, NULL, SW_SHOW);
If you are trying to open the default program FROM a 32 bit program in 64 bit Windows the ShellExecute and ShellExecuteEX may display the "How do you want to open this file?" dialog box each time. This is due to the way that the default program registered itself in Windows I think.
I could reproduce this error on Windows 11 fresh install where the Photos is set to the Default Program for .jpg files.
In my case, I found that if I use the ShellExecuteExW function and pass the extension into the .lpClass of SHELLEXECUTEINFOW Type that it works.
It should also work with the ShellExecuteExA function
Make sure it's not an exe, reg, bat file, or a URL you are trying to open. It has to be a document type of file.
Use the .lpClass to pass the extension like ".jpg"
Add the SEE_MASK_CLASSNAME As Long = &H1 to the .fMask parameter you are passing in like .fMask = YourMaskValue Or SEE_MASK_CLASSNAME
The reason I think this works is it bypasses any redirection and reads directly from the HKEY_CLASSES_ROOT.jpg

Can I cancel some files in IFileDialogEvents::OnFileOk with Multiple select?

I was wondering if I can cancel some files selected from file dialogs?
This is the method I'm registered to:
https://msdn.microsoft.com/en-us/library/windows/desktop/bb775879(v=vs.85).aspx
I would like to do my custom validations, and the documentation says that I can return S_FALSE to cancel the opening.
If some files fail validation (my custom one) - I want to be able to continue opening just the valid ones.
Current situation, is that I delete the failed files and then the application (word/adobe) says that the file doesn't exist.
I prefer that it won't try to open them (to change the "selected files" somehow)
Is that possible?

MFC CFileDialog open only select files

Using CFileDialog as a file open, I need to allow the user to only select a file that is displayed in the dialog list area, such as by clicking on it. We don't want the user to be able to type in a name in the File Name control. The OPENFILENAME (OFN) struct has several different flags (http://msdn.microsoft.com/en-US/library/ms646839%28v=vs.80%29.aspx), but I don't see one that prevents the user from typing in a filename.
The closest thing I saw was OFN_FILEMUSTEXIST, but that only specifies that the file exists; it still allows the user to type in a name.
Is there any way to do this without inheriting a new class?
MORE INFO
We need to prevent them from typing in a filename because they could open an inappropriate one. With the lpszFilter parameter, we filter the filenames so it only displays files with ABC in the filename (not the extension). So if they typed in a filename, they could enter something like myCoolFileDEF.ext. If the file exists, it will go ahead and let them open it (the dialog will close w/o an error message) even though they were only supposed to open files with ABC in the filename.
Since you are using MFC, just inherit a CFileDialog and disable the file name edit control and combobox. I don't see the point of using CFileDialog AND writing another OFNHookProc callback, though you could start from GetOpenFileName if you want to.
As a previous answer notes, you could root around in the dialog for the filename control and disable it. This is not without penalty though - if you turn on the CFileDialog hook callback logic, you get the "old style" file dialog on Vista and above, not the "new style" one. The "new style" file dialog is a lot more restrictive in what can be customized, and, as far as I know, doesn't provide a supported way to get at the filename control.
Reading your question, my first instinct is that you're over-designing your solution: if you supply a filter then the user has to go to quite a lot of trouble to select the wrong sort of file, and most users won't do that. If they do, it's possible that the user knows better than your program. If it were me, I would just use a filter, then after the file dialog has closed, check the returned filename - if it doesn't match the required pattern, I'd put up a message dialog to ask if the user if they're really sure, and open the file anyway if they insist that they are.

How to set window properties by editing the file at runtime?

I'm using MFC (superstructure of Win32 API) in C++.
I have a component Window and JSON file. In JSON file are height, width, top, left with values (it is not so important).
What I have now:
I've a running program and JSON file. If I edit the JSON file and save that, changes will not change. Changes takes effect after when I close and start new program.
What I need:
If I edit the JSON file and save that, change will be reflected immediately while runtime.
Any ideas, using pointers or how to do this?
You need to create an event using FindFirstChangeNotification and then WaitForSingleObject on it. It will signal when a specified event happens to the directory content. You'll then need to reread the and modify your window's position

want to open text file in some text editor programmatically in c/c++

I want to open a text file into some text editor say notepad programmatically in c/c++.
Also i want to see real time updation of text into that text file while opening in a editor.
Please suggest.
Most editors accepts the path of the file-to-be-opened as 1st argument. E.g.
notepad.exe c:/foo.txt
Just execute it as a shell/runtime command in your program.
If you're doing something as simple as monitoring a log file, you want a unix program called "tail", or its Windows equivalent.
It will give you a simple Notepad-like Window which displays the contents of a log file in (more or less) real time.
Having the editor (notepad, tail, whatever) continually monitor the file for changes isn't your job as the C++ developer, it's up to the program.
To get the file to open in the default application specified, try this (C#):
System.Diagnostics.Process.Start("text.txt");
To specify an application, try this:
System.Diagnostics.Process.Start( "notepad.exe", "text.txt");
I'm not aware of any way to handle real time updation of the file in the editor however.
After you have it running, see above. you can possibly keep the file updated using SendMessage from the Windows API and sending Ctrl+S(save) to the notepad window.
To see real time update in your editor window try to find editor's window handle (you may use EnumWindows() function). Insert text in the editor's textfield or reread it from the file and call RedrawWindow() after that. However calling it after each letter could give some nasty flickering if the text come from a program.