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
这是带有按钮的简单 win32 gui 应用程序,但是当我单击按钮时,必须有一个消息框(22 行),但出现错误:
Buttons.exe:时间表:不安全地重新输入。也许是“外国人”
导入不安全”应该是“安全”吗?
我该如何解决它?
正如 Daniel Wagner 评论的那样,这是 Win32 软件包中的一个错误。MessageBoxW
必须安全进口,因为它有很多副作用。
The messageBox
函数是“不安全”导入的包装器MessageBoxW
功能。当一个不安全导入的函数函数被不安全导入时,Haskell 假定该线程在返回之前不会调用任何 Haskell 代码。但是,如果您致电MessageBoxW
,Windows 会向您在第 30 行创建的窗口抛出相当多的窗口消息,因此当您处于不安全的外部函数中时,Haskell 代码将会运行。这也是为什么呼吁messageBox
将工作until该窗口已创建。
一种可能的解决方法是简单地自行更正该函数。首先,改变
import Graphics.Win32
to
import Graphics.Win32 hiding (messageBox, c_MessageBox)
然后,复制以下定义messageBox
and c_MessageBox
从模块Graphics.Win32.Misc
, with unsafe
删除和/或safe
added:
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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)