Pregunta

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

Aquí hay una simple aplicación Win32 GUI con un botón, pero cuando hago clic en el botón debe haber un cuadro de mensaje (22 línea) pero hay error:

Buttons.exe: Anexo: Vuelva a entrar inseguro. ¿Quizás una 'importación extranjera insegura' debería ser 'segura'?

Cómo puedo arreglarlo ?

¿Fue útil?

Solución

Como comentó Daniel Wagner, este es un error en el paquete Win32. MessageBoxW Debe importarse de manera segura, debido a los muchos efectos secundarios que tiene.

los messageBox la función es un envoltorio para el 'inseguro' importado MessageBoxW función. Cuando se importa una función de función insegura importada, Haskell supone que el hilo no llamará a ningún código de Haskell hasta que regrese. Sin embargo, si llamas MessageBoxW, Windows arrojará bastantes mensajes de ventana a la ventana que creó en la línea 30, por lo que el código Haskell se ejecutará mientras esté en una función extranjera insegura. Esta es también la razón por la cual las llamadas a messageBox trabajará Hasta que Esa ventana ha sido creada.

Una posible solución es simplemente corregir la función usted mismo. Primero, cambie

import Graphics.Win32

a

import Graphics.Win32 hiding (messageBox, c_MessageBox)

Luego, copie las definiciones de messageBox y c_MessageBox del módulo Graphics.Win32.Misc, con unsafe eliminado y/o safe adicional:

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top