По сути, вам нужно создать форму без рамки, а затем бросить свой собственный «заголовок заголовка», который в основном будет областью вверху, которую вы можете настроить по своему усмотрению. Это сложное решение для полной реализации должным образом, но это, вероятно, способ, который наилучшим образом достигнет этого.

росто интересно, есть ли возможный способ добавить пользовательскую кнопку в строку заголовка с помощью VB.NET. Я видел много таких вопросов о переполнении стека, но не смог получить верный и рабочий ответ.

Может кто-нибудь помочь мне с этим вопросом? Я также проверил на Google и другом веб-сайте, но он не отображается. Я хочу, чтобы код работал в Windows XP, Windows Vista и Windows 7.

Я был быблагодарный если вы сможете дать рабочий код, и кнопка должна даже быть в состоянии принять события щелчка и опубликовать его в той форме, в которой он находится, для какого-либо действия.

заранее спасибо

Ответы на вопрос(3)

его ответ здесь:

Следующее будет работать в XP, у меня нет машины Vista, пригодной для тестирования, но я думаю, что ваши проблемы как-то связаны с неправильным hWnd. Во всяком случае, с плохо прокомментированным кодом.

Я думаю, что это не отображается графически в Vista и 7. Переведенная версия кода Мэтью выглядит следующим образом:

' The state of our little button
Private _buttState As ButtonState = ButtonState.Normal
Private _buttPosition As New Rectangle()

<DllImport("user32.dll")> _
Private Shared Function GetWindowDC(hWnd As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindowRect(hWnd As IntPtr, ByRef lpRect As Rectangle) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function ReleaseDC(hWnd As IntPtr, hDC As IntPtr) As Integer
End Function
Protected Overrides Sub WndProc(ByRef m As Message)
    Dim x As Integer, y As Integer
    Dim windowRect As New Rectangle()
    GetWindowRect(m.HWnd, windowRect)

    Select Case m.Msg
        ' WM_NCPAINT
        ' WM_PAINT
        Case &H85, &Ha
            MyBase.WndProc(m)

            DrawButton(m.HWnd)

            m.Result = IntPtr.Zero

            Exit Select

        ' WM_ACTIVATE
        Case &H86
            MyBase.WndProc(m)
            DrawButton(m.HWnd)

            Exit Select

        ' WM_NCMOUSEMOVE
        Case &Ha0
            ' Extract the least significant 16 bits
            x = (CInt(m.LParam) << 16) >> 16
            ' Extract the most significant 16 bits
            y = CInt(m.LParam) >> 16

            x -= windowRect.Left
            y -= windowRect.Top

            MyBase.WndProc(m)

            If Not _buttPosition.Contains(New Point(x, y)) AndAlso _buttState = ButtonState.Pushed Then
                _buttState = ButtonState.Normal
                DrawButton(m.HWnd)
            End If

            Exit Select

        ' WM_NCLBUTTONDOWN
        Case &Ha1
            ' Extract the least significant 16 bits
            x = (CInt(m.LParam) << 16) >> 16
            ' Extract the most significant 16 bits
            y = CInt(m.LParam) >> 16

            x -= windowRect.Left
            y -= windowRect.Top

            If _buttPosition.Contains(New Point(x, y)) Then
                _buttState = ButtonState.Pushed
                DrawButton(m.HWnd)
            Else
                MyBase.WndProc(m)
            End If

            Exit Select

        ' WM_NCLBUTTONUP
        Case &Ha2
            ' Extract the least significant 16 bits
            x = (CInt(m.LParam) << 16) >> 16
            ' Extract the most significant 16 bits
            y = CInt(m.LParam) >> 16

            x -= windowRect.Left
            y -= windowRect.Top

            If _buttPosition.Contains(New Point(x, y)) AndAlso _buttState = ButtonState.Pushed Then
                _buttState = ButtonState.Normal
                ' [[TODO]]: Fire a click event for your button 
                '           however you want to do it.
                DrawButton(m.HWnd)
            Else
                MyBase.WndProc(m)
            End If

            Exit Select

        ' WM_NCHITTEST
        Case &H84
            ' Extract the least significant 16 bits
            x = (CInt(m.LParam) << 16) >> 16
            ' Extract the most significant 16 bits
            y = CInt(m.LParam) >> 16

            x -= windowRect.Left
            y -= windowRect.Top

            If _buttPosition.Contains(New Point(x, y)) Then
                m.Result = DirectCast(18, IntPtr)
            Else
                ' HTBORDER
                MyBase.WndProc(m)
            End If

            Exit Select
        Case Else

            MyBase.WndProc(m)
            Exit Select
    End Select
End Sub

Private Sub DrawButton(hwnd As IntPtr)
    Dim hDC As IntPtr = GetWindowDC(hwnd)
    Dim x As Integer, y As Integer

    Using g As Graphics = Graphics.FromHdc(hDC)
        ' Work out size and positioning
        Dim CaptionHeight As Integer = Bounds.Height - ClientRectangle.Height
        Dim ButtonSize As Size = SystemInformation.CaptionButtonSize
        x = Bounds.Width - 4 * ButtonSize.Width
        y = (CaptionHeight - ButtonSize.Height) \ 2
        _buttPosition.Location = New Point(x, y)

        ' Work out color
        Dim color As Brush
        If _buttState = ButtonState.Pushed Then
            color = Brushes.LightGreen
        Else
            color = Brushes.Red
        End If

        ' Draw our "button"
        g.FillRectangle(color, x, y, ButtonSize.Width, ButtonSize.Height)
    End Using

    ReleaseDC(hwnd, hDC)
End Sub

Private Sub Form1_Load(sender As Object, e As EventArgs)
    _buttPosition.Size = SystemInformation.CaptionButtonSize
End Sub
 Axe30 мая 2011 г., 08:06
Я был рад, что вы можете впереди, дал мне кусок кода, чтобы помочь мне. У меня в настоящее время Windows 7, и он не в состоянии сделать. Я действительно не пробовал это на Windows XP. Но еще раз спасибо за вашу помощь! Следующий код, похоже, выдает ошибку о том, что 18 нельзя преобразовать в IntPtr: «m.Result = DirectCast (18, IntPtr)». Еще раз спасибо за вашу помощь! ура
 Shahin30 мая 2011 г., 13:29
Добро пожаловать :) Честно говоря, я попробовал этот код в C #, и он работает, поэтому я преобразовал его в VB.NET. удачи
Решение Вопроса

я могу придумать два способа сделать это:

Скрыть заголовок и заменить его своим, что я не рекомендую.Создайте кнопку как очень маленькую форму, которую вы будете удерживать в правильном положении каждый раз, когда ваше окно перемещается.
 NightHowler12 июн. 2017 г., 13:59
Второй метод очень умный. Бриллиант LOL XD
 Shahin30 мая 2011 г., 07:22
+1 это быстрый и хороший способ
 Axe30 мая 2011 г., 07:19
Спасибо за этот ответ, но вы уверены, что в DLL-библиотеках Windows нет функции для добавления кнопки в строку заголовка? Я видел коды, которые используют эти API, но не очень хорошо работают! Пожалуйста, помогите мне

http://www.dreamincode.net/forums/topic/69215-2008-custom-title-bar/

По сути, вам нужно создать форму без рамки, а затем бросить свой собственный «заголовок заголовка», который в основном будет областью вверху, которую вы можете настроить по своему усмотрению. Это сложное решение для полной реализации должным образом, но это, вероятно, способ, который наилучшим образом достигнет этого.

Ваш ответ на вопрос