Frage

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

Hier ist eine einfache Win32 -GUI -Anwendung mit einer Schaltfläche, aber wenn ich auf die Schaltfläche klicke, muss ein Meldungsfeld (22 Zeile) vorhanden sein, aber es gibt Fehler:

buttons.exe: Zeitplan: Unsicher wiederhergestellt. Vielleicht sollte ein "ausländischer Import Unsicheres" "sicher" sein?

Wie kann ich es reparieren ?

War es hilfreich?

Lösung

Wie Daniel Wagner kommentierte, ist dies ein Fehler im Win32 -Paket. MessageBoxW Muss sicher importiert werden, aufgrund der vielen Nebenwirkungen, die es hat.

Das messageBox Funktion ist ein Wrapper für den importierten "Unsicher" MessageBoxW Funktion. Wenn eine unsicher importierte Funktionsfunktion unsicher importiert wird, geht Haskell davon aus, dass der Thread keinen Haskell -Code aufruft, wenn er zurückgibt. Wenn Sie jedoch anrufen MessageBoxW, Windows werfen einige Fenstermeldungen in das in Zeile 30 erstellte Fenster. Dies ist auch der Grund, warum Anrufe zu messageBox wird funktionieren bis um Dieses Fenster wurde erstellt.

Eine mögliche Problemumgehung besteht darin, die Funktion selbst einfach zu korrigieren. Erstens ändern sich

import Graphics.Win32

zu

import Graphics.Win32 hiding (messageBox, c_MessageBox)

Kopieren Sie dann die Definitionen von messageBox und c_MessageBox Aus dem Modul Graphics.Win32.Misc, mit unsafe entfernt und/oder safe hinzugefügt:

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top