Is it possible to replace the system open file dialog? - windows

I want to replace the standard system open file dialog with the one I wrote, that means no matter within which programs you are opening a file, my dialog will be shown instead of the standard one, is this possible?
It seems that that there is no such API provided to accomplish this, is it possible to use some hooking technique, but this has to be reliable and not to be treated as spyware by anti-virus tools?
any other options?
If this is not possible, is it possible to add to the spacebar or toolbar in the standard open file dialog a button which invokes my dialog, which allow users select a file and in turn returns the path of the selected file to the "File name" input box of the standard dialog?
Any hits, links and code examples will be appreciated.

Starting in Vista, the FileOpen/FileSave dialogs are now "Common Item Dialogs" of which IFileOpenDialog & IFileSaveDialog are the two published implementations.
Since they're just COM objects with known CLSIDs you might get away with just replacing them by re-registering using their CLSIDs. Never tried something like that, might trip all sorts of alarm bells.
Pre-Vista file dialogs can be hooked in process, but I've never come across anything about global hooks or equivalent.

If you copy a file/folder to a dialog's filename field it usually pastes the full path anyway.
For example, if you have open both a program calling the standard open/save dialog box and also have a window open at the file or path that you want to work with (open from/save to), you can simply copy the file/folder from the explorer window, and then paste into the filename field of the dialog box, and it will insert the full path of the file/folder. No custom script is required!
Alternatively, for those programs that use custom dialog boxes where this step fails, copy the same file/folder in the window into the address bar of the same window (assuming it is visible). This will paste the full path, which you can copy again, and then paste this full path into the custom dialog box. I often use this when creating Office hyperlinks (Ctrl+K), because the Insert Hyperlink dialog does not work for the first method.
You can also use similar methods but paste into address bar fields and it works.

Related

Determining if currently renaming a file in Windows Explorer

I am trying to check a Windows Explorer view to see if a file name is currently being renamed / edited when typing.
I have a system hook installed that monitors the keyboard for specific keystrokes and fires certain events. This is done in this manner:
If the keyboard hook sees the key pressed it fires a message to another thread and continue processing other system hooks.
Other thread receives the message and checks to see if an Explorer window is active and gets the interface to the IFolderView2.
Call IFolderView2::GetFocusedItem() to get the focused item in the folder view.
Check if the focused item is being renamed / is in edit mode (SVSI_EDIT) using IFolderView2:: GetSelectionState() - this is the part that fails
If not in rename mode perform an action on that file.
I've tried everything on Windows 7 but the SVSI_EDIT flag (0x00000002 specifically) is never returned. It's always (SVSI_FOCUSED | SVSI_SELECT) regardless of if the file is being renamed. Setting the SVSI_EDIT flag with works with IFolderView::SelectItem with the flag puts it into rename mode but I want to determine if it's in this mode already.
This has only been tested on Windows 7 x64 so far.
Does anyone know a way to determine if Explorer / the IFolderView etc. is currently in the rename file state? Any sneaky method will do if it's not possible through these interfaces.
If one file in in renaming mode, Windows will create a EDIT control at the position of the item. So things got straight:
Find the currently-focused control.
Get the CLASS of the control.
Check whether it's CLASS is an EDIT.
On CodeProject there is a great example about how to find the focused control. To get the CLASS name of that control, use GetClassName API.

Is there a way to parent a standard Windows dialog inside another form?

I know it's possible to take a dialog that you built yourself and parent it on another form. But is it possible to parent a standard Windows system dialog on a form that you designed?
Specifically, I'm trying to set up a form with multiple tabs that provide different ways to obtain a reference to data used by the program. One of those tabs should represent the file system, and the ideal way to do this would be with the standard Open dialog that can be instantiated with the COM identifier CLSID_FileOpenDialog.
Is there any way to take a system dialog and cause it to appear parented on another window, without the border, title bar, etc?
There are ways to use a hook, either via SetWindowsHookEx() or SetWinEventHook(), to grab a system dialog's HWND, then you can do whatever you want with it, such as call SetParent(). But just because you CAN does not mean you SHOULD. System dialogs are designed to run as their own windows, not embedded in someone else's window. A better solution might be to use the same Shell display components that are used by Windows Explorer (and system dialogs) via IShellFolder::CreateViewObject() or SHCreateShellFolderView(), or find a third-party solution that does the hard work of interacting with the Shell for you.

Can the last opened file location be directly altered?

As I understand it, when a file open dialog box (such as GetOpenFileName) is used, Windows will automatically remember where the last file was that was opened by the program, and Windows remembers these locations separately for each program. Is there a way to directly alter this, in order to cause the file picking dialog for program X to start in C:\Example\Directory?
I'm attempting to automate a program which has been programmed to work only through a GUI, and I don't have any access to the internals of this program (such as being able to alter how it calls the file picker). Instead, I'm using a mouse macro (via AutoHotkey). If I can be completely sure that the file picker will start in a particular place, I should be able to automate the rest with mouse clicks.
If you had access to the source code, I'd suggest you just change the lpstrInitialDir property of the OPENFILENAME passed to GetOpenFileName().
Outside of that, you'll want to change the registry keys for the MRUs:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32
What might make more sense, and might fix the issue you're having, is also changing the Working Directory so that the default location isn't "My Documents", if you're experiencing that.
Depending on the operating system, the results vary:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839%28v=vs.85%29.aspx

Windows SaveAs dlg with OFN_OVERWRITEPROMPT doesn't detect file deletions?

I'm using a perfectly usual SaveAs dialog (in Delphi Win32 XE2, the system is Win 7 /64), setting OFN_OVERWRITEPROMPT (or the Delphi wrapper's equivalent dlgSave.Options := [ofPathMustExist, ofOverwritePrompt];. So if I select an existing file, the dialog asks for confirmation to overwrite the file.
Everything works as it should except for one silly thing: when I choose a file, then delete that file right in the same dialog, then press OK, the dialog still asks if it's ok to overwrite the (already deleted) file. Apparently, the dialog checks file existence against a pre-loaded list, not the file system. The problem is not specific to Delphi and can be shown very easily even in Notepad:
Run Notepad.exe
Enter some text
Save as a file
Click File Save As again, in the SaveAs dialog do:
Click on the same file to select it,
Right-click and delete the file,
click OK.
The file is no longer there, but you still get the overwrite prompt.
Can anybody please suggest a way to work around this minor but annoying Windows bug? I assume some message processing / callbacks / hooks might be required? A way of checking the file presence in code while the modal SaveAs dialog is open?

WinAPI: Call context menu entry provided by shell extension

The software Dropbox provides an shell extension which adds context menu items to all files in a specific folder. One of these generates a public link to view the selected file.
In a C# tool I want to call this entry without any user interaction. I want to achieve the same behavior as if the user clicked on the context menu item of a selected file.
I know that the shell extension is provided by a DLL, is it possible to make a call to this DLL to achieve the expected behavior?
Shell extensions implement IContextMenu and it is possible to execute menu commands without showing a menu (See this blog post for details about "hosting" IContextMenu)
Once you have the menu, you would call IContextMenu::GetCommandString and look for a specific verb, if Dropbox does not have a somewhat unique verb, you are going to have to do something hacky, either match by menu text alone, or call the Dropbox shell extension dll directly (DllGetClassObject export) and fake everything (Pretend to be COM and shell) or if you know the CLSID, you can at least get help from COM and just do the shell part.
There is a freeware tool called runmenu that allows you to play with shell menus/IContextMenu (I'm sure you can find a copy somewhere)

Resources