Jonathan Wilson asks why the clipboard APIs still require GlobalAlloc and friends. Why is there not a SetClipboardDataEx or something that does what SetClipboardData does but without needing to call GlobalAlloc?

Okay, here's your function:

HANDLE SetClipboardDataEx(UINT uFormat, void *pvData, DWORD cbData)
{
    if (uFormat == CF_BITMAP ||
        uFormat == CF_DSPBITMAP ||
        uFormat == CF_PALETTE ||
        uFormat == CF_METAFILEPICT ||
        uFormat == CF_DSPMETAFILEPICT ||
        uFormat == CF_ENHMETAFILE ||
        uFormat == CF_DSPENHMETAFILE ||
        uFormat == CF_OWNERDISPLAY) {
        return NULL; // these are not HGLOBAL format
    }

    HANDLE hRc = NULL;
    HGLOBAL hglob = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT,
                                cbData);
    if (hglob) {
        void *pvGlob = GlobalLock(hglob);
        if (pvGlob) {
            CopyMemory(pvGlob, pvData, cbData);
            GlobalUnlock(hglob);
            hRc = SetClipboardData(uFormat, hglob);
        }
        if (!hRc) {
            GlobalFree(hglob);
        }
    }
    return hRc;
}

Whoop-dee-doo.

Historically, Windows doesn't go out of its way to include functions like this because you can easily write them yourself, or you can at least find a framework library that did it for you. Windows focused on doing the things that only Windows could do, providing you the building blocks with which you can create your own programs.

Besides, the classic clipboard is so old-school. The OLE clipboard provides a much richer interface, where you can generate data dynamically (for example as a stream) and expose it in formats other than just a chunk of bytes. Since SetClipboardData is old-school, if the window manager folks had written a function like SetClipboardDataEx, people would instead have asked the not unreasonable question, "Why did you bother to write a function that provides no essential new functionality to an old interface that was supplanted over a decade ago?"