Imports Sticker.Systems

Public Class FormSticker
#Region "Переменные по окошку"
    Private _ScreenDC As IntPtr = IntPtr.Zero
    Private _MemDC As IntPtr = IntPtr.Zero
    Private _BitmapHandle As IntPtr = IntPtr.Zero
    Private _OldBitmapHandle As IntPtr = IntPtr.Zero
    Private _Size As Win32API.Size = Nothing
    Private _PoinSource As Win32API.Point = Nothing
    Private _TopPos As Win32API.Point = Nothing
    Private _Blend As Win32API.BLENDFUNCTION = Nothing
    Private _CurPos As Point = Nothing
    Private _Opacity As Byte = 255

    Private bmpDest As Bitmap = Nothing
    Private bmpSrc As Bitmap = Nothing
#End Region

    Private Sub FormSticker_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.DoubleClick
        dlgColor.ShowDialog()
        UpdateWindow()
    End Sub

    Private Sub FormSticker_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        UpdateWindow()
    End Sub

    Public Sub UpdateWindow()
        bmpDest = New Bitmap(Me.Size.Width, Me.Size.Height)
        Using g As Graphics = Graphics.FromImage(bmpDest)
            With g
                .InterpolationMode = Drawing2D.InterpolationMode.NearestNeighbor
                .SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
                .TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
                'Рисуем тень
                bmpSrc = My.Resources.Стикер_Фон
                'ВЛ (15x13)
                .DrawImage(bmpSrc, New RectangleF(0, 0, 15, 13), New RectangleF(0, 0, 15, 13), GraphicsUnit.Pixel)
                'НЛ (15x35)
                .DrawImage(bmpSrc, New RectangleF(0, bmpDest.Height - 35, 15, 35), New RectangleF(0, bmpSrc.Height - 35, 15, 35), GraphicsUnit.Pixel)
                'ВП 64x13
                .DrawImage(bmpSrc, New RectangleF(bmpDest.Width - 64, 0, 64, 13), New RectangleF(bmpSrc.Width - 64, 0, 64, 13), GraphicsUnit.Pixel)
                'НП 64x35
                .DrawImage(bmpSrc, New RectangleF(bmpDest.Width - 64, bmpDest.Height - 35, 64, 35), New RectangleF(bmpSrc.Width - 64, bmpSrc.Height - 35, 64, 35), GraphicsUnit.Pixel)
                'ВГ ~x13
                .DrawImage(bmpSrc, New RectangleF(15, 0, bmpDest.Width - 79, 13), New RectangleF(15, 0, 64, 13), GraphicsUnit.Pixel)
                'НГ ~x35
                .DrawImage(bmpSrc, New RectangleF(15, bmpDest.Height - 35, bmpDest.Width - 79, 35), New RectangleF(15, bmpSrc.Height - 35, 64, 35), GraphicsUnit.Pixel)
                'ЛВ 15x~
                .DrawImage(bmpSrc, New RectangleF(0, 13, 15, bmpDest.Height - 48), New RectangleF(0, 13, 15, 108), GraphicsUnit.Pixel)
                'ПВ 64x~
                .DrawImage(bmpSrc, New RectangleF(bmpDest.Width - 64, 13, 64, bmpDest.Height - 48), New RectangleF(bmpSrc.Width - 64, 13, 64, 108), GraphicsUnit.Pixel)
                'Прорисовываем фон стикера
                Dim StickerPath As New Drawing2D.GraphicsPath
                StickerPath.AddLine(7, 8, bmpDest.Width - 10, 8)           'Верхняя граница
                StickerPath.AddLine(bmpDest.Width - 10, 8, bmpDest.Width - 10, bmpDest.Height - 35)       'Правая граница
                StickerPath.AddBezier(bmpDest.Width - 10, bmpDest.Height - 35, _
                      bmpDest.Width - 15, bmpDest.Height - 10, _
                      bmpDest.Width - 72, bmpDest.Height - 9, _
                      bmpDest.Width - 72, bmpDest.Height - 9)              'Изгиб
                StickerPath.AddLine(bmpDest.Width - 72, bmpDest.Height - 9, 7, bmpDest.Height - 9)        'Нижняя граница
                StickerPath.CloseFigure()                   'Замыкаем
                .FillPath(New SolidBrush(dlgColor.Color), StickerPath)
                'Уткаем текст
                Dim sf As New StringFormat(StringFormatFlags.LineLimit)
                sf.Alignment = StringAlignment.Center
                sf.LineAlignment = StringAlignment.Center
                .DrawString("Сходить за молочком и забрать кошку от ветеринара", Me.Font, New SolidBrush(Me.ForeColor), New Rectangle(10, 10, bmpDest.Width - 20, bmpDest.Height - 20), sf)
                'Рисуем уголок
                bmpSrc = My.Resources.Стикер_Уголок
                .DrawImage(bmpSrc, bmpDest.Width - bmpSrc.Width, bmpDest.Height - bmpSrc.Height, bmpSrc.Width, bmpSrc.Height)
                'Рисуем гвоздик
                bmpSrc = My.Resources.Стикер_Гвоздик
                .DrawImage(bmpSrc, (bmpDest.Width - bmpSrc.Width) \ 2, 0, bmpSrc.Width, bmpSrc.Height)
            End With
        End Using

        Me.SetImage(bmpDest, Me.Opacity)
        bmpDest.Dispose()
    End Sub

#Region "Перемещение окна"
    Private Sub FormClock_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then _CurPos = e.Location
    End Sub

    Private Sub FormClock_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
        If e.Button = Windows.Forms.MouseButtons.Left Then
            _CurPos = Nothing
        End If
    End Sub

    Private Sub FormClock_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Me.Location += e.Location - _CurPos
        End If
    End Sub
#End Region

#Region "Многослойное окно"
    Public Sub AddStyle(ByVal Style As Integer)
        Win32API.SetWindowLong(Me.Handle, Win32API.GWL_EXSTYLE, Win32API.GetWindowLong(Me.Handle, Win32API.GWL_EXSTYLE) Or Style)
    End Sub

    Public Sub RemoveStyle(ByVal Style As Integer)
        Win32API.SetWindowLong(Me.Handle, Win32API.GWL_EXSTYLE, Win32API.GetWindowLong(Me.Handle, Win32API.GWL_EXSTYLE) And Not Style)
    End Sub

    'Создаем многослойное окно
    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Dim CP As CreateParams = MyBase.CreateParams
            CP.ExStyle = CP.ExStyle Or Win32API.WS_EX_LAYERED
            Return CP
        End Get
    End Property

    'Перегружаем свойство прозрачности
    Overloads Property Opacity() As Byte
        Get
            Return _Opacity
        End Get
        Set(ByVal value As Byte)
            If _Opacity <> value Then
                _Opacity = value
                UpdateWindow()
            End If
        End Set
    End Property

    Public Sub SetImage(ByRef Bitmap As Bitmap, ByVal Opacity As Byte)
        _ScreenDC = Win32API.GetDC(0)                  'Получим контекст дисплея
        _MemDC = Win32API.CreateCompatibleDC(_ScreenDC) 'Совместимый с дисплеем контекс   
        _BitmapHandle = IntPtr.Zero                    'Хендл изображения
        _OldBitmapHandle = IntPtr.Zero                 'Сохраним хендл
        _Opacity = Opacity
        Try
            _BitmapHandle = Bitmap.GetHbitmap(Color.FromArgb(0))     'Получик контекст битмапа
            _OldBitmapHandle = Win32API.SelectObject(_MemDC, _BitmapHandle)
            _Size = New Win32API.Size(Bitmap.Width, Bitmap.Height)
            _PoinSource = New Win32API.Point(0, 0)
            _TopPos = New Win32API.Point(Me.Left, Me.Top)
            _Blend = New Win32API.BLENDFUNCTION(Win32API.AC_SRC_OVER, 0, Opacity, Win32API.AC_SRC_ALPHA)
            Win32API.UpdateLayeredWindow(Me.Handle, _ScreenDC, _TopPos, _Size, _MemDC, _PoinSource, 0, _Blend, Win32API.ULW_ALPHA)
        Finally
            Win32API.ReleaseDC(IntPtr.Zero, _ScreenDC)
            If _BitmapHandle <> IntPtr.Zero Then
                Win32API.SelectObject(_MemDC, _OldBitmapHandle)
                Win32API.DeleteObject(_BitmapHandle)
            End If
            Win32API.DeleteDC(_MemDC)
            _Size = Nothing
            _PoinSource = Nothing
            _TopPos = Nothing
            _Blend = Nothing
        End Try
    End Sub
#End Region
End Class
