├── .gitignore
├── App.config
├── BorderlessForm.csproj
├── BorderlessForm.sln
├── FormBase.cs
├── LICENSE.md
├── MainForm.Designer.cs
├── MainForm.cs
├── MainForm.resx
├── Native.cs
├── Program.cs
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
├── Resources.resx
├── Settings.Designer.cs
└── Settings.settings
├── README.md
└── screenshot.png
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 |
11 | [Dd]ebug/
12 | [Rr]elease/
13 | x64/
14 | build/
15 | [Bb]in/
16 | [Oo]bj/
17 |
18 | # MSTest test Results
19 | [Tt]est[Rr]esult*/
20 | [Bb]uild[Ll]og.*
21 |
22 | *_i.c
23 | *_p.c
24 | *.ilk
25 | *.meta
26 | *.obj
27 | *.pch
28 | *.pdb
29 | *.pgc
30 | *.pgd
31 | *.rsp
32 | *.sbr
33 | *.tlb
34 | *.tli
35 | *.tlh
36 | *.tmp
37 | *.tmp_proj
38 | *.log
39 | *.vspscc
40 | *.vssscc
41 | .builds
42 | *.pidb
43 | *.log
44 | *.scc
45 |
46 | # Visual C++ cache files
47 | ipch/
48 | *.aps
49 | *.ncb
50 | *.opensdf
51 | *.sdf
52 | *.cachefile
53 |
54 | # Visual Studio profiler
55 | *.psess
56 | *.vsp
57 | *.vspx
58 |
59 | # Guidance Automation Toolkit
60 | *.gpState
61 |
62 | # ReSharper is a .NET coding add-in
63 | _ReSharper*/
64 | *.[Rr]e[Ss]harper
65 |
66 | # TeamCity is a build add-in
67 | _TeamCity*
68 |
69 | # DotCover is a Code Coverage Tool
70 | *.dotCover
71 |
72 | # NCrunch
73 | *.ncrunch*
74 | .*crunch*.local.xml
75 |
76 | # Installshield output folder
77 | [Ee]xpress/
78 |
79 | # DocProject is a documentation generator add-in
80 | DocProject/buildhelp/
81 | DocProject/Help/*.HxT
82 | DocProject/Help/*.HxC
83 | DocProject/Help/*.hhc
84 | DocProject/Help/*.hhk
85 | DocProject/Help/*.hhp
86 | DocProject/Help/Html2
87 | DocProject/Help/html
88 |
89 | # Click-Once directory
90 | publish/
91 |
92 | # Publish Web Output
93 | *.Publish.xml
94 | *.pubxml
95 |
96 | # NuGet Packages Directory
97 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
98 | #packages/
99 |
100 | # Windows Azure Build Output
101 | csx
102 | *.build.csdef
103 |
104 | # Windows Store app package directory
105 | AppPackages/
106 |
107 | # Others
108 | sql/
109 | *.Cache
110 | ClientBin/
111 | [Ss]tyle[Cc]op.*
112 | ~$*
113 | *~
114 | *.dbmdl
115 | *.[Pp]ublish.xml
116 | *.pfx
117 | *.publishsettings
118 |
119 | # RIA/Silverlight projects
120 | Generated_Code/
121 |
122 | # Backup & report files from converting an old project file to a newer
123 | # Visual Studio version. Backup files are not needed, because we have git ;-)
124 | _UpgradeReport_Files/
125 | Backup*/
126 | UpgradeLog*.XML
127 | UpgradeLog*.htm
128 |
129 | # SQL Server files
130 | App_Data/*.mdf
131 | App_Data/*.ldf
132 |
133 | # =========================
134 | # Windows detritus
135 | # =========================
136 |
137 | # Windows image file caches
138 | Thumbs.db
139 | ehthumbs.db
140 |
141 | # Folder config file
142 | Desktop.ini
143 |
144 | # Recycle Bin used on file shares
145 | $RECYCLE.BIN/
146 |
147 | # Mac crap
148 | .DS_Store
149 |
--------------------------------------------------------------------------------
/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/BorderlessForm.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {1DBA6E10-6A05-48F0-BED9-6F33E0D3E986}
8 | WinExe
9 | Properties
10 | BorderlessForm
11 | BorderlessForm
12 | v3.5
13 | 512
14 | Client
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Form
49 |
50 |
51 | MainForm.cs
52 |
53 |
54 | Form
55 |
56 |
57 |
58 |
59 |
60 | MainForm.cs
61 |
62 |
63 | ResXFileCodeGenerator
64 | Resources.Designer.cs
65 | Designer
66 |
67 |
68 | True
69 | Resources.resx
70 | True
71 |
72 |
73 | SettingsSingleFileGenerator
74 | Settings.Designer.cs
75 |
76 |
77 | True
78 | Settings.settings
79 | True
80 |
81 |
82 |
83 |
84 |
85 |
86 |
93 |
--------------------------------------------------------------------------------
/BorderlessForm.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BorderlessForm", "BorderlessForm.csproj", "{1DBA6E10-6A05-48F0-BED9-6F33E0D3E986}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Any CPU = Debug|Any CPU
9 | Release|Any CPU = Release|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {1DBA6E10-6A05-48F0-BED9-6F33E0D3E986}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {1DBA6E10-6A05-48F0-BED9-6F33E0D3E986}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {1DBA6E10-6A05-48F0-BED9-6F33E0D3E986}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {1DBA6E10-6A05-48F0-BED9-6F33E0D3E986}.Release|Any CPU.Build.0 = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/FormBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Drawing;
5 | using System.Linq;
6 | using System.Runtime.InteropServices;
7 | using System.Text;
8 | using System.Windows.Forms;
9 |
10 | namespace BorderlessForm
11 | {
12 | ///
13 | /// Based on http://customerborderform.codeplex.com/
14 | ///
15 | public class FormBase : Form
16 | {
17 | public void DecorationMouseDown(HitTestValues hit, Point p)
18 | {
19 | NativeMethods.ReleaseCapture();
20 | var pt = new POINTS { X = (short)p.X, Y = (short)p.Y };
21 | NativeMethods.SendMessage(Handle, (int)WindowMessages.WM_NCLBUTTONDOWN, (int)hit, pt);
22 | }
23 |
24 | public void DecorationMouseDown(HitTestValues hit)
25 | {
26 | DecorationMouseDown(hit, MousePosition);
27 | }
28 |
29 | public void DecorationMouseUp(HitTestValues hit, Point p)
30 | {
31 | NativeMethods.ReleaseCapture();
32 | var pt = new POINTS { X = (short)p.X, Y = (short)p.Y };
33 | NativeMethods.SendMessage(Handle, (int)WindowMessages.WM_NCLBUTTONUP, (int)hit, pt);
34 | }
35 |
36 | public void DecorationMouseUp(HitTestValues hit)
37 | {
38 | DecorationMouseUp(hit, MousePosition);
39 | }
40 |
41 | protected override void OnHandleCreated(EventArgs e)
42 | {
43 | base.OnHandleCreated(e);
44 |
45 | if (!DesignMode)
46 | SetWindowRegion(Handle, 0, 0, Width, Height);
47 | }
48 |
49 | protected void ShowSystemMenu(MouseButtons buttons)
50 | {
51 | ShowSystemMenu(buttons, MousePosition);
52 | }
53 |
54 | protected static int MakeLong(short lowPart, short highPart)
55 | {
56 | return (int)(((ushort)lowPart) | (uint)(highPart << 16));
57 | }
58 |
59 | protected void ShowSystemMenu(MouseButtons buttons, Point pos)
60 | {
61 | NativeMethods.SendMessage(Handle, (int)WindowMessages.WM_SYSMENU, 0, MakeLong((short)pos.X, (short)pos.Y));
62 | }
63 |
64 | protected override void WndProc(ref Message m)
65 | {
66 | if (DesignMode)
67 | {
68 | base.WndProc(ref m);
69 | return;
70 | }
71 |
72 | switch (m.Msg)
73 | {
74 | case (int)WindowMessages.WM_NCCALCSIZE:
75 | {
76 | // Provides new coordinates for the window client area.
77 | WmNCCalcSize(ref m);
78 | break;
79 | }
80 | case (int)WindowMessages.WM_NCPAINT:
81 | {
82 | // Here should all our painting occur, but...
83 | WmNCPaint(ref m);
84 | break;
85 | }
86 | case (int)WindowMessages.WM_NCACTIVATE:
87 | {
88 | // ... WM_NCACTIVATE does some painting directly
89 | // without bothering with WM_NCPAINT ...
90 | WmNCActivate(ref m);
91 | break;
92 | }
93 | case (int)WindowMessages.WM_SETTEXT:
94 | {
95 | // ... and some painting is required in here as well
96 | WmSetText(ref m);
97 | break;
98 | }
99 | case (int)WindowMessages.WM_WINDOWPOSCHANGED:
100 | {
101 | WmWindowPosChanged(ref m);
102 | break;
103 | }
104 | case 174: // ignore magic message number
105 | {
106 | break;
107 | }
108 | default:
109 | {
110 | base.WndProc(ref m);
111 | break;
112 | }
113 | }
114 | }
115 |
116 | private void SetWindowRegion(IntPtr hwnd, int left, int top, int right, int bottom)
117 | {
118 | var rgn = NativeMethods.CreateRectRgn(0, 0, 0, 0);
119 | var hrg = new HandleRef((object)this, rgn);
120 | var r = NativeMethods.GetWindowRgn(hwnd, hrg.Handle);
121 | RECT box;
122 | NativeMethods.GetRgnBox(hrg.Handle, out box);
123 | if (box.left != left || box.top != top || box.right != right || box.bottom != bottom)
124 | {
125 | var hr = new HandleRef((object)this, NativeMethods.CreateRectRgn(left, top, right, bottom));
126 | NativeMethods.SetWindowRgn(hwnd, hr.Handle, NativeMethods.IsWindowVisible(hwnd));
127 | }
128 | NativeMethods.DeleteObject(rgn);
129 | }
130 |
131 | public FormWindowState MinMaxState
132 | {
133 | get
134 | {
135 | var s = NativeMethods.GetWindowLong(Handle, NativeConstants.GWL_STYLE);
136 | var max = (s & (int)WindowStyle.WS_MAXIMIZE) > 0;
137 | if (max) return FormWindowState.Maximized;
138 | var min = (s & (int)WindowStyle.WS_MINIMIZE) > 0;
139 | if (min) return FormWindowState.Minimized;
140 | return FormWindowState.Normal;
141 | }
142 | }
143 |
144 | private void WmWindowPosChanged(ref Message m)
145 | {
146 | DefWndProc(ref m);
147 | UpdateBounds();
148 | var pos = (WINDOWPOS)Marshal.PtrToStructure(m.LParam, typeof(WINDOWPOS));
149 | SetWindowRegion(m.HWnd, 0, 0, pos.cx, pos.cy);
150 | m.Result = NativeConstants.TRUE;
151 | }
152 |
153 | private void WmNCCalcSize(ref Message m)
154 | {
155 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowmessages/wm_nccalcsize.asp
156 | // http://groups.google.pl/groups?selm=OnRNaGfDEHA.1600%40tk2msftngp13.phx.gbl
157 |
158 | var r = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
159 | var max = MinMaxState == FormWindowState.Maximized;
160 |
161 | if (max)
162 | {
163 | var x = NativeMethods.GetSystemMetrics(NativeConstants.SM_CXSIZEFRAME);
164 | var y = NativeMethods.GetSystemMetrics(NativeConstants.SM_CYSIZEFRAME);
165 | var p = NativeMethods.GetSystemMetrics(NativeConstants.SM_CXPADDEDBORDER);
166 | var w = x + p;
167 | var h = y + p;
168 |
169 | r.left += w;
170 | r.top += h;
171 | r.right -= w;
172 | r.bottom -= h;
173 |
174 | var appBarData = new APPBARDATA();
175 | appBarData.cbSize = Marshal.SizeOf(typeof(APPBARDATA));
176 | var autohide = (NativeMethods.SHAppBarMessage(NativeConstants.ABM_GETSTATE, ref appBarData) & NativeConstants.ABS_AUTOHIDE) != 0;
177 | if (autohide) r.bottom -= 1;
178 |
179 | Marshal.StructureToPtr(r, m.LParam, true);
180 | }
181 |
182 | m.Result = IntPtr.Zero;
183 | }
184 |
185 | private void WmNCPaint(ref Message msg)
186 | {
187 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_8gdw.asp
188 | // example in q. 2.9 on http://www.syncfusion.com/FAQ/WindowsForms/FAQ_c41c.aspx#q1026q
189 |
190 | // The WParam contains handle to clipRegion or 1 if entire window should be repainted
191 | //PaintNonClientArea(msg.HWnd, (IntPtr)msg.WParam);
192 |
193 | // we handled everything
194 | msg.Result = NativeConstants.TRUE;
195 | }
196 |
197 | private void WmSetText(ref Message msg)
198 | {
199 | // allow the system to receive the new window title
200 | DefWndProc(ref msg);
201 |
202 | // repaint title bar
203 | //PaintNonClientArea(msg.HWnd, (IntPtr)1);
204 | }
205 |
206 | private void WmNCActivate(ref Message msg)
207 | {
208 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowmessages/wm_ncactivate.asp
209 |
210 | bool active = (msg.WParam == NativeConstants.TRUE);
211 |
212 | if (MinMaxState == FormWindowState.Minimized)
213 | DefWndProc(ref msg);
214 | else
215 | {
216 | // repaint title bar
217 | //PaintNonClientArea(msg.HWnd, (IntPtr)1);
218 |
219 | // allow to deactivate window
220 | msg.Result = NativeConstants.TRUE;
221 | }
222 | }
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | License
2 | =======
3 |
4 | [MIT X11](http://en.wikipedia.org/wiki/MIT_License)
5 |
--------------------------------------------------------------------------------
/MainForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace BorderlessForm
2 | {
3 | partial class MainForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.components = new System.ComponentModel.Container();
32 | this.TopLeftCornerPanel = new System.Windows.Forms.Panel();
33 | this.TopRightCornerPanel = new System.Windows.Forms.Panel();
34 | this.BottomLeftCornerPanel = new System.Windows.Forms.Panel();
35 | this.BottomRightCornerPanel = new System.Windows.Forms.Panel();
36 | this.TopBorderPanel = new System.Windows.Forms.Panel();
37 | this.BottomBorderPanel = new System.Windows.Forms.Panel();
38 | this.LeftBorderPanel = new System.Windows.Forms.Panel();
39 | this.RightBorderPanel = new System.Windows.Forms.Panel();
40 | this.MinimizeLabel = new System.Windows.Forms.Label();
41 | this.MaximizeLabel = new System.Windows.Forms.Label();
42 | this.CloseLabel = new System.Windows.Forms.Label();
43 | this.TitleLabel = new System.Windows.Forms.Label();
44 | this.SystemLabel = new System.Windows.Forms.Label();
45 | this.DecorationToolTip = new System.Windows.Forms.ToolTip(this.components);
46 | this.SuspendLayout();
47 | //
48 | // TopLeftCornerPanel
49 | //
50 | this.TopLeftCornerPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(87)))), ((int)(((byte)(154)))));
51 | this.TopLeftCornerPanel.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
52 | this.TopLeftCornerPanel.Location = new System.Drawing.Point(0, 0);
53 | this.TopLeftCornerPanel.Name = "TopLeftCornerPanel";
54 | this.TopLeftCornerPanel.Size = new System.Drawing.Size(1, 1);
55 | this.TopLeftCornerPanel.TabIndex = 0;
56 | //
57 | // TopRightCornerPanel
58 | //
59 | this.TopRightCornerPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
60 | this.TopRightCornerPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(87)))), ((int)(((byte)(154)))));
61 | this.TopRightCornerPanel.Cursor = System.Windows.Forms.Cursors.SizeNESW;
62 | this.TopRightCornerPanel.Location = new System.Drawing.Point(471, 0);
63 | this.TopRightCornerPanel.Name = "TopRightCornerPanel";
64 | this.TopRightCornerPanel.Size = new System.Drawing.Size(1, 1);
65 | this.TopRightCornerPanel.TabIndex = 1;
66 | //
67 | // BottomLeftCornerPanel
68 | //
69 | this.BottomLeftCornerPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
70 | this.BottomLeftCornerPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(87)))), ((int)(((byte)(154)))));
71 | this.BottomLeftCornerPanel.Cursor = System.Windows.Forms.Cursors.SizeNESW;
72 | this.BottomLeftCornerPanel.Location = new System.Drawing.Point(0, 246);
73 | this.BottomLeftCornerPanel.Name = "BottomLeftCornerPanel";
74 | this.BottomLeftCornerPanel.Size = new System.Drawing.Size(1, 1);
75 | this.BottomLeftCornerPanel.TabIndex = 1;
76 | //
77 | // BottomRightCornerPanel
78 | //
79 | this.BottomRightCornerPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
80 | this.BottomRightCornerPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(87)))), ((int)(((byte)(154)))));
81 | this.BottomRightCornerPanel.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
82 | this.BottomRightCornerPanel.Location = new System.Drawing.Point(471, 246);
83 | this.BottomRightCornerPanel.Name = "BottomRightCornerPanel";
84 | this.BottomRightCornerPanel.Size = new System.Drawing.Size(1, 1);
85 | this.BottomRightCornerPanel.TabIndex = 1;
86 | //
87 | // TopBorderPanel
88 | //
89 | this.TopBorderPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
90 | | System.Windows.Forms.AnchorStyles.Right)));
91 | this.TopBorderPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(87)))), ((int)(((byte)(154)))));
92 | this.TopBorderPanel.Cursor = System.Windows.Forms.Cursors.SizeNS;
93 | this.TopBorderPanel.Location = new System.Drawing.Point(1, 0);
94 | this.TopBorderPanel.Name = "TopBorderPanel";
95 | this.TopBorderPanel.Size = new System.Drawing.Size(470, 1);
96 | this.TopBorderPanel.TabIndex = 2;
97 | //
98 | // BottomBorderPanel
99 | //
100 | this.BottomBorderPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
101 | | System.Windows.Forms.AnchorStyles.Right)));
102 | this.BottomBorderPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(87)))), ((int)(((byte)(154)))));
103 | this.BottomBorderPanel.Cursor = System.Windows.Forms.Cursors.SizeNS;
104 | this.BottomBorderPanel.Location = new System.Drawing.Point(1, 246);
105 | this.BottomBorderPanel.Name = "BottomBorderPanel";
106 | this.BottomBorderPanel.Size = new System.Drawing.Size(470, 1);
107 | this.BottomBorderPanel.TabIndex = 3;
108 | //
109 | // LeftBorderPanel
110 | //
111 | this.LeftBorderPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
112 | | System.Windows.Forms.AnchorStyles.Left)));
113 | this.LeftBorderPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(87)))), ((int)(((byte)(154)))));
114 | this.LeftBorderPanel.Cursor = System.Windows.Forms.Cursors.SizeWE;
115 | this.LeftBorderPanel.Location = new System.Drawing.Point(0, 1);
116 | this.LeftBorderPanel.Name = "LeftBorderPanel";
117 | this.LeftBorderPanel.Size = new System.Drawing.Size(1, 245);
118 | this.LeftBorderPanel.TabIndex = 4;
119 | //
120 | // RightBorderPanel
121 | //
122 | this.RightBorderPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
123 | | System.Windows.Forms.AnchorStyles.Right)));
124 | this.RightBorderPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(87)))), ((int)(((byte)(154)))));
125 | this.RightBorderPanel.Cursor = System.Windows.Forms.Cursors.SizeWE;
126 | this.RightBorderPanel.Location = new System.Drawing.Point(471, 1);
127 | this.RightBorderPanel.Name = "RightBorderPanel";
128 | this.RightBorderPanel.Size = new System.Drawing.Size(1, 245);
129 | this.RightBorderPanel.TabIndex = 5;
130 | //
131 | // MinimizeLabel
132 | //
133 | this.MinimizeLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
134 | this.MinimizeLabel.BackColor = System.Drawing.Color.White;
135 | this.MinimizeLabel.Font = new System.Drawing.Font("Marlett", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
136 | this.MinimizeLabel.Location = new System.Drawing.Point(399, 1);
137 | this.MinimizeLabel.Name = "MinimizeLabel";
138 | this.MinimizeLabel.Size = new System.Drawing.Size(24, 24);
139 | this.MinimizeLabel.TabIndex = 7;
140 | this.MinimizeLabel.Text = "0";
141 | this.MinimizeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
142 | this.DecorationToolTip.SetToolTip(this.MinimizeLabel, "Minimize");
143 | //
144 | // MaximizeLabel
145 | //
146 | this.MaximizeLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
147 | this.MaximizeLabel.BackColor = System.Drawing.Color.White;
148 | this.MaximizeLabel.Font = new System.Drawing.Font("Marlett", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
149 | this.MaximizeLabel.Location = new System.Drawing.Point(423, 1);
150 | this.MaximizeLabel.Name = "MaximizeLabel";
151 | this.MaximizeLabel.Size = new System.Drawing.Size(24, 24);
152 | this.MaximizeLabel.TabIndex = 8;
153 | this.MaximizeLabel.Text = "1";
154 | this.MaximizeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
155 | this.DecorationToolTip.SetToolTip(this.MaximizeLabel, "Maximize");
156 | //
157 | // CloseLabel
158 | //
159 | this.CloseLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
160 | this.CloseLabel.BackColor = System.Drawing.Color.White;
161 | this.CloseLabel.Font = new System.Drawing.Font("Marlett", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
162 | this.CloseLabel.Location = new System.Drawing.Point(447, 1);
163 | this.CloseLabel.Name = "CloseLabel";
164 | this.CloseLabel.Size = new System.Drawing.Size(24, 24);
165 | this.CloseLabel.TabIndex = 9;
166 | this.CloseLabel.Text = "r";
167 | this.CloseLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
168 | this.DecorationToolTip.SetToolTip(this.CloseLabel, "Close");
169 | //
170 | // TitleLabel
171 | //
172 | this.TitleLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
173 | | System.Windows.Forms.AnchorStyles.Right)));
174 | this.TitleLabel.BackColor = System.Drawing.Color.White;
175 | this.TitleLabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
176 | this.TitleLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(68)))), ((int)(((byte)(68)))), ((int)(((byte)(68)))));
177 | this.TitleLabel.Location = new System.Drawing.Point(1, 1);
178 | this.TitleLabel.Name = "TitleLabel";
179 | this.TitleLabel.Size = new System.Drawing.Size(470, 24);
180 | this.TitleLabel.TabIndex = 10;
181 | this.TitleLabel.Text = "Title";
182 | this.TitleLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
183 | //
184 | // SystemLabel
185 | //
186 | this.SystemLabel.BackColor = System.Drawing.Color.White;
187 | this.SystemLabel.Location = new System.Drawing.Point(1, 1);
188 | this.SystemLabel.Name = "SystemLabel";
189 | this.SystemLabel.Size = new System.Drawing.Size(24, 24);
190 | this.SystemLabel.TabIndex = 11;
191 | this.SystemLabel.Text = "g";
192 | this.SystemLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
193 | //
194 | // MainForm
195 | //
196 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
197 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
198 | this.BackColor = System.Drawing.Color.White;
199 | this.ClientSize = new System.Drawing.Size(472, 247);
200 | this.Controls.Add(this.SystemLabel);
201 | this.Controls.Add(this.MinimizeLabel);
202 | this.Controls.Add(this.MaximizeLabel);
203 | this.Controls.Add(this.CloseLabel);
204 | this.Controls.Add(this.TitleLabel);
205 | this.Controls.Add(this.RightBorderPanel);
206 | this.Controls.Add(this.LeftBorderPanel);
207 | this.Controls.Add(this.BottomBorderPanel);
208 | this.Controls.Add(this.TopBorderPanel);
209 | this.Controls.Add(this.TopRightCornerPanel);
210 | this.Controls.Add(this.BottomLeftCornerPanel);
211 | this.Controls.Add(this.BottomRightCornerPanel);
212 | this.Controls.Add(this.TopLeftCornerPanel);
213 | this.Location = new System.Drawing.Point(0, 0);
214 | this.Name = "MainForm";
215 | this.Text = "Title";
216 | this.ResumeLayout(false);
217 |
218 | }
219 |
220 | #endregion
221 |
222 | private System.Windows.Forms.Panel TopLeftCornerPanel;
223 | private System.Windows.Forms.Panel TopRightCornerPanel;
224 | private System.Windows.Forms.Panel BottomLeftCornerPanel;
225 | private System.Windows.Forms.Panel BottomRightCornerPanel;
226 | private System.Windows.Forms.Panel TopBorderPanel;
227 | private System.Windows.Forms.Panel BottomBorderPanel;
228 | private System.Windows.Forms.Panel LeftBorderPanel;
229 | private System.Windows.Forms.Panel RightBorderPanel;
230 | private System.Windows.Forms.Label MinimizeLabel;
231 | private System.Windows.Forms.Label MaximizeLabel;
232 | private System.Windows.Forms.Label TitleLabel;
233 | private System.Windows.Forms.Label SystemLabel;
234 | private System.Windows.Forms.Label CloseLabel;
235 | private System.Windows.Forms.ToolTip DecorationToolTip;
236 | }
237 | }
238 |
239 |
--------------------------------------------------------------------------------
/MainForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Diagnostics;
6 | using System.Drawing;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Windows.Forms;
10 |
11 | namespace BorderlessForm
12 | {
13 | public partial class MainForm : FormBase
14 | {
15 | private FormWindowState previousWindowState;
16 |
17 | private Color hoverTextColor = Color.FromArgb(62, 109, 181);
18 |
19 | public Color HoverTextColor
20 | {
21 | get { return hoverTextColor; }
22 | set { hoverTextColor = value; }
23 | }
24 |
25 | private Color downTextColor = Color.FromArgb(25, 71, 138);
26 |
27 | public Color DownTextColor
28 | {
29 | get { return downTextColor; }
30 | set { downTextColor = value; }
31 | }
32 |
33 | private Color hoverBackColor = Color.FromArgb(213, 225, 242);
34 |
35 | public Color HoverBackColor
36 | {
37 | get { return hoverBackColor; }
38 | set { hoverBackColor = value; }
39 | }
40 |
41 | private Color downBackColor = Color.FromArgb(163, 189, 227);
42 |
43 | public Color DownBackColor
44 | {
45 | get { return downBackColor; }
46 | set { downBackColor = value; }
47 | }
48 |
49 | private Color normalBackColor = Color.White;
50 |
51 | public Color NormalBackColor
52 | {
53 | get { return normalBackColor; }
54 | set { normalBackColor = value; }
55 | }
56 |
57 | public enum MouseState
58 | {
59 | Normal,
60 | Hover,
61 | Down
62 | }
63 |
64 | protected void SetLabelColors(Control control, MouseState state)
65 | {
66 | if (!ContainsFocus) return;
67 |
68 | var textColor = ActiveTextColor;
69 | var backColor = NormalBackColor;
70 |
71 | switch (state)
72 | {
73 | case MouseState.Hover:
74 | textColor = HoverTextColor;
75 | backColor = HoverBackColor;
76 | break;
77 | case MouseState.Down:
78 | textColor = DownTextColor;
79 | backColor = DownBackColor;
80 | break;
81 | }
82 |
83 | control.ForeColor = textColor;
84 | control.BackColor = backColor;
85 | }
86 |
87 | public MainForm()
88 | {
89 | InitializeComponent();
90 |
91 | Activated += MainForm_Activated;
92 | Deactivate += MainForm_Deactivate;
93 |
94 | foreach (var control in new[] { SystemLabel, MinimizeLabel, MaximizeLabel, CloseLabel })
95 | {
96 | control.MouseEnter += (s, e) => SetLabelColors((Control)s, MouseState.Hover);
97 | control.MouseLeave += (s, e) => SetLabelColors((Control)s, MouseState.Normal);
98 | control.MouseDown += (s, e) => SetLabelColors((Control)s, MouseState.Down);
99 | }
100 |
101 | TopLeftCornerPanel.MouseDown += (s, e) => DecorationMouseDown(e, HitTestValues.HTTOPLEFT);
102 | TopRightCornerPanel.MouseDown += (s, e) => DecorationMouseDown(e, HitTestValues.HTTOPRIGHT);
103 | BottomLeftCornerPanel.MouseDown += (s, e) => DecorationMouseDown(e, HitTestValues.HTBOTTOMLEFT);
104 | BottomRightCornerPanel.MouseDown += (s, e) => DecorationMouseDown(e, HitTestValues.HTBOTTOMRIGHT);
105 |
106 | TopBorderPanel.MouseDown += (s, e) => DecorationMouseDown(e, HitTestValues.HTTOP);
107 | LeftBorderPanel.MouseDown += (s, e) => DecorationMouseDown(e, HitTestValues.HTLEFT);
108 | RightBorderPanel.MouseDown += (s, e) => DecorationMouseDown(e, HitTestValues.HTRIGHT);
109 | BottomBorderPanel.MouseDown += (s, e) => DecorationMouseDown(e, HitTestValues.HTBOTTOM);
110 |
111 | SystemLabel.MouseDown += SystemLabel_MouseDown;
112 | SystemLabel.MouseUp += SystemLabel_MouseUp;
113 |
114 | TitleLabel.MouseDown += TitleLabel_MouseDown;
115 | TitleLabel.MouseUp += (s, e) => { if (e.Button == MouseButtons.Right && TitleLabel.ClientRectangle.Contains(e.Location)) ShowSystemMenu(MouseButtons); };
116 | TitleLabel.Text = Text;
117 | TextChanged += (s, e) => TitleLabel.Text = Text;
118 |
119 | var marlett = new Font("Marlett", 8.5f);
120 |
121 | MinimizeLabel.Font = marlett;
122 | MaximizeLabel.Font = marlett;
123 | CloseLabel.Font = marlett;
124 | SystemLabel.Font = marlett;
125 |
126 | MinimizeLabel.MouseClick += (s, e) => { if (e.Button == MouseButtons.Left) WindowState = FormWindowState.Minimized; };
127 | MaximizeLabel.MouseClick += (s, e) => { if (e.Button == MouseButtons.Left) ToggleMaximize(); };
128 | previousWindowState = MinMaxState;
129 | SizeChanged += MainForm_SizeChanged;
130 | CloseLabel.MouseClick += (s, e) => Close(e);
131 | }
132 |
133 | void SystemLabel_MouseUp(object sender, MouseEventArgs e)
134 | {
135 | if (e.Button == MouseButtons.Right) ShowSystemMenu(MouseButtons);
136 | }
137 |
138 | private DateTime systemClickTime = DateTime.MinValue;
139 | private DateTime systemMenuCloseTime = DateTime.MinValue;
140 |
141 | void SystemLabel_MouseDown(object sender, MouseEventArgs e)
142 | {
143 | if (e.Button == MouseButtons.Left)
144 | {
145 | var clickTime = (DateTime.Now - systemClickTime).TotalMilliseconds;
146 | if (clickTime < SystemInformation.DoubleClickTime)
147 | Close();
148 | else
149 | {
150 | systemClickTime = DateTime.Now;
151 | if ((systemClickTime - systemMenuCloseTime).TotalMilliseconds > 200)
152 | {
153 | SetLabelColors(SystemLabel, MouseState.Normal);
154 | ShowSystemMenu(MouseButtons, PointToScreen(new Point(8, 32)));
155 | systemMenuCloseTime = DateTime.Now;
156 | }
157 | }
158 | }
159 | }
160 |
161 | void Close(MouseEventArgs e)
162 | {
163 | if (e.Button == MouseButtons.Left) Close();
164 | }
165 |
166 | void DecorationMouseDown(MouseEventArgs e, HitTestValues h)
167 | {
168 | if (e.Button == MouseButtons.Left) DecorationMouseDown(h);
169 | }
170 |
171 | private Color activeBorderColor = Color.FromArgb(43, 87, 154);
172 |
173 | public Color ActiveBorderColor
174 | {
175 | get { return activeBorderColor; }
176 | set { activeBorderColor = value; }
177 | }
178 |
179 | private Color inactiveBorderColor = Color.FromArgb(131, 131, 131);
180 |
181 | public Color InactiveBorderColor
182 | {
183 | get { return inactiveBorderColor; }
184 | set { inactiveBorderColor = value; }
185 | }
186 |
187 | void MainForm_Deactivate(object sender, EventArgs e)
188 | {
189 | SetBorderColor(InactiveBorderColor);
190 | SetTextColor(InactiveTextColor);
191 | }
192 |
193 | void MainForm_Activated(object sender, EventArgs e)
194 | {
195 | SetBorderColor(ActiveBorderColor);
196 | SetTextColor(ActiveTextColor);
197 | }
198 |
199 | private Color activeTextColor = Color.FromArgb(68, 68, 68);
200 |
201 | public Color ActiveTextColor
202 | {
203 | get { return activeTextColor; }
204 | set { activeTextColor = value; }
205 | }
206 |
207 | private Color inactiveTextColor = Color.FromArgb(177, 177, 177);
208 |
209 | public Color InactiveTextColor
210 | {
211 | get { return inactiveTextColor; }
212 | set { inactiveTextColor = value; }
213 | }
214 |
215 | protected void SetBorderColor(Color color)
216 | {
217 | TopLeftCornerPanel.BackColor = color;
218 | TopBorderPanel.BackColor = color;
219 | TopRightCornerPanel.BackColor = color;
220 | LeftBorderPanel.BackColor = color;
221 | RightBorderPanel.BackColor = color;
222 | BottomLeftCornerPanel.BackColor = color;
223 | BottomBorderPanel.BackColor = color;
224 | BottomRightCornerPanel.BackColor = color;
225 | }
226 |
227 | protected void SetTextColor(Color color)
228 | {
229 | SystemLabel.ForeColor = color;
230 | TitleLabel.ForeColor = color;
231 | MinimizeLabel.ForeColor = color;
232 | MaximizeLabel.ForeColor = color;
233 | CloseLabel.ForeColor = color;
234 | }
235 |
236 | void MainForm_SizeChanged(object sender, EventArgs e)
237 | {
238 | var maximized = MinMaxState == FormWindowState.Maximized;
239 | MaximizeLabel.Text = maximized ? "2" : "1";
240 |
241 | var panels = new[] { TopLeftCornerPanel, TopRightCornerPanel, BottomLeftCornerPanel, BottomRightCornerPanel,
242 | TopBorderPanel, LeftBorderPanel, RightBorderPanel, BottomBorderPanel };
243 |
244 | foreach (var panel in panels)
245 | {
246 | panel.Visible = !maximized;
247 | }
248 |
249 | if (previousWindowState != MinMaxState)
250 | {
251 | if (maximized)
252 | {
253 | SystemLabel.Left = 0;
254 | SystemLabel.Top = 0;
255 | CloseLabel.Left += RightBorderPanel.Width;
256 | CloseLabel.Top = 0;
257 | MaximizeLabel.Left += RightBorderPanel.Width;
258 | MaximizeLabel.Top = 0;
259 | MinimizeLabel.Left += RightBorderPanel.Width;
260 | MinimizeLabel.Top = 0;
261 | TitleLabel.Left -= LeftBorderPanel.Width;
262 | TitleLabel.Width += LeftBorderPanel.Width + RightBorderPanel.Width;
263 | TitleLabel.Top = 0;
264 | }
265 | else if (previousWindowState == FormWindowState.Maximized)
266 | {
267 | SystemLabel.Left = LeftBorderPanel.Width;
268 | SystemLabel.Top = TopBorderPanel.Height;
269 | CloseLabel.Left -= RightBorderPanel.Width;
270 | CloseLabel.Top = TopBorderPanel.Height;
271 | MaximizeLabel.Left -= RightBorderPanel.Width;
272 | MaximizeLabel.Top = TopBorderPanel.Height;
273 | MinimizeLabel.Left -= RightBorderPanel.Width;
274 | MinimizeLabel.Top = TopBorderPanel.Height;
275 | TitleLabel.Left += LeftBorderPanel.Width;
276 | TitleLabel.Width -= LeftBorderPanel.Width + RightBorderPanel.Width;
277 | TitleLabel.Top = TopBorderPanel.Height;
278 | }
279 |
280 | previousWindowState = MinMaxState;
281 | }
282 | }
283 |
284 | private FormWindowState ToggleMaximize()
285 | {
286 | return WindowState = WindowState == FormWindowState.Maximized ? FormWindowState.Normal : FormWindowState.Maximized;
287 | }
288 |
289 | private DateTime titleClickTime = DateTime.MinValue;
290 | private Point titleClickPosition = Point.Empty;
291 |
292 | void TitleLabel_MouseDown(object sender, MouseEventArgs e)
293 | {
294 | if (e.Button == MouseButtons.Left)
295 | {
296 | var clickTime = (DateTime.Now - titleClickTime).TotalMilliseconds;
297 | if (clickTime < SystemInformation.DoubleClickTime && e.Location == titleClickPosition)
298 | ToggleMaximize();
299 | else
300 | {
301 | titleClickTime = DateTime.Now;
302 | titleClickPosition = e.Location;
303 | DecorationMouseDown(HitTestValues.HTCAPTION);
304 | }
305 | }
306 | }
307 | }
308 | }
309 |
--------------------------------------------------------------------------------
/MainForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
--------------------------------------------------------------------------------
/Native.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 |
7 | namespace BorderlessForm
8 | {
9 | public enum GetWindow_Cmd : uint
10 | {
11 | GW_HWNDFIRST = 0,
12 | GW_HWNDLAST = 1,
13 | GW_HWNDNEXT = 2,
14 | GW_HWNDPREV = 3,
15 | GW_OWNER = 4,
16 | GW_CHILD = 5,
17 | GW_ENABLEDPOPUP = 6
18 | }
19 |
20 | public enum HitTestValues
21 | {
22 | HTERROR = -2,
23 | HTTRANSPARENT = -1,
24 | HTNOWHERE = 0,
25 | HTCLIENT = 1,
26 | HTCAPTION = 2,
27 | HTSYSMENU = 3,
28 | HTGROWBOX = 4,
29 | HTMENU = 5,
30 | HTHSCROLL = 6,
31 | HTVSCROLL = 7,
32 | HTMINBUTTON = 8,
33 | HTMAXBUTTON = 9,
34 | HTLEFT = 10,
35 | HTRIGHT = 11,
36 | HTTOP = 12,
37 | HTTOPLEFT = 13,
38 | HTTOPRIGHT = 14,
39 | HTBOTTOM = 15,
40 | HTBOTTOMLEFT = 16,
41 | HTBOTTOMRIGHT = 17,
42 | HTBORDER = 18,
43 | HTOBJECT = 19,
44 | HTCLOSE = 20,
45 | HTHELP = 21
46 | }
47 |
48 | public enum WindowMessages
49 | {
50 | WM_NULL = 0x0000,
51 | WM_CREATE = 0x0001,
52 | WM_DESTROY = 0x0002,
53 | WM_MOVE = 0x0003,
54 | WM_SIZE = 0x0005,
55 | WM_ACTIVATE = 0x0006,
56 | WM_SETFOCUS = 0x0007,
57 | WM_KILLFOCUS = 0x0008,
58 | WM_ENABLE = 0x000A,
59 | WM_SETREDRAW = 0x000B,
60 | WM_SETTEXT = 0x000C,
61 | WM_GETTEXT = 0x000D,
62 | WM_GETTEXTLENGTH = 0x000E,
63 | WM_PAINT = 0x000F,
64 | WM_CLOSE = 0x0010,
65 |
66 | WM_QUIT = 0x0012,
67 | WM_ERASEBKGND = 0x0014,
68 | WM_SYSCOLORCHANGE = 0x0015,
69 | WM_SHOWWINDOW = 0x0018,
70 |
71 | WM_ACTIVATEAPP = 0x001C,
72 |
73 | WM_SETCURSOR = 0x0020,
74 | WM_MOUSEACTIVATE = 0x0021,
75 | WM_GETMINMAXINFO = 0x24,
76 | WM_WINDOWPOSCHANGING = 0x0046,
77 | WM_WINDOWPOSCHANGED = 0x0047,
78 |
79 | WM_CONTEXTMENU = 0x007B,
80 | WM_STYLECHANGING = 0x007C,
81 | WM_STYLECHANGED = 0x007D,
82 | WM_DISPLAYCHANGE = 0x007E,
83 | WM_GETICON = 0x007F,
84 | WM_SETICON = 0x0080,
85 |
86 | // non client area
87 | WM_NCCREATE = 0x0081,
88 | WM_NCDESTROY = 0x0082,
89 | WM_NCCALCSIZE = 0x0083,
90 | WM_NCHITTEST = 0x84,
91 | WM_NCPAINT = 0x0085,
92 | WM_NCACTIVATE = 0x0086,
93 |
94 | WM_GETDLGCODE = 0x0087,
95 |
96 | WM_SYNCPAINT = 0x0088,
97 |
98 | // non client mouse
99 | WM_NCMOUSEMOVE = 0x00A0,
100 | WM_NCLBUTTONDOWN = 0x00A1,
101 | WM_NCLBUTTONUP = 0x00A2,
102 | WM_NCLBUTTONDBLCLK = 0x00A3,
103 | WM_NCRBUTTONDOWN = 0x00A4,
104 | WM_NCRBUTTONUP = 0x00A5,
105 | WM_NCRBUTTONDBLCLK = 0x00A6,
106 | WM_NCMBUTTONDOWN = 0x00A7,
107 | WM_NCMBUTTONUP = 0x00A8,
108 | WM_NCMBUTTONDBLCLK = 0x00A9,
109 |
110 | // keyboard
111 | WM_KEYDOWN = 0x0100,
112 | WM_KEYUP = 0x0101,
113 | WM_CHAR = 0x0102,
114 |
115 | WM_SYSCOMMAND = 0x0112,
116 |
117 | // menu
118 | WM_INITMENU = 0x0116,
119 | WM_INITMENUPOPUP = 0x0117,
120 | WM_MENUSELECT = 0x011F,
121 | WM_MENUCHAR = 0x0120,
122 | WM_ENTERIDLE = 0x0121,
123 | WM_MENURBUTTONUP = 0x0122,
124 | WM_MENUDRAG = 0x0123,
125 | WM_MENUGETOBJECT = 0x0124,
126 | WM_UNINITMENUPOPUP = 0x0125,
127 | WM_MENUCOMMAND = 0x0126,
128 |
129 | WM_CHANGEUISTATE = 0x0127,
130 | WM_UPDATEUISTATE = 0x0128,
131 | WM_QUERYUISTATE = 0x0129,
132 |
133 | // mouse
134 | WM_MOUSEFIRST = 0x0200,
135 | WM_MOUSEMOVE = 0x0200,
136 | WM_LBUTTONDOWN = 0x0201,
137 | WM_LBUTTONUP = 0x0202,
138 | WM_LBUTTONDBLCLK = 0x0203,
139 | WM_RBUTTONDOWN = 0x0204,
140 | WM_RBUTTONUP = 0x0205,
141 | WM_RBUTTONDBLCLK = 0x0206,
142 | WM_MBUTTONDOWN = 0x0207,
143 | WM_MBUTTONUP = 0x0208,
144 | WM_MBUTTONDBLCLK = 0x0209,
145 | WM_MOUSEWHEEL = 0x020A,
146 | WM_MOUSELAST = 0x020D,
147 |
148 | WM_PARENTNOTIFY = 0x0210,
149 | WM_ENTERMENULOOP = 0x0211,
150 | WM_EXITMENULOOP = 0x0212,
151 |
152 | WM_NEXTMENU = 0x0213,
153 | WM_SIZING = 0x0214,
154 | WM_CAPTURECHANGED = 0x0215,
155 | WM_MOVING = 0x0216,
156 |
157 | WM_ENTERSIZEMOVE = 0x0231,
158 | WM_EXITSIZEMOVE = 0x0232,
159 |
160 | WM_MOUSELEAVE = 0x02A3,
161 | WM_MOUSEHOVER = 0x02A1,
162 | WM_NCMOUSEHOVER = 0x02A0,
163 | WM_NCMOUSELEAVE = 0x02A2,
164 |
165 | WM_MDIACTIVATE = 0x0222,
166 | WM_HSCROLL = 0x0114,
167 | WM_VSCROLL = 0x0115,
168 |
169 | WM_SYSMENU = 0x313,
170 |
171 | WM_PRINT = 0x0317,
172 | WM_PRINTCLIENT = 0x0318,
173 | }
174 |
175 | public enum SystemCommands
176 | {
177 | SC_SIZE = 0xF000,
178 | SC_MOVE = 0xF010,
179 | SC_MINIMIZE = 0xF020,
180 | SC_MAXIMIZE = 0xF030,
181 | SC_MAXIMIZE2 = 0xF032, // fired from double-click on caption
182 | SC_NEXTWINDOW = 0xF040,
183 | SC_PREVWINDOW = 0xF050,
184 | SC_CLOSE = 0xF060,
185 | SC_VSCROLL = 0xF070,
186 | SC_HSCROLL = 0xF080,
187 | SC_MOUSEMENU = 0xF090,
188 | SC_KEYMENU = 0xF100,
189 | SC_ARRANGE = 0xF110,
190 | SC_RESTORE = 0xF120,
191 | SC_RESTORE2 = 0xF122, // fired from double-click on caption
192 | SC_TASKLIST = 0xF130,
193 | SC_SCREENSAVE = 0xF140,
194 | SC_HOTKEY = 0xF150,
195 |
196 | SC_DEFAULT = 0xF160,
197 | SC_MONITORPOWER = 0xF170,
198 | SC_CONTEXTHELP = 0xF180,
199 | SC_SEPARATOR = 0xF00F
200 | }
201 |
202 | [StructLayout(LayoutKind.Sequential)]
203 | public struct RECT
204 | {
205 | public int left;
206 | public int top;
207 | public int right;
208 | public int bottom;
209 |
210 | public RECT(int left, int top, int right, int bottom)
211 | {
212 | this.left = left;
213 | this.top = top;
214 | this.right = right;
215 | this.bottom = bottom;
216 | }
217 |
218 | public static RECT FromXYWH(int x, int y, int width, int height)
219 | {
220 | return new RECT(x,
221 | y,
222 | x + width,
223 | y + height);
224 | }
225 | }
226 |
227 | [StructLayout(LayoutKind.Sequential)]
228 | internal struct WINDOWPOS
229 | {
230 | internal IntPtr hwnd;
231 | internal IntPtr hWndInsertAfter;
232 | internal int x;
233 | internal int y;
234 | internal int cx;
235 | internal int cy;
236 | internal uint flags;
237 | }
238 |
239 | [StructLayout(LayoutKind.Sequential)]
240 | public struct POINTS
241 | {
242 | public short X;
243 | public short Y;
244 | }
245 |
246 | [Flags]
247 | public enum WindowStyle
248 | {
249 | WS_OVERLAPPED = 0x00000000,
250 | WS_POPUP = -2147483648, //0x80000000,
251 | WS_CHILD = 0x40000000,
252 | WS_MINIMIZE = 0x20000000,
253 | WS_VISIBLE = 0x10000000,
254 | WS_DISABLED = 0x08000000,
255 | WS_CLIPSIBLINGS = 0x04000000,
256 | WS_CLIPCHILDREN = 0x02000000,
257 | WS_MAXIMIZE = 0x01000000,
258 | WS_CAPTION = 0x00C00000,
259 | WS_BORDER = 0x00800000,
260 | WS_DLGFRAME = 0x00400000,
261 | WS_VSCROLL = 0x00200000,
262 | WS_HSCROLL = 0x00100000,
263 | WS_SYSMENU = 0x00080000,
264 | WS_THICKFRAME = 0x00040000,
265 | WS_GROUP = 0x00020000,
266 | WS_TABSTOP = 0x00010000,
267 | WS_MINIMIZEBOX = 0x00020000,
268 | WS_MAXIMIZEBOX = 0x00010000,
269 | WS_TILED = WS_OVERLAPPED,
270 | WS_ICONIC = WS_MINIMIZE,
271 | WS_SIZEBOX = WS_THICKFRAME,
272 | WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW,
273 | WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
274 | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX),
275 | WS_POPUPWINDOW = (WS_POPUP | WS_BORDER | WS_SYSMENU),
276 | WS_CHILDWINDOW = (WS_CHILD)
277 | }
278 |
279 | [StructLayout(LayoutKind.Sequential)]
280 | public struct NativeMessage
281 | {
282 | public IntPtr handle;
283 | public uint msg;
284 | public IntPtr wParam;
285 | public IntPtr lParam;
286 | public uint time;
287 | public System.Drawing.Point p;
288 | }
289 |
290 | [StructLayout(LayoutKind.Sequential)]
291 | public struct APPBARDATA
292 | {
293 | public int cbSize; // initialize this field using: Marshal.SizeOf(typeof(APPBARDATA));
294 | public IntPtr hWnd;
295 | public uint uCallbackMessage;
296 | public uint uEdge;
297 | public RECT rc;
298 | public int lParam;
299 | }
300 |
301 | public static class NativeMethods
302 | {
303 | [DllImport("user32.dll")]
304 | public static extern bool ReleaseCapture();
305 |
306 | [DllImport("user32.dll")]
307 | public static extern IntPtr SetCapture(IntPtr hWnd);
308 |
309 | [DllImport("user32.dll")]
310 | public static extern IntPtr GetCapture();
311 |
312 | [DllImport("user32.dll")]
313 | [return: MarshalAs(UnmanagedType.Bool)]
314 | public static extern bool SetForegroundWindow(IntPtr hWnd);
315 |
316 | [DllImport("user32.dll", SetLastError = true)]
317 | public static extern IntPtr SetActiveWindow(IntPtr hWnd);
318 |
319 | [DllImport("user32.dll")]
320 | public static extern int SendMessage(IntPtr hwnd, int msg, int wparam, int lparam);
321 |
322 | [DllImport("user32.dll")]
323 | public static extern int PostMessage(IntPtr hwnd, int msg, int wparam, int lparam);
324 |
325 | [DllImport("user32.dll")]
326 | public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
327 |
328 | [DllImport("user32.dll")]
329 | public static extern int TrackPopupMenuEx(IntPtr hmenu, uint fuFlags, int x, int y,
330 | IntPtr hwnd, IntPtr lptpm);
331 |
332 | [DllImport("user32.dll")]
333 | public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
334 |
335 | [DllImport("user32.dll")]
336 | public static extern int SendMessage(IntPtr hwnd, int msg, int wparam, POINTS pos);
337 |
338 | [DllImport("user32.dll")]
339 | public static extern int PostMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
340 |
341 | [DllImport("user32.dll")]
342 | public static extern int PostMessage(IntPtr hwnd, int msg, int wparam, POINTS pos);
343 |
344 | [DllImport("user32.dll")]
345 | public static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
346 |
347 | [DllImport("user32.dll")]
348 | [return: MarshalAs(UnmanagedType.Bool)]
349 | public static extern bool IsWindowVisible(IntPtr hWnd);
350 |
351 | [DllImport("gdi32.dll")]
352 | public static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
353 |
354 | [DllImport("user32.dll")]
355 | public static extern int GetWindowRgn(IntPtr hWnd, IntPtr hRgn);
356 |
357 | [DllImport("gdi32.dll")]
358 | public static extern int GetRgnBox(IntPtr hrgn, out RECT lprc);
359 |
360 | [DllImport("user32.dll")]
361 | public static extern Int32 GetWindowLong(IntPtr hWnd, Int32 Offset);
362 |
363 | [DllImport("user32.dll")]
364 | public static extern int GetSystemMetrics(int smIndex);
365 |
366 | [DllImport("user32.dll", SetLastError = true)]
367 | public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
368 |
369 | [DllImport("shell32.dll")]
370 | public static extern int SHAppBarMessage(uint dwMessage, [In] ref APPBARDATA pData);
371 |
372 | [DllImport("gdi32.dll")]
373 | public static extern bool DeleteObject(IntPtr hObj);
374 | }
375 |
376 | public static class NativeConstants
377 | {
378 | public const int SM_CXSIZEFRAME = 32;
379 | public const int SM_CYSIZEFRAME = 33;
380 | public const int SM_CXPADDEDBORDER = 92;
381 |
382 | public const int GWL_ID = (-12);
383 | public const int GWL_STYLE = (-16);
384 | public const int GWL_EXSTYLE = (-20);
385 |
386 | public const int WM_NCLBUTTONDOWN = 0x00A1;
387 | public const int WM_NCRBUTTONUP = 0x00A5;
388 |
389 | public const uint TPM_LEFTBUTTON = 0x0000;
390 | public const uint TPM_RIGHTBUTTON = 0x0002;
391 | public const uint TPM_RETURNCMD = 0x0100;
392 |
393 | public static readonly IntPtr TRUE = new IntPtr(1);
394 | public static readonly IntPtr FALSE = new IntPtr(0);
395 |
396 | public const uint ABM_GETSTATE = 0x4;
397 | public const int ABS_AUTOHIDE = 0x1;
398 | }
399 | }
400 |
--------------------------------------------------------------------------------
/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Windows.Forms;
5 |
6 | namespace BorderlessForm
7 | {
8 | static class Program
9 | {
10 | ///
11 | /// The main entry point for the application.
12 | ///
13 | [STAThread]
14 | static void Main()
15 | {
16 | Application.EnableVisualStyles();
17 | Application.SetCompatibleTextRenderingDefault(true);
18 | Application.Run(new MainForm());
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("BorderlessForm")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("BorderlessForm")]
13 | [assembly: AssemblyCopyright("Copyright © 2013")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("0e7f6f9f-7e75-4158-aa86-0cf9f8a3c2b2")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.18051
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace BorderlessForm.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BorderlessForm.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.18051
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace BorderlessForm.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BorderlessForm
2 |
3 | Implements a borderless window using Windows Forms that uses normal controls to preserve the functionality of sizable windows such as:
4 |
5 | - Move by dragging the title bar
6 | - Size by dragging the borders and corners
7 | - Maximize, minimize, and close buttons
8 | - System menu
9 | - Double click title bar to maximize
10 | - Aero snap
11 |
12 | The window decoration controls in the example are simple labels and can be changed to provide a custom look.
13 |
14 | Example screenshot:
15 |
16 | 
17 |
18 | Unsupported:
19 |
20 | - Border shadow ("glow"). Office 2013 and Visual Studio 2013 implement this using [4 additional top level windows](http://stackoverflow.com/a/15303486) that keep in sync with the main window's size and position.
21 |
22 |
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mganss/BorderlessForm/6f145e364f059b8e1b65a20dbf325d96e590d405/screenshot.png
--------------------------------------------------------------------------------