Delayed Rendering of Clipboard Data | CodeGuru

Delayed Rendering of Clipboard Data

Programs such as Word use multiple Clipboard formats and copying them all to the Clipboard whenever copy or cut options are selected will be a waste as it’s unlikely that all of them would be used at once. Windows provides an intelligent alternative to simply copy all the data on the Clipboard. An application sending […]

Written By
CodeGuru Staff
CodeGuru Staff
Jan 3, 2006
2 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

Programs such as Word use multiple Clipboard formats and copying them all to the Clipboard whenever copy or cut options are selected will be a waste as it’s unlikely that all of them would be used at once.

Windows provides an intelligent alternative to simply copy all the data on the Clipboard. An application sending data to the Clipboard can register the Clipboard format without passing any data. This is done by passing null as the handle to the data block when SetClipboardData () is called. The effect of passing a null handle is that the Clipboard doesn’t recieve any data but it records that it will be provided with the data when it’s needed.

For an example, you can set the null data handle for a CF_TEXT clipboard format:

OpenClipboard ();
EmptyClipboard ();
SetClipboardData (CF_TEXT, NULL);
CloseClipboard ();

When you need to paste that data into, say, Notepad, Windows recognizes that the CF_TEXT data needs to be loaded and it sends a WM_RENDERFORMAT message to the window that called SetClipboardData () with a null handle. The program then calls SetClipboardData () again, but this time passes a handle to a memory block containing the data. And then, Windows pastes the data into Notepad.

There is one situation that pops up when an application uses delayed rendering. That is what will happen when the application that’s to supply the data is terminated before the Clipboard data is requested. In such a situation, the supplying program recieves a WM_RENDERALLFORMATS message before it terminates. The result is that the data is put in the Clipboard before the program terminates and is available to all other programs.

In the included project, the application displays a message when the Clipboard asks for the data to be copied to it. To see it, type some text in the edit box on the dialog box then click copy to Clipboard. Then, open Notepad and press Ctrl + V; at this time, the application will display a message.

The following code from the included project will make things clearer.

void CDelayedrenderingDlg::OnCopy()
{
   //Open the Clipboard and then clear its contents
   OpenClipboard ();
   EmptyClipboard ();

   //Now, instead of the memory handle we pass NULL;
   //this indicates that the data will be made available
   //when the user requests it.
   SetClipboardData (CF_TEXT, NULL);
   CloseClipboard ();
}

void CDelayedrenderingDlg::OnRenderFormat (UINT nFormat)
{
   //Check whether the requested data is of type text
   if (nFormat == CF_TEXT)
   {
      //Get the data from the edit control and put it on the
      //Clipboard because the user has requested it
      CString strEditText;
      HANDLE hClipboard;
      LPTSTR lpszBuffer;

      (GetDlgItem (IDC_EDIT))->GetWindowText (strEditText);

      hClipboard = GlobalAlloc (GPTR, strEditText.GetLength () + 1);
      lpszBuffer = (LPTSTR) GlobalLock (hClipboard);
      _tcscpy (lpszBuffer, strEditText);
      GlobalUnlock (hClipboard);

      //Note that we don't open the Clipboard here because it's
      //already opened by the application that needs the data
      SetClipboardData (CF_TEXT, hClipboard);
      CloseClipboard ();
   }
   AfxMessageBox (_T("Data send to the clipboard"));
}

void CDelayedrenderingDlg::OnRenderAllFormats ()
{
   //The application recieves this message before it quits so
   //that the data could be put on the Clipboard

   //Get the data from the edit control and put it on the
   //Clipboard because the user has requested it
   CString strEditText;
   HANDLE hClipboard;
   LPTSTR lpszBuffer;

   //This time we need to open the Clipboard
   OpenClipboard ();
   EmptyClipboard ();

   (GetDlgItem (IDC_EDIT))->GetWindowText (strEditText);

   hClipboard = GlobalAlloc (GPTR, strEditText.GetLength () + 1);
   lpszBuffer = (LPTSTR) GlobalLock (hClipboard);
   _tcscpy (lpszBuffer, strEditText);
   GlobalUnlock (hClipboard);

   //Set the text on the Clipboard and then close it
   SetClipboardData (CF_TEXT, hClipboard);
   CloseClipboard ();
   AfxMessageBox (_T("Application terminating, so data copied to
                      Clipboard."));
}
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.