[Closed] How to perform LMB click with maxscript?
Hi!
I’m trying to perform a click with the left mouse button, using maxscript, but with no success for now. The task is to select the object under the mouse. Here is the code that I have(it includes some code of denisT and other guys that I found on the net):
(
function SetMousePos x y =
(
(dotnetClass "Cursor").Position = dotnetObject "System.Drawing.Point" x y
)
function MakeParam LoWord HiWord =
(
bit.or (bit.shift HiWord 16) (bit.and LoWord 0xFFFF)
)
function LeftMouseButtonClick x y =
(
WM_LBUTTONDOWN = 0x0201
WM_LBUTTONUP = 0x0202
MK_LBUTTON = 0x0001
stopLoop = false
hwnd = undefined
for w in (windows.getChildrenHWND #max) where w[4] == "ViewPanel" while stopLoop == false do
(
hwnd = w[1]
stopLoop = true
)
hwnd = (windows.getChildrenHWND hwnd)[1][1]
p0 = MakeParam x y
uiaccessor.sendmessage hwnd WM_LBUTTONDOWN MK_LBUTTON p0
uiaccessor.sendmessage hwnd WM_LBUTTONUP 0 p0
-- windows.sendmessage hwnd WM_LBUTTONDOWN MK_LBUTTON 0
-- windows.sendmessage hwnd WM_LBUTTONUP 0 0
)
--
rectShape = convertToSplineShape (Rectangle())
--
vptDiff = mouse.screenpos - mouse.pos
gw.setTransform (matrix3 1)
vertScreenPos = gw.wtransPoint (getKnotPoint rectShape 1 1)
--
posToSetX1 = vptDiff[1] + vertScreenPos[1]
posToSetY1 = vptDiff[2] + vertScreenPos[2]
--
SetMousePos posToSetX1 posToSetY1
--
LeftMouseButtonClick posToSetX1 posToSetY1
)
The script creates a recganel, converts it to an edhtable spline object, then moves the cursor over the first knot. But the LeftMouseButtonClick fn not works as I want.
Like this:
(
function SetMousePos x y =
(
(dotnetClass "Cursor").Position = dotnetObject "System.Drawing.Point" x y
)
fn makeParam LoWord HiWord =
(
bit.or (bit.shift HiWord 16) (bit.and LoWord 0xFFFF)
)
function LeftMouseButtonClick x y =
(
WM_LBUTTONDOWN = 0x0201
WM_LBUTTONUP = 0x0202
MK_LBUTTON = 0x0001
stopLoop = false
hwnd = undefined
for w in (windows.getChildrenHWND #max) where w[4] == "ViewPanel" while stopLoop == false do
(
hwnd = w[1]
stopLoop = true
)
hwnd = (windows.getChildrenHWND hwnd)[1][1]
p0 = makeParam x y
windows.postmessage hwnd WM_LBUTTONDOWN MK_LBUTTON p0
windows.postmessage hwnd WM_LBUTTONUP 0 p0
-- windows.sendmessage hwnd WM_LBUTTONDOWN MK_LBUTTON 0
-- windows.sendmessage hwnd WM_LBUTTONUP 0 0
)
rectShape = convertToSplineShape (Rectangle())
--
vptDiff = mouse.screenpos - mouse.pos
gw.setTransform (matrix3 1)
vertScreenPos = gw.wtransPoint (getKnotPoint rectShape 1 1)
--
posToSetX1 = vptDiff[1] + vertScreenPos[1]
posToSetY1 = vptDiff[2] + vertScreenPos[2]
--
SetMousePos posToSetX1 posToSetY1
--
LeftMouseButtonClick posToSetX1 posToSetY1
)
Still not working.
you was picking from wrong place. here is how it should be:
(
fn makeParam LoWord HiWord =
(
bit.or (bit.shift HiWord 16) (bit.and LoWord 0xFFFF)
)
fn LeftMouseButtonClick pos =
(
WM_LBUTTONDOWN = 0x0201
WM_LBUTTONUP = 0x0202
viewHWND = for w in (windows.getChildrenHWND #max) where w[4] == "ViewPanel" do exit with (windows.getChildrenHWND w[1])[1][1]
pp = makeParam (pos.x as integer) (pos.y as integer)
windows.postmessage viewHWND WM_LBUTTONDOWN 0 pp
windows.postmessage viewHWND WM_LBUTTONUP 0 pp
)
delete objects
gc()
sp = convertToSplineShape (circle())
gw.setTransform (matrix3 1)
pos = gw.TransPoint (getKnotPoint sp 1 1)
-- SetMousePos posToSetX1 posToSetY1
LeftMouseButtonClick pos
)
no reason to move mouse, no reason to pass mouse button id (message tells everything)
Thank you.
I’ve read your code and the LeftMouseClickButton fn is the same as mine(shorter). My hwnd have the same value as your viewHWND, but your function works and mine not.
Then I found that the knot position that I pass to the function is not the world knot position, but shifted. You pass the world knot position and everything works. If I pass the world knot position , like you, my code also work – with the postMessgave as you suggested. Last few days I’ve tested with the world knot position, but not with the postMessage.
(
function SetMousePos x y =
(
(dotnetClass "Cursor").Position = dotnetObject "System.Drawing.Point" x y
)
function MakeParam LoWord HiWord =
(
bit.or (bit.shift HiWord 16) (bit.and LoWord 0xFFFF)
)
function LeftMouseButtonClick x y =
(
WM_LBUTTONDOWN = 0x0201
WM_LBUTTONUP = 0x0202
MK_LBUTTON = 0x0001
stopLoop = false
hwnd = undefined
for w in (windows.getChildrenHWND #max) where w[4] == "ViewPanel" while stopLoop == false do
(
hwnd = w[1]
stopLoop = true
)
hwnd = (windows.getChildrenHWND hwnd)[1][1]
p0 = makeParam x y
windows.postmessage hwnd WM_LBUTTONDOWN 0 p0
windows.postmessage hwnd WM_LBUTTONUP 0 p0
-- windows.sendmessage hwnd WM_LBUTTONDOWN MK_LBUTTON 0
-- windows.sendmessage hwnd WM_LBUTTONUP 0 0
)
rectShape = convertToSplineShape (Rectangle())
--
vptDiff = mouse.screenpos - mouse.pos
gw.setTransform (matrix3 1)
vertScreenPos = gw.transPoint (getKnotPoint rectShape 1 1)
--
posToSetX1 = /* vptDiff[1] + */ vertScreenPos[1]
posToSetY1 = /* vptDiff[2] + */ vertScreenPos[2]
--
SetMousePos posToSetX1 posToSetY1
--
LeftMouseButtonClick posToSetX1 posToSetY1
)
Thank you again.
Hi miauu, I’ve tried this with your function (and DenisTs’) and it’s not selecting the object on the first run of the function. Any idea why?
with redraw on LeftMouseButtonClick posToSetX1 posToSetY1
I just tested it. In Prespective viewprot the fn works with no problems. In orthographic viewports the fn works a bit strange. When the ortho viewport is maximized the fn works properly. if the viewport(top, bottom, left, right, front, back) is not maximized – for some vpts the fn works, for other – not.
Create new scene, create only one shape object and use this:
(
function SetMousePos x y =
(
(dotnetClass "Cursor").Position = dotnetObject "System.Drawing.Point" x y
)
function MakeParam LoWord HiWord =
(
bit.or (bit.shift HiWord 16) (bit.and LoWord 0xFFFF)
)
function LeftMouseButtonClick x y =
(
WM_LBUTTONDOWN = 0x0201
WM_LBUTTONUP = 0x0202
MK_LBUTTON = 0x0001
stopLoop = false
hwnd = undefined
for w in (windows.getChildrenHWND #max) where w[4] == "ViewPanel" while stopLoop == false do
(
hwnd = w[1]
stopLoop = true
)
hwnd = (windows.getChildrenHWND hwnd)[1][1]
p0 = makeParam x y
windows.postmessage hwnd WM_LBUTTONDOWN 0 p0
windows.postmessage hwnd WM_LBUTTONUP 0 p0
-- windows.sendmessage hwnd WM_LBUTTONDOWN MK_LBUTTON 0
-- windows.sendmessage hwnd WM_LBUTTONUP 0 0
)
-- rectShape = convertToSplineShape (Rectangle())
rectShape = objects[1]
--
vptDiff = mouse.screenpos - mouse.pos
gw.setTransform (matrix3 1)
vertScreenPos = gw.transPoint (getKnotPoint rectShape 1 1)
--
posToSetX1 = /* vptDiff[1] + */ vertScreenPos[1]
posToSetY1 = /* vptDiff[2] + */ vertScreenPos[2]
--
SetMousePos posToSetX1 posToSetY1
--
LeftMouseButtonClick posToSetX1 posToSetY1
)
That code was missing the convertToSplineShape bit so it errored out.
It seems to work now as expected when I created a fresh scene but it wasn’t earlier. I’ve tweaked the original code a bit to cater for more mouse clicks.
-- Original thread: https://forums.cgsociety.org/t/how-to-perform-lmb-click-with-maxscript/1745770/4?u=treedwannab
-- MS mouse help: https://docs.microsoft.com/en-us/windows/win32/inputdev/mouse-input
(
fn makeParam LoWord HiWord = (
bit.or (bit.shift HiWord 16) (bit.and LoWord 0xFFFF)
)
-- mouseButtonClick function - Default is a single left click.
fn mouseButtonClick pos mouseAction:#WM_LBUTTON = (
case of (
( mouseAction == #WM_LBUTTON ): ( mouseMsg = [0x0201,0x0202] )
( mouseAction == #WM_MBUTTON ): ( mouseMsg = [0x0207,0x0208] )
( mouseAction == #WM_RBUTTON ): ( mouseMsg = [0x0204,0x0205] )
( mouseAction == #WM_XBUTTON ): ( mouseMsg = [0x020B,0x020C] )
( mouseAction == #WM_LBUTTONDBLCLK ): ( mouseMsg = [0x0203,0] )
( mouseAction == #WM_MBUTTONDBLCLK ): ( mouseMsg = [0x0209,0] )
( mouseAction == #WM_RBUTTONDBLCLK ): ( mouseMsg = [0x0206,0] )
( mouseAction == #WM_XBUTTONDBLCLK ): ( mouseMsg = [0x020D,0] )
( default ): ( mouseMsg = [0x0201,0x0202] )
)
viewHWND = for w in (windows.getChildrenHWND #max) where w[4] == "ViewPanel" do exit with (windows.getChildrenHWND w[1])[1][1]
pp = makeParam (pos.x as integer) (pos.y as integer)
if mouseMsg.x > 0 do windows.postmessage viewHWND mouseMsg.x 0 pp
if mouseMsg.y > 0 do windows.postmessage viewHWND mouseMsg.y 0 pp
)
gc()
rectShape = convertToSplineShape (Rectangle())
vptDiff = mouse.screenpos - mouse.pos
gw.setTransform (matrix3 1)
vertScreenPos = gw.transPoint (getKnotPoint rectShape 1 1)
posToSetX1 = /* vptDiff[1] + */ vertScreenPos[1]
posToSetY1 = /* vptDiff[2] + */ vertScreenPos[2]
SetMousePos = [posToSetX1,posToSetY1]
with redraw on mouseButtonClick SetMousePos mouseAction:#WM_LBUTTON
)