module QuoteSource.DataImport ( initDataImportServer, ServerState ) where import Foreign.Marshal.Alloc import System.Win32.DLL import System.Win32.Types import Foreign import Foreign.C.Types import Foreign.C.String import QuoteSource.DDE import QuoteSource.XlParser import Data.IORef import Text.Printf import Data.Binary data ServerState = ServerState { dde :: DdeState, appName :: String } ddeCallback :: IORef ServerState -> CUInt -> CUInt -> HANDLE -> HANDLE -> HANDLE -> HANDLE -> LPDWORD -> LPDWORD -> IO HANDLE ddeCallback state msgType format hConv hsz1 hsz2 hData dwData1 dwData2 | msgType == ddeXtypConnect = handleConnect state hsz1 hsz2 | msgType == ddeXtypPoke = handlePoke state hsz1 hData | otherwise = do putStrLn $ printf "msgtype: %08x" $ toInteger msgType return nullHANDLE where handleConnect state hsz1 hsz2 = do myAppName <- appName <$> readIORef state myDdeState <- dde <$> readIORef state maybeAppName <- queryString myDdeState 256 hsz2 case maybeAppName of Just incomingAppName -> do putStrLn incomingAppName return $ if incomingAppName == myAppName then ddeResultTrue else ddeResultFalse Nothing -> return ddeResultFalse handlePoke state hsz1 hData = do myDdeState <- dde <$> readIORef state maybeTopic <- queryString myDdeState 256 hsz1 case maybeTopic of Nothing -> return ddeResultFalse initDataImportServer :: String -> IO (IORef ServerState) initDataImportServer applicationName = do s <- newIORef ServerState { appName = applicationName, dde = nullDdeState } d <- initializeDde applicationName "default" (ddeCallback s) modifyIORef s (\state -> state {dde = d}) putStrLn "DataImportServer initialized" return s