Re: How to write graphics to MS Windows clipboard
- Posted by CChris <christian.cuvier at agriculture.gouv.fr> May 16, 2007
- 791 views
Andrew Katz wrote: > > Andrew Katz wrote: > > > > CChris wrote: > > > The following example code was tested and works for me, with colors and all:
include win32lib.ew -- first a simplified version of Guillermo's code constant xGetWindowDC = registerw32Function(user32,"GetWindowDC",{C_POINTER},C_POINTER) integer void global procedure bmpToClipboard(atom hBmp) -- hBmp must be a bitmap handle if not w32Func(xOpenClipboard, {NULL}) then void=message_box("Failed to open clipboard.","Error",MB_ICONERROR+MB_OK) return end if -- current thread now has exclusive access to clipboard void=w32Func(xEmptyClipboard,{}) if w32Func(xSetClipboardData,{CF_BITMAP,hBmp}) != hBmp then void=message_box("Failed to copy bitmap to clipboard.","Error",MB_ICONERROR+MB_OK) end if -- release clipboard w32Proc(xCloseClipboard,{}) end procedure global procedure captureToClipboard(integer id,integer x,integer y,integer cx,integer cy,integer client) -- id is the surce window; copy rectangle at {x,y}, cx pixel wide and cy poxel high -- if client is true, x and y are client coordinates, else absolute window coordinates atom hDC,hBmp,hWnd,hMemDC,hOldBmp -- where's the pic? hWnd=getHandle(id) if client then hDC=getDC(id) else hDC=w32Func(xGetWindowDC,{hWnd}) end if if not hDC then void=message_box("Not a valid window.","Error",MB_ICONERROR+MB_OK) return end if -- create a target compatible DC hMemDC=w32Func(xCreateCompatibleDC,{hDC}) -- create the bitmap we'll send to clipboard, with supplied dimensions. -- It will be written to using hMemDC. hBmp=w32Func(xCreateCompatibleBitmap,{hDC,cx,cy}) if not hBmp then void=message_box("Failed to create temporary bitmap.","Error",MB_ICONERROR+MB_OK) return end if -- select bitmap into tempDC hOldBmp=w32Func(xSelectObject,{hMemDC,hBmp}) -- now copy source rectangle to it void=w32Func(xBitBlt,{hMemDC,0,0,cx,cy,hDC,x,y,SrcCopy}) -- send bitmap to clipboard bmpToClipboard(hBmp) -- now we no longer own it -- clean up hOldBmp=w32Func(xSelectObject,{hMemDC,hOldBmp}) deleteObject(hOldBmp) void=w32Func(xDeleteDC,{hMemDC}) if client then releaseDC(id) else hDC=w32Func(xReleaseDC,{hWnd,hDC}) end if end procedure constant w=create(Window,"test",0,50,50,300,300,0) ,b=create(Button,"push",w,20,200,60,30,0) procedure q(integer self,integer event,sequence data) setWindowBackColor(w,Green) setPenColor(w,Red) drawRectangle(w,w32True,100,100,200,200) end procedure setHandler(w,w32HActivate,routine_id("q")) procedure p(integer self,integer event,sequence data) captureToClipboard(w,30,80,100,120,1) end procedure setHandler(b,w32HClick,routine_id("p")) WinMain(w,Normal)
Perhaps using a temporary Pixmap will cut down on raw API calls, I'll check that later. Using the currently undocumented replaceObject() procedure will help too. But at least this is a correct starting point. CChris