C# Winform下一个热插拔的MIS/MRP/ERP框架11(启航)
初学时,有了想法却完全不知道该从何下指,此序列将抛砖引玉,与大家共同学习进步。
一个程序的初始,必然是启动。
我的要求:
1、应用程序保持单例;
2、从配置文件加载一些基础数据进行初始化;
3、显示软件的LOGO页面;
4、判断应用程序是否有更新;
4、进入用户登录界面;
5、用户成功登录后显示主界面。
如上图,基本达成目标,这个项目也是很简单的结构:
看窗体名称就知道各自的用途了。主要的Program.cs代码如下:
- static class Program
- {
- public static bool 切换用户 = false;
- /// <summary>
- /// 主体框架应用程序的主入口点。
- /// </summary>
- [STAThread]
- static void Main()
- {
- string 实例标识 = Assembly.GetExecutingAssembly().GetName().Name + "_SingtonB20";
- Mutex mutex = new Mutex(true, 实例标识, out bool 单实例);
- if (!单实例)
- {
- 唤醒进程(实例标识);
- return;
- }
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Application.DoEvents();
- //初始化全局DS
- if (GlbInfo.DSGlb == null) GlbInfo.DSGlb = new System.Data.DataSet();
- else
- {
- GlbInfo.DSGlb.Clear();
- GlbInfo.DSGlb.Tables.Clear();
- }
- //加载全局多语言资源
- try
- {
- AppInit.CreateDT_MulLang(AppInfo.GetFile(AppInfo.AppFile.MulMessage), "Message_Core");
- AppInit.CreateDT_MulLang(AppInfo.GetFile(AppInfo.AppFile.MulSurface), "Surface_Core");
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- Environment.Exit();
- }
- //展示闪屏窗体
- Fm20Splash 闪屏窗 = new Fm20Splash();
- 闪屏窗.ShowDialog();
- //系统检测正常则显示登录界面,否则退出应用
- if (闪屏窗.DialogResult == DialogResult.OK)
- {
- 显示登录:
- 切换用户 = false;
- Fm20Login fmLogin = new Fm20Login();
- fmLogin.ShowDialog();
- if (fmLogin.DialogResult == DialogResult.OK)
- {
- Application.Run(new Fm20Main());
- }
- else
- {
- Application.Exit();
- }
- //当关闭主程序的时候会执行这个代码,在关闭主程序的时候需要给IsLogin 设置成true
- //重新回到登录窗口.
- if (切换用户)
- {
- goto 显示登录;
- }
- }
- else
- {
- Application.Exit();
- }
- }
- public static void 唤醒进程(string 进程名称)
- {
- try
- {
- Process proc = Process.GetCurrentProcess();
- string assemblyName = Assembly.GetExecutingAssembly().GetName().Name + 进程名称;
- foreach (Process 进程 in Process.GetProcessesByName(进程名称))
- {
- if (proc.Id != 进程.Id)
- {
- IntPtr hWnd = 进程.MainWindowHandle;
- if (WinAPI.IsIconic(hWnd))
- {
- WinAPI.ShowWindowAsync(hWnd, WinAPIConst.SW_RESTORE);
- }
- WinAPI.SetForegroundWindow(hWnd);
- return;
- }
- }
- }
- catch
- {
- }
- }
- }
Program.cs
一、第一个被运行的窗体(闪屏窗口):
- /// <summary>
- /// Splash闪屏窗体
- /// </summary>
- public partial class Fm20Splash : Fm11Base
- {
- /// <summary>
- /// 创建闪屏窗体
- /// </summary>
- public Fm20Splash()
- {
- InitializeComponent();
- OINI oINI = new OINI(AppInfo.GetFile(AppInfo.AppFile.ConfigCore));
- GlbInfo.Language = oINI.ReadString("Global", "CurrentLang", "LL");
- string licCompany = oINI.ReadString("Global", "License_To_" + GlbInfo.Language, "所有人");
- LabLicTo.Text = MultiLang.Surface(this, "LabLicTo", "授权给: ") + licCompany;
- if (GlbInfo.Language == "LL") LabSysTitle.Text = "IMES (智能制造执行系统)"; else LabSysTitle.Text= "IMES (Intelligent Manufacturing Execution System)";
- }
- private void Fm20Splash_MouseDown(object sender, MouseEventArgs e)
- {
- WinAPI.ReleaseCapture();
- WinAPI.SendMessage(Handle, WinAPIConst.WM_SYSCOMMAND, WinAPIConst.SC_MOVE + WinAPIConst.HTCAPTION, );
- }
- private static bool Delay(int delayTime)
- {
- DateTime now = DateTime.Now;
- int s;
- do
- {
- TimeSpan spand = DateTime.Now - now;
- s = spand.Seconds;
- Application.DoEvents();
- }
- while (s < delayTime);
- return true;
- }
- private void Fm20Splash_Shown(object sender, EventArgs e)
- {
- //开始检测系统配置是否符合要求
- //检测1:FRAMEWORK
- //检测2:检查组件资源
- #region 检测1:检测更新
- SetMainStatus(MultiLang.Surface(this, "ChkAppVersion","正在检查系统版本..."));
- Delay();
- string localPath = AppDomain.CurrentDomain.BaseDirectory;
- localPath = localPath.Substring(, localPath.Length - );
- string updateTxtFile = localPath + @"\UpdateLog.txt";
- //当更新指引文件不存在(如调试时),将跳过自动更新检测.
- if (File.Exists(updateTxtFile))
- {
- string[] allLines = File.ReadAllLines(localPath + @"\UpdateLog.txt");
- string remotePath = string.Empty;
- foreach (string line in allLines)
- {
- if (line.IndexOf("UpdatePath=") >= )
- {
- remotePath = line.Substring(line.IndexOf("UpdatePath=") + );
- break;
- }
- }
- if (NeedUpdate(localPath, remotePath))
- {
- File.Delete(localPath + "\\" + @"A19.exe");
- File.Copy(remotePath + "\\" + @"A19.exe", localPath + "\\" + @"A19.exe", true);
- string updFile = AppDomain.CurrentDomain.BaseDirectory + @"A19.exe";
- Process.Start(updFile);
- DialogResult = DialogResult.Cancel;
- Application.Exit();
- }
- }
- #endregion
- #region 清理过期插件版本,只保留最近的一项
- //根目录下不存在DLL或EXE原文件,则查找日期最后面的文件作为加载文件
- //查找M开头的exe和dll文件,规划M2-M8为模组EXE命名区域.如M22,M88
- var modFiles = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory).Select(f => new FileInfo(f)).Where(f => ((f.Name.IndexOf("M") == ) && f.Name.IndexOf("--") == ) && (f.Name.IndexOf(".exe") >= || f.Name.IndexOf(".dll") >= )).OrderBy(f => f.Name);
- string prevFileSpl = string.Empty;
- FileInfo ofi = null;
- foreach (var s in modFiles)
- {
- if (!string.IsNullOrEmpty(prevFileSpl))
- {
- if (s.Name.Substring(, s.Name.IndexOf("--")) == prevFileSpl.Substring(, prevFileSpl.IndexOf("--")))
- {
- if (s.LastWriteTime >= ofi.LastWriteTime)
- {
- ofi.Delete();
- }
- else
- {
- s.Delete();
- }
- }
- }
- ofi = s;
- prevFileSpl = s.Name;
- }
- #endregion
- DialogResult = DialogResult.OK;
- }
- /// <summary>
- /// 判断程序是否需要更新
- /// </summary>
- /// <param name="localPath"></param>
- /// <param name="remotePath"></param>
- /// <returns></returns>
- private bool NeedUpdate(string localPath, string remotePath)
- {
- try
- {
- FileInfo fiUL = new FileInfo(localPath + @"\UpdateLog.txt");
- FileInfo fiUR = new FileInfo(remotePath + @"\UpdateLog.txt");
- if (fiUL.LastWriteTime == fiUR.LastWriteTime)
- {
- SetMainStatus(MultiLang.Surface(this, "ChkAppVersion","正在检查系统版本...") + "OK!");
- return false;
- }
- else
- {
- return true;
- }
- }
- catch (Exception)
- {
- //出错将返回false,比如:没有设置好更新路径。
- return false;
- }
- }
- }
Fm20Splash.cs
它继承自一个基类窗体Fm11Base,默认会做一些例如加载多语言文本的事情,没这个需求直接继承Form也可以。
二、这个页面通过后(有更新的话会跳到自动更新程序,可以忽略),会进入到登录窗体:
- /// <summary>
- /// 登录窗体
- /// </summary>
- public partial class Fm20Login : Fm11Base
- {
- bool IsLogin = false;
- protected internal string SelAccountNO ;
- protected internal string SelAccountName ;
- private static readonly string DftAESKeyOfDlls = @"James/Wang/";
- private bool m_aeroEnabled;
- private static Fm20LoginTitle fm20LoginTitle;
- public string UserID
- {
- get { return TxtUserID.Text; }
- set { TxtUserID.Text = value; }
- }
- public Fm20Login()
- {
- m_aeroEnabled = false;
- InitializeComponent();
- fm20LoginTitle = new Fm20LoginTitle();
- }
- #region 无边框窗体处理
- /// <summary>
- /// 拖动无边框窗体
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void OnFormDrag(object sender, MouseEventArgs e)
- {
- WinAPI.ReleaseCapture();
- WinAPI.SendMessage(Handle, WinAPIConst.WM_SYSCOMMAND, WinAPIConst.SC_MOVE + WinAPIConst.HTCAPTION, );
- }
- protected override CreateParams CreateParams
- {
- get
- {
- m_aeroEnabled = CheckAeroEnabled();
- CreateParams cp = base.CreateParams;
- if (!m_aeroEnabled)
- cp.ClassStyle |= WinAPIConst.CS_DropSHADOW;
- return cp;
- }
- }
- private bool CheckAeroEnabled()
- {
- if (Environment.OSVersion.Version.Major >= )
- {
- int enabled = ;
- WinAPI.DwmIsCompositionEnabled(ref enabled);
- return (enabled == ) ? true : false;
- }
- return false;
- }
- protected override void WndProc(ref Message m)
- {
- base.WndProc(ref m);
- switch (m.Msg)
- {
- case WinAPIConst.WM_NCPAINT:
- if (m_aeroEnabled)
- {
- var v = ;
- WinAPI.DwmSetWindowAttribute(this.Handle, , ref v, );
- WinAPIConst.MARGINS margins = new WinAPIConst.MARGINS()
- {
- bottomHeight = ,
- leftWidth = ,
- rightWidth = ,
- topHeight =
- };
- WinAPI.DwmExtendFrameIntoClientArea(this.Handle, ref margins);
- }
- break;
- default:
- break;
- }
- if (m.Msg == WinAPIConst.WM_NCHITTEST && (int)m.Result == WinAPIConst.HTCLIENT)
- m.Result = (IntPtr)WinAPIConst.HTCAPTION;
- }
- #endregion
- private void MitClose_Click(object sender, EventArgs e)
- {
- DialogResult = DialogResult.Cancel;
- }
- private void MitMini_Click(object sender, EventArgs e)
- {
- WindowState = FormWindowState.Minimized;
- }
- private void Fm20Login_Shown(object sender, EventArgs e)
- {
- if (!fm20LoginTitle.Visible)
- {
- fm20LoginTitle.Show(this);
- }
- else
- {
- fm20LoginTitle.BringToFront();
- }
- fm20LoginTitle.Left = this.Left + this.Width / - fm20LoginTitle.Width / ;
- fm20LoginTitle.Top = this.Top + SplPnlMain.Panel1.Height - fm20LoginTitle.Height / ;
- }
- private void Fm20Login_Move(object sender, EventArgs e)
- {
- fm20LoginTitle.Left = this.Left + this.Width / - fm20LoginTitle.Width / ;
- fm20LoginTitle.Top = this.Top + SplPnlMain.Panel1.Height - fm20LoginTitle.Height / ;
- }
- private void Fm20Login_Load(object sender, EventArgs e)
- {
- try
- {
- LabStsVersion.Text = "Version: " + this.ProductVersion;
- TstMILangLL.Checked = (GlbInfo.Language == "LL");
- TstMILangLI.Checked = !TstMILangLL.Checked;
- PicLogo.Image = Image.FromFile(AppInfo.GetPath(AppInfo.AppPath.Image) + @"\App\LoginLd.png");
- //读取上一次记住的用户名
- OINI oPIniFile = new OINI(AppInfo.GetFile(AppInfo.AppFile.ConfigCore));
- TxtUserID.Text = oPIniFile.ReadString("Login", "LastUserID", string.Empty);
- SetMainStatus("..");
- }
- catch (Exception)
- {
- }
- }
- private void TxtUserCode_TextChanged(object sender, EventArgs e)
- {
- CmdClearUser.Visible = !(string.IsNullOrEmpty(TxtUserID.Text.Trim()));
- }
- private void TxtUserCode_Enter(object sender, EventArgs e)
- {
- PicFeedUser.BackgroundImage= Properties.Resources.LoginUserB;
- }
- private void TxtUserCode_Leave(object sender, EventArgs e)
- {
- PicFeedUser.BackgroundImage = Properties.Resources.LoginUserH;
- }
- private void TxtUserPass_TextChanged(object sender, EventArgs e)
- {
- CmdClearPwd.Visible = !(string.IsNullOrEmpty(TxtUserPass.Text.Trim()));
- }
- private void TxtUserPass_Enter(object sender, EventArgs e)
- {
- PicFeedLock.BackgroundImage = Properties.Resources.LoginPwdB;
- }
- private void TxtUserPass_Leave(object sender, EventArgs e)
- {
- PicFeedLock.BackgroundImage = Properties.Resources.LoginPwdH;
- }
- private void CmdClearUser_Click(object sender, EventArgs e)
- {
- TxtUserID.Clear();
- }
- private void CmdClearPwd_Click(object sender, EventArgs e)
- {
- TxtUserPass.Clear();
- }
- private void SetLanguage(string tagLang)
- {
- try
- {
- OINI oINI = new OINI(AppInfo.GetFile(AppInfo.AppFile.ConfigCore));
- oINI.WriteString("Global", "CurrentLang", tagLang);
- TstMILangLL.Checked = (tagLang == "LL");
- TstMILangLI.Checked = !TstMILangLL.Checked;
- GlbInfo.Language = tagLang;
- InitObjectsText(this);
- }
- catch (Exception)
- {
- throw;
- }
- }
- private void TstMILangLL_Click(object sender, EventArgs e)
- {
- SetLanguage("LL");
- }
- private void TstMILangLI_Click(object sender, EventArgs e)
- {
- SetLanguage("LI");
- }
- private void CmdLogin_Click(object sender, EventArgs e)
- {
- string tmpSts1 = MultiLang.Surface(this, "VeriUser", "正在验证用户...");
- SetMainStatus(tmpSts1);
- try
- {
- string postUserID = TxtUserID.Text;
- string postUserPass = TxtUserPass.Text;
- if (string.IsNullOrEmpty(postUserID) || string.IsNullOrEmpty(postUserPass))
- {
- MyMsg.Information("T.201001/用户名和密码不能为空.");
- TxtUserID.Focus();
- return;
- }
- if ((SelAccountNO == "DEMOH") )
- {
- MyMsg.Warning("T.201002/此帐套尚未开放,请选择其它帐套.");
- return;
- }
- if (SelAccountNO == "DEMO")
- {
- MyMsg.Warning("T.201003/您登录的是演示库,数据可能随时丢失,如需正式作业,请登录NORMAL正式库.");
- }
- string connStrCurAct = GetConnStrFromCfg(SelAccountNO, "ConnStr");
- string connStrExt1 = GetConnStrFromCfg(SelAccountNO, "ConnStrExt1");
- string connStrExt2 = GetConnStrFromCfg(SelAccountNO, "ConnStrExt2");
- string connStrExt3 = GetConnStrFromCfg(SelAccountNO, "ConnStrExt3");
- string connStrExt4 = GetConnStrFromCfg(SelAccountNO, "ConnStrExt4");
- string connStrExt5 = GetConnStrFromCfg(SelAccountNO, "ConnStrExt5");
- this.Cursor = Cursors.WaitCursor;
- #region 用户ERP登录验证部分
- DBContext dBContext = new DBContext(connStrCurAct);
- if (!dBContext.IsConnected)
- {
- MyMsg.Error("T.1010/数据库连接已经创建,但无法开启!", dBContext.ConnectErrorMessage);
- return;
- }
- postUserPass = OCrypto.AES16Encrypt(postUserPass, DftAESKeyOfDlls);
- SqlParameter[] paras = new SqlParameter[]
- {
- new SqlParameter("@UserID", postUserID),
- new SqlParameter("@PasswordHash", postUserPass)
- };
- string sqlText= "SELECT U.*, D.DeptCode, D.DeptNameLL, D.DeptNameLI FROM SYS_User AS U LEFT OUTER JOIN Base_Department AS D ON U.DeptRKEY = D.DeptRKEY WHERE (U.UserID= @UserID) AND (U.PasswordHash= @PasswordHash)";
- DataTable tmpDTUInfo = dBContext.SqlToDT(sqlText, paras);
- if (tmpDTUInfo.Rows.Count > )
- {
- DataRow drUser = tmpDTUInfo.Rows[];
- if (!OString.NZ2Bool(drUser["IActived"]))
- {
- IsLogin = false;
- SetMainStatus(MultiLang.Surface(this, "LoginFail1", "登录失败(帐号未激活),请联系管理员!"));
- }
- else if (OString.NZ2Bool(drUser["ILocked"]))
- {
- IsLogin = false;
- SetMainStatus(MultiLang.Surface(this, "LoginFail2", "登录失败(帐号被锁定),请联系管理员!"));
- }
- else
- {
- GlbInfo.User.UserID = OString.NZ2Str(drUser["UserID"]);
- GlbInfo.User.UserNameLL = OString.NZ2Str(drUser["UserNameLL"]);
- GlbInfo.User.IsAdmin = OString.NZ2Bool(drUser["Hero"]);
- GlbInfo.User.RolesUserIDS = OString.NZ2Str(drUser["RolesUserIDS"]);
- GlbInfo.User.RightsList.Clear();
- IsLogin = true;
- }
- }
- else
- {
- IsLogin = false;
- SetMainStatus(MultiLang.Surface(this, "LoginFail3", "登录失败(帐号不存在),请重新尝试!"));
- }
- if (IsLogin)
- {
- GlbInfo.ActNO = SelAccountNO;
- GlbInfo.ActName = SelAccountName;
- GlbInfo.ConnStrCurAct = connStrCurAct;
- GlbInfo.ConnStrExt1 = connStrExt1;
- GlbInfo.ConnStrExt2 = connStrExt2;
- GlbInfo.ConnStrExt3 = connStrExt3;
- GlbInfo.ConnStrExt4 = connStrExt4;
- GlbInfo.ConnStrExt5 = connStrExt5;
- fm20LoginTitle.Close();
- if (ChkRemember.Checked)
- {
- try
- {
- //记录下登录用户,以便下次不必输入用户名
- OINI oPIniFile = new OINI(AppInfo.GetFile(AppInfo.AppFile.ConfigCore));
- oPIniFile.WriteString("Login", "LastUserID", postUserID);
- }
- catch (Exception)
- {
- }
- }
- DialogResult = DialogResult.OK;
- }
- else
- {
- TxtUserPass.Text = string.Empty;
- TxtUserPass.Focus();
- MyMsg.Warning("T.201004/用户名或密码错误,请检查.");
- }
- #endregion
- }
- catch (Exception ex)
- {
- SetMainStatus(tmpSts1 + "出现异常!");
- MyMsg.Exclamation(ex.Message);
- }
- finally
- {
- this.Cursor = Cursors.Default;
- }
- }
- /// <summary>
- /// 从配置文件中获取指定帐套数据库连接字符串(已加密)
- /// </summary>
- /// <param name="actNO">帐套代码</param>
- /// <param name="tKey">定义的连接串Key</param>
- /// <returns></returns>
- private string GetConnStrFromCfg(string actNO, string tKey)
- {
- try
- {
- StringCollection Idents = new StringCollection();
- OINI oINI = new OINI(AppInfo.GetFile(AppInfo.AppFile.ConfigCore));
- return oINI.ReadString("Account:" + actNO, tKey, string.Empty);
- }
- catch (Exception ex)
- {
- MyMsg.Error(ex.Message);
- return string.Empty;
- }
- }
- private void LabChkRemember_DoubleClick(object sender, EventArgs e)
- {
- try
- {
- //记录下登录用户,以便下次不必输入用户名
- OINI oPIniFile = new OINI(AppInfo.GetFile(AppInfo.AppFile.ConfigCore));
- oPIniFile.WriteString("Login", "LastUserID", string.Empty);
- MyMsg.Information("已经清除登录历史,下次登录将不再显示当前帐号名称.");
- }
- catch (Exception)
- {
- }
- }
- }
Login.cs
登录界面是一个起点,涉及到文件操作以及数据库的连接/存取,下次再分解。
C# Winform下一个热插拔的MIS/MRP/ERP框架11(启航)的更多相关文章
- C# Winform下一个热插拔的MIS/MRP/ERP框架13(窗体基类)
作为一个ERP数据处理框架,大部分的开发场景都差不多. 理想中,对于通用数据处理,我的步骤如下: 1.为窗体指定数据来源(数据表/查询等): 2.拖入编辑控件,指定绑定字段: 3.结束. 为此,我设计 ...
- C# Winform下一个热插拔的MIS/MRP/ERP框架15(窗体基类场景1)
最基础的窗体基类其实是通过应用场景反推的结构. 以下是场景一: 单表应用,普通的数据,比如单位/颜色/特殊字典等使用者少的,无需过多控制的可以使用一个数据表格来管理. 和Excel表格差不多,批量修改 ...
- C# Winform下一个热插拔的MIS/MRP/ERP框架14(自动更新)
对于软件来说,启用自动更新是非常必要的. 根据软件的应用场景,我们可以设计不同的更新模型. 目前,IMES框架运行在.Net framework 4.0下面,使用的Win系统版本在Win7,域内管控, ...
- C# Winform下一个热插拔的MIS/MRP/ERP框架12(数据处理基类)
作为ERP等数据应用程序,数据库的处理是重中之重. 在框架中,我封装了一个数据库的基类,在每个模组启动或窗体启动过程中,实例化一个基类即可调用CRUD操作(create 添加read读取 update ...
- C# Winform下一个热插拔的MIS/MRP/ERP框架(通用控件)
一直对商业控件不感冒, 结合日常工作, 我写了几个常用控件. 一.下拉框控件(仿Access下拉框:F4下拉,自动输入,支持单/多列显示),可在Datagridview中使用. 1.常规: 2.Dat ...
- C# Winform下一个热插拔的MIS/MRP/ERP框架(简介)
Programmer普弱哥们都喜欢玩自己的框架,我也不例外. 理想中,这个框架要易于理解.易于扩展.易于维护:最重要的,易于CODING. 系统是1主体框架+N模组的多个EXE/DLL组成的,在主体框 ...
- C# Winform下一个热插拔的MIS/MRP/ERP框架(多语言方案)
个别时候,我们需要一种多语种切换方案. 我的方案是这样的: 1.使用文本文本存储多语言元素,应用程序启动时加载到内存表中: 2.应用程序启动时从配置文件加载语种定义: 3.所有窗体继承自一个Base基 ...
- C# Winform下一个热插拔的MIS/MRP/ERP框架16(窗体基类场景2)
如果没有特别需求,和场景1一样只变更表名,主键字段,检测字段等名称,不需要写其它代码了. * 清单列表+单笔编辑/保存,适用于大多数基础资料管理以及简单的单据资料录入(当然,排版是要改一改的): * ...
- [C#]Winform下回车或Tab键自动切换下一个控件焦点
满足用户体验,在数据录入时,能在输入完一个信息后通过回车或Tab键自动的切换到下一个控件(字段). 在界面控件设计时,默认可以通过设置控件的TabIndex来实现.但在布局调整时或者是对输入的内容有选 ...
随机推荐
- 处理大数据对象clob数据和blob数据
直接上下代码: package com.learn.jdbc.chap06; import java.io.File; import java.io.FileInputStream; import j ...
- JavaScript高级程序设计学习
1.变量 变量使用var操作符定义,var message,定义一个message变量,可用来保存任何类型的变量.未经初始化的变量值为undifided: 如果没变量没有被var定义,那么被执行后会成 ...
- jenkins 学习记录2
主题 在之前的学习中(http://www.cnblogs.com/abcwt112/p/6274575.html)我已经学会怎么打包了..这篇文章记录分享我学习如何利用jenkins将打完的包发布到 ...
- Eclipse中建立Maven项目后,Java Resources资源文件下没有src/main/java文件夹
当建立好一个Maven项目后,在Java Resources资源文件夹下没有看到src/main/java文件夹,然后手动去创建Source Folder时,提示该文件已存在,如图: 有一个解决办法: ...
- springBean之BeanFactory与ApplicationContext
一.主要区别: 两者都是通过xml配置文件加载bean,ApplicationContext和BeanFacotry相比,提供了更多的扩展功能,但其主要区别在于后者是延迟加载,如果Bean的某一个属性 ...
- Python嵌套、递归、高阶函数
一.嵌套函数 1.嵌套函数简单的理解可以看作是在函数的内部再定义函数,实现函数的“私有”. 2.特点: <1> 函数内部可以再次定义函数. <2> 只有被调用时才会执行(外部函 ...
- Texture Filter
[Texture Filter] 我们的纹理是要贴到三维图形表面的,而三维图形上的pixel中心和纹理上的texel中心并不一至(pixel不一定对应texture上的采样中心texel),大小也不一 ...
- SpringMVC简单的文件上传
引入依赖包: <!-- 文件上传的依赖 --> <dependency> <groupId>commons-fileupload</groupId> & ...
- Leetcode:Longest Substring Without Repeating Characters分析和实现
题目大意是传入一条字符串,计算出这样的这样一条子字符串,要求子字符串是原字符串的连续的某一段,且子字符串内不包含两个或两个以上的重复字符.求符合上面条件的字符串中最长的那一条的长度. 首先注意到任意一 ...
- zend studio在线安装svn的插件
这个,其实真的很简单 ,但是让我纠结了很久. 安装步骤: 1.确保电脑能够上网: 2.打开zend studio,然后选择help->welcome会弹出一个欢迎页面; 3.等待几秒后可以看到右 ...