【问题】
之前已经实现了,使用C#下载ST中的歌曲,现在想要添加新功能。
在下载一首歌曲完毕后,在右下角可以出现提示窗口,用于显示,可点击打开文件和文件夹的功能。
就类似于360浏览器(还是迅雷?)中,文件下载完毕后的提示窗口一样。
【图】
【解决过程】
1.之前已经知道有NotifyIcon了,本来打算去找找,看看是否可能通过NotifyIcon中去添加带点击的“打开文件”和“打开目录”的,但是找了半天,官网中关于
的解释,没有看到合适的属性和方法。
2.同理,打算去通过
中显示的文字中,添加带链接的文字,然后可以点击“打开文件”和“打开目录”的。
结果只看到一些关于捕获鼠标点击事件的。
貌似理论上也许支持根据获得的鼠标点击,打开对应的文件夹,但是却不支持自定义点击不同的文字,实现打开文件还是目录,所以,还是放弃此条路。
3.网上找了半天,没看到逻辑清晰的实现方法。
4.貌似只能是自己去实现,新建form并显示,然后支持两可以点击的label或button,然后打开对应的文件和文件夹了。
5.新建一个窗口:
6.新建好了窗体后,经过尝试,把窗体Style改为FixedToolWindow,是最合适的:
然后拖动两个LinkLabel上去:
最后再经过一些调整字体和位置,变成:
7.接下来,就是去实现对应的事件,即,鼠标点击,所对应要执行的动作了。
双击文字,自动新建对应的事件函数:
namespace downloadSongtasteMusic { public partial class completeHint : Form { public completeHint() { InitializeComponent(); } private void lklOpenFile_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { } private void lklOpenFolder_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { } } }
接下来,就是去实现对应的函数,即可。
8.先去折腾,打开文件夹的功能。
关于调用资源管理器打开文件夹的折腾过程参见:
【已解决】C#中调用资源管理器(Explorer.exe)打开指定文件夹 + 并选中指定文件 + 调用(系统默认的播放类)软件(如WMP)打开(播放歌曲等)文件
9.但是上述只是去打开固定的路径C:\,而此处想要打开从主窗体中获得的当前路径:txbSaveTo.Text,所以,又遇到了如何从另外一个窗体中获得变量的值的问题,具体折腾过程参考:
【已解决】C#中,如何在一个(子)窗体中,获得另一个(父)窗体中的(控件)变量的值
10.但是,此时窗体显示出来的位置,还不是所希望的右下角的位置。
所以就要计算窗体显示的位置,希望显示在任务栏之上,屏幕的右下角,所以需要知道当前的任务栏的高度和位置。
【已解决】C#中获得当前任务栏的大小(宽度和高度) 和 当前屏幕的右下角位置 – 均支持任务栏的下右上左四种模式
11.然后期间需要用到倒计时关闭窗口,详细过程参见:
12.已经可以实现了显示右下角显示窗口了,并且也支持点击“目录”可以打开文件夹并选中刚下载的文件。
现在就是去优化窗口的显示,确保每次只打开单个窗口,不要重复生成新窗口。
期间,涉及到子窗体设置父窗体中的值,折腾过程参考:
【已解决】C#中,如何在一个(子)窗体中,设置另外一个(父)窗体中的值
13.至此,算是基本完成了,可以在右下角显示提示窗口,窗口中,点击支持,打开文件夹并定位文件,打开文件并播放。
并且提示窗口可以点击关闭,或者等待延迟5秒自动关闭。
【总结】
想要实现右下角显示窗口,主要是根据当前任务栏的位置,计算出要显示的位置,即可。
上面所说的,其他的功能,都是辅助需要实现的。和右下角显示提示窗口,关系不是很大,但是也是常常会遇到的需求而已。
父窗体中frmDownloadSongtasteMusic.cs相关部分的代码:
namespace downloadSongtasteMusic { public partial class frmDownloadSongtasteMusic : Form { private string curFullFilename; public completeHint hintWindow; private Timer closeWindowTimer; public void resetHintWindow() { if (hintWindow != null) { //NOTE: here also will call completeHint_FormClosed !!! hintWindow.Close(); } hintWindow = null; } public void closeHintWindow(object sender, EventArgs e) { closeWindowTimer.Stop(); resetHintWindow(); } public void showCompleteHint() { //open hint window if (hintWindow == null) { hintWindow = new completeHint(); } hintWindow.Owner = this; hintWindow.initParameter(curFullFilename, txbSaveTo.Text); hintWindow.Show(); //add timer to close window after several seconds closeWindowTimer = new Timer(); closeWindowTimer.Interval = 5000; closeWindowTimer.Tick += new EventHandler(closeHintWindow); closeWindowTimer.Start(); } } }
子窗体completeHint.cs的代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace downloadSongtasteMusic { public partial class completeHint : Form { private string curFullFilename; private string curFolderPath; private frmDownloadSongtasteMusic curParentForm; public completeHint() { InitializeComponent(); curParentForm = null; } public void initParameter(string fullFilename, string folderPath) { curFullFilename = fullFilename; curFolderPath = folderPath; curParentForm = (frmDownloadSongtasteMusic)this.Owner; } private void lklOpenFile_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { //open file System.Diagnostics.Process.Start(curFullFilename); } private void lklOpenFolder_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { //open folder System.Diagnostics.Process.Start("Explorer.exe", "/select," + curFullFilename); // Note: only 2 para !!! } // get current taskbar size(width, height), support four mode: taskbar bottom/right/up/left public Size getCurTaskbarSize() { int width = 0, height = 0; if ((Screen.PrimaryScreen.Bounds.Width == Screen.PrimaryScreen.WorkingArea.Width) && (Screen.PrimaryScreen.WorkingArea.Y == 0)) { //taskbar bottom width = Screen.PrimaryScreen.WorkingArea.Width; height = Screen.PrimaryScreen.Bounds.Height - Screen.PrimaryScreen.WorkingArea.Height; } else if ((Screen.PrimaryScreen.Bounds.Height == Screen.PrimaryScreen.WorkingArea.Height) && (Screen.PrimaryScreen.WorkingArea.X == 0)) { //taskbar right width = Screen.PrimaryScreen.Bounds.Width - Screen.PrimaryScreen.WorkingArea.Width; height = Screen.PrimaryScreen.WorkingArea.Height; } else if ((Screen.PrimaryScreen.Bounds.Width == Screen.PrimaryScreen.WorkingArea.Width) && (Screen.PrimaryScreen.WorkingArea.Y > 0)) { //taskbar up width = Screen.PrimaryScreen.WorkingArea.Width; //height = Screen.PrimaryScreen.WorkingArea.Y; height = Screen.PrimaryScreen.Bounds.Height - Screen.PrimaryScreen.WorkingArea.Height; } else if ((Screen.PrimaryScreen.Bounds.Height == Screen.PrimaryScreen.WorkingArea.Height) && (Screen.PrimaryScreen.WorkingArea.X > 0)) { //taskbar left width = Screen.PrimaryScreen.Bounds.Width - Screen.PrimaryScreen.WorkingArea.Width; height = Screen.PrimaryScreen.WorkingArea.Height; } return new Size(width, height); } // get current right bottom corner position(X, Y), support four mode: taskbar bottom/right/up/left public Point getCornerLocation() { int xPos = 0, yPos = 0; if( (Screen.PrimaryScreen.Bounds.Width == Screen.PrimaryScreen.WorkingArea.Width) && (Screen.PrimaryScreen.WorkingArea.Y == 0)) { //taskbar bottom xPos = Screen.PrimaryScreen.WorkingArea.Width - this.Size.Width; yPos = Screen.PrimaryScreen.WorkingArea.Height - this.Size.Height; } else if((Screen.PrimaryScreen.Bounds.Height == Screen.PrimaryScreen.WorkingArea.Height) && (Screen.PrimaryScreen.WorkingArea.X == 0) ) { //taskbar right xPos = Screen.PrimaryScreen.WorkingArea.Width - this.Size.Width; yPos = Screen.PrimaryScreen.WorkingArea.Height - this.Size.Height; } else if((Screen.PrimaryScreen.Bounds.Width == Screen.PrimaryScreen.WorkingArea.Width) && (Screen.PrimaryScreen.WorkingArea.Y > 0) ) { //taskbar up xPos = Screen.PrimaryScreen.WorkingArea.Width - this.Size.Width; yPos = Screen.PrimaryScreen.WorkingArea.Y; } else if ((Screen.PrimaryScreen.Bounds.Height == Screen.PrimaryScreen.WorkingArea.Height) && (Screen.PrimaryScreen.WorkingArea.X > 0)) { //taskbar left xPos = Screen.PrimaryScreen.WorkingArea.X; yPos = Screen.PrimaryScreen.WorkingArea.Height - this.Size.Height; } return new Point(xPos, yPos); } private void completeHint_Load(object sender, EventArgs e) { Size curTaskbarSize = getCurTaskbarSize(); this.Location = getCornerLocation(); } private void completeHint_FormClosed(object sender, FormClosedEventArgs e) { if (curParentForm != null) { //!!! should NOT call resetHintWindow here, otherwise will dead loop curParentForm.hintWindow = null; } } } }
需要的,可以自己参考相关部分的代码。
转载请注明:在路上 » 【已解决】C#中如何在右下角添加提示窗口,用于显示打开文件和文件夹