I had a go at exercise 10.4 "Write a program to drag and drop pictures...". The program seemed to work - I could drag and drop although the results weren't particularly elegant but after dragging a picture for about 10 seconds I got User error: Error raised in function CreateEllipticRgn Trying to run the program again gave the same error immediately. Hugs was unable to point me at where the problem was occurring. Picture> :i CreateEllipticRgn Unknown reference `CreateEllipticRgn' Picture> :f CreateEllipticRgn ERROR: No current definition for name "CreateEllipticRgn" Does anyone have any ideas what's happening? I've attached the offending module below. I can supply Draw and Region if required. Dominic. ================================================================================================== module Picture (Picture (Region, Over, EmptyPic), Color (Black, Blue, Green, Cyan, Red, Magenta, Yellow, White), regionToGRegion, shapeToGRegion, drawRegionInWindow, drawPic, draw, spaceClose, module Region ) where import Draw import Region import SOEGraphics hiding (Region) import qualified SOEGraphics as G (Region) data Picture = Region Color Region | Picture `Over` Picture | EmptyPic deriving Show type Vector = (Float,Float) xWin2 = xWin `div` 2 yWin2 = yWin `div` 2 drawPic :: Window -> Picture -> IO () drawPic w (Region c r) = drawRegionInWindow w c r drawPic w (p1 `Over` p2) = do drawPic w p2; drawPic w p1 drawPic w EmptyPic = return () drawRegionInWindow :: Window -> Color -> Region -> IO () drawRegionInWindow w c r = drawInWindow w (withColor c (drawRegion (regionToGRegion r))) regionToGRegion :: Region -> G.Region regionToGRegion r = regToGReg (0,0) (1,1) r regToGReg :: Vector -> Vector -> Region -> G.Region regToGReg loc sca Empty = createRectangle (0,0) (0,0) regToGReg loc sca (Shape s) = shapeToGRegion loc sca s regToGReg loc (sx,sy) (Scale (u,v) r) = regToGReg loc (sx*u,sy*v) r regToGReg (lx,ly) (sx,sy) (Translate (u,v) r) = regToGReg (lx+sx*u,ly+v*sy) (sx,sy) r regToGReg loc sca (r1 `Union` r2) = primGReg loc sca r1 r2 orRegion regToGReg loc sca (r1 `Intersect` r2) = primGReg loc sca r1 r2 andRegion regToGReg loc sca (Complement r) = primGReg loc sca winRect r diffRegion winRect ::Region winRect = Shape (Rectangle (pixelToInch xWin) (pixelToInch yWin)) primGReg loc sca r1 r2 op = let gr1 = regToGReg loc sca r1 gr2 = regToGReg loc sca r2 in op gr1 gr2 shapeToGRegion :: Vector -> Vector -> Shape -> G.Region shapeToGRegion (lx,ly) (sx,sy) s = case s of Rectangle s1 s2 -> createRectangle (trans (-s1/2,-s2/2)) (trans (s1/2,s2/2)) Ellipse r1 r2 -> createEllipse (trans (-r1,-r2)) (trans (r1,r2)) Polygon vs -> createPolygon (map trans vs) RtTriangle s1 s2 -> createPolygon (map trans [(0,0),(s1,0),(0,s2)]) where trans :: Vertex -> Point trans (x,y) = (xWin2+inchToPixel(lx+x*sx), yWin2-inchToPixel(ly+y*sy)) draw :: String -> Picture -> IO () draw s p = runGraphics $ do w <- openWindow s (xWin,yWin) drawPic w p spaceClose w picToList :: Picture -> [(Color,Region)] picToList EmptyPic = [] picToList (Region c r) = [(c,r)] picToList (p1 `Over` p2) = picToList p1 ++ picToList p2 adjust :: [(Color,Region)] -> Coordinate -> (Maybe (Color,Region),[(Color,Region)]) adjust regs p = case (break (\(_,r) -> r `containsR` p) regs) of (top,hit:rest) -> (Just hit, top++rest) (_,[]) -> (Nothing,regs) moveTop :: [(Color,Region)] -> Coordinate -> [(Color,Region)] moveTop [] p = [] moveTop ((cTop,rTop):rest) (x,y) = (cTop,Translate (x,y) rTop):rest loop :: Window -> [(Color,Region)] -> IO () loop w regs = do clearWindow w sequence_ [drawRegionInWindow w c r | (c,r) <- reverse regs] (x,y) <- getLBP w let c = (pixelToInch (x-xWin2),pixelToInch (yWin2-y)) in case (adjust regs c) of (Nothing,_) -> closeWindow w (Just hit, newRegs) -> loop1 w (hit:newRegs) c loop1 :: Window -> [(Color,Region)] -> Coordinate -> IO () loop1 w regs (x,y)= do e <- getWindowEvent w case e of MouseMove{pt = (x',y')} -> do clearWindow w sequence_ [drawRegionInWindow w c r | (c,r) <- reverse newRegs] loop1 w newRegs (pixelToInch (x'-xWin2),pixelToInch (yWin2-y')) where newRegs = moveTop regs ((pixelToInch (x'-xWin2))-x, (pixelToInch (yWin2-y'))-y) Button{pt=p,isLeft=l,isDown=d} | l == True && d == False -> loop w regs _ -> loop1 w regs (x,y) draw2 :: String -> Picture -> IO () draw2 s p = runGraphics $ do w <- openWindow s (xWin,yWin) loop w (picToList p) r1 = Shape (Rectangle 3 2) r2 = Shape (Ellipse 1 1.5) reg1 = r1 `Intersect` Complement r2 pic1 = Region Blue r1 pic2 = Region Red r2 pic3 = Region Yellow (Translate (1,1) reg1) pic4 = pic1 `Over` pic2 `Over` pic3 main = draw2 "" pic4 ------------------------------------------------------------------------------------------------- 21st century air travel http://www.britishairways.com