Форум программистов, компьютерный форум, киберфорум
Наши страницы
Storm23
Войти
Регистрация
Восстановить пароль
Рейтинг: 5.00. Голосов: 3.

Форма с произвольным дизайном заголовка и бордера

Запись от Storm23 размещена 25.06.2015 в 11:03
Обновил(-а) Storm23 25.06.2015 в 16:13

Контрол позволяет создавать формы с произвольным оформлением заголовка и границы окна.
  • Оформление не зависит от темы Windows. Можно задавать произвольный цвет заголовка и бордера окна.
  • В заголовке окна можно размещать произвольные контролы.
  • Поддерживается перетаскивание и ресайз окна с помощью мышки. Возможно перетаскивание не только за заголовок окна, но и за любой участок форма.

Код контрола:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
//===============================
// (C) Storm23, 2015
//===============================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
 
namespace Templates
{
    public partial class BorderLessForm : Form
    {
        /// <summary>
        /// Border color
        /// </summary>
        [DefaultValue(typeof(Color), "Transparent")]
        public Color BorderColor { get; set; }
 
        /// <summary>
        /// Header back color
        /// </summary>
        [DefaultValue(typeof(Color), "Transparent")]
        public Color HeaderBackColor { get; set; }
 
        /// <summary>
        /// Width of area where user can handle window border
        /// </summary>
        [DefaultValue(4)]
        public int ResizeHandleSize { get; set; }
 
        /// <summary>
        /// Width of area where user can change window size (right bottom corner)
        /// </summary>
        [DefaultValue(10)]
        public int ResizeHandleSizeBottomRight { get; set; }
 
        /// <summary>
        /// Window can be resized
        /// </summary>
        [DefaultValue(true)]
        public bool Resizeable { get; set; }
 
        /// <summary>
        /// Window can be moved
        /// </summary>
        [DefaultValue(true)]
        public bool Moveable { get; set; }
 
        /// <summary>
        /// Draws grip at right bottom corner
        /// </summary>
        [DefaultValue(true)]
        public bool GripVisible { get; set; }
 
        /// <summary>
        /// Height of top window header
        /// </summary>
        [DefaultValue(20)]
        public int HeaderHeight { get; set; }
 
        /// <summary>
        /// Allows to drag form by any part of the window
        /// </summary>
        [DefaultValue(false)]
        public bool MoveOnWholeForm { get; set; }
 
        public BorderLessForm()
        {
            FormBorderStyle = FormBorderStyle.None;
            Padding = new Padding(2, 2, 2, 2);
            ResizeHandleSize = 4;
            ResizeHandleSizeBottomRight = 10;
            Resizeable = true;
            Moveable = true;
            HeaderHeight = 20;
            HeaderBackColor = Color.Transparent;
            BorderColor = Color.Transparent;
            MoveOnWholeForm = false;
 
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);
        }
 
        protected override void OnMouseDoubleClick(MouseEventArgs e)
        {
            base.OnMouseDoubleClick(e);
 
            if (Resizeable)
            if (e.Y < HeaderHeight && ControlBox)
            {
                if (WindowState == FormWindowState.Maximized)
                    WindowState = FormWindowState.Normal;
                else
                    WindowState = FormWindowState.Maximized;
            }
        }
 
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
 
            if (ControlBox)
            {
                if (HeaderBackColor != Color.Transparent)
                {
                    using (var brush = new SolidBrush(HeaderBackColor))
                        e.Graphics.FillRectangle(brush, 0, 0, Width, HeaderHeight);
                }
 
                if(ShowIcon)
                    e.Graphics.DrawIcon(Icon, new Rectangle(ResizeHandleSize + 1, 1, HeaderHeight, HeaderHeight));
            }
 
            if(BorderColor != Color.Transparent)
            {
                using(var pen = new Pen(BorderColor))
                e.Graphics.DrawRectangle(pen, 0, 0, Width - 1, Height - 1);
 
                if(SizeGripStyle != System.Windows.Forms.SizeGripStyle.Hide)
                if(Resizeable)
                using(var pen = new Pen(BorderColor, 5))
                {
                    e.Graphics.DrawLine(pen, Width - 4, Height, Width, Height - 4);
                }
            }
        }
 
        #region Move
        public const int WM_NCLBUTTONDOWN = 0xA1;
        public const int HT_CAPTION = 0x2;
 
        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
        [DllImport("user32.dll")]
        public static extern bool ReleaseCapture();
 
        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            if (Moveable && (e.Y < HeaderHeight || MoveOnWholeForm))
            {
                ReleaseCapture();
                SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
                return;
            }
 
            base.OnMouseMove(e);
        }
        #endregion
 
        #region Resize
        protected override void WndProc(ref Message m)
        {
            if(!Resizeable)
            {
                base.WndProc(ref m);
                return;
            }
 
            const UInt32 WM_NCHITTEST = 0x0084;
            const UInt32 WM_MOUSEMOVE = 0x0200;
 
            const UInt32 HTLEFT = 10;
            const UInt32 HTRIGHT = 11;
            const UInt32 HTBOTTOMRIGHT = 17;
            const UInt32 HTBOTTOM = 15;
            const UInt32 HTBOTTOMLEFT = 16;
            const UInt32 HTTOP = 12;
            const UInt32 HTTOPLEFT = 13;
            const UInt32 HTTOPRIGHT = 14;
 
            bool handled = false;
            if (m.Msg == WM_NCHITTEST || m.Msg == WM_MOUSEMOVE)
            {
                Size formSize = this.Size;
                Point screenPoint = new Point(m.LParam.ToInt32());
                Point clientPoint = this.PointToClient(screenPoint);
 
                var boxes = new Dictionary<UInt32, Rectangle>() {
                    {HTBOTTOMRIGHT, new Rectangle(formSize.Width - ResizeHandleSizeBottomRight, formSize.Height - ResizeHandleSizeBottomRight, ResizeHandleSizeBottomRight, ResizeHandleSizeBottomRight)},
                    {HTBOTTOMLEFT, new Rectangle(0, formSize.Height - ResizeHandleSize, ResizeHandleSize, ResizeHandleSize)},
                    {HTBOTTOM, new Rectangle(ResizeHandleSize, formSize.Height - ResizeHandleSize, formSize.Width - 2*ResizeHandleSize, ResizeHandleSize)},
                    {HTRIGHT, new Rectangle(formSize.Width - ResizeHandleSize, ResizeHandleSize, ResizeHandleSize, formSize.Height - 2*ResizeHandleSize)},
                    {HTTOPRIGHT, new Rectangle(formSize.Width - ResizeHandleSize, 0, ResizeHandleSize, ResizeHandleSize) },
                    {HTTOP, new Rectangle(ResizeHandleSize, 0, formSize.Width - 2*ResizeHandleSize, ResizeHandleSize) },
                    {HTTOPLEFT, new Rectangle(0, 0, ResizeHandleSize, ResizeHandleSize) },
                    {HTLEFT, new Rectangle(0, ResizeHandleSize, ResizeHandleSize, formSize.Height - 2*ResizeHandleSize) }
                };
 
                foreach (KeyValuePair<UInt32, Rectangle> hitBox in boxes)
                {
                    if (hitBox.Value.Contains(clientPoint))
                    {
                        m.Result = (IntPtr)hitBox.Key;
                        handled = true;
                        break;
                    }
                }
            }
 
            if (!handled)
                base.WndProc(ref m);
        }
        #endregion
    }
}
Описание свойств:
  • Color BorderColor - цвет бордера (по умолчанию - прозрачный)
  • Color HeaderBackColor - цвет верхнего заголовка окна (по умолчанию - прозрачный)
  • int ResizeHandleSize - ширина границ окна, за которые можно тянуть
  • int ResizeHandleSizeBottomRight - размер нижнего правого угла окна, которым можно менять размер окна
  • bool Resizeable - разрешает менять размеры формы
  • bool Moveable - разрешает передвигать форму
  • bool GripVisible - рисует значок изменения размера в нижнем правом углу
  • int HeaderHeight - высота заголовка окна
  • bool MoveOnWholeForm - разрешает тянуть форму за любой участок (не только за заголовок)

Для использования компонента, просто унаследуйте вашу форму от контрола:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
using System.Windows.Forms;
using Templates;
 
namespace Tester
{
    public partial class Form1 : BorderLessForm //<-----
    {
        public Form1()
        {
            InitializeComponent();
        }
    }
}
Название: 1.png
Просмотров: 2603

Размер: 2.0 Кб Название: 2.png
Просмотров: 2576

Размер: 2.0 Кб Название: 3.png
Просмотров: 2536

Размер: 8.1 Кб
Размещено в C#, WinForms
Просмотров 2328 Комментарии 7
Всего комментариев 7
Комментарии
  1. Старый комментарий
    А что делать с самим кодом контрола?
    Запись от AntwortenSucher размещена 25.06.2015 в 12:45 AntwortenSucher вне форума
  2. Старый комментарий
    Аватар для Storm23
    Цитата:
    Сообщение от AntwortenSucher Просмотреть комментарий
    А что делать с самим кодом контрола?
    http://www.cyberforum.ru/blogs/529033/blog3301.html
    Запись от Storm23 размещена 25.06.2015 в 16:11 Storm23 вне форума
  3. Старый комментарий
    Привет, выложи пожалуйста код проекта который на третьей картинке, там где контролы в тайтле.
    Запись от m0 размещена 14.02.2017 в 23:32 m0 вне форума
    Обновил(-а) m0 14.02.2017 в 23:41
  4. Старый комментарий
    Аватар для Storm23
    Цитата:
    Сообщение от m0 Просмотреть комментарий
    Привет, выложи пожалуйста код проекта который на третьей картинке, там где контролы в тайтле.
    Держи https://www.dropbox.com/s/t71h1d8vtz...on361.zip?dl=0
    Запись от Storm23 размещена 15.02.2017 в 03:01 Storm23 вне форума
  5. Старый комментарий
    Цитата:
    Сообщение от Storm23 Просмотреть комментарий
    Большое спасибо.
    Запись от m0 размещена 15.02.2017 в 10:44 m0 вне форума
  6. Старый комментарий
    Аватар для Medivh
    Цитата:
    Сообщение от Storm23 Просмотреть комментарий
    Спасибо! Разобрался хоть как то в этом всем.
    Запись от Medivh размещена 24.05.2018 в 10:36 Medivh вне форума
  7. Старый комментарий
    Аватар для aenye
    О даааа! Спасибо тебе, Гений! Как я только не велосипедировал, чтобы изменить цвет чертовой шапки окна...
    Запись от aenye размещена 11.01.2019 в 01:12 aenye вне форума
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru