Re: How to write graphics to MS Windows clipboard

new topic     » goto parent     » topic index » view thread      » older message » newer message

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

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu