Get Max Window position using dotNet


#1

I’m trying to find a way to get the location of a max window (ie Layers Manager) using dotNet. I can’t seem to find anything talking about it online.

I did find a function “getWindowsRect()” but can’t seem to implement it into Max.

I think there might be a way to do it using the C# compiler in dotNet but have no idea how to do this.

If anyone can shed some light on this I would appreciate it.

Thanks


#2

I wrote a little something to do this a while back - It uses dotnet to call the API function you mentioned, albeit in a VB environment.

http://lonerobot.net/?p=710

The script featured at the top is downloadable at the bottom of the post. :slight_smile:


#3

Hey thanks for the reply.

I am very new to DotNet and know nothing of VB so could you maybe be a little more specific. I tried your tool and it does exactly what I need it to do.

I just need to get at the position values of each window open in max. I tried ciphering through your code but I don’t understand VB. The command I mentioned before (GetWindowRect) was there but I just couldn’t follow it.

Sorry if I’m asking too much, I have just been wrestling with this for a couple days now.

Thanks Again

Steve


#4

try the maxscript command: [b]getMAXWindowPos/b with that you can get the position of the max main window.


#5

Hi Steve,

Sorry i didnt see you reply until now.

I didnt mean to confuse you refering to VB, i use the vb compiler to register a dotnetclass that can be used within max. If you call

DialogWindowOpsClass()

you’ll notice that it returns a dotnetobject. This has a few methods that you can use in maxscript to get the window information you need. The function just compiles it directly via mxs and dotnet, rather than doing it in visual studio and providing the assembly dll.

this function is the core of the window box script. you then need to get the handle of the layer manager window. I got this by testing if the window name starts with “Layer”, seems good enough to me. I’ve put a couple of other methods at the bottom that you can use with this class too.

	 fn DialogWindowOpsClass = 
  	(
  	source = ""
  	source += "Imports System.Runtime.InteropServices
"
  	source += "Imports System.Drawing
"
  	source += "Public Class DialogWindowOps
"
  	source += "Public Structure RECT
"
  	source += "Public left As Integer
"
  	source += "Public top As Integer
"
  	source += "Public right As Integer
"
  	source += "Public bottom As Integer
"
  	source += "Public ReadOnly Property Width() As Integer
"
  	source += "Get
"
  	source += "Return right - left
"
  	source += "End Get
"
  	source += "End Property
"
  	source += "Public ReadOnly Property Height() As Integer
"
  	source += "Get
"
  	source += "Return bottom - top
"
  	source += "End Get
"
  	source += "End Property
"
  	source += "End Structure
"
  	source += "Public Structure POINTAPI
"
  	source += "Public x As Integer
"
  	source += "Public y As Integer
"
  	source += "End Structure
"
  	source += "Public Structure WINDOWPLACEMENT
"
  	source += "Public Length As Integer
"
  	source += "Public flags As Integer
"
  	source += "Public showCmd As Integer
"
  	source += "Public ptMinPosition As POINTAPI
"
  	source += "Public ptMaxPosition As POINTAPI
"
  	source += "Public rcNormalPosition As RECT
"
  	source += "End Structure
"
  	source += "<DllImport(\"user32.dll\")> _
"
  	source += "Public Shared Function MoveWindow(ByVal hWnd As System.IntPtr, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal bRepaint As Boolean) As Boolean
"
  	source += "End Function
"
  	source += "<DllImport(\"user32.dll\")> _
"
  	source += "Public Shared Function GetWindowRect(ByVal hWnd As System.IntPtr, ByRef lpRect As RECT) As Boolean
"
  	source += "End Function
"
  	source += "<DllImport(\"user32.dll\")> _
"
  	source += "Public Shared Function GetWindowPlacement(ByVal hWnd As System.IntPtr, ByRef lpwndpl As WINDOWPLACEMENT) As Boolean
"
  	source += "End Function
"
  	source += "Public Function WindowSize(ByVal Hwnd As System.IntPtr) As System.Drawing.Size
"
  	source += "Dim LPRECT As RECT
"
  	source += "GetWindowRect(Hwnd, LPRECT)
"
  	source += "Dim WinSize As System.drawing.size = New System.drawing.size(LPRECT.Width, LPRECT.Height)
"
  	source += "Return WinSize
"
  	source += "End Function
"
  	source += "Public Function WindowPosition(ByVal Hwnd As System.IntPtr) As System.Drawing.Point
"
  	source += "Dim intRet As Integer
"
  	source += "Dim wpTemp As WINDOWPLACEMENT = New WINDOWPLACEMENT()
"
  	source += "wpTemp.Length = System.Runtime.InteropServices.Marshal.SizeOf(wpTemp)
"
  	source += "intRet = GetWindowPlacement(Hwnd, wpTemp)
"
  	source += "Dim WinPoint As System.drawing.point = New System.drawing.point(wpTemp.rcNormalPosition.left, wpTemp.rcNormalPosition.top)
"
  	source += "Return WinPoint
"
  	source += "End Function
"
  	source += "End Class"  
  
  	VBProvider = dotnetobject "Microsoft.VisualBasic.VBCodeProvider"
  	compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
  	compilerParams.ReferencedAssemblies.add "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.drawing.dll"	
  	compilerParams.GenerateInMemory = on
  	compilerResults = VBProvider.CompileAssemblyFromSource compilerParams #(source)
  
  		
  		-- this is very useful to debug your source code and check for referencing errors
  		if (compilerResults.Errors.Count > 0 ) then
  		 (
  			 errs = stringstream ""
  			 for i = 0 to (compilerResults.Errors.Count-1) do
  			 (
  				 err = compilerResults.Errors.Item[i]
  				 format "Error:% Line:% Column:% %
" err.ErrorNumber err.Line \											  
  													  err.Column err.ErrorText to:errs 
  			 )
  			 MessageBox (errs as string) title: "Errors encountered while compiling VB code"
  			 return undefined
  		 ) 	
  	return compilerResults.CompiledAssembly.CreateInstance "DialogWindowOps"
  	)
  	
  	
  		WindowOps = DialogWindowOpsClass()
  		DialogList = for i in (UIAccessor.GetPopupDialogs()) where i != 0 collect i
  		LayerManagerHandle= (for i in DialogList where ((dotnetobject "system.string" (UIAccessor.GetWindowText i)).startswith "Layer") collect i)[1]	
  		intPtrLayerManagerHandle = dotnetobject "System.IntPtr" LayerManagerHandle		
  		Layermanagerposition = WindowOps.WindowPosition intPtrLayerManagerHandle
  		format "Layer Manager Position Via MXS and Dotnet = [%,%]
" Layermanagerposition.x Layermanagerposition.y
  			
  ------------------------------------------		
  -- get window size 
  ------------------------------------------		
  --		LayerManagerSize = WindowOps.Windowsize intPtrLayerManagerHandle
  --		format "Layer Manager Size = [%,%]
" LayerManagerSize.width Layermanagersize.height
  ------------------------------------------			
  -- set the positon according to size with movemwindow
  ------------------------------------------
  --		WindowOps.moveWindow intPtrLayerManagerHandle 0 0 LayerManagerSize.width Layermanagersize.height true

#6

Are you looking for the position of a viewport? Or Max it self?


#7

Paul, I went through your gdi tutorial and as far as I remember, you do not provide a way to get viewport position.
In maxscript I found only the max window position command. I bound the dotnet overlay text to the max main window and refresh its position with a timer that checks the window position. But it would be better having the viewport position since with my quick and dirty method, it is not possible to display the text in the current active viewport etc.

You have an easy way to find out the positon of the viewport?


#8

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.