Re: How to write graphics to MS Windows clipboard
- Posted by CChris <christian.cuvier at agriculture.gouv.fr> May 16, 2007
- 748 views
Andrew Katz wrote: > > Andrew Katz wrote: > > > > CChris wrote: > > > > > > > > I assume your graphics are displayed on some window. > > > A way nicer version using a Pixmap:
include win32lib.ew 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 w32Proc(xCloseClipboard,{}) end procedure global procedure captureToClipboard(integer id,integer x,integer y,integer cx,integer cy) -- id is the source window; copy rectangle at {x,y}, cx pixel wide and cy poxel high integer tmpx -- create a temporary area for the bitmap tmpx=create(Pixmap,"",0,0,0,cx,cy,0) -- copy pic bitBlt(tmpx,0,0,id,x,y,cx,cy,SrcCopy) -- send bitmap to clipboard bmpToClipboard(getHandle(tmpx)) -- clean up destroy(tmpx) end procedure constant xGetWindowDC = registerw32Function(user32,"GetWindowDC",{C_POINTER},C_POINTER) global procedure captureToClipboardEx(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,hWnd integer tmpx -- 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 tmpx=create(Pixmap,"",0,0,0,cx,cy,0) -- create a target compatible DC void=w32Func(xBitBlt,{getDC(tmpx),0,0,cx,cy,hDC,x,y,SrcCopy}) -- send bitmap to clipboard bmpToClipboard(getHandle(tmpx)) -- now we no longer own it -- clean up destroy(tmpx) 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) end procedure setHandler(b,w32HClick,routine_id("p")) WinMain(w,Normal)
Both routine work and the clipboard holds he expected value. I'll have to add support for full window DCs in the library so that the distinction wbetween the non -Ex and -Ex routines is no longer necessary. Also, I had noticed earlier, and forgotten, that if you call registerw32function() on some dll routine, then define_c_func() returns -1 if invoked on the same routine thereafter. I'll have to investigate. Derek, any idea? CChris