- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
Short Version:
目标:在 C# 中的无边界 WinForm 中深沉、黑暗的 Windows 7 阴影
已知的现有解决方案 1: 使用 CreateParams 的简单 XP 风格投影。
问题:太弱、太轻、太丑。
已知现有解决方案2:用位图替换form的GDI。
问题:无法使用控件,只能用作启动画面。
这篇文章的目标:找到这个问题的中间解决方案或一个更好的解决方案。
...
Long Version:
(编辑:如果不清楚的话,我指的是沿着任何窗体边框的阴影。)我知道有一种方法可以使用 C# 制作 XP 风格的阴影:
C# 代码 1 - 简单的 XP 风格阴影(问题:变亮、变弱、变丑)
// Define the CS_DROPSHADOW constant
private const int CS_DROPSHADOW = 0x00020000;
// Override the CreateParams property
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ClassStyle |= CS_DROPSHADOW;
return cp;
}
}
但是,我正在尝试弄清楚如何使它们看起来像 Windows 7 中的那样(更深和更大的阴影),但无法找出最佳方法。
我现在创建了一个方法,它可以让我覆盖整个 GDI 表单并看起来像启动画面(不是我的功劳):
C#代码2:用Bitmap替换form GDI(问题:不能使用form控件,GUI难维护)
public void SetBitmap(Bitmap bitmap, byte opacity)
{
if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
throw new ApplicationException("The bitmap must be 32ppp with alpha-channel.");
// 1. Create a compatible DC with screen;
// 2. Select the bitmap with 32bpp with alpha-channel in the compatible DC;
// 3. Call the UpdateLayeredWindow.
IntPtr screenDc = Win32.GetDC(IntPtr.Zero);
IntPtr memDc = Win32.CreateCompatibleDC(screenDc);
IntPtr hBitmap = IntPtr.Zero;
IntPtr oldBitmap = IntPtr.Zero;
try
{
hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); // grab a GDI handle from this GDI+ bitmap
oldBitmap = Win32.SelectObject(memDc, hBitmap);
Win32.Size size = new Win32.Size(bitmap.Width, bitmap.Height);
Win32.Point pointSource = new Win32.Point(0, 0);
Win32.Point topPos = new Win32.Point(Left, Top);
Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION();
blend.BlendOp = Win32.AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = opacity;
blend.AlphaFormat = Win32.AC_SRC_ALPHA;
Win32.UpdateLayeredWindow(this.Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, Win32.ULW_ALPHA);
}
finally
{
Win32.ReleaseDC(IntPtr.Zero, screenDc);
if (hBitmap != IntPtr.Zero)
{
Win32.SelectObject(memDc, oldBitmap);
Win32.DeleteObject(hBitmap);
}
Win32.DeleteDC(memDc);
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00080000; // This form has to have the WS_EX_LAYERED extended style
return cp;
}
}
但是,这确实为我提供了完整的 32 位背景(因为我需要手动添加阴影),但我无法创建可见的表单元素。
所以基本上,我试图找出这两种方法之间的中间值。可以在不丢失其他功能/导致过度重绘要求的情况下给我深色阴影的东西。
最佳答案
好的,经过大约 4 小时的头脑 Storm 和编码,我终于制定了一个解决方案。基本上,我制作了两种形式。
形式 #1:通过修改和组合 8 张图像(每个方向 4 个角渐变 + 4 个线性渐变)创建阴影,并使用我在上面发布的第二个代码将它们设置为背景(< strong>C# 代码 2:用位图替换表单 GDI)。代码几乎可以解释它。
public partial class Dropshadow : Form
{
public Dropshadow(Form parentForm)
{
/*This bit of code makes the form click-through.
So you can click forms that are below it in z-space */
int wl = GetWindowLong(this.Handle, -20);
wl = wl | 0x80000 | 0x20;
SetWindowLong(this.Handle, -20, wl);
InitializeComponent();
//Makes the start location the same as parent.
this.StartPosition = parentForm.StartPosition;
parentForm.Activated += ParentForm_Activated; //Fires on parent activation to do a this.BringToFront()
this.Deactivate += This_Deactivated; //Toggles a boolean that ensures that ParentForm_Activated does fire when clicking through (this)
parentForm.Closed += ParentForm_Closed; //Closes this when parent closes
parentForm.Move += ParentForm_Move; //Follows movement of parent form
//Draws border with standard bitmap modifications and merging
/* Omitted function to avoid extra confusion */
Bitmap getShadow = DrawBlurBorder(parentForm.ClientSize.Width, parentForm.ClientSize.Height);
/* **This code was featured in the original post:** */
SetBitmap(getShadow, 255); //Sets background as 32-bit image with full alpha.
this.Location = Offset; //Set within DrawBlurBorder creates an offset
}
private void ParentForm_Activated(object o, EventArgs e)
{
/* Sets this form on top when parent form is activated.*/
if (isBringingToFront)
{
/*Hopefully prevents recusion*/
isBringingToFront = false;
return;
}
this.BringToFront();
/* Some special tweaks omitted to avoid confusion */
}
private void This_Deactivated(object o, EventArgs e)
{
/* Prevents recusion. */
isBringingToFront = true;
}
/* Closes this when parent form closes. */
private void ParentForm_Closed(object o, EventArgs e)
{
this.Close();
}
/* Adjust position when parent moves. */
private void ParentForm_Move(object o, EventArgs e)
{
if(o is Form)
this.Location = new Point((o as Form).Location.X + Offset.X, (o as Form).Location.Y + Offset.Y);
}
}
Form #2:这只是在启动时启动了 dropshadow 表单,我还创建了一些接口(interface)以允许进一步的集成和灵 active ,我省略了这些接口(interface)以避免额外的混淆。确保 Dropshadow 表单不会从事件表单中取消鼠标点击的基本方法,并且如果 Dropshadow 表单位于顶部,则不会强制用户必须单击按钮两次。
关于c# - 无边框形式的 Windows 7 风格 Dropshadow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8793445/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!