{"id":15183,"date":"2010-01-25T07:00:00","date_gmt":"2010-01-25T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2010\/01\/25\/why-doesnt-the-window-manager-have-a-setclipboarddataex-helper-function\/"},"modified":"2010-01-25T07:00:00","modified_gmt":"2010-01-25T07:00:00","slug":"why-doesnt-the-window-manager-have-a-setclipboarddataex-helper-function","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20100125-00\/?p=15183","title":{"rendered":"Why doesn&#039;t the window manager have a SetClipboardDataEx helper function?"},"content":{"rendered":"<p>\nJonathan Wilson asks\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/pages\/407234.aspx#760970\">\nwhy the clipboard APIs still require GlobalAlloc and friends<\/a>.\nWhy is there not a <code>SetClipboardDataEx<\/code>\nor something that does what <code>SetClipboardData<\/code>\ndoes but without needing to call <code>GlobalAlloc<\/code>?\n<\/p>\n<p>\nOkay, here&#8217;s your function:\n<\/p>\n<pre>\nHANDLE SetClipboardDataEx(UINT uFormat, void *pvData, DWORD cbData)\n{\n    if (uFormat == CF_BITMAP ||\n        uFormat == CF_DSPBITMAP ||\n        uFormat == CF_PALETTE ||\n        uFormat == CF_METAFILEPICT ||\n        uFormat == CF_DSPMETAFILEPICT ||\n        uFormat == CF_ENHMETAFILE ||\n        uFormat == CF_DSPENHMETAFILE ||\n        uFormat == CF_OWNERDISPLAY) {\n        return NULL; \/\/ these are not HGLOBAL format\n    }\n    HANDLE hRc = NULL;\n    HGLOBAL hglob = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT,\n                                cbData);\n    if (hglob) {\n        void *pvGlob = GlobalLock(hglob);\n        if (pvGlob) {\n            CopyMemory(pvGlob, pvData, cbData);\n            GlobalUnlock(hglob);\n            hRc = SetClipboardData(uFormat, hglob);\n        }\n        if (!hRc) {\n            GlobalFree(hglob);\n        }\n    }\n    return hRc;\n}\n<\/pre>\n<p>\nWhoop-dee-doo.\n<\/p>\n<p>\nHistorically,\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2010\/01\/21\/9951193.aspx\">\nWindows doesn&#8217;t go out of its way to include functions like this\nbecause you can easily write them yourself<\/a>,\nor you can at least find a framework library\nthat did it for you.\nWindows focused on doing the things that only Windows could do,\nproviding you the building blocks with which you can create\nyour own programs.\n<\/p>\n<p>\nBesides, the classic clipboard is so old-school.\nThe OLE clipboard provides a much richer interface,\nwhere you can\ngenerate data dynamically<\/a>\n(for example\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2008\/03\/19\/8080215.aspx\">\nas a stream<\/a>)\nand expose it in formats other than just a chunk of bytes.\nSince <code>SetClipboardData<\/code> is old-school,\nif the window manager folks had written a function like\n<code>SetClipboardDataEx<\/code>,\npeople would instead have asked the not unreasonable question,\n&#8220;Why did you bother to write a function that provides no essential new\nfunctionality to an old interface that was supplanted over a decade ago?&#8221;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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&#8217;s your function: HANDLE SetClipboardDataEx(UINT uFormat, void *pvData, DWORD cbData) { if (uFormat == CF_BITMAP || uFormat == CF_DSPBITMAP || uFormat == CF_PALETTE [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-15183","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>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&#8217;s your function: HANDLE SetClipboardDataEx(UINT uFormat, void *pvData, DWORD cbData) { if (uFormat == CF_BITMAP || uFormat == CF_DSPBITMAP || uFormat == CF_PALETTE [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/15183","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=15183"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/15183\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=15183"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=15183"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=15183"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}