c# - How to fix borderless form resize with controls on borders of the form? -
i have borderless winform needed resize, , managed way:
protected override void wndproc(ref message m) { const int wmnchittest = 0x84; const int htleft = 10; const int htright = 11; const int httop = 12; const int httopleft = 13; const int httopright = 14; const int htbottom = 15; const int htbottomleft = 16; const int htbottomright = 17; if (m.msg == wmnchittest) { console.write(true + "\n"); int x = (int)(m.lparam.toint64() & 0xffff); int y = (int)((m.lparam.toint64() & 0xffff0000) >> 16); point pt = pointtoclient(new point(x, y)); size clientsize = clientsize; ///allow resize on lower right corner if (pt.x >= clientsize.width - 16 && pt.y >= clientsize.height - 16 && clientsize.height >= 16) { m.result = (intptr)(ismirrored ? htbottomleft : htbottomright); return; } ///allow resize on lower left corner if (pt.x <= 16 && pt.y >= clientsize.height - 16 && clientsize.height >= 16) { m.result = (intptr)(ismirrored ? htbottomright : htbottomleft); return; } ///allow resize on upper right corner if (pt.x <= 16 && pt.y <= 16 && clientsize.height >= 16) { m.result = (intptr)(ismirrored ? httopright : httopleft); return; } ///allow resize on upper left corner if (pt.x >= clientsize.width - 16 && pt.y <= 16 && clientsize.height >= 16) { m.result = (intptr)(ismirrored ? httopleft : httopright); return; } ///allow resize on top border if (pt.y <= 16 && clientsize.height >= 16) { m.result = (intptr)(httop); return; } ///allow resize on bottom border if (pt.y >= clientsize.height - 16 && clientsize.height >= 16) { m.result = (intptr)(htbottom); return; } ///allow resize on left border if (pt.x <= 16 && clientsize.height >= 16) { m.result = (intptr)(htleft); return; } ///allow resize on right border if (pt.x >= clientsize.width - 16 && clientsize.height >= 16) { m.result = (intptr)(htright); return; } } else { console.write(false + "\n"); } base.wndproc(ref m); }
the problem there controls on left , right borders of form, resize override used on code above doesn't work on areas in there controls of kind.
here example:
on image above can see label inside marked area on left border of form , won't let me resize it.
is there way solve issue?
the problem here is label control gets mouse notifications, not borderless form. far best way solve problem making label transparent mouse. know how that, wm_nchittest permits returning httransparent. windows keeps looking next candidate notification, label's parent.
especially easy label since don't have use mouse events @ all:
using system; using system.windows.forms; public class labelex : label { protected override void wndproc(ref message m) { const int wmnchittest = 0x84; const int httransparent = -1; if (!designmode && m.msg == wmnchittest) m.result = new intptr(httransparent); else base.wndproc(ref m); } }
works control class, you'd want more selective if button. might need, still pretty awkward if have lot of different kind of controls close edge. technique can use called "sub-classing" in native windows programming. universally used in winforms create wrapper .net classes native windows controls. works here too, can have peek @ messages of control , intercept wm_nchittest way:
const int edge = 16; class mousefilter : nativewindow { private form form; public mousefilter(form form, control child) { this.form = form; this.assignhandle(child.handle); } protected override void wndproc(ref message m) { const int wmnchittest = 0x84; const int httransparent = -1; if (m.msg == wmnchittest) { var pos = new point(m.lparam.toint32()); if (pos.x < this.form.left + edge || pos.y < this.form.top + edge|| pos.x > this.form.right - edge || pos.y > this.form.bottom - edge) { m.result = new intptr(httransparent); return; } } base.wndproc(ref m); } }
and create mousefilter instance every control gets close window edge:
protected override void onload(eventargs e) { base.onload(e); subclasschildren(this.controls); } private void subclasschildren(control.controlcollection ctls) { foreach (control ctl in ctls) { var rc = this.rectangletoclient(this.rectangletoscreen(ctl.displayrectangle)); if (rc.left < edge || rc.right > this.clientsize.width - edge || rc.top < edge || rc.bottom > this.clientsize.height - edge) { new mousefilter(this, ctl); } subclasschildren(ctl.controls); } }
Comments
Post a Comment