MaxScript 防止你的UI被循环阻塞或卡死

windows.processPostedMessages()

貌似在max2012增加了一个函数 windows.processPostedMessages() ,可以防止循环时max变得未响应

-- 你可以这样使用他
try DestroyDialog roll catch()
rollout roll "--"
(
button btn1 "0000"
on btn1 pressed do
(
for i = 1 to 500 do
(
windows.processPostedMessages() --将此函数加在此处可防止UI冻结
btn1.text = i as string
sleep 0.01
)
)
)
CreateDialog roll

DoEvents

但是要在低版本使用怎么办?你可以将windows.processPostedMessages()替换为.net的函数

-- 你可以这样使用他
try DestroyDialog roll catch()
rollout roll "--"
(
button btn1 "0000"
on btn1 pressed do
(
for i = 1 to 500 do
(
(dotnetclass"System.Windows.Forms.Application").DoEvents() --将此函数加在此处可防止UI冻结
btn1.text = i as string
sleep 0.01
)
)
)
CreateDialog roll

最佳方案

上面2种方法存在一个问题,假设你循环对100个物体进行转换多边形操作,由于此时UI是不被冻结的,你可以轻松选择场景中的物体,然后删除他们,这时候物体不存在,代码则会报告异常
SDK内提供一个更为精妙的设计,可以让你仅解冻需要更新的UI句柄,在代码执行时你将只能操作被预先添加的界面,其他界面将被冻结无法操作

-- 在实际使用时你可能需要将他封装的更好
iGlobal = (dotnetClass "Autodesk.Max.GlobalInterface").Instance
maxSDK = iGlobal.MaxSDK
messageFilter = maxSDK.WindowsMessageFilter.Create()
fn checkMessages =
(
messageFilter.RunNonBlockingMessageLoop()
not messageFilter.Aborted
)
try DestroyDialog roll catch()
rollout roll "--"
(
button btn1 "0000"
on btn1 pressed do
(
hwnd = roll.hwnd --windows.getMAXHWND()
messageFilter.AddUnfilteredWindow (dotnetObject "System.IntPtr" hwnd)
for i = 1 to 500 do
(
checkMessages()
btn1.text = i as string
sleep 0.01
)
messageFilter.ClearUnfilteredWindowList()
)
)
CreateDialog roll
posted @   trykle  阅读(853)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示