.ShowDialog() 显示两次
本文关键字:两次 显示 ShowDialog | 更新日期: 2023-09-27 18:35:21
我有一个烦人的问题...我只是想显示一个对话框,但它总是显示两次......代码如下:
private void tmr_sysdt_Tick(object sender, EventArgs e)
{
lbl_time.Text = System.DateTime.Now.ToLongTimeString();
lbl_date.Text = System.DateTime.Now.ToLongDateString();
if (GetLastInputTime() > Program.timeout)
{
frm_lockscreen login= new frm_lockscreen();
tmr_sysdt.Enabled = false;
if (login.ShowDialog(this) == DialogResult.OK) tmr_sysdt.Enabled = true;
}
}
tmr_sysdt.Interval is 1000
.
问题很简单 - 但对我来说无法解决 - 对话框一式两份显示(第二个与第一个同时出现)。
我不知道,所以任何想法都会受到赞赏:)
谢谢,如果您需要更多详细信息,请发表评论!
PS.:对不起,英语不好
编辑: 获取最后输入时间()
[DllImport("user32.dll")]
static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
static uint GetLastInputTime()
{
uint idleTime = 0;
LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);
lastInputInfo.dwTime = 0;
uint envTicks = (uint)Environment.TickCount;
if (GetLastInputInfo(ref lastInputInfo))
{
uint lastInputTick = lastInputInfo.dwTime;
idleTime = envTicks - lastInputTick;
}
return ((idleTime > 0) ? (idleTime / 1000) : 0);
}
[StructLayout(LayoutKind.Sequential)]
struct LASTINPUTINFO
{
public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO));
[MarshalAs(UnmanagedType.U4)]
public UInt32 cbSize;
[MarshalAs(UnmanagedType.U4)]
public UInt32 dwTime;
}
你能试试这个代码吗?只是为了确保不会同时调用处理程序中的逻辑两次:
static bool busy = false;
private void tmr_sysdt_Tick(object sender, EventArgs e)
{
if (busy)
{
return;
}
busy = true;
try
{
lbl_time.Text = System.DateTime.Now.ToLongTimeString();
lbl_date.Text = System.DateTime.Now.ToLongDateString();
if (GetLastInputTime() > Program.timeout)
{
frm_lockscreen login = new frm_lockscreen();
tmr_sysdt.Enabled = false;
if (login.ShowDialog(this) == DialogResult.OK) tmr_sysdt.Enabled = true;
}
}
finally
{
busy = false;
}
}
您遇到的问题是,用于检查用户上次活动并显示登录框的代码采用多次创建的表单。
因此,实际上,这些"主要表单"中的每一个都在检查用户活动并显示登录框。
通过将繁忙的布尔值设置为静态,"主窗体"的每个实例将此布尔值读取为相同的值。因此,检查+显示登录只执行一次。
我建议将此代码移动到您只创建一次的表单中,并在应用程序的整个生命周期内保持打开状态。(如果你有这样的表格)
您想重复使用您的frm_lockscreen并阻止重新进入您的 Tick 事件
private frm_lockscreen _lockScreen;
private frm_lockscreen LockScreen
{
get { return _lockScreen ?? (_lockScreen = new frm_lockscreen()); }
}
private void tmr_sysdt_Tick(object sender, EventArgs e)
{
// prevent reentry
if (!Monitor.TryEnter(tmr_sysdt)) return;
try {
lbl_time.Text = System.DateTime.Now.ToLongTimeString();
lbl_date.Text = System.DateTime.Now.ToLongDateString();
if (GetLastInputTime() > Program.timeout)
{
tmr_sysdt.Enabled = false;
if (LockScreen.ShowDialog(this) == DialogResult.OK) tmr_sysdt.Enabled = true;
}
}
finally {
Monitor.Exit(tmr_sysdt);
}
}
原因是您的外部 if 条件返回 true 两次:
if (GetLastInputTime() > Program.timeout)
要找到罪魁祸首,您必须检查 GetLastInputTime() 和 Program.Timeout 返回的值