窗体下面显示重要闪烁信息,30秒后消失

本文介绍了一段用于显示定制信息的JavaScript脚本,该脚本可在网页加载时以弹窗形式展示特定消息,并支持多种显示模式及背景颜色的设置。

脚本说明:
第一步:把如下代码加入<body>区域中
<script language="javascript">
//显示的信息,可以使用HTML语法,注意引号用法,单套双。
var message='<b><font size=5 face=arial color=red><a href="http://www.52xyxy.com" target="_blank">JAVA大部分资料是网上搜集的,一小部分是自己写的,只是为了方便网友</a></font></b>'

//背景色
var backgroundcolor="#eeffee"

//0 代表信息永远显示,1 代表信息只显示一段时间,2为随机显示模式;
var displaymode=1

//如果显示模式为在指定时间内显示,输入时间段(1000为1秒);
var displayduration=30000

//1代表闪烁,0代表不闪烁;
var flashmode=1
//如果设置了闪烁,输入闪烁的颜色;
var flashtocolor="lightgreen"

////下面不必修改///


function regenerate(){
window.location.reload()
}

var which=0

function regenerate2(){
if (document.layers)
setTimeout("window.onresize=regenerate",400)
}


function display2(){
if (document.layers){
if (topmsg.visibility=="show")
topmsg.visibility="hide"
else
topmsg.visibility="show"
}
else if (document.all){
if (topmsg.style.visibility=="visible")
topmsg.style.visibility="hidden"
else
topmsg.style.visibility="visible"
setTimeout("display2()",Math.round(Math.random()*10000)+10000)
}
}

function flash(){
if (which==0){
if (document.layers)
topmsg.bgColor=flashtocolor
else
topmsg.style.backgroundColor=flashtocolor
which=1
}
else{
if (document.layers)
topmsg.bgColor=backgroundcolor
else
topmsg.style.backgroundColor=backgroundcolor
which=0
}
}


if (document.all){
document.write('<span id="topmsg" style="position:absolute;visibility:hidden">'+message+'</span>')
}


function logoit(){
document.all.topmsg.style.left=document.body.scrollLeft+document.body.clientWidth/2-document.all.topmsg.offsetWidth/2
document.all.topmsg.style.top=document.body.scrollTop+document.body.clientHeight-document.all.topmsg.offsetHeight-4
}


function logoit2(){
topmsg.left=pageXOffset+window.innerWidth/2-topmsg.document.width/2
topmsg.top=pageYOffset+window.innerHeight-topmsg.document.height-5
setTimeout("logoit2()",90)
}

function setmessage(){
document.all.topmsg.style.left=document.body.scrollLeft+document.body.clientWidth/2-document.all.topmsg.offsetWidth/2
document.all.topmsg.style.top=document.body.scrollTop+document.body.clientHeight-document.all.topmsg.offsetHeight-4
document.all.topmsg.style.backgroundColor=backgroundcolor
document.all.topmsg.style.visibility="visible"
if (displaymode==1)
setTimeout("topmsg.style.visibility='hidden'",displayduration)
else if (displaymode==2)
display2()
if (flashmode==1)
setInterval("flash()",1000)
window.onscroll=logoit
window.onresize=new Function("window.location.reload()")
}


function setmessage2(){
topmsg=new Layer(window.innerWidth)
topmsg.bgColor=backgroundcolor
regenerate2()
topmsg.document.write(message)
topmsg.document.close()
logoit2()
topmsg.visibility="show"
if (displaymode==1)
setTimeout("topmsg.visibility='hide'",displayduration)
else if (displaymode==2)
display2()
if (flashmode==1)
setInterval("flash()",1000)
}


if (document.layers)
window.onload=setmessage2
else if (document.all)
window.onload=setmessage
</script>

<think>我们正在处理一个WinForm窗体在调用ShowDialog方法关闭后出现闪烁的问题。根据用户描述,闪烁发生在关闭通过ShowDialog弹出的窗体后,主窗体出现快速闪烁(动图中有一闪而过的黑色)。用户指出,在弹出窗体的关闭按钮事件中调用了this.Close()和this.Dispose(),并指出导致闪烁的原因在this.Dispose()。根据引用[1],用户已经发现闪烁的原因在于调用了this.Dispose()。在WinForm中,当使用ShowDialog显示窗体时,窗体在关闭时会自动释放资源(即自动调用Dispose)。因此,在按钮事件中再次调用Dispose会导致重复释放,可能引起闪烁问题。引用[3]提供了一种解决方案:在主窗体中重写CreateParams属性,设置双缓冲。代码示例如下: ```csharpprotectedoverride CreateParams CreateParams{get{CreateParams cp= base.CreateParams;cp.ExStyle|=0x02000000;//启用双缓冲returncp;}} ```引用[4]则提到对于容器控件(如TableLayoutPanel)可以设置DoubleBuffered属性为true,通过反射来实现。 然而,我们的问题具体是关闭ShowDialog窗体后主窗体闪烁。因此,我们首先应该解决重复Dispose的问题,然后再考虑双缓冲等优化。解决步骤:1.在弹出窗体中,不要显式调用Dispose(),因为ShowDialog关闭后会自动调用Dispose。所以,修改弹出窗体的关闭按钮事件,只调用Close()即可。 2.如果问题仍然存在,则考虑在主窗体上启用双缓冲(如引用[3]的方法)。 根据引用[1]中的用户代码:```csharpprivate voidbutton1_Click(objectsender,EventArgs e) {this.Close();this.Dispose(); //导致闪烁的原因在此} ```修改为: ```csharpprivatevoid button1_Click(object sender, EventArgse){this.Close(); //只需关闭,Dispose会自动调用}``` 如果修改后仍然有闪烁,可以尝试在主窗体中启用双缓冲(通过重写CreateParams属性)。 此外,引用[2]提到DialogResult属性,我们可以通过设置窗体的DialogResult属性来关闭窗体,这样也可以避免重复Dispose。例如: ```csharpprivatevoid button1_Click(object sender, EventArgse){this.DialogResult= DialogResult.OK; //或DialogResult.Cancel等//这样设置后,窗体会自动关闭,并且不会重复Dispose}``` 总结解决方案: 1.避免在ShowDialog显示窗体的关闭事件中显式调用Dispose()。2.使用设置DialogResult的方式来关闭窗体(推荐做法)。 3.如果主窗体仍有闪烁,尝试启用主窗体的双缓冲。现在,我们按照用户要求生成相关问题。</think>### WinForm ShowDialog 关闭后窗体闪烁的解决方法 在 WinForm 中使用 `ShowDialog()` 关闭窗体后出现闪烁问题,通常由以下原因及解决方案: #### 🛑 核心原因分析 1. **资源重复释放** 引用[1]指出:在 `ShowDialog` 窗体中显式调用 `Dispose()` 会导致闪烁(`this.Dispose()` 是导致闪烁的原因)。因为 `ShowDialog()` 关闭时会**自动释放资源**,再次手动释放造成冲突。 2. **双缓冲未启用** 主窗体未启用双缓冲时,重绘操作可能引发闪烁(引用[3][4])。 #### ✅ 解决方案 ##### 1. 移除重复释放代码(首要步骤) ```csharp // 弹出窗体中的关闭按钮事件(修改后) private void btnClose_Click(object sender, EventArgs e) { // 仅关闭窗体,不要调用 Dispose() this.Close(); // 或使用标准做法(推荐): this.DialogResult = DialogResult.Cancel; // 引用[2] } ``` > 📌 **关键说明**:`ShowDialog()` 窗体关闭时 .NET 会自动调用 `Dispose`,手动调用会导致资源重复释放引发闪烁。 ##### 2. 为主窗体启用双缓冲 ```csharp // 在主窗体类中添加以下代码(引用[3]) protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; // 启用 WS_EX_COMPOSITED (双缓冲) return cp; } } ``` ##### 3. 容器控件双缓冲(可选) 若闪烁发生在 Panel/TableLayoutPanel 等容器内: ```csharp // 在窗体初始化时调用 private void EnableDoubleBuffering(Control control) { var prop = control.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); prop.SetValue(control, true, null); // 引用[4] } // 使用示例 EnableDoubleBuffering(tableLayoutPanel1); EnableDoubleBuffering(panel1); ``` #### 💡 其他优化建议 - **避免在关闭事件中执行耗时操作** 复杂逻辑应放在 `DialogResult` 判断后执行 - **检查自定义绘制代码** 若使用 GDI+ 绘制,确保遵循异步绘制规范(引用[5]) - **窗体加载优化** 初始隐藏控件,加载完成后显示: ```csharp this.Opacity = 0; this.Shown += (s, e) => { this.Opacity = 1; }; ``` #### 📊 解决流程总结 ```mermaid graph TD A[出现闪烁问题] --> B{检查弹出窗体} B -->|存在Dispose调用| C[移除Dispose代码] B -->|无Dispose问题| D[为主窗体启用双缓冲] C --> E[改用DialogResult关闭] D --> F[为容器控件启用双缓冲] E --> G[验证闪烁是否解决] F --> G G -->|未解决| H[检查GDI+绘制逻辑] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值