Хочу изменить цвет фрейма/рамки у формы. Большая кастомизация не требуется и убирать рамку и делать свою тоже не нужно. Как просто поменять цвет фрейма на другой? К примеру как на скриншотах (1 - оригинал, 2 - желаемый вид). На втором панель серая.
Обрабатывать WM_NCPAINT (и еще несколько сообщений) и рисовать эту рамку самостоятельно. Вот простейший пример, основанный на OpenSource-проекте customerborderform.codeplex.com. Он не совершенный, так как нет двойной буферизации и при изменении размера окно мерцает, но думаю как основа будет полезен.
Вспомогательные классы
NativeMethods
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsTest
{
public class NativeMethods
{
#region WindowMessages
public enum WindowMessages
{
WM_NULL = 0x0000,
WM_CREATE = 0x0001,
WM_DESTROY = 0x0002,
WM_MOVE = 0x0003,
WM_SIZE = 0x0005,
WM_ACTIVATE = 0x0006,
WM_SETFOCUS = 0x0007,
WM_KILLFOCUS = 0x0008,
WM_ENABLE = 0x000A,
WM_SETREDRAW = 0x000B,
WM_SETTEXT = 0x000C,
WM_GETTEXT = 0x000D,
WM_GETTEXTLENGTH = 0x000E,
WM_PAINT = 0x000F,
WM_CLOSE = 0x0010,
WM_QUIT = 0x0012,
WM_ERASEBKGND = 0x0014,
WM_SYSCOLORCHANGE = 0x0015,
WM_SHOWWINDOW = 0x0018,
WM_ACTIVATEAPP = 0x001C,
WM_SETCURSOR = 0x0020,
WM_MOUSEACTIVATE = 0x0021,
WM_GETMINMAXINFO = 0x24,
WM_WINDOWPOSCHANGING = 0x0046,
WM_WINDOWPOSCHANGED = 0x0047,
WM_CONTEXTMENU = 0x007B,
WM_STYLECHANGING = 0x007C,
WM_STYLECHANGED = 0x007D,
WM_DISPLAYCHANGE = 0x007E,
WM_GETICON = 0x007F,
WM_SETICON = 0x0080,
// non client area
WM_NCCREATE = 0x0081,
WM_NCDESTROY = 0x0082,
WM_NCCALCSIZE = 0x0083,
WM_NCHITTEST = 0x84,
WM_NCPAINT = 0x0085,
WM_NCACTIVATE = 0x0086,
WM_GETDLGCODE = 0x0087,
WM_SYNCPAINT = 0x0088,
// non client mouse
WM_NCMOUSEMOVE = 0x00A0,
WM_NCLBUTTONDOWN = 0x00A1,
WM_NCLBUTTONUP = 0x00A2,
WM_NCLBUTTONDBLCLK = 0x00A3,
WM_NCRBUTTONDOWN = 0x00A4,
WM_NCRBUTTONUP = 0x00A5,
WM_NCRBUTTONDBLCLK = 0x00A6,
WM_NCMBUTTONDOWN = 0x00A7,
WM_NCMBUTTONUP = 0x00A8,
WM_NCMBUTTONDBLCLK = 0x00A9,
// keyboard
WM_KEYDOWN = 0x0100,
WM_KEYUP = 0x0101,
WM_CHAR = 0x0102,
WM_SYSCOMMAND = 0x0112,
// menu
WM_INITMENU = 0x0116,
WM_INITMENUPOPUP = 0x0117,
WM_MENUSELECT = 0x011F,
WM_MENUCHAR = 0x0120,
WM_ENTERIDLE = 0x0121,
WM_MENURBUTTONUP = 0x0122,
WM_MENUDRAG = 0x0123,
WM_MENUGETOBJECT = 0x0124,
WM_UNINITMENUPOPUP = 0x0125,
WM_MENUCOMMAND = 0x0126,
WM_CHANGEUISTATE = 0x0127,
WM_UPDATEUISTATE = 0x0128,
WM_QUERYUISTATE = 0x0129,
// mouse
WM_MOUSEFIRST = 0x0200,
WM_MOUSEMOVE = 0x0200,
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
WM_LBUTTONDBLCLK = 0x0203,
WM_RBUTTONDOWN = 0x0204,
WM_RBUTTONUP = 0x0205,
WM_RBUTTONDBLCLK = 0x0206,
WM_MBUTTONDOWN = 0x0207,
WM_MBUTTONUP = 0x0208,
WM_MBUTTONDBLCLK = 0x0209,
WM_MOUSEWHEEL = 0x020A,
WM_MOUSELAST = 0x020D,
WM_PARENTNOTIFY = 0x0210,
WM_ENTERMENULOOP = 0x0211,
WM_EXITMENULOOP = 0x0212,
WM_NEXTMENU = 0x0213,
WM_SIZING = 0x0214,
WM_CAPTURECHANGED = 0x0215,
WM_MOVING = 0x0216,
WM_ENTERSIZEMOVE = 0x0231,
WM_EXITSIZEMOVE = 0x0232,
WM_MOUSELEAVE = 0x02A3,
WM_MOUSEHOVER = 0x02A1,
WM_NCMOUSEHOVER = 0x02A0,
WM_NCMOUSELEAVE = 0x02A2,
WM_MDIACTIVATE = 0x0222,
WM_HSCROLL = 0x0114,
WM_VSCROLL = 0x0115,
WM_PRINT = 0x0317,
WM_PRINTCLIENT = 0x0318,
}
#endregion //WindowMessages
#region DCX enum
[Flags()]
internal enum DCX
{
DCX_CACHE = 0x2,
DCX_CLIPCHILDREN = 0x8,
DCX_CLIPSIBLINGS = 0x10,
DCX_EXCLUDERGN = 0x40,
DCX_EXCLUDEUPDATE = 0x100,
DCX_INTERSECTRGN = 0x80,
DCX_INTERSECTUPDATE = 0x200,
DCX_LOCKWINDOWUPDATE = 0x400,
DCX_NORECOMPUTE = 0x100000,
DCX_NORESETATTRS = 0x4,
DCX_PARENTCLIP = 0x20,
DCX_VALIDATE = 0x200000,
DCX_WINDOW = 0x1,
}
#endregion //DCX
#region RECT structure
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public RECT(int left, int top, int right, int bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public Rectangle Rect { get { return new Rectangle(this.left, this.top, this.right - this.left, this.bottom - this.top); } }
public static RECT FromXYWH(int x, int y, int width, int height)
{
return new RECT(x,
y,
x + width,
y + height);
}
public static RECT FromRectangle(Rectangle rect)
{
return new RECT(rect.Left,
rect.Top,
rect.Right,
rect.Bottom);
}
}
#endregion RECT structure
#region TRACKMOUSEEVENT structure
[StructLayout(LayoutKind.Sequential)]
public class TRACKMOUSEEVENT
{
public TRACKMOUSEEVENT()
{
this.cbSize = Marshal.SizeOf(typeof(NativeMethods.TRACKMOUSEEVENT));
this.dwHoverTime = 100;
}
public int cbSize;
public int dwFlags;
public IntPtr hwndTrack;
public int dwHoverTime;
}
#endregion
#region TernaryRasterOperations enum
public enum TernaryRasterOperations
{
SRCCOPY = 0x00CC0020, /* dest = source*/
SRCPAINT = 0x00EE0086, /* dest = source OR dest*/
SRCAND = 0x008800C6, /* dest = source AND dest*/
SRCINVERT = 0x00660046, /* dest = source XOR dest*/
SRCERASE = 0x00440328, /* dest = source AND (NOT dest )*/
NOTSRCCOPY = 0x00330008, /* dest = (NOT source)*/
NOTSRCERASE = 0x001100A6, /* dest = (NOT src) AND (NOT dest) */
MERGECOPY = 0x00C000CA, /* dest = (source AND pattern)*/
MERGEPAINT = 0x00BB0226, /* dest = (NOT source) OR dest*/
PATCOPY = 0x00F00021, /* dest = pattern*/
PATPAINT = 0x00FB0A09, /* dest = DPSnoo*/
PATINVERT = 0x005A0049, /* dest = pattern XOR dest*/
DSTINVERT = 0x00550009, /* dest = (NOT dest)*/
BLACKNESS = 0x00000042, /* dest = BLACK*/
WHITENESS = 0x00FF0062, /* dest = WHITE*/
};
#endregion
#region Constants
public static readonly IntPtr TRUE = new IntPtr(1);
public static readonly IntPtr FALSE = new IntPtr(0);
public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
#endregion
#region API methods
[DllImport("user32.dll")]
public static extern IntPtr GetDCEx(IntPtr hwnd, IntPtr hrgnclip, uint fdwOptions);
[DllImport("user32.dll")]
public static extern int ReleaseDC(IntPtr hwnd, IntPtr hDC);
[DllImport("user32.dll")]
public static extern int GetWindowRect(IntPtr hwnd, ref RECT lpRect);
public const int VK_LBUTTON = 0x01;
public const int VK_RBUTTON = 0x02;
public static int GetLastError()
{
return System.Runtime.InteropServices.Marshal.GetLastWin32Error();
}
[DllImport("gdi32.dll")]
public static extern bool DeleteDC(IntPtr hDC);
#endregion
}
}
SystemMetric
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindowsFormsTest
{
public enum SystemMetric : int
{
/// <summary>
/// The width of a window border, in pixels. This is equivalent to the SM_CXEDGE value for windows with the 3-D look.
/// </summary>
SM_CXBORDER = 5,
/// <summary>
/// The width of a cursor, in pixels. The system cannot create cursors of other sizes.
/// </summary>
SM_CXCURSOR = 13,
/// <summary>
/// This value is the same as SM_CXFIXEDFRAME.
/// </summary>
SM_CXDLGFRAME = 7,
/// <summary>
/// This value is the same as SM_CXSIZEFRAME.
/// </summary>
SM_CXFRAME = 32,
/// <summary>
/// The width of a button in a window caption or title bar, in pixels.
/// </summary>
SM_CXSIZE = 30,
/// <summary>
/// The thickness of the sizing border around the perimeter of a window that can be resized, in pixels.
/// SM_CXSIZEFRAME is the width of the horizontal border, and SM_CYSIZEFRAME is the height of the vertical border.
/// This value is the same as SM_CXFRAME.
/// </summary>
SM_CXSIZEFRAME = 32,
/// <summary>
/// The height of a window border, in pixels. This is equivalent to the SM_CYEDGE value for windows with the 3-D look.
/// </summary>
SM_CYBORDER = 6,
/// <summary>
/// The height of a caption area, in pixels.
/// </summary>
SM_CYCAPTION = 4,
/// <summary>
/// This value is the same as SM_CYSIZEFRAME.
/// </summary>
SM_CYFRAME = 33,
/// <summary>
/// The height of a button in a window caption or title bar, in pixels.
/// </summary>
SM_CYSIZE = 31,
/// <summary>
/// The thickness of the sizing border around the perimeter of a window that can be resized, in pixels.
/// SM_CXSIZEFRAME is the width of the horizontal border, and SM_CYSIZEFRAME is the height of the vertical border.
/// This value is the same as SM_CYFRAME.
/// </summary>
SM_CYSIZEFRAME = 33,
/// <summary>
/// The height of a small caption, in pixels.
/// </summary>
SM_CYSMCAPTION = 51,
/// <summary>
/// The recommended height of a small icon, in pixels. Small icons typically appear in window captions and in small icon view.
/// </summary>
SM_CYSMICON = 50,
/// <summary>
/// The height of small caption buttons, in pixels.
/// </summary>
SM_CYSMSIZE = 53,
}
}
Собственно форма
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
/*https://customerborderform.codeplex.com*/
namespace WindowsFormsTest
{
public partial class Form1 : Form
{
/*Параметры отображения окна*/
Color TextColor = Color.Black;//цвет текста
Color FrameColor = Color.Red;//цвет рамки
bool EnableNonClientAreaPaint = true;//использовать нестандартную рамку
[DllImport("user32.dll")]
static extern int GetSystemMetrics(SystemMetric smIndex);
public Form1()
{
InitializeComponent();
}
/// <summary>
/// Custom client area paint
/// </summary>
protected void OnNonClientAreaPaint(NonClientPaintEventArgs e)
{
/*Размеры рамки*/
int w = GetSystemMetrics(SystemMetric.SM_CXSIZEFRAME);
int h = GetSystemMetrics(SystemMetric.SM_CYSIZEFRAME);
/*Размеры кнопки*/
int w2 = (GetSystemMetrics(SystemMetric.SM_CXSIZE));
int h2 = GetSystemMetrics(SystemMetric.SM_CYSIZE);
Rectangle rc;
StringFormat fmt=StringFormat.GenericDefault;
fmt.Alignment = StringAlignment.Center;
fmt.LineAlignment = StringAlignment.Center;
Brush br=new SolidBrush(TextColor);//brush for text
Brush fbr = new SolidBrush(FrameColor);//brush for frame
Font font = new Font("Arial", 14);
Pen p = new Pen(FrameColor, (float)w);
using(br)
using(fbr)
using(font)
using (p)
{
/*border*/
e.Graphics.DrawRectangle(p, w / 2.0f, h / 2.0f, e.Bounds.Width - w, e.Bounds.Height - h );
/*title area*/
rc = new Rectangle(w, h, e.Bounds.Width, h2);
e.Graphics.FillRectangle(fbr, rc);
e.Graphics.DrawString(this.Text, SystemFonts.CaptionFont, br, rc);
/*close butt*/
rc=new Rectangle(e.Bounds.Width-w-w2, h, w2, h2-4);
e.Graphics.DrawString("x", font, br, rc ,fmt);
/*max butt*/
rc = new Rectangle(e.Bounds.Width - w - w2*2, h, w2, h2-4);
e.Graphics.DrawString("■", font, br, rc, fmt);
/*min butt*/
rc = new Rectangle(e.Bounds.Width - w - w2*3, h, w2, h2-4);
e.Graphics.DrawString("–", font, br, rc, fmt);
}
}
protected override void WndProc(ref Message m)
{
if (!this.EnableNonClientAreaPaint)
{
base.WndProc(ref m);
return;
}
switch (m.Msg)
{
case (int)NativeMethods.WindowMessages.WM_NCPAINT:
{
// Here should all our painting occur, but...
DefWndProc(ref m);
WmNCPaint(ref m);
this.Refresh();
break;
}
case (int)NativeMethods.WindowMessages.WM_NCACTIVATE:
{
// ... WM_NCACTIVATE does some painting directly
// without bothering with WM_NCPAINT ...
WmNCActivate(ref m);
break;
}
case (int)NativeMethods.WindowMessages.WM_SETTEXT:
{
// ... and some painting is required in here as well
WmSetText(ref m);
break;
}
case (int)NativeMethods.WindowMessages.WM_NCMOUSEMOVE:
{
//PaintNonClientArea(this.Handle, (IntPtr)1);
//this.Refresh();
WmNCMouseMove(ref m);
break;
}
case (int)NativeMethods.WindowMessages.WM_ERASEBKGND:
{
WmEraseBkgnd(ref m);
break;
}
default:
{
base.WndProc(ref m);
break;
}
}
}
#region Wm ... (Windows message...)
protected void OnUpdateWindowState()
{ }
private void WmEraseBkgnd(ref Message m)
{
base.WndProc(ref m);
//Log(MethodInfo.GetCurrentMethod(), "{0}", WindowState);
OnUpdateWindowState();
}
#endregion
public Point PointToWindow(Point screenPoint)
{
return new Point(screenPoint.X - Location.X, screenPoint.Y - Location.Y);
}
#region WmNC ... (Windows message... Non Client)
/// <summary>
/// Handle WmNCMouseMove, so buttons aren't repainted due to mouse movement
/// </summary>
private void WmNCMouseMove(ref Message msg)
{
Point clientPoint = this.PointToWindow(new Point(msg.LParam.ToInt32()));
msg.Result = IntPtr.Zero;
}
private void PaintNonClientArea(IntPtr hWnd, IntPtr hRgn)
{
NativeMethods.RECT windowRect = new NativeMethods.RECT();
if (NativeMethods.GetWindowRect(hWnd, ref windowRect) == 0)
return;
Rectangle bounds = new Rectangle(0, 0,
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top);
if (bounds.Width == 0 || bounds.Height == 0)
return;
// The update region is clipped to the window frame. When wParam is 1, the entire window frame needs to be updated.
Region clipRegion = null;
if (hRgn != (IntPtr)1)
clipRegion = System.Drawing.Region.FromHrgn(hRgn);
// MSDN states that only WINDOW and INTERSECTRGN are needed,
// but other sources confirm that CACHE is required on Win9x
// and you need CLIPSIBLINGS to prevent painting on overlapping windows.
IntPtr hDC = NativeMethods.GetDCEx(/*hWnd*/this.Handle, /*hRgn*/(IntPtr)0,
(int)(NativeMethods.DCX.DCX_WINDOW /*| NativeMethods.DCX.DCX_INTERSECTRGN*/
| NativeMethods.DCX.DCX_CACHE | NativeMethods.DCX.DCX_CLIPSIBLINGS));
if (hDC == IntPtr.Zero)
return;
try
{
using (Graphics g = Graphics.FromHdc(hDC))
{
//cliping rect is not cliping rect but actual rectangle
OnNonClientAreaPaint(new NonClientPaintEventArgs(g, bounds, clipRegion));
}
//NOTE: The Graphics object would realease the HDC on Dispose.
// So there is no need to call NativeMethods.ReleaseDC(msg.HWnd, hDC);
}
finally
{
NativeMethods.ReleaseDC(this.Handle, hDC);
}
}
private void WmNCPaint(ref Message msg)
{
// The WParam contains handle to clipRegion or 1 if entire window should be repainted
PaintNonClientArea(msg.HWnd, (IntPtr)msg.WParam);
// we handled everything
msg.Result = NativeMethods.TRUE;
}
private void WmSetText(ref Message msg)
{
// allow the system to receive the new window title
DefWndProc(ref msg);
// repaint title bar
PaintNonClientArea(msg.HWnd, (IntPtr)1);
}
private void WmNCActivate(ref Message msg)
{
bool active = (msg.WParam == NativeMethods.TRUE);
if (WindowState == FormWindowState.Minimized)
DefWndProc(ref msg);
else
{
// repaint title bar
PaintNonClientArea(msg.HWnd, (IntPtr)1);
// allow to deactivate window
msg.Result = NativeMethods.TRUE;
}
}
#endregion
}
public class NonClientPaintEventArgs : EventArgs
{
public Graphics Graphics;
public Rectangle Bounds;
public Region clipRegion;
public NonClientPaintEventArgs(Graphics g, Rectangle bounds, Region cr)
{
this.Graphics = g;
this.Bounds = bounds;
clipRegion = cr;
}
}
}
Вот как это выглядит
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
В общем на GitGub нашел библиотеку MpvPlayerUINET https://github
Пишу транслитератор, а точнее, пытаюсь уже обработанное слово перевести на русский язык
При попытке сравнения структур , получаю следующее сообщение "Process is terminating due to StackOverflowException"
Есть таблица какие люди когда приходятВ таблице данные лежат как на фото1