Joining the Clipboard Chain Best practices - delphi

Further to my post on custom format clipboard, I am considering the possibility of writing my own custom clipboad monitoring component.
Prior to the statement:
ClipboardWindow:=SetClipboardViewer(Form1.Handle);
I have seen in a sample code I studied the following snippet:
OpenClipboard(Form1.Handle);
EmptyClipboard;
CloseClipboard;
whereas others don't include a cleaning code at all. I am confused.
I believe Clipbrd.TClipboard.Clear just does the same the VCL way.
My question is:
When clearing the clipboard before joining the clipboard chain is mandatory ?

No, there is no need to clear the clipboard. Indeed, you shouldn't. Other clipboard monitors will needlessly react to the update, and the user may want to paste that thing that you just destroyed.
Additionally, there is a lot more to clipboard chain monitoring than just adding yourself to the chain. You must pass the events along to the next window (result handle from SetClipboardViewer), and you must, without failure, remove yourself from the chain when your app exits. Also, you need to avoid blocking the clipboard unnecessarily. Typically, this means waiting to register for the clipboard events until you're ready to actually process events. For example, don't make it the first thing in your startup, if you're going to subsequently open a dialog asking the user where he wants to store the data, if he has a license key, etc..
I have tips, as well as common pitfalls here:
http://www.clipboardextender.com/developing-clipboard-aware-programs-for-windows/6

The rule is as simple as possible: if you want to delete the clipboard content (so other apps can't use it) delete it. if not, keep it.
You don't know if your use wants to keep the data OR You want to implement something fancy?
Do you know those applications (Paint Shop Pro is one of them) that are asking: "You left a large image (10MB of data) in clipboard. Do you want to keep it or clear it?"
You could do something similar. :)

Related

How can I lock the clipboard so that no other application is allows to change the clipboard?

In my application I want to lock the clipboard to prevent other application from changing the clipboard. How can I achieve this using Delphi 2007?
There is no facility for that. The user is the ultimate owner of the clipboard. When the user wants something else on the clipboard, the user will cut or copy something new. You, as the application developer, don't get a vote. (Users who discover programs trying to assert votes they don't have are likely to uninstall those programs and give them poor reviews.)
You can monitor the clipboard to discover when it changes with wm_ClipboardUpdate, but by the time you receive the notification, there's already something new there.
The purpose of the clipboard is to make data stored in it to be available to any program at any time and therefore provide easy way from transferring such data between different applications.
Because of that there is no official mechanism which would allow blocking access to the clipboard.
Any way if you are perhaps thinking of trying to block other application of accessing the clipboard in order to avoid them to be able to intercept some data from your application that has been stored there for copying purposes (which is the only reason I can think of why you would want to do this) there is another even better way.
Instead of using Windows default clipboard for string parts of data for copy and paste operations go and implement your own custom clipboard that will only be available from your own application similar as Microsoft does with its Office Clipboard (https://support.office.com/en-us/article/Copy-and-paste-multiple-items-by-using-the-Office-Clipboard-714a72af-1ad4-450f-8708-c2931e73ec8a).
In order to do this you only need to design a storing mechanism and then override default Cut, Copy and Paste shortcuts to use your mechanism instead of the default Windows Clipboard.

UWP/WinRT: How to save and then restore a simple TextBox for resume from termination?

In this document describing the lifecycle of a Windows 10 UWP app, it states:
Users now expect your app to remember its state as they multitask on their device. For example, they expect the page to be scrolled to the same position and all of the controls to be in the same state as before. By understanding the application lifecycle of launching, suspending, and resuming, you can provide this kind of seamless behavior.
However, there doesn't appear to be much documentation on how this is actually achieved. I gather that everything is to be manually saved by the app developer, and then recreated from scratch on resume using whatever data you stashed away when the app was suspending, all in order to create the illusion that the exact memory state of the app never changed.
I'm trying to puzzle through this using just a minimal example, a XAML page containing nothing other than a TextBox. Even this situation, though, I'm struggling a bit to understand how to achieve the goal. I'll provide more general thoughts, but my concrete question simply is how do you save and then restore a simple TextBox for resume from termination? I'm working in C++/CX but will take any help I can get.
Here are my thoughts on this so far:
At minimum, obviously the text of the TextBox has to be saved.
This could be saved into the ApplicationData::Current->LocalSettings.
One issue I see immediately is that the document I cited above on lifecycles states that apps must take care of their saving within 5 seconds of the suspend signal or face termination. A Textbox could potentially hold a lot of data, causing a save to potentially be cutoff in the face of busy IO, particularly if we start scaling beyond the trivial single TextBox situation.
Fortunately, the document states, "We recommended that you use the application data APIs for this purpose because they are guaranteed to complete before the app enters the Suspended state. For more info, see Accessing app data with the UWP app." Unfortunately, when you follow that link, there is nothing relevant there providing any more detail, and I can't find anything documenting this behavior in the API's. By saving into ApplicationData::Current->LocalSettings are we safe from being cut off with corrupted or lost data?
Once the minimum has been taken care of, next we'll probably need extras like cursor and window position.
We can get the cursor position with TextBox->SelectionStart, which as far as I can tell, is undocumented in the API of this usage of returning the current cursor position. This seems an easy fit to also store as an int into ApplicationData::Current->LocalSettings.
How can we get, save, and restore the scroll position of the TextBox window?
Now that we've got the extras, how about the hard stuff, like undo history? I'm assuming this is impossible as my question on Stackoverflow on how to access the TextBox's undo facility has gotten no answers. Nonetheless, it does seem like a poor user-experience if they swap to another app, come back thinking that the app never closed due to the beautiful and seamless restore from termination we implemented, and their undo history has been wiped out.
Is there anything else that would need to be saved for the TextBox to create the ideal user-experience? Am I missing something or is there an easier way to do all this? How would something like Microsoft's Edge Browser handle the complex case where there are dozens of tabs, form inputs, scroll positions, etc. that all need to be saved in 5 seconds?
The App lifecyle document you reference has been updated for Windows 10, but seems to have lost some of the important bits that you are wondering about.
I found an old blog post, Managing app lifecycle so your apps feel "always alive", that seems to be the inspiration for your link.
In the blog post, there is a paragraph towards the end that reads:
Save the right data at the right time
Always save important data incrementally throughout the life of your app. Because your app has only up to five seconds to run suspending event handler code, you need to ensure that your important app data has been saved to persistent storage by the time it is suspended.
There are two types of data for you to manage as you write your app: session data and user data. Session data is temporary data that is relevant to the user’s current experience in your app. For example, the current stock the user is viewing, the current page the user is reading in an eBook or the scroll position in a long list of items. User data is persistent and must always be accessible to the user, no matter what. For example, an in-progress document that the user is typing, a photo that was taken in the app or the user’s progress in your game.
Given the above, I'll attempt to answer your questions:
how do you save and then restore a simple TextBox for resume from termination?
As the end user is typing in the TextBox, the app saves the contents in the background to the data store. To borrow from how word processing software works, you auto-save the textbox "document". I would consider the textbox content to be what the blog post above describes as "user data". Since the save is done outside of suspension, there is no time window to worry about.
When your app resumes from termination, it checks the data store and loads any data into the textbox.
Once the minimum has been taken care of, next we'll probably need extras like cursor and window position.
I would consider these items "session data" and would save them during suspension. After all there is no need to keep track of this info while the app is active. The user doesn't care where the cursor was 10 minutes ago when he started typing - he only cares about the cursor position at the time of suspension.
how about the hard stuff, like undo history?
I would consider undo history to be "user data" and would save it while it is happening (outside of suspension). In other words, as the user types in content, your app should be saving the information necessary to undo.

Disable Sending keypresses to an application using Delphi

I'm looking for a line of code in Delphi which can disable sending keys to an application. For example I have a game.exe, I want to disable sending keys to it, so you can not play it.
How to do that? Please Guide me step by step :)
Hiding and blocking input should be separate questions. Your question is so vague that I'm tempted to vote to close it, but here are some general ideas instead;
If you want to block all input from getting to an application,you can simply grab the focus away from that particular application, or keep your window on top and make it full screen. This is often called "Kiosk mode".
You could also forcibly hide all the application's windows.
You could intercept the window messages that are bound for that application and handle them yourself. See the link from Johan on Keyboard hooking.

How to log user activity with time spent and application name using c#.net 2.0?

I am creating one desktop application in which I want to track user activity on the system like opened Microsoft Excel with file name and worked for ... much of time on that..
I want to create on xml file to maintain that log.
Please provide me help on that.
This feels like one of those questions where you have to figure out what is meant by the question itself. Taken at face value, it sounds like you want to monitor how long a user spends in any process running in their session, however it may be that you only really want to know if, and for how long a user spends time in a specific subset of all running processes.
Since I'm not sure which of these is the correct assumption to make, I will address both as best I can.
Regardless of whether you are monitoring one or all processes, you need to know what processes are running when you start up, and you need to be notified when a new process is created. The first of these requirements can be met using the GetProcesses() method of the System.Diagnostics.Process class, the second is a tad more tricky.
One option for checking whether new processes exist is to call GetProcesses after a specified interval (polling) and determine whether the list of processes has changed. While you can do this, it may be very expensive in terms of system resources, especially if done too frequently.
Another option is to look for some mechanism that allows you to register to be notified of the creation of a new process asynchronously, I don't believe such a thing exists within the .NET Framework 2.0 but is likely to exist as part of the Win32 API, unfortunately I cant give you a specific function name because I don't know what it is.
Finally, however you do it, I recommend being as specific as you can about the notifications you choose to subscribe for, the less of them there are, the less resources are used generating and processing them.
Once you know what processes are running and which you are interested in you will need to determine when focus changes to a new process of interest so that you can time how long the user spends actually using the application, for this you can use the GetForegroundWindow function to get the window handle of the currently focused window.
As far as longing to an XML file, you can either use an external library such as long4net as suggested by pranay's answer, or you can build the log file using the XmlTextWriter or XmlDocument classes in the System.Xml namespace

Need to send a pasting command from one program to another?

I am using one program to monitor the keyboard for input but would like to use that same program to populate the clipboard then automatically paste to the cursor location of the other program? Can this be done... I am using Delphi 4 Pro.
It's possible, but this is very poor design. The clipboard is provided for the benefit and use of the user, not the programmer. You will end up trashing pre-existing clipboard data. It is not possible to 100% faithfully and reliably cache the clipboard contents and restore it later.
That said, you can send Ctrl+V keystrokes or WM_Paste messages to the other window.
Send the target window a wm_Paste message.
But only put data on the clipboard if the user has told you to. The clipboard is something that should always be under control of the user, or else you run the risk of clobbering other data the user was already storing there.

Resources