Solved

VB.NET Changing Toolbar GUI

Posted on 2003-11-08
21
1,324 Views
Last Modified: 2007-12-19
Hey all,

I've been wondering to change the Toolbar GUI (or in general every control GUI). Dunno if what I say is correct but I want to change the appearance of the Toolbar :). I've came very far in this all but I've still not found what I actually want. If you watch controls correctly you see a small black line beside it. Especially when you got a MDI Form on it with a flat Toolbar (docked left). So I have been wondering if it isn't possible to just remake the whole Toolbar GUI, so also the 3d border you see. I've made the following with all I've seen on the internet.

Filename: Toolbar.vb

Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Text
Imports System.Windows.Forms

Public Class CustomToolbar
    Inherits System.Windows.Forms.ToolBar

    Public Sub New()
        Me.SetStyle(ControlStyles.UserPaint, True)
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        ControlPaint.DrawBorder3D(e.Graphics, e.ClipRectangle, Border3DStyle.Flat)
    End Sub
End Class


If you run this code you will see a nice flat border inside the Toolbar. What I want is to only see this Border and not the black lines from the normal Toolbar. I've already tried to set the left -1, top-1 but that's not working. Then the border is gone :/ (At least the left and top border.)

I've already made a way around it tho but I rather see it in the control then the solution I have now:
I made a picturebox over the black line in a specific color with width 2. So then the black line is gone and it looks quiet good but I don't think it's a nice way to do it right?

So I wonder if you can completely rewrite the Paint() / OnPaint() sub or something like that. Like forms. They have 3d borders that I can't change. I'd like to see those flat too ;). Can someone give me a clue? The appearance->flat doesn't do what I want ;p. Same as FormBorderStyle.

Thanks in advance,
 Tony
0
Comment
Question by:paing0d
  • 13
  • 4
  • 2
  • +2
21 Comments
 

Author Comment

by:paing0d
ID: 9710383
Does anybody know if it's possible or not? Since I haven't seen a single reaction yet :/
0
 

Author Comment

by:paing0d
ID: 9711229
It has something to do with this I guess:

    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Dim cParams As CreateParams
            cParams = MyBase.CreateParams

            cParams.ExStyle = cParams.ExStyle Or 512
            cParams.Style = cParams.Style Or 8388608

            Return cParams
        End Get
    End Property

This will make a sunken Toolbar. Know I just need to find out how to make it transparant or invisible :p
It's all in the WinUser.h but I don't know how to convert it to integers yet :/ or even better... use it as it
is written there, like: #define WS_BORDER           0x00800000L
0
 
LVL 4

Expert Comment

by:NetPointer
ID: 9711929
Paing0d is correct, u have to override createparams for this...

NetPointer
0
 

Author Comment

by:paing0d
ID: 9715106
I tried to do it but I don't know what constants I need to use. Can someone help me with that? Since I know it's all in the WinUser.h.

I need to know how to use the vars in WinUser.h. Any clue? Even if you make custom controls they got a black line if they are docked to the left. I really need more help with this all. I found lots and I know I'm almost there :)
0
 
LVL 4

Expert Comment

by:NetPointer
ID: 9716841
private const CONSTANTFROMWINUSER = HEXVALUE

u define it like this and then use it in your createparams...

HTH
NetPointer
0
 

Author Comment

by:paing0d
ID: 9717121
can you give an example plz?

This is in the WinUser.h
#define WS_BORDER           0x00800000L

Would it be something like this?
private const WS_BORDER= 0x00800000L (this doesn't work)

since I believe 0x00800000L are bits and its not a hex value.
How to convert the bits to hex? Maybe some other solution? :)
0
 
LVL 4

Expert Comment

by:NetPointer
ID: 9717618
Here is one example:
try this for yr solution: Const x As Integer = &H800000

Public Class NumTextbox
    Inherits TextBox
    Const ES_NUMBER As Integer = &H2000

    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Dim param As System.Windows.Forms.CreateParams
            param = MyBase.CreateParams
            param.Style = param.Style Or ES_NUMBER
            Return param
        End Get
    End Property
End Class
0
 

Author Comment

by:paing0d
ID: 9718626
so basicly:

#define BF_LEFT         0x0001
#define BF_TOP          0x0002
#define BF_RIGHT        0x0004
#define BF_BOTTOM       0x0008

becomes:
Const BF_LEFT As Integer = &H1
Const BF_TOP As Integer = &H2
Const BF_RIGHT As Integer = &H4
Const BF_BOTTOM As Integer = &H8

is that correct?

Still need to find out what constants I need to use to make the blackline dissapear ;p
You will hear more soon I hope :x
0
 

Author Comment

by:paing0d
ID: 9758463
Still need help :( Dunno what to do :/
0
 
LVL 4

Expert Comment

by:NetPointer
ID: 9765743
Hey, where u had stuck?

elaborate and I will try to help u..

what u mean by blackline?

Regards,
NetPointer
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 

Author Comment

by:paing0d
ID: 9767091
Make the following:
- MDI Form
- Toolbar docked left at MDI Form
- MDI Child Form

In the mdiform_load you make a new instance of the MDI Child Form. If you maximize the MDI Child Form (inside the MDI Form) then you see at the right of the toolbar and left of the MDI Child Form a black line. So if you see it like I see it you see a thick black line :). I want that line to dissapear, but I don't know how, since I need to use vars I think that give me the possibility to do it but which ones? Also I can't change everything in the Toolbar GUI. If you modify the Toolbar GUI there are certain regions I can't modify, and that is the border (about 2px at left, 2px at top, 2px at right and 2px at bottom). That's the only thing I need to know. How to totally 'remake' the Toolbar (or in general every control) GUI. Since I can't 'totally' remake it. Still regions I can't modify.
0
 

Author Comment

by:paing0d
ID: 9846570
Nobody knows how to make the control GUI's I want? :(
0
 

Author Comment

by:paing0d
ID: 9878591
I know it's possible since the .NET studio has it. It's all flat even the borders (so they must have rewritten the GUI right?). Can nobody put me on the right track again? I really like to know how to make it all flat in general, and I like to make it my self too (so getting components from other developers isn't really an option for me.) If I can make it totally flat then I believe I can totally rewrite the component's GUI? Maybe I'm confused and just talking things that don't make sense but then please tell me so I know how to get on the right track again.

Thanks in advance,
Tony
0
 
LVL 3

Expert Comment

by:the-edge
ID: 9880800
this question is very interesting. i'm sorry but i can't help you, i'm also monitoring this question cause i want to know it too.
maybe consider a reposting of this question, old question are often ignored.

bye

the edge
0
 

Author Comment

by:paing0d
ID: 9890031
Oh man I'm so close...
I found the following:
http://www.dotnet247.com/247reference/msgs/21/109372.aspx
http://www.syncfusion.com/FAQ/WinForms/FAQ_c41c.asp#q1027q

Can someone please translate it to VB.NET? Most I can translate my self but it would be nice if someone can translate it for me.
Especially the following parts:
cparams.ExStyle &= ~512 /*WS_EX_CLIENTEDGE*/;
cparams.Style &= ~8388608 /*WS_BORDER*/;  
cp.Style |= 0x800000; // WS_BORDER

No clue how to translate that into VB.NET. I hope someone can help me with translating the following:
http://www.syncfusion.com/FAQ/WinForms/FAQ_c41c.asp#q1027q

          protected override CreateParams CreateParams
          {
               get
               {
                     System.Windows.Forms.CreateParams cp = base.CreateParams;
                     if(this.needFlatBorder)
                     {
                          cparams.ExStyle &= ~512 /*WS_EX_CLIENTEDGE*/;
                         cparams.Style &= ~8388608 /*WS_BORDER*/;
                         cp.Style |= 0x800000; // WS_BORDER
                    }
               }
          }
 
          protected override void WndProc(ref Message m)
          {
               if(m.Msg == 133/*WM_NCPAINT*/)
               {
                    this.DrawFlatNCBorder(ref m);
               }
               base.WndProc(ref m);
          }
 
          private void DrawFlatNCBorder(ref Message msg)
          {
               IntPtr hRgn1 = (IntPtr) msg.WParam;
               // The update region is clipped to the window frame. When wParam is 1, the entire window frame needs to be updated.
               IntPtr hdc = NativeMethods.GetDCEx(msg.HWnd, hRgn1, 1/*DCX_WINDOW*/|0x0020/*DCX_PARENTCLIP*/);
               if (hdc != IntPtr.Zero)
               {
                    using (Graphics g = Graphics.FromHdc(hdc))
                    {
                         Rectangle bounds = new Rectangle(0,0,this.Width,this.Height);
                         ControlPaint.DrawBorder(g,bounds,this.borderColor,ButtonBorderStyle.Solid);
 
                         // create a clipping region for remaining parts to be drawn excluding
                         // the border we did just drew
                         bounds.Inflate(-1, -1);
                         IntPtr hRgn2 = NativeMethods.CreateRectRgn(bounds.Left, bounds.Top, bounds.Right, bounds.Bottom);

                         if(hRgn2 == (IntPtr)1)
                         {
                              // Provide a new clipping region.
                              msg.WParam = (IntPtr) hRgn2;
                         }
                         else
                         {
                              // combine with existing clipping region.
                              NativeMethods.CombineRgn(hRgn1, hRgn1, hRgn2, NativeMethods.RGN_AND);
                              NativeMethods.DeleteObject(hRgn2);
                         }
                    }
                    msg.Result = (IntPtr) 1;
                    NativeMethods.ReleaseDC(msg.HWnd, hdc);
               }                
               Invalidate();
          }
 
Tony
0
 

Author Comment

by:paing0d
ID: 9890166
Protected Overrides ReadOnly Property CreateParams() As CreateParams
   Get
      Dim cp As System.Windows.Forms.CreateParams = MyBase.CreateParams
      cparams.ExStyle = cparams.ExStyle And Not 512 'WS_EX_CLIENTEDGE
      cparams.Style = cparams.Style And Not 8388608 'WS_BORDER
      cp.Style = cp.Style Or &H800000 ' WS_BORDER
   End Get
End Property


Protected Overrides Sub WndProc(ByRef m As Message)
   If m.Msg = 133 Then 'WM_NCPAINT
      Me.DrawFlatNCBorder(m)
   End If
   MyBase.WndProc(m)
End Sub 'WndProc

I believe this is correct? Couldn't fix the following:
      If Me.needFlatBorder Then 'Me.needFlatBorder doesn't exist
         cparams.ExStyle = cparams.ExStyle And Not 512 'WS_EX_CLIENTEDGE
         cparams.Style = cparams.Style And Not 8388608 'WS_BORDER
         cp.Style = cp.Style Or &H800000 ' WS_BORDER
      End If

so I made it into:
         cparams.ExStyle = cparams.ExStyle And Not 512 'WS_EX_CLIENTEDGE
         cparams.Style = cparams.Style And Not 8388608 'WS_BORDER
         cp.Style = cp.Style Or &H800000 ' WS_BORDER

Now it's just the last method that needs translation if the above is correct.

Tony
0
 

Author Comment

by:paing0d
ID: 9891942
Still having some problems tho.
This is what I think it should be but there are 2 problems left:

    Private Sub DrawFlatNCBorder(ByRef msg As Message)
        Dim hRgn1 As IntPtr = CType(msg.WParam, IntPtr)
        Dim bounds As New Rectangle(0, 0, Me.Width, Me.Height)
        Dim hRgn2 As IntPtr = NativeMethods.CreateRectRgn(bounds.Left, bounds.Top, bounds.Right, bounds.Bottom)

        ' The update region is clipped to the window frame. When wParam is 1, the entire window frame needs to be updated.

        Dim hdc As IntPtr = NativeMethods.GetDCEx(msg.HWnd, hRgn1, 1 Or &H20) 'DCX_WINDOW
        'DCX_PARENTCLIP

        If Not hdc.Equals(IntPtr.Zero) Then
            Dim g As Graphics = Graphics.FromHdc(hdc)
            Try
                ControlPaint.DrawBorder(g, bounds, Me.borderColor, ButtonBorderStyle.Solid)

                ' create a clipping region for remaining parts to be drawn excluding
                ' the border we did just drew
                bounds.Inflate(-1, -1)

                If hRgn2.Equals(New System.IntPtr(1)) Then
                    ' Provide a new clipping region.
                    msg.WParam = hRgn2
                Else
                    ' combine with existing clipping region.
                    NativeMethods.CombineRgn(hRgn1, hRgn1, hRgn2, NativeMethods.RGN_AND)
                    NativeMethods.DeleteObject(hRgn2)
                End If
            Finally
                g.Dispose()
            End Try

            msg.Result = New System.IntPtr(1)
            NativeMethods.ReleaseDC(msg.HWnd, hdc)
        End If

        Invalidate()
    End Sub 'DrawFlatNCBorder

'System.Drawing.NativeMethods' is not accessible in this context because it is 'Private'.
'borderColor' is not a member of 'WindowsApplication1.UserControl1'.

I hope when those are fixed that it's gonna work.
Btw I'm glad that someone replied. Even tho you doesn't know the answer
it keeps stimulating me to find the answer. Been quiet for a while but
now I'm more stimulated then ever to find the answer :)

Take care guys,
Tony
0
 
LVL 3

Expert Comment

by:the-edge
ID: 9893403
>>'borderColor' is not a member of 'WindowsApplication1.UserControl1'

System.Windows.Forms.UserControl has not a borderColor property; try to declare it by yourself.

can you post the entire class or mail me it so i can try it on my pc?
my mail is

g2k2 @ _nospam_ katamail . com

(remove spaces and _nospam_)

the edge
0
 

Author Comment

by:paing0d
ID: 9893565
Hey thanks for your reply but I think I've found a better way to do it.
Check this out :)

    Public Declare Function GetWindowDC Lib "user32" Alias "GetWindowDC" (ByVal hwnd As Int32) As IntPtr
    Public Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" (ByVal hwnd As Int32, ByVal hdc As Int32) As IntPtr

    Protected Overrides Sub WndProc(ByRef m As Message)
        Const WM_NCPAINT As Integer = &H85
        If m.Msg = WM_NCPAINT Then
            Dim hDC As IntPtr = GetWindowDC(m.HWnd.ToInt32)
            Dim graph As Graphics = Graphics.FromHdc(hDC)
            Dim pen1 As New Pen(Color.Blue)
            Dim pen2 As New Pen(Color.Yellow)

            Dim width As Integer = Bounds.Width - 1
            Dim height As Integer = Bounds.Height - 1

            graph.DrawRectangle(pen1, 0, 0, width, height)
            'graph.DrawRectangle(pen2, 1, 1, width - 2, height - 2)

            pen1.Dispose()
            pen2.Dispose()
            graph.Dispose()
            ReleaseDC(m.HWnd.ToInt32, hDC.ToInt32)

            m.Result = IntPtr.Zero
        Else
            MyBase.WndProc(m)
        End If
    End Sub 'WndProc

If you make a custom control and put this in it then you get a blue border in the non-client area :D
Just need to test it out a little and I hope it solves my 'problem'. Btw I've changed the code a bit, so maybe
it aint fully working. Changed the Long to Int32 and some other things too, but this is working fine for me.
Tomorrow is a great day for research :p

Tony
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 10256259
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

PAQ with points refunded

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

TheLearnedOne
EE Cleanup Volunteer
0
 

Accepted Solution

by:
SpazMODic earned 0 total points
ID: 10314765
PAQed, with points refunded (500)

SpazMODic
EE Moderator
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Normally the drop down box control found in the .Net framework tools is able to select just one data and value at a time, which is displayed on the text area.   But what if you want to have multiple values to be selected in the drop down box? As …
More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now