[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);
}
}
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
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.