Я пытаюсь отбросить тень вокруг всей формы, как на первом рисунке, за исключением того, что это WPF, а не WinForm. теперь я хочу отбросить ту же тень на winform.
Это то, что я хочу.. ¬
Не это... ¬
Я пытаюсь отбросить тень вокруг всей формы, как на первом рисунке, за исключением того, что это WPF, а не WinForm. теперь я хочу отбросить ту же тень на winform.
Это то, что я хочу.. ¬
Не это... ¬
В WinForms вы можете просто переопределить свойство protected CreateParams
и добавить флаг CS_DROPSHADOW
в стили классов. Например:
public class ShadowedForm : Form {
protected override CreateParams CreateParams {
get {
const int CS_DROPSHADOW = 0x20000;
CreateParams cp = base.CreateParams;
cp.ClassStyle |= CS_DROPSHADOW;
return cp;
}
}
// ... other code ...
}
Но, пара предостережений & hellip;
Этот флаг работает только на окнах верхнего уровня. В Win32-talk это означает перекрывающиеся и всплывающие окна. Он не влияет на дочерние окна (например, элементы управления). Я думал, что я где-то слышал, что это ограничение было удалено из Windows 8, но я не могу найти ссылку, подтверждающую это, и у меня нет Windows 8 для тестирования.
Возможно, пользователь полностью отключил эту функцию. Если это так, вы не получите тени для теней, независимо от того, как вы их просите. Это по дизайну. Ваше приложение не должно пытаться переопределить этот запрос. Вы можете определить, включены ли тени или отключены с помощью P/Вызов функции SystemParametersInfo
и передачи флага SPI_GETDROPSHADOW
.
Тема Aero также добавляет тени в окна верхнего уровня. Этот эффект является отдельным и отличается от CS_DROPSHADOW
и работает только при включенном Aero. Невозможно отключить и выключить отдельные окна. Более того, поскольку тема Aero удалена из Windows 8, у нее никогда не будет этих теней.
Вот моя реализация С#. Это похоже на Эл. Петро, но вы заметите, что когда вы теряете фокус и восстанавливаете фокус, тень перерисовывается.
Я также добавил код, позволяющий перетаскивать мышь.
public partial class Form1: Form
{
[DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
private static extern IntPtr CreateRoundRectRgn
(
int nLeftRect, // x-coordinate of upper-left corner
int nTopRect, // y-coordinate of upper-left corner
int nRightRect, // x-coordinate of lower-right corner
int nBottomRect, // y-coordinate of lower-right corner
int nWidthEllipse, // height of ellipse
int nHeightEllipse // width of ellipse
);
[DllImport("dwmapi.dll")]
public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
[DllImport("dwmapi.dll")]
public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
[DllImport("dwmapi.dll")]
public static extern int DwmIsCompositionEnabled(ref int pfEnabled);
private bool m_aeroEnabled; // variables for box shadow
private const int CS_DROPSHADOW = 0x00020000;
private const int WM_NCPAINT = 0x0085;
private const int WM_ACTIVATEAPP = 0x001C;
public struct MARGINS // struct for box shadow
{
public int leftWidth;
public int rightWidth;
public int topHeight;
public int bottomHeight;
}
private const int WM_NCHITTEST = 0x84; // variables for dragging the form
private const int HTCLIENT = 0x1;
private const int HTCAPTION = 0x2;
protected override CreateParams CreateParams
{
get
{
m_aeroEnabled = CheckAeroEnabled();
CreateParams cp = base.CreateParams;
if (!m_aeroEnabled)
cp.ClassStyle |= CS_DROPSHADOW;
return cp;
}
}
private bool CheckAeroEnabled()
{
if (Environment.OSVersion.Version.Major >= 6)
{
int enabled = 0;
DwmIsCompositionEnabled(ref enabled);
return (enabled == 1) ? true : false;
}
return false;
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_NCPAINT: // box shadow
if (m_aeroEnabled)
{
var v = 2;
DwmSetWindowAttribute(this.Handle, 2, ref v, 4);
MARGINS margins = new MARGINS()
{
bottomHeight = 1,
leftWidth = 1,
rightWidth = 1,
topHeight = 1
};
DwmExtendFrameIntoClientArea(this.Handle, ref margins);
}
break;
default:
break;
}
base.WndProc(ref m);
if (m.Msg == WM_NCHITTEST && (int)m.Result == HTCLIENT) // drag the form
m.Result = (IntPtr)HTCAPTION;
}
public Form1()
{
m_aeroEnabled = false;
this.FormBorderStyle = FormBorderStyle.None;
InitializeComponent();
}
}
Humm,, Прошел мимо кода, и вы получите окна 7 Drop Shadow например → > http://marcin.floryan.pl/wp-content/uploads/2010/08/WPF-Window-native-shadow.png
Imports System.Runtime.InteropServices
Public Class IMSS_SplashScreen
Private aeroEnabled As Boolean
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
CheckAeroEnabled()
Dim cp As CreateParams = MyBase.CreateParams
If Not aeroEnabled Then
cp.ClassStyle = cp.ClassStyle Or NativeConstants.CS_DROPSHADOW
Return cp
Else
Return cp
End If
End Get
End Property
Protected Overrides Sub WndProc(ByRef m As Message)
Select Case m.Msg
Case NativeConstants.WM_NCPAINT
Dim val = 2
If aeroEnabled Then
NativeMethods.DwmSetWindowAttribute(Handle, 2, val, 4)
Dim bla As New NativeStructs.MARGINS()
With bla
.bottomHeight = 1
.leftWidth = 1
.rightWidth = 1
.topHeight = 1
End With
NativeMethods.DwmExtendFrameIntoClientArea(Handle, bla)
End If
Exit Select
End Select
MyBase.WndProc(m)
End Sub
Private Sub CheckAeroEnabled()
If Environment.OSVersion.Version.Major >= 6 Then
Dim enabled As Integer = 0
Dim response As Integer = NativeMethods.DwmIsCompositionEnabled(enabled)
aeroEnabled = (enabled = 1)
Else
aeroEnabled = False
End If
End Sub
End Class
Public Class NativeStructs
Public Structure MARGINS
Public leftWidth As Integer
Public rightWidth As Integer
Public topHeight As Integer
Public bottomHeight As Integer
End Structure
End Class
Public Class NativeMethods
<DllImport("dwmapi")> _
Public Shared Function DwmExtendFrameIntoClientArea(ByVal hWnd As IntPtr, ByRef pMarInset As NativeStructs.MARGINS) As Integer
End Function
<DllImport("dwmapi")> _
Friend Shared Function DwmSetWindowAttribute(ByVal hwnd As IntPtr, ByVal attr As Integer, ByRef attrValue As Integer, ByVal attrSize As Integer) As Integer
End Function
<DllImport("dwmapi.dll")> _
Public Shared Function DwmIsCompositionEnabled(ByRef pfEnabled As Integer) As Integer
End Function
End Class
Public Class NativeConstants
Public Const CS_DROPSHADOW As Integer = &H20000
Public Const WM_NCPAINT As Integer = &H85
End Class
Насколько я знаю, в WinForms нет прямого способа сделать это.
Вместо этого вы можете выполнить следующие шаги:
1) Создайте изображение, имеющее требуемую тень, используя фотошоп или любой другой инструмент.
2) Используйте это изображение в качестве фонового изображения вашей формы.
3) Установите для свойства FormBorderStyle формы значение None.
4) Вы закончили!
5) Примечание. Обязательно сохраните изображение в правильном формате (например, png), чтобы эффект отбрасывания мог работать.