Splash和登录表单(问题和解决方案)

目录

介绍

什么是流程?

我该怎么做?

创建启动窗体

创建登录表单

结论



对知识的投资总是能带来最大的利益。
本杰明·富兰克林

介绍

在本文中,我想讨论Splash\Login Forms创建的问题。我经常在论坛上偶然发现新手程序员关于Splash\Login Forms的问题。在我看来,这些问题的答案往往没有提供全面的信息。所以我决定写这篇文章。它充分描述了这些问题和解决方案。

首先,我想讨论一个问题——是什么导致了这些问题的出现?在我看来,当我们开始在Windows系统中执行程序时,它与有关Windows体系结构和Windows进程的信息不足或概念模糊有关。这是主要问题。因此,让我们解决它。我不打算复述一本关于Windows的大好书,没有意义。我只想让您有机会了解在Windows中创建实例程序。这将使您了解如何创建Splash\Login Forms

什么是流程?

首先,我们将讨论“Windows中的进程的定义。进程——它是可执行程序的副本,它由两个组件组成:

  1. 内核的一个对象,操作系统通过该对象管理进程。它保留有关该过程的static信息。
  2. 包含进程的可执行代码和数据的地址空间。

该过程本身不做任何事情,即它是惰性的。为了让它做某事,它应该至少有一个线程。线程负责在进程的地址空间中执行代码。因此,当进程启动时,操作系统会自动创建主线程,而主线程又可以生成其他线程。此外,如果我们希望我们的应用程序响应鼠标移动、按钮单击等,我们必须在线程中创建一个消息循环。所以我们有一些结构:进程——线程——消息循环。如果我们想关闭程序,我们需要关闭主消息循环。当您关闭主窗体或执行Application.Exit()方法以及主线程中的ExitThread()方法时,就会发生这种情况。

我该怎么做?

上面讨论的所有内容都是当我们选择使用Windows窗体应用程序创建项目模板时,Visual Studio会自动创建。有了这些知识,请看一下代码,我们肯定都反复看到过:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

当你调用一个方法Application.Run (new Form1 ())Form时,我们创建一个新线程,它创建一个消息循环,以及一个类的对象并显示它。让我们仔细考虑这种方法。此方法已重载,并且可能具有以下选项:

  1. Run()
  2. Run(ApplicationContext)
  3. Run(Form)

(有关其他信息,请参阅此链接

在本文的上下文中,我们对第一种重载方法不感兴趣,当然,除非您决定在不安全的代码中创建一些东西,即我们已经讨论过的第三种方法。但第二个是我们将特别感兴趣的。这将创建对象类ApplicationContext,该类负责创建线程和消息的标准周期。现在一切都很简单——我们必须创建一个ApplicationContext类的后代类LoginTestContext,我们将使用应用程序形式创建一个逻辑:

public class LoginTestContext: ApplicationContext
{
    // here we can declare the all forms application and manage it directly
    //(show, close, set as MainForm and so on) 
    private frmLogIn fLogin;
    private frmMain fMain;

    public LoginTestContext()
    {     
      CreateSplashForm();

      CreateLoginForm();
    }
}

(有关其他信息,请参阅此链接。)

我们进入应用程序的入口点将如下所示:

[STAThread]
static void Main()
{
     Application.EnableVisualStyles();
     Application.SetCompatibleTextRenderingDefault(false);

     //Run the application with our context. It is splash, log and main forms
     Application.Run(new LoginTestContext());    
}

创建启动窗体

就是这样!Splash窗体会在我们需要的时候显示。在这里,您可以做一些真正必要的操作,例如加载任何资源,同时显示进度条或其他类型的信息,而不是休眠线程。

private static void CreateSplashForm()
{
     Form fSplash = new Form();
     fSplash.BackgroundImage = System.Drawing.Image.FromFile(@"backg.bmp");

     fSplash.BackgroundImageLayout = ImageLayout.Center;
     fSplash.FormBorderStyle = FormBorderStyle.None;
     fSplash.StartPosition = FormStartPosition.CenterScreen;
     fSplash.TopMost = true;
     
     //it sets transparency for the background of image
     fSplash.TransparencyKey = System.Drawing.Color.White;
     
     //set the splash form size and we are sure the image fit to the form
     fSplash.Width = (int)fSplash.BackgroundImage.PhysicalDimension.Width;
     fSplash.Height = (int)fSplash.BackgroundImage.PhysicalDimension.Height;

     fSplash.Show();
     System.Threading.Thread.Sleep(2000);
     fSplash.Close();
}

创建登录表单

现在我们将讨论登录表单的建立问题。登录窗体位于启动窗体之后。在任何情况下,登录表单都应关闭。当它自行关闭时,我们必须确定是否在应用程序中进行登录:

private void CreateLoginForm()
{
    fLogin = new frmLogIn();
    fLogin.Closed += new EventHandler(fLogin_Closed);
    fLogin.TopMost = true;
    fLogin.Show();
}
     
void fLogin_Closed( object sender, EventArgs e )
{
    if (LWork.LoginWork.Login)
    {
        fMain = new frmMain();
        this.MainForm = fMain; //set the main message loop application in this form
        fMain.Show();
    }
    else
    {
        ExitThread();
    }
}

注册过程是在staticLoginWork中实现的。

public static void DoLogin( string NikName, string Password )
{
    if (IsExistNikName(NikName))
    {
        if (_user.Password == HashString(Password))
        {
          _Logged = true;
        }
    }
    else
        _Logged = false;
}

查找列表IsExistNikName (string name)中的用户名的功能使用lambda表达式UserData => UserData.Nikname == NikName实现。在这个例子中,实体lambda表达式的解释过于简单。有关lambda表达式的更多信息,请参阅此链接

private static bool IsExistNikName( string NikName )
{
    if (_UserDataList.Count == 0)
    {
        return false;
    }

     //here I use a lambda expression for the searching the nikname 
     //in the user data list
     _user = _UserDataList.FirstOrDefault(UserData => UserData.Nikname == NikName);

     if (String.IsNullOrEmpty(_user.Nikname))
     {
        return false;
     }

    return true;
}

为了安全起见,使用以下函数对用户的密码进行哈希处理:

public static string HashString( string s )
{
     //encode string to the array of bytes
     byte[] data = Encoding.Default.GetBytes(s);

     //hashing
     MD5 md5 = new MD5CryptoServiceProvider();
     byte[] result = md5.ComputeHash(data);
     
     //do hexadecimal-formatted string
     StringBuilder sb = new StringBuilder();
     foreach (byte item in result)
     {
        sb.Append(item.ToString("X"));
     }

     return sb.ToString();
}

保存、加载注册用户数据的过程是使用XML序列化和UserData结构实现的。数据存储在本地XML文件中:

[Serializable]
public struct UserData
{
    private string _Name;

    public string Name
    {
      get { return _Name; }
      set { _Name = value; }
    }

    private string _Nikname;

    public string Nikname
    {
      get { return _Nikname; }
      set { _Nikname = value; }
    }

    private string _Password;

    public string Password
    {
      get { return _Password; }
      set { _Password = value; }
    }
}

结论

这就是我想告诉你的关于这个话题的全部内容。我希望我成功地充分揭示了本文的主题。

https://www.codeproject.com/Articles/106751/Splash-and-Login-Forms-Problems-and-Solutions

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值