WinUI3 : how to know which uielement was dropped in UIElement.drop() event - c++

I'm working on a WinUI3 desktop application with c++. I was trying to perform a drag-and-drop operation. When I drop a textbox on a canvas I get a drop event from the canvas. In that drop event, as a sender, we can get a reference to the canvas instance[ the UIElement on which the drop happened ], but how to know which element was dropped on the canvas?
I came across this documentation on how to process drop events, but it's unclear how to pass data between dragstaring and drop events.
It would be of great help if you could help me understand which UIElement was dropped when we receive UIElement.drop() event
Thank you

Although the Drag and drop documentation (which is a UWP doc, not a WinUI3 doc which in many cases cannot be found...) says
In most cases, the system will construct a data package for you. The
system automatically handles: Images, Text
This doesn't work for WinUI3 for some reason (maybe it depends on app identity, packaging, security, etc.), there's nothing constructed automatically in the target data object.
So you must hook the DragStarting event and put what you want in it so you will get it back in the Drop event.
You can't put/get the source element itself as an object from a drag & drop operation, you must put yourself some information you find suitable about it in the Data object. D&D as a general OS feature only supports serializable or well-known data (text, image bits, a stream, etc.).
To do that you can use one of the SetXXX methods of the DataPackage class, like SetText for example.

Related

Qt/QML: Delay window rendering until data is available

I am building an application using Qt/QML. The QML of my main window is very complex and depends on lots of data which must be loaded via HTTP and then be processed by a C++ backend before it is ready to be displayed.
The C++ backend provides a signal which is fired when the data is ready. Until then, I want the window to be empty except for a simple loading indicator being displayed. Of course, I could use a simple overlay which hides my actual interface until the data is available, but this would mean that the QML code of my actual user interface is already loaded and tries to access the not-yet-available data, which is causing a lot of errors, so I would need to add dozens of dummy values and NOTIFY signals for each single property which might not yet be available.
What is the best way to completely deactivate a portion of QML code and to enable it as soon as a signal is triggered?
My personal experience is to not give data to your view components, don't bind them. For example, set your text value to an empty string or don't set it, set your image component source to an empty string or don't set it at first. When your signal comes in with data ready, you assign the data to the views at that time.

Save Workspace MFC C++ MDI

I have a MFC MDI application. The app can have 2 or more dialogs open. I want to implement the "Save Workspace" feature so that the user, when opening the workspace next time, opens the dialogs that were opened when he saved and closed the workspace. How to do this?
The functionality is built into the CMDIFrameWndEx implementation. SaveMDIState stores the current setup, while LoadMDIState restores it. The documentation also explains, how to persist the position and size of the frame window itself, in case that's something you want, too.
Generally this is accomplished by storing the current state of the application into some sort of persistent store. Depending on your architecture this could be a local configuration file (xml, json, etc) stored under the Windows User's profile directory (you could also use the Windows Registry), a remote store such as a database could be used or perhaps such state could be stored into cloud storage. Just depends on how the application currently handles configuration and how universal you want to make the state storage.
You will want to implement some sort or running history of UI state. Storing the currently open windows and their locations when they are loaded, closed and moved. Inject a history tracker into each MDI child that is created. This could be a singleton type in the MDI parent. It should have facility to look up a window by its handle and should store the relevant information in a structure that makes sense for serialization. In each of the afore mentioned events add calls to the tracker with the appropriate changes. The tracker should persist along whatever rules you determine are appropriate.
The load process then requires that the MDI parent interrogate the tracker after it has initialized with what ever stored state existed. Using the stored information (window type and location (and data?)) the MDI parent then opens up the appropriate children at the appropriate locations.

ListView in android for dynamic data

how to refresh List View dynamic data content in android?
I tried loading dynamic data for the List View in android application but no luck .Any advice how to accomplish this?
Call notifyDataSetChanged() on your Adapter object once you've modified the data in that adapter.
Some additional specifics on how/when to call notifyDataSetChanged() can be viewed in this Google I/O video.
Or else Look at this link.it may helpful.
Dynamic ListView in Android app
Or else
The right thing to do is to call notifyDataSetChanged() on your Adapter.
Troubleshooting
If calling notifyDataSetChanged() doesn't work all the layout methods won't help either. Believe me the list view was properly updated. If you fail to find the difference you need to check where the data in your adapter comes from.
If this is just a collection you're keeping in memory check that you actually deleted the item from the collection before calling the notifyDataSetChanged().
If you're working with a database or service backend you'll have to call the method to retrieve the information again (or manipulate the in memory data) before calling the notifyDataSetChanged().
The thing is this notifyDataSetChanged only works if the dataset has changed. So that is the place to look if you don't find changes coming through. Debug if needed.
UI Thread
It is true that this has to be called from the UI thread. Other answers have examples on how to achieve this. However this is only required if you're working on this information from outside the UI thread. That is from a service or a non UI thread. In simple cases you'll be updating your data from a button click or another activity/fragment. So still within the UI thread. No need to always pop that runOnUiTrhead in.
More Information
Another nice post about the power of list Views is found here:http://www.vogella.com/articles/AndroidListView/article.html

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.).