├── .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 | ![Example](screenshot.png "Example screenshot") 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 --------------------------------------------------------------------------------