2011-09-05 8 views
5
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í está la aplicación GUI simple win32 con un botón, pero cuando hago clic en el botón tiene que haber un cuadro de mensaje (22 líneas), pero hay un error:cuadro de mensaje de error: importación extranjera insegura

botones .exe: horario: re-ingresado inseguro. ¿Quizás un 'extranjero importa inseguro' debería ser 'seguro'?

¿Cómo puedo arreglarlo?

+3

I puede' t responde cómo solucionarlo, pero parece un error. Probablemente debería quejarse al responsable de cualquier paquete que proporcione Graphics.Win32. –

Respuesta

5

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

La función messageBox es un contenedor para la función 'insegura' importada MessageBoxW. Cuando una función de función importada insegura se importa de manera insegura, Haskell supone que el hilo no llamará a ningún código Haskell hasta que vuelva. Sin embargo, si llama al 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 se encuentre en una función extranjera insegura. Esta es también la razón por la cual las llamadas a messageBox funcionarán hasta esa ventana ha sido creada.

Una posible solución es simplemente corregir la función usted mismo. En primer lugar, cambiar

import Graphics.Win32 

a

import Graphics.Win32 hiding (messageBox, c_MessageBox) 

A continuación, copie las definiciones de messageBox y c_MessageBox desde el módulo Graphics.Win32.Misc, con unsafe retirado y/o safe añadido:

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 
+0

¡Gran respuesta Tinctorius! Preguntas de seguimiento: – CoR

+0

1. ¿Dónde puedo encontrar Graphics.Win32.Misc en Haskell dir? Solo tengo archivos .hi en la carpeta lib. 2. Este es el último error de Yers. ¿Te preguntas por qué no se ha solucionado en el paquete de Haskel? – CoR

+1

1) Puede copiar la definición desde [aquí] (https://github.com/Tinctorius/win32/blob/5fc830d7e956ad890ec12d0ed29bcae6662625bd/Graphics/Win32/Misc.hsc#L127); esta versión ya está corregida Alternativamente, podría decir 'cabal unpack win32' en un símbolo del sistema (que creará una carpeta llamada" win32 "en su directorio actual, y descargará y descomprimirá la biblioteca win32 allí) y luego lo buscará. 2) El responsable original nunca respondió a mi correo electrónico. He enviado [una solicitud de extracción a través de Github] (https://github.com/haskell/win32/pull/5) ahora, que debería resolverse mucho más rápido :) –