[Closed] UIAccessor- skinops.loadEnvelope
Can’t quite figure out how to get this to work. I already have a script that pushes the ‘Match by Name’ and ‘OK’ buttons on the skinops.loadEnvelope dialog:
fn confirmLoadEnvelopes removeIncomingPrefix:false removeCurrentPrefix:false =
(
--local BM_SETCHECK = 241
local hwnd = dialogMonitorOps.getWindowHandle()
if (uiAccessor.getWindowText hwnd == "Load Envelopes") then
(
--controls = windows.getChildrenHWND hwnd
--print controls
--UIAccessor.SendMessage 4657876P BM_SETCHECK 1 1 --(if removeIncomingPrefix then 1 else 0) 0 -- 0 0 == unchecked
--UIAccessor.SendMessage 3740438P BM_SETCHECK 1 1 --(if removeIncomingPrefix then 1 else 0) 0 -- 0 0 == unchecked
--if removeIncomingPrefix then UIAccessor.PressButton 1248992
--if removeCurrentPrefix then UIAccessor.PressButton 1380070
UIAccessor.PressButtonByName hwnd "Match by Name"
forceCompleteRedraw()
UIAccessor.PressButtonByName hwnd "OK"
)
true
),
fn confTT = (confirmLoadEnvelopes removeIncomingPrefix:true removeCurrentPrefix:true),
fn confTF = (confirmLoadEnvelopes removeIncomingPrefix:true removeCurrentPrefix:false),
fn confFT = (confirmLoadEnvelopes removeIncomingPrefix:false removeCurrentPrefix:true),
fn confFF = (confirmLoadEnvelopes removeIncomingPrefix:false removeCurrentPrefix:false),
fn loadEnvelope theSkin envFile removeIncomingPrefix:false removeCurrentPrefix:false =
(
--determine which confirmLoadEnvelopes to use
local confirmFn = case of
(
(removeIncomingPrefix and removeCurrentPrefix):confTT
(removeIncomingPrefix and not removeCurrentPrefix):confTF
(not removeIncomingPrefix and removeCurrentPrefix):confFT
(not removeIncomingPrefix and not removeCurrentPrefix):confFF
)
DialogMonitorOps.Enabled = true --DialogMonitorOps.Enabled = false
DialogMonitorOps.RegisterNotification confirmFn id:#pressSkinOK
skinOps.LoadEnvelope theSkin envFile
DialogMonitorOps.unRegisterNotification id:#pressSkinOK
DialogMonitorOps.Enabled = false
ok
),
I want to add in the ability to check the “Remove Incoming Prefix” and “Remove Current Prefix” checkboxes. I tried to do this based on some of Zeboxx’s code, but cannot get it to work, can anyone give me some help (and an explanation)? Could use it ASAP. Thanks.
the big bit you’re missing is the checkbutton (un)checking function – good idea to store it somewhere
-- toggle an UI checkbox's checked state via UI messages/notifications
-- usage:
-- hwnd -- HWND of the control
-- state -- checked state. 1 = check, 0 = uncheck
-- result:
-- value: OK
-- effect: should check/uncheck the checkbox and have its change effected
fn setUICheckboxState hwnd state = (
local BN_CLICKED = 0 -- clicky message ID
local BM_SETCHECK = 241 -- checkbutton toggle message ID
local WM_COMMAND = 273 -- windows command message
local parent = UIAccessor.getParentWindow hwnd
local id = UIAccessor.getWindowResourceID hwnd
windows.sendMessage hwnd BM_SETCHECK state 0
windows.sendMessage parent WM_COMMAND ((bit.shift BN_CLICKED 16) + id) hwnd
OK
)
After that, it’s a fairly simple matter to get the checkboxes…
After you have identified the correct dialog (hwnd == “title you need”), add this code for testing…
local children = windows.getchildrenhwnd hwnd
print children
In your case, that should give some results such as these:
#(10948078P, 13438340P, 13438340P, "Button", "OK")
#(9637278P, 13438340P, 13438340P, "Button", "Cancel")
...
#(9506296P, 13438340P, 13438340P, "Button", "Remove Incoming Prefix")
#(8916402P, 13438340P, 13438340P, "Button", "Remove Current Prefix")
#(9833856P, 13438340P, 13438340P, "Button", "Load Vertex Data")
These are the children (UI controls, in this case) details of the dialog in an array.
The first element in each child is the hwnd of the control, the 2nd and 3rd you may ignore here, the 4th is the type – can also ignore it – and the 5th is the title.
So now you can replace the previous testing code with something like:
local children = windows.getchildrenhwnd hwnd
for child in children do (
if (child[5] == "Remove Incoming Prefix") then (
setUICheckboxState child[1] 1
)
else if (child[5] == "Remove Current Prefix") then (
setUICheckboxState child[1] 1
)
)
And you’re all set.
Note that I could’ve used an OR above, but logic-wise it’s better to keep them separate as they are, essentially, who separate operations.
Edit: similarly, the checkbox (un)checking function could use true/false – would probably be nicer, but I prefer keeping it 1/0 myself so that it’s absolutely clear I’m mucking with windows UI messages code.
After that, just press the OK button and you should be all done.
If you want an explanation of what setUICheckboxState does, have a search in these forums… it’s pretty technical
fn setUICheckboxState hwnd state =
(
/****************************************************************************
<DOC> toggle an UI checkbox's checked state via UI messages/notifications
Arguments:
<int> hwnd: HWND of the control
<int> state: checked state. 1 = check, 0 = uncheck
<skin modifier> curObj: The selected skin modifier (must be in modify panel)
Return:
<ok> should check/uncheck the checkbox and have its change effected
*************************************************************************/
local BN_CLICKED = 0 -- clicky message ID
local BM_SETCHECK = 241 -- checkbutton toggle message ID
local WM_COMMAND = 273 -- windows command message
local parent = UIAccessor.getParentWindow hwnd
local id = UIAccessor.getWindowResourceID hwnd
windows.sendMessage hwnd BM_SETCHECK state 0
windows.sendMessage parent WM_COMMAND ((bit.shift BN_CLICKED 16) + id) hwnd
OK
),
fn confirmLoadEnvelopes removeIncomingPrefix:0 removeCurrentPrefix:0 =
(
/*************************************************************************
<DOC> Manipulate the Load Envelopes dialog via the UI Accessor.
Arguments:
<int> removeIncomingPrefix: Corresponds to the "Remove Incoming Prefix" checkbox. 0 is false, 1 is true
<int> removeCurrentPrefix: Corresponds to the "Remove Current Prefix" checkbox. 0 is false, 1 is true
Return:
<bool> true (needed for DialogMonitorOps)
*************************************************************************/
--local BM_SETCHECK = 241
local hwnd = dialogMonitorOps.getWindowHandle()
if (uiAccessor.getWindowText hwnd == "Load Envelopes") then
(
local children = windows.getChildrenHWND hwnd
for child in children do
(
if (child[5] == "Remove Incoming Prefix") then
(
setUICheckboxState child[1] 1
)
else if (child[5] == "Remove Current Prefix") then
(
setUICheckboxState child[1] 1
)
)
UIAccessor.PressButtonByName hwnd "Match by Name"
forceCompleteRedraw()
UIAccessor.PressButtonByName hwnd "OK"
--UIAccessor.PressDefaultButton()
)
true
),
fn confTT = (confirmLoadEnvelopes removeIncomingPrefix:1 removeCurrentPrefix:1),
fn confTF = (confirmLoadEnvelopes removeIncomingPrefix:1 removeCurrentPrefix:0),
fn confFT = (confirmLoadEnvelopes removeIncomingPrefix:0 removeCurrentPrefix:1),
fn confFF = (confirmLoadEnvelopes removeIncomingPrefix:0 removeCurrentPrefix:0),
fn loadEnvelope theSkin envFile removeIncomingPrefix:false removeCurrentPrefix:false =
(
/*************************************************************************
<DOC> Load an .env file. There is no function for silently loading an .env, so this
is a UI Accessor workaround.
Arguments:
<skin modifier> theSkin: The selected skin modifier (must be in modify panel)
<string> envFile: Filename of the .env file.
Return:
<ok>
****************************************************************************/
--determine which confirmLoadEnvelopes to use
local confirmFn = case of
(
(removeIncomingPrefix and removeCurrentPrefix):confTT
(removeIncomingPrefix and not removeCurrentPrefix):confTF
(not removeIncomingPrefix and removeCurrentPrefix):confFT
(not removeIncomingPrefix and not removeCurrentPrefix):confFF
)
DialogMonitorOps.Enabled = true --DialogMonitorOps.Enabled = false
DialogMonitorOps.RegisterNotification confirmFn id:#pressSkinOK
skinOps.LoadEnvelope theSkin envFile
DialogMonitorOps.unRegisterNotification id:#pressSkinOK
DialogMonitorOps.Enabled = false
ok
),
Awesome! That’s the code for anyone who needs it. So you’d put that in a struct, and call:
<struct>.loadEnvelope <skin modifier> <envelope filename> removeIncomingPrefix:true removeCurrentPrefix:true
For anyone that wants it, there you go. Nothing like refreshing every 5 minutes saying ‘where is zeboxx, where is zeboxx’ and then getting a great answer and your code works.
Great~!:buttrock:
Meet the same problem too.
It is so ugly that in runtime you have to clicke any button.
After see the solution.
I think i can’t find the answer by myself in my life…