{"id":37083,"date":"2004-12-09T07:00:00","date_gmt":"2004-12-09T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2004\/12\/09\/dragging-a-shell-object-part-4-adding-a-prettier-drag-icon\/"},"modified":"2004-12-09T07:00:00","modified_gmt":"2004-12-09T07:00:00","slug":"dragging-a-shell-object-part-4-adding-a-prettier-drag-icon","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20041209-00\/?p=37083","title":{"rendered":"Dragging a shell object, part 4: Adding a prettier drag icon"},"content":{"rendered":"<p><P>\nYou may have noticed that the drag feedback is rather sad-looking.\nJust a box, maybe with a plus sign or an arrow; you don&#8217;t\neven know what it is you&#8217;re dragging.\n<\/P>\n<P>\nLet&#8217;s fix that.  We&#8217;ll drag the icon of the file around.\nWe&#8217;ll need to add the drag image to the data object.\n<\/P>\n<PRE>\nvoid OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)\n{\n  IDataObject *pdto;\n  if (SUCCEEDED(<FONT COLOR=\"blue\">GetDataObjectOfFileWithCuteIcon(\n                hwnd, g_pszTarget, &amp;pdto))<\/FONT>) {\n     IDropSource *pds = new CDropSource();\n     &#8230;\n<\/PRE>\n<P>\nThis new function <CODE>GetDataObjectOfFileWithCuteIcon<\/CODE>\ncreates the data object and then attaches the cute icon to it.\n<\/P>\n<PRE>\nHRESULT GetDataObjectOfFileWithCuteIcon(HWND hwnd,\n LPCWSTR pszPath, IDataObject **ppdto)\n{\n  HRESULT hr = GetUIObjectOfFile(hwnd, pszPath,\n                    IID_IDataObject, (void**)ppdto);\n  if (SUCCEEDED(hr)) {\n    IDragSourceHelper *pdsh;\n    if (SUCCEEDED(CoCreateInstance(CLSID_DragDropHelper, NULL, CLSCTX_ALL,\n                                   IID_IDragSourceHelper, (void**)&amp;pdsh))) {\n      SHDRAGIMAGE sdi;\n      if (CreateDragImage(pszPath, &amp;sdi)) {\n        pdsh-&gt;InitializeFromBitmap(&amp;sdi, *ppdto);\n        DeleteObject(sdi.hbmpDragImage);\n      }\n      pdsh-&gt;Release();\n    }\n  }\n  return hr;\n}\n<\/PRE>\n<P>\nWe use the\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/shellcc\/platform\/shell\/programmersguide\/shell_basics\/shell_basics_programming\/transferring\/dataobject.asp\">\nshell drag\/drop helper object<\/A>\nto attach the bitmap to the data object.\nThe shell drag\/drop helper object requires that the data object\nbe able to accept arbitrary blobs, but fortunately, the standard\nshell data object does this.\n<\/P>\n<P>\nThe nasty part is generating the drag image.\nThis is not the fun part, and you&#8217;re not going to learn anything\nfrom this function.  It just has to be written.\n<\/P>\n<PRE>\nBOOL CreateDragImage(LPCWSTR pszPath, SHDRAGIMAGE *psdi)\n{\n  psdi-&gt;hbmpDragImage = NULL;\n  SHFILEINFOW sfi;\n  HIMAGELIST himl = (HIMAGELIST)\n    SHGetFileInfoW(pszPath, 0, &amp;sfi, sizeof(sfi), SHGFI_SYSICONINDEX);\n  if (himl) {\n    int cx, cy;\n    ImageList_GetIconSize(himl, &amp;cx, &amp;cy);\n    psdi-&gt;sizeDragImage.cx = cx;\n    psdi-&gt;sizeDragImage.cy = cy;\n    psdi-&gt;ptOffset.x = cx;\n    psdi-&gt;ptOffset.y = cy;\n    psdi-&gt;crColorKey = CLR_NONE;\n    HDC hdc = CreateCompatibleDC(NULL);\n    if (hdc) {\n      psdi-&gt;hbmpDragImage = CreateBitmap(cx, cy, 1, 32, NULL);\n      if (psdi-&gt;hbmpDragImage) {\n        HBITMAP hbmPrev = SelectBitmap(hdc, psdi-&gt;hbmpDragImage);\n        ImageList_Draw(himl, sfi.iIcon, hdc, 0, 0, ILD_NORMAL);\n        SelectBitmap(hdc, hbmPrev);\n      }\n      DeleteDC(hdc);\n    }\n  }\n  return psdi-&gt;hbmpDragImage != NULL;\n}\n<\/PRE>\n<P>\nTo create the drag image, we ask\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/shellcc\/platform\/shell\/reference\/functions\/shgetfileinfo.asp\">\nthe <CODE>SHGetFileInfo<\/CODE> function<\/A>\nto give us the imagelist handle and icon index\nfor the icon that represents the file.\nThe icon size in the imagelist goes into\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/shellcc\/platform\/shell\/reference\/structures\/shdragimage.asp\">\nthe <CODE>SHDRAGIMAGE<\/CODE> structure<\/A>\nas the bitmap dimensions and as the cursor point.\n(We put the cursor at the bottom right corner of the image.)\nSince we are creating an alpha-blended bitmap, we don&#8217;t need\na color-key.\nFinally, we create a memory DC to house an ARGB bitmap into which\nwe draw the icon.\n<\/P>\n<P>\nIf you run this program, you should see the icon for a text file\nbeing dragged around as you drag your throwaway file around\nthe screen.\n<\/P>\n<P>\nNext time, a way to make somebody else do the heavy lifting for you.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>You may have noticed that the drag feedback is rather sad-looking. Just a box, maybe with a plus sign or an arrow; you don&#8217;t even know what it is you&#8217;re dragging. Let&#8217;s fix that. We&#8217;ll drag the icon of the file around. We&#8217;ll need to add the drag image to the data object. void OnLButtonDown(HWND [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-37083","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>You may have noticed that the drag feedback is rather sad-looking. Just a box, maybe with a plus sign or an arrow; you don&#8217;t even know what it is you&#8217;re dragging. Let&#8217;s fix that. We&#8217;ll drag the icon of the file around. We&#8217;ll need to add the drag image to the data object. void OnLButtonDown(HWND [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/37083","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=37083"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/37083\/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=37083"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=37083"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=37083"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}