13.1.1 Copying Text to the Clipboard

To copy a short string of text to the clipboard, your application should follow these steps:

1.Copy the string to global memory.

2.Open the clipboard.

3.Clear the clipboard.

4.Give the global memory handle to the clipboard.

5.Close the clipboard.

The application should copy text to the clipboard when the user chooses the Copy command from the Edit menu. To process the menu input and copy the text string to the clipboard, your application should have a WM_COMMAND case in its window procedure. To implement the Cut and Copy commands, add the following statements:

case IDM_CUT:
case IDM_COPY:

    if (hText != NULL) {

        /* Allocate memory and copy the string to it. */

        hData = GlobalAlloc(GMEM_MOVEABLE, GlobalSize (hText));

        if (hData == NULL  ||
                (lpData = GlobalLock(hData)) == NULL ||
                (lpszText = GlobalLock(hText)) == NULL) {
            OutOfMemory();
            return TRUE;
        }

        lstrcpy(lpData, lpszText);
        GlobalUnlock(hData);
        GlobalUnlock(hText);

        /*
         * Clear the current contents of the clipboard,
         * and set the data handle to the new string.
         */

        if (OpenClipboard(hwnd)) {
            EmptyClipboard();
            SetClipboardData(CF_TEXT, hData);
            CloseClipboard();
        }

        hData = NULL;
        if (wParam == IDM_CUT) {
            GlobalFree(hText);
            hText = NULL;
            EnableMenuItem(GetMenu (hwnd), IDM_CUT, MF_GRAYED);
            EnableMenuItem(GetMenu(hwnd), IDM_COPY, MF_GRAYED);
            InvalidateRect(hwnd, NULL, TRUE);
            UpdateWindow(hwnd);
        }
    }

    return TRUE;

The GlobalAlloc function allocates enough memory to hold the string. The GMEM_MOVEABLE flag specifies movable memory. The clipboard can take either fixed or movable memory but should not be given discardable memory. Movable memory is the most efficient.

Note:

Always check the return value when allocating or locking memory; a NULL return value indicates an out-of-memory condition.

You must lock movable memory in order to retrieve the memory address. Use the Windows lstrcpy function instead of the C run-time strcpy function, since strcpy cannot handle mixed pointers (string is a short pointer, and lpData is a long pointer). The clipboard requires the string to have a terminating null character. Finally, the memory must be unlocked before it can be copied to the clipboard.

Each time your application copies the string to the clipboard, this code allocates another global memory object. The reason is that once the application passes a data handle to the clipboard, the clipboard takes ownership of it. This means that the application can no longer use the handle other than to view contents, and that it must not attempt to free the handle or change its contents.

The OpenClipboard function opens the clipboard for the specified window. OpenClipboard will fail if another window already has the clipboard open.

The EmptyClipboard function clears all existing handles in the clipboard and assigns ownership of the clipboard to the window that has it open. An application must empty the clipboard before copying data to it.

The SetClipboardData function copies the memory handle to the clipboard and identifies the data format, CF_TEXT. The clipboard is then closed by the CloseClipboard function.

Since the clipboard now owns the global memory identified by the hData variable, it is convenient to set this handle to zero to prevent attempts to free or change the memory.