Notifications
Clear all

[Closed] Docked .Net controller redraw issue

Wow, thanks! This is perfect.

I used this


public static class User32
{
    [DllImport("user32.dll")]
    static extern bool RedrawWindow(IntPtr hWnd, IntPtr lprcUpdate, IntPtr hrgnUpdate, uint flags);
    public static bool RedrawAllWindow(IntPtr hWnd, uint flags) 
    { 
        return RedrawWindow(hWnd, IntPtr.Zero, IntPtr.Zero, flags); 
    }
}

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

absolutely right… i’m doing the same.

so because you are using your own controls it shouldn’t be a big deal to add to your list one more – pain-hook native window

Very nice!

I knew that I was overdoing something…
After a little thinking I guessed that MAX creates dotnetcontrols with some wrong window style flag. And I was right with this idea. MAX sets the WS_CLIPCHILDREN flag supposing that dotnetcontrol can’t be a parent. Setting this flag also blocks the redrawing of combined controls like ListView(body and header), NumericUpDown(buttons and textbox), etc.

So the good solution is more simple than using of NativeWindow. The thing that we need is only remove the WS_CLIPCHILDREN flag:


fn CreateWindowLongAssembly =
(
	source = "using System;
"
	source += "using System.Runtime.InteropServices;
"
	source += "class WindowLong
"
	source += "{
"
	source += "		[DllImport(\"user32.dll\", EntryPoint=\"GetWindowLong\")]
"
	source += "		public static extern Int32 GetWindowLong(IntPtr hWnd, Int32 index);
"
	source += "		[DllImport(\"user32.dll\", EntryPoint=\"SetWindowLong\")]
"
	source += "		public static extern Int32 SetWindowLong(IntPtr hWnd, Int32 index, Int32 newVal);
"
	source += "}
"

	csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
	compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"

	compilerParams.GenerateInMemory = on
	compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
	
	assembly = compilerResults.CompiledAssembly
	assembly.CreateInstance "WindowLong"
)
global WindowLong = CreateWindowLongAssembly()

mapped fn removeCLIPCHILDREN control =
(
	GWL_STYLE = -16
	WS_CLIPCHILDREN = 0x02000000L 

	hwnd = control.get_handle asdotnetobject:on
	flags = bit.xor (WindowLong.GetWindowLong hwnd GWL_STYLE) WS_CLIPCHILDREN
	WindowLong.SetWindowLong hwnd GWL_STYLE flags
)


(
	try
	(
		cui.unregisterDialogBar DialogBar
		closeRolloutFloater DialogBar
	)
	catch()
	
	global DialogBar = newRolloutFloater "rf#" 250 300
		
	rollout redrawRol "Redraw Test"
	(
		dotnetcontrol lv "ListView" width:220 height:100
		dotnetcontrol pn "UserControl" width:220 height:24
		
		on redrawRol open do
		(
			lv.view = lv.view.Details
			lv.Columns.add "Name" 100
			lv.Columns.add "ID" 100
			
			bt = dotnetobject "Button"
			bt.text = "Button"
			bt.Dock = bt.Dock.Left
			
			lb = dotnetobject "Label"
			lb.text = "Label"
			lb.Dock = lb.Dock.Right
			
			pn.controls.addrange #(lb,bt)
			
			removeCLIPCHILDREN #(lv,pn)
		)
	)		
	addRollout redrawRol DialogBar
	cui.registerDialogBar DialogBar style:#(#cui_dock_all, #cui_floatable, #cui_handles, #cui_dock_horz, #cui_max_sized)	
)

Enjoy!

being absolutely correct I have to say that MAX doesn’t set this flag, it leaves it the way how it was set on control creation. Probably for dialogs in Docked mode MAX takes this flag into account when sends redraw messages.

because in max 2012 they using a lot of different type of controls with different nature.
they did something with window messaging. A lot of old windows those never flicker are flickering terribly in 2012. I can’t say that all window messaging system is completely broken in 2012 but was irreparably improved for sure.

Page 2 / 2