packages feed

reactivity-0.3.0.0: src/Graphics/Subclass.hs

module Graphics.Subclass (subclassProc) where

import Unsafe.Coerce
import Data.IORef
import Foreign.Ptr
import Control.Monad
import Graphics.Win32
import Graphics.Win32Extras

-- | This function subclasses a window and takes care of freeing
-- the function pointer when the window closes. The parameter function
-- is passed a function that invokes the default behaviour of the
-- window.
subclassProc :: HWND -> (WindowClosure -> WindowClosure) -> IO ()
subclassProc wnd proc = do
	procVar <- newIORef Nothing
	let closure wnd msg wParam lParam = do
		may <- readIORef procVar
		case may of
			Just (funPtr, oldProc) -> do
				when (msg == wM_NCDESTROY) $ do
					c_SetWindowLongPtr wnd gWLP_WNDPROC oldProc
					freeHaskellFunPtr funPtr
				proc (callWindowProc (unsafeCoerce oldProc)) wnd msg wParam lParam
			Nothing -> proc (\_ _ _ _ -> return 0) wnd msg wParam lParam
	funPtr <- mkWindowClosure closure
	oldProc <- c_SetWindowLongPtr wnd gWLP_WNDPROC (unsafeCoerce funPtr)
	writeIORef procVar (Just (funPtr, oldProc))