Question

import Graphics.Win32
import System.Win32.DLL
import Control.Exception (bracket)
import Foreign
import System.Exit
main :: IO ()
main = do
    mainInstance <- getModuleHandle Nothing
    hwnd <- createWindow_ 200 200 wndProc mainInstance
    createButton_ hwnd mainInstance
    messagePump hwnd
wndProc :: HWND -> WindowMessage -> WPARAM -> LPARAM -> IO LRESULT
wndProc hwnd wmsg wParam lParam
    | wmsg == wM_DESTROY = do
        sendMessage hwnd wM_QUIT 1 0
        return 0
    | wmsg == wM_COMMAND && wParam == 1 = do
        messageBox nullPtr "Yahoo!!" "Message box" 0 -- Error! Why? :(
        return 0
    | otherwise = defWindowProc (Just hwnd) wmsg wParam lParam
createWindow_ :: Int -> Int -> WindowClosure -> HINSTANCE -> IO HWND
createWindow_ width height wndProc mainInstance = do
    let winClass = mkClassName "ButtonExampleWindow"
    icon <- loadIcon Nothing iDI_APPLICATION
    cursor <- loadCursor Nothing iDC_ARROW
    bgBrush <- createSolidBrush (rgb 240 240 240)
    registerClass (cS_VREDRAW + cS_HREDRAW, mainInstance, Just icon, Just cursor, Just bgBrush, Nothing, winClass)
    w <- createWindow winClass "Button example" wS_OVERLAPPEDWINDOW Nothing Nothing (Just width) (Just height) Nothing Nothing mainInstance wndProc
    showWindow w sW_SHOWNORMAL
    updateWindow w
    return w
createButton_ :: HWND -> HINSTANCE -> IO ()
createButton_ hwnd mainInstance = do
    hBtn <- createButton "Press me" wS_EX_CLIENTEDGE (bS_PUSHBUTTON + wS_VISIBLE + wS_CHILD) (Just 50) (Just 80) (Just 80) (Just 20) (Just hwnd) (Just (castUINTToPtr 1)) mainInstance
    return ()
messagePump :: HWND -> IO ()
messagePump hwnd = allocaMessage $ \ msg ->
    let pump = do
        getMessage msg (Just hwnd) `catch` \ _ -> exitWith ExitSuccess
        translateMessage msg
        dispatchMessage msg
        pump
    in pump

Voici l'application IUG win32 simple avec un bouton, mais lorsque je clique sur le bouton il doit y avoir une boîte de message (22 lignes), mais il y a erreur:

buttons.exe: Horaire: re-saisie des conditions dangereuses. Peut-être un « étranger importer dangereux » devrait être « sûr »?

Comment puis-je résoudre ce problème?

Était-ce utile?

La solution

Comme Daniel Wagner a commenté, ce bogue dans le package Win32. MessageBoxW doit être importé en toute sécurité, en raison des nombreux effets secondaires dont il dispose.

La fonction messageBox est une enveloppe pour la fonction d'importation « unsafely » de MessageBoxW. Lorsqu'une fonction de fonction importée est importée dans des conditions dangereuses dans des conditions dangereuses, Haskell suppose que le fil n'appellera aucun code Haskell jusqu'à ce qu'il revienne. Cependant, si vous appelez MessageBoxW, Windows jeter un bon nombre de messages de fenêtre à la fenêtre vous avez créé à la ligne 30, de sorte que le code Haskell sera RAN pendant que vous êtes dans une fonction étrangère dangereuse. Ceci est la raison pour laquelle les appels à messageBox travailleront jusqu'à cette fenêtre a été créé.

Une solution possible est de simplement corriger la fonction vous-même. Tout d'abord, le changement

import Graphics.Win32

à

import Graphics.Win32 hiding (messageBox, c_MessageBox)

Ensuite, copier les définitions de messageBox et c_MessageBox à partir du module Graphics.Win32.Misc, avec unsafe enlevé et / ou safe ajouté:

messageBox :: HWND -> String -> String -> MBStyle -> IO MBStatus
messageBox wnd text caption style =
  withTString text $ \ c_text ->
  withTString caption $ \ c_caption ->
  failIfZero "MessageBox" $ c_MessageBox wnd c_text c_caption style
foreign import stdcall safe "windows.h MessageBoxW"
  c_MessageBox :: HWND -> LPCTSTR -> LPCTSTR -> MBStyle -> IO MBStatus
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top