Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to Remove a Titlebar from a .Sizable Form

Status
Not open for further replies.

PixelGod

Programmer
Aug 24, 2015
16
US
As some may already know, I am relatively new to the VB.net scene and I am learning as I go. With any luck, you guys can help me (yet again)! Everyone has been extremely helpful and patient with me so far. Let's see if you can assist with me with my latest conundrum:

I have created a new form with FormBorderStyle.Sizable as its border option. However, I do not want the Titlebar present on the form because I have created my own custom titlebars. However, when I removed the form's caption and controlbox, there is still a "ghost" titlebar present. Albeit, much smaller than the original, for some reason I cannot get it to disappear. (Screenshot attached) Any ideas?

Code:
newForm.FormBorderStyle = FormBorderStyle.Sizable
newForm.ControlBox = False
newForm.Text = ""

In advance, thank you for you assistance!
 
 http://files.engineering.com/getfile.aspx?folder=76b3be34-6016-4910-b478-92858ae118c0&file=TitlebarWindow.png
A number of thoughts:

[ol 1]
[li]You could use your current method, but lower the position of your titlebar by a few pixels - probably the easiest method.[/li]
[li]You could use [tt]FormBorderStyle.None[/tt], but then you would have to handle the various mouse events to do your own sizing code - not as easy as 1, but much easier than 3.[/li]
[li]The nastiest, but probably most effective would be to trap low level Windows Messages. I've not done this for several years, but there should be plenty of advice here or on other forums - in the meantime I'll try to find something I've written (although it will be for VS 2005 or VS 2008 and for Windows XP)[/li]
[/ol]
 
Sorry, I forgot to say that if you use method 3 you would need to look at Windows Messages relating to the ClientArea and NonClientArea - it may be possible to set the NonClientArea Size to 0, which should remove the TitleBar completely.
 
softhemc, again I appreciate all of the great help!

However, I am slightly unclear as to what you mean by "lower the position of your titlebar." Are you referencing the form-generated titlebar, or the custom designed one?

If it is the first option, I was not aware that we could manually control the height of the form titlebar. If so, I would like to set it at 0 so that my custom titlebar is at the very top of the form as a titlebar should be!

If it is the later, this will not work for the effect I want to achieve. If you view the screenshot there is the block of white space just above the titlebar that I need to get rid of. It is making my brain hurt trying to determine why the current code is not abolishing it from my current form. (Works fine in different FormBorderStyles)

I toyed with the idea of using [tt]FormBorderStyle.None[/tt], but I am not very familiar with the system drawing tools, nor am I sure of how I would add a handler for the created border itself. My fear is that if I used a "MouseOver" even for a rectangle area, it would cover the entire surface area of the form since the border encompasses it!

I have read a few article about manipulating &hwnd or some other things like that, but I do not understand most of it when I read it and am a bit hesitant with trying to jump into it.

Please provide any other ideas that you may come up with. I will mess with a few different hypothesis that I am boiling-up and return with my results.

Again, many thanks!
 
I'll be tied up for the next couple of hours - but I'll see what I can come up with a bit later.

 
I've had a quick look at the image and could you not move your custom titlebar up by a couple of pixels?
 
softhemc,

No, it's not really possible. The custom titlebar is currently set to [tt]TitleBar.Top = 0[/tt], unless there is some other method I could use. If this portion of the form was actually part of the client, though, wouldn't it be filled with the form background color?
 
What happens if you use SizableToolWindow instead of Sizable? And what version of Windows are you running this on?
 
Same result using [tt]FormBorderStyle.SizableToolWindow[/tt]. I am running Visual Studio Community 2015 on Windows 10.
 
Well, your question inspired a functional investigation. I went ahead and compiled my current program and transferred it to a USB. I ran the program on my Windows 7 machine, and viola(!), the white space was gone!

So... now it appears that we have an API issue with Windows 10 when applying this code. [pc1] I am not exactly sure how to tackle this, and that does not bode well for any past programs that utilize the same coding.

Will continue to dig to see if I can generate a plausible resolution. Please see the attached image to see the Windows 7 results.
 
 http://files.engineering.com/getfile.aspx?folder=d2f5dd4d-7938-4fe6-b761-c875497a10b4&file=TitlebarWindow7.png
Yep, the reason I asked was because my own testing on XP and W7 did not exhibit the problem.
 
I've just spotted your conversations with strongm, which makes redundant that I was going to say that the appearance is as required under Win7 using both VS2013 and VS2015, but that under Win10 the problem is experienced.

I've tried to remove the problem using the OnPaint event, but to no avail. I haven't been able to locate my low level stuff - it was written for a former client and I don't have a copy of the source.

I'm looking at one or two other things, so I'll get back to you later.
 
I appreciate all of the help. You guys have been absolutely splendid during this whole process. I attempted to simply set the [tt]FormBorderStyle[/tt] to [tt]FormBorderStyle.FixedToolWindow[/tt] and then handling mouse events to still make it sizable, but the program keeps throwing error codes and crashing.

I then attempted to do a borderless window and draw my own bounding box that allowed adjusting the form -- I apparently have no clue how to draw a box in vb.net.

I opened a like-minded question on another forum to see if I could fish for more suggestions. The only thing provided was to set the border to [tt]None[/tt] and that we had to override WndProc() and handle the WM_NCHITTEST message. Then somehow handle [tt]m.Result[/tt] to the "appropriate edge constant". Now, reading this, it sounds like something I could try, but I must be honest -- it's like reading a foreign language to me! I do not know what any of these events or procedures are. I am going to do my research on them and attempt some sort of code based on it, but if you have any iota on what to do with this, feel free to make more suggestions!

Again, I will be sure to report back on any findings. Thanks!
 
That suggestion was my option 3 in my first reply, but I no longer have access to my original source code so I would need to research this again from scratch. It will take too long for me to do between now and the weekend, so if nothing has materialised between now and then I'll have a go at that.

Maybe strongm has something using the API that he could suggest, since I think he has answered some questions on that in the VB 6 forum.
 
I'm over 90% certain I have a solution - but it will take me a while to put a test program together, so as I said earlier I'll do this over the weekend. By the way it does not involve any nasty low level calls.
 
Let me know what you find out! I know that I was able to establish a drag-and-drop protocol without low level hub-bub, but this WndProc stuff has me stumped. I was able to successfully utilize it to resize forms set to [tt]FormBorderStyle.None[/tt] and [tt]FormBorderStyle.FixedToolWindow[/tt], but I cannot seem to parse it in a way that I can effectively utilize it in a dynamically-created form. The code uses calls to [tt]Me.Bounds[/tt], but this form reference cannot be used in a form that doesn't currently exist! Trying to figure out how I can put this code into the form at creation time, but I'm running out of ideas.

So, anything new may provide me the steam and inspiration I need. If only Windows 10 has been as polite enough as to incorporate an easier way to perform what would seem such a standard task!

Thank you for all of the help, by all means, do not take unnecessary time out of your weekend for me! Get back to me at your leisure -- I'll be around.
 
Most of what I tried yesterday nearly worked - but I've got a new solution which will almost certainly work. I'll post this late tomorrow.
 
Well, I was able to produce the effect that I wanted, but the code seems to make for a very sluggish windowed interface and the click & drag subroutine that I created is now very jerky across the screen. May be due to a slower redraw rate due to whatever the new code is doing to slow things down. I will put my work-around resolution here, but if you are able to find something simpler and cleaner -- I will gladly accept it!

I modulated the [tt]WndProc[/tt] code due to the need to put this as the handler for multiple windows when I needed it. So, I created a new class called [tt]SubclassHWND.vb[/tt]:

Code:
Public Class SubclassHWND
    Inherits NativeWindow

    Public Const WM_NCHITTEST = &H84
    Public Const BorderSize As Integer = 10
    Public frm As Form = Nothing

    Public Sub setFrm(ByVal sender As Form)
        frm = sender
    End Sub

    Protected Overloads Overrides Sub WndProc(ByRef m As Message)
        if m.Msg = WM_NCHITTEST Then
            Dim x As Integer = m.LParam.ToInt32 And &HFFFF
            Dim y As Integer = (m.LParam.ToInt32 >> 16) And &HFFFF
            Dim p As Point = New Point(x, y)
            If frm.Bounds.Contains(p) Then
                Dim top As Boolean = Math.Abs(frm.Bounds.Y - y) < BorderSize
                Dim bottom As Boolean = Math.Abs(frm.Bounds.Bottom - y) < BorderSize
                Dim left As Boolean = Math.Abs(frm.Bounds.X - x) < BorderSize
                Dim right As Boolean = Math.Abs(frm.Bounds.Right - x) < BorderSize
                If top And left Then
                    m.Result = NCHITTEST.HTTOPLEFT
                ElseIf top And right Then
                    m.Result = NCHITTEST.HTTOPRIGHT
                ElseIf bottom And left Then
                    m.Result = NCHITTEST.HTBOTTOMLEFT
                ElseIf bottom And right Then
                    m.Result = NCHITTEST.HTBOTTOMRIGHT
                ElseIf top Then
                    m.Result = NCHITTEST.HTTOP
                ElseIf bottom Then
                    m.Result = NCHITTEST.HTBOTTOM
                ElseIf left Then
                    m.Result = NCHITTEST.HTLEFT
                ElseIf right Then
                    m.Result = NCHITTEST.HTRIGHT
                Else
                    m.Result = NCHITTEST.HTCAPTION
                End If
                Exit Sub
            End If
        End If
        Debug.WriteLine(m.ToString())
        MyBase.WndProc(m)
    End Sub
End Class

Public Enum NCHITTEST
    HTBOTTOM = 15
    HTBOTTOMLEFT = 16
    HTBOTTOMRIGHT = 17
    HTCAPTION = 2
    HTLEFT = 10
    HTRIGHT = 11
    HTTOP = 12
    HTTOPLEFT = 13
    HTTOPRIGHT = 14
End Enum

In the code I use to generate the forms I inserted:

Code:
newForm.FormBorderStyle = FormBorderStyle.FixedToolWindow
newForm.ControlBox = False
newForm.Text = String.Empty
Dim s As SubclassHWND = New SubclassHWND()
s.setFrm(newForm)
s.AssignHandle(newForm.Handle)

This is certainly a lot to swallow, and I was hoping that Windows would have a cleaner way to manipulate all of this, but alas, they do not. If you can think of anything that may work in it stead, please let me know! Again, thank you for all of the wonderful help and ideas that you have already supplied. I couldn't have done it otherwise. :)

Hoorah! A sizable window in Windows 10 without that pesky white bar at the top. Looks much cleaner.
 
Sorry this has taken so long, I've had a few other things on.

I've got a solution which seems to work very smoothly, but does involve a "cheat". I'm doing some more testing and also trying to remove the cheat.

I'll post the solution by the end of tomorrow, hopefully without the cheat.
 
I'm still using the 'cheat', however I think you might want to consider it aswell.

Create a very basic form with only what will be used in all your created forms e.g. Blank out the TitleBar and set the FormBorderStyle. Also if your replacement TitleBar is standard across all your created forms then include that as well. The benefits are all the prebuilt Events and Properties that come with the form avoiding potential AddHandler and RemoveHandler code etc.

So I've used this (below is the formname.Designer.vb page - use show all files to see it in Solution Explorer:)
Code:
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class MyCodeDesignedForm
	Inherits System.Windows.Forms.Form

	'Form overrides dispose to clean up the component list.
	<System.Diagnostics.DebuggerNonUserCode()> _
	Protected Overrides Sub Dispose(ByVal disposing As Boolean)
		Try
			If disposing AndAlso components IsNot Nothing Then
				components.Dispose()
			End If
		Finally
			MyBase.Dispose(disposing)
		End Try
	End Sub

	'Required by the Windows Form Designer
	Private components As System.ComponentModel.IContainer

	'NOTE: The following procedure is required by the Windows Form Designer
	'It can be modified using the Windows Form Designer.  
	'Do not modify it using the code editor.
	<System.Diagnostics.DebuggerStepThrough()> _
	Private Sub InitializeComponent()
		Me.SuspendLayout()
		'
		'MyCodeDesignedForm
		'
		Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
		Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
		Me.ClientSize = New System.Drawing.Size(643, 299)
		Me.ControlBox = False
		Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow
		Me.MaximizeBox = False
		Me.MinimizeBox = False
		Me.Name = "MyCodeDesignedForm"
		Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
		Me.ResumeLayout(False)

	End Sub
End Class
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top