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

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

Related

SHGetFileInfo performance issues

Here is an excerpt from the Windows documentation about the SHGetFileInfo() function:
You should call this function from a background thread. Failure to do so could cause the UI to stop responding.
Does this apply to extracting the folder icons as well?
One of our applications resembles Windows Explorer, and we pursue two antagonistic goals: to support as many Windows Explorer's features as possible, and to be as fast as possible. Having the latter in mind, I assigned to each folder the default icon (obtained with the help of the SHGFI_USEFILEATTRIBUTES flag). But after some time it turned out, that a few of our customers use custom folder icons.
So, should I create new threads to calculate the icon for each folder, or is there a way to quickly extract a folder icon in the main thread, given the fact that the number of custom folder icons is negligible?
For example, a way to retrieve only cached icons could be a solution, I think. There is a function IShellItemImageFactory::GetImage(), which allows to obtain only cached icons, but it unfortunately returns HBITMAP instead of HICON.
It seems that I found an appropriate solution.
First of all, I prepare and store a pair containing the default folder icon and its index in the system image list. Then, when the request for a folder icon arrives, I immediately return the default icon, and launch a thread from the Windows thread pool.
In the launched thread I calculate the actual folder icon and its index with the help of the SHGetFileInfo API. If the index is the same as index of the default icon, I destroy the icon. Only if the obtained index differs from the default icon index, I post notification to the control in the main thread.
In this way the control is notified only about folders that really have custom icons, and the main thread is not overburdened with redundant notifications.

How can I open an *modal* file dialog with IFileOpenDialog?

I've been trying to implement a file dialog into my C++ application for a while now, and I achieved good success with the code described in this article (It is german, but the code should be understandable):
https://msdn.microsoft.com/de-de/library/windows/desktop/ff485843(v=vs.85).aspx
However, using this code in my window class, which is a CDialogImpl, I just can't find out how to make this file picker modal. If I use this code, I can just spawn multiple file picker.
Of course, I could just keep track of the state by adding a member variable representing the state, but it would still not solve the problem of being able to click around in the main window while the dialog is opened.
Is there any way which would allow me to make this window modal? I've been trying to scan through all available methods, but I couldn't find anything. I didn't find any flags which could be passed in the creation, neither any options which I could set after creation.
Any help is appreciated!
The example you link to is very simple and has no UI other than the file dialog. Your program is more complex, having a window from which the file dialog is invoked.
You need to provide an owner for the file dialog. When you do that the owner is disabled, part of what makes the dialog modal. Failing to pass an owner means that the other windows are not disabled and so still respond to user input.
The example code provides no owner, but since there are no other windows in that program, that is benign. Modality is only meaningful when there are multiple windows.
So, to solve the problem, pass the owner, the handle of your window, to the Show method of the file dialog.
Disabling owner windows is one of the key parts of a modal dialog. You will find that any API for modal dialogs expects you to specify an owner. Get into the habit of expecting to provide that ownwr window, and looking for the means to do so.

SetCursor while dragging files into a window

I'm using windows API to create an application with a window only, so everything inside this window is drawn using Direct2D.
Now I want to drop some files in specific parts of my window's client area, and I'm handling the message WM_DROPFILES. No problem here, when the files are dropped in those specific areas, I can treat them correctly and everything is working properly. BTW, my window is DragAcceptFiles(hWnd, true), it always accepts drag/drops.
I want the mouse cursor to be different depending on the area of the window the mouse is in. In the areas that I don't treat the drop, I want the cursor to be the invalid icon, and for the areas of the window that I do handle the drops, I want the correct drop icon.
The first thing I noticed is that no message is generated when files are being dragged into the window, and for this reason I added a mouse hook (WH_MOUSE_LL using SetWindowsHookEx). When the hook is processed, I only look at the WM_MOUSEMOVE message, so I can change the cursor according to the area the mouse is in.
The problem is that the SetCursor does nothing, if my windows is configured to accept drag files, the cursor is always the drag/drop cursor, no matter how many times I call SetCursor.
It seems impossible to change the cursor this way, but is there any other way of doing what I'm trying to achieve?
You need to write a class in your code that implements the IDropTarget interface, then create an instance of that class and pass it to RegisterDragDrop() to associate it with your window. Do not use DragAcceptFiles() anymore.
Whenever the user drags anything (not just files) over your window, your IDropTarget::DragEnter() and IDropTarget::DragOver(), IDropTarget::DragLeave() methods will be called accordingly, giving you the current coordinates of the drag and information about the data being dragged (so you can filter out any data you don't want to accept). If you choose to accept the data, and the user actually drops the data onto your window, your IDropTarget::Drop() method will be called.
As the drop target, it is not your responsibility to change the cursor. It is the responsibility of the drop source instead to handle that as needed. In your IDropTarget::DragEnter() and IDropTarget::DragOver() implementations, all you need to do is set the pdwEffect output parameter to an appropriate DROPEFFECT value. That value gets passed back to the drop source, which then displays visual feedback to the user (like changing the cursor) in its IDropSource::GiveFeedback() implementation.
It is possible for your IDropTarget to be invoked without user interaction (ie, programmably from another apps, and not just for drag&drop operations). That is why the drop source, not the drop target, decides whether or not to display UI updates to the user, since only the drop source knows why it is invoking your IDropTarget in the first place. The drop target does not know (or care) why it is being invoked, only that it is being given some data and asked whether it will accept or reject that data, nothing more.
Refer to MSDN for more details:
OLE and Data Transfer
Transferring Shell Objects with Drag-and-Drop and the Clipboard

How can the drop target override the cursor shape in a drag and drop originating from the outside?

I have an MFC window which acts as a drop target. Depending on where the user drops certain types of data, I'd like to change the cursor shape to indicate what action will occur, only the actions are not move/copy/link, but more complex actions for which I have custom cursors.
Here's an example, if it helps. Imagine I have a window with 2 squares where the user can drop a file: in the first square, the file is e-mailed, in the second, the file is stored on Dropbox. I have one e-mail cursor and one dropbox cursor, and I'd like the cursor to change accordingly when the user hovers over the squares.
In MFC, you can create a COleDropSource object and override its GiveFeedback() method to do exactly this. However, this only works if you can pass that object to COleDataSource::DoDragDrop(), ie if you start the drag operation yourself. If the drag originates inside my application, this method works and I can get the desired cursor type. If the drag originates from Windows Explorer, I don't have a chance of providing my own COleDropSource object, and so I can't override the cursor shape.
Setting the cursor directly in OnDragOver() does not work, since Windows uses the result value of that method to change the cursor, so I only see the desired cursor for a fraction of a second before Windows changes it back to one of the standard shapes.
Is there any other way of solving this?
(This question is similar to this one, only I'm using MFC so the proposed solution there does not work.)
I'm afraid the source application is reponsible for the user feedback. You can provide hints to the source application via IDropTarget but it's the sources reponsiblity for using that feedback.
It makes sense really, the source application is the one that really knows what the data is and what can be done with it (think dragging a file from a zip file etc.).

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.