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/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
我有一个名为posts的模型,它有很多附件。附件模型使用回形针。我制作了一个用于创建附件的独立模型,效果很好,这是此处说明的View(https://github.com/thoughtbot/paperclip):@attachment,:html=>{:multipart=>true}do|form|%>posts中的嵌套表单如下所示:prohibitedthispostfrombeingsaved:@attachment,:html=>{:multipart=>true}do|at_form|%>附件记录已创建,但它是空的。文件未上传。同时,帖子已成功创建...有什么想法吗?
之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
查看Ruby代码,它具有以下proc_arity:staticVALUEproc_arity(VALUEself){intarity=rb_proc_arity(self);returnINT2FIX(arity);}更多的是C编码风格问题,但为什么staticVALUE在单独的一行而不是像这样的:staticVALUEproc_arity(VALUEself) 最佳答案 它来自UNIX世界,因为它有助于轻松grep函数的定义:$grep-n'^proc_arity'*.c或使用vim:/^proc_arity