【问题】
之前已经实现了,使用C#下载ST中的歌曲,现在想要添加新功能。
在下载一首歌曲完毕后,在右下角可以出现提示窗口,用于显示,可点击打开文件和文件夹的功能。
就类似于360浏览器(还是迅雷?)中,文件下载完毕后的提示窗口一样。
【图】
.jpg)
【解决过程】
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#中如何在右下角添加提示窗口,用于显示打开文件和文件夹




