如何用C#做一个类似于桌面插件的程序(转)
2008-06-17 15:12
405 查看
最近看到有人问如何做一个“桌面天气秀”类似的软件,开始我以为做这个东西很复杂,因为觉得至少要传递Message给Desktop。但事实上,一试之后发现做这个程序竟然很简单。
以下就把做的步骤列出来,供大家参考。
首先,需要设置窗体样式,这里面要设置的有:
l 设置FormBorderStyle为None;
l 设置TopMost为false;
l 设置ShowInTaskbar为false;
l 为了能穿透桌面,要把BackColor设为White,在把TransparentKey设为White;
这样,窗体的基本设置就完成了,为了显示要画的内容,则需要在窗体的Paint事件中去做,我这里所画的内容是显示当前月的所有天,相当于一个小日历。
private void Draw( Graphics g )
{
const float REG_HEIGHT = 30f;
const float START_POS_X = 0f;
const float START_POS_Y = 0f;
const int BLANK_SPACE_NUM = 5;
// Draw day of week signal
RectangleF recRegion = new RectangleF( START_POS_X, START_POS_Y,
(float)(this.Width), REG_HEIGHT );
const string FORMAT_STRING = "{0}{1}{2}{3}{4}{5}{6}";
string strDraw = string.Format( FORMAT_STRING,
"SUN".PadLeft( BLANK_SPACE_NUM, ' ' ),
"MON".PadLeft( BLANK_SPACE_NUM, ' ' ),
"TUE".PadLeft( BLANK_SPACE_NUM, ' ' ),
"WED".PadLeft( BLANK_SPACE_NUM, ' ' ),
"THU".PadLeft( BLANK_SPACE_NUM, ' ' ),
"FRI".PadLeft( BLANK_SPACE_NUM, ' ' ),
"SAT".PadLeft( BLANK_SPACE_NUM, ' ' ) );
Font myFont = new Font( "宋体", 11, FontStyle.Bold );
StringFormat sfDraw = new StringFormat();
sfDraw.Alignment = StringAlignment.Near;
sfDraw.LineAlignment = StringAlignment.Far;
Brush brDraw = new SolidBrush( Color.Wheat );
g.DrawString( strDraw, myFont, brDraw, recRegion, sfDraw );
DateTime dtFirstDate = DateTime.Now.AddDays( 1 - DateTime.Now.Day );
int nStartIndex = (int)(dtFirstDate.DayOfWeek);
nStartIndex++;
TimeSpan tsDays = dtFirstDate.AddMonths( 1 ) - dtFirstDate;
// Draw every day in this month
strDraw = "";
int i = 0;
for( ; i < tsDays.Days; i++ )
{
switch( dtFirstDate.AddDays( i ).DayOfWeek )
{
case DayOfWeek.Sunday:
case DayOfWeek.Monday:
case DayOfWeek.Tuesday:
case DayOfWeek.Wednesday:
case DayOfWeek.Thursday:
case DayOfWeek.Friday:
strDraw += (i+1).ToString().PadLeft( BLANK_SPACE_NUM, ' ');
break;
case DayOfWeek.Saturday:
strDraw += (i+1).ToString().PadLeft( BLANK_SPACE_NUM, ' ');
strDraw = strDraw.PadLeft( BLANK_SPACE_NUM * 7, ' ' );
recRegion = new RectangleF( START_POS_X,
START_POS_Y + REG_HEIGHT * ( 1 + ( (i+1) + nStartIndex - 7 ) / 7 ),
(float)(this.Width), REG_HEIGHT );
g.DrawString( strDraw, myFont, brDraw, recRegion, sfDraw );
strDraw = "";
break;
}
}
if( strDraw != "" )
{
strDraw = strDraw.PadRight( BLANK_SPACE_NUM * 7, ' ' );
recRegion = new RectangleF( START_POS_X,
START_POS_Y + REG_HEIGHT * ( 1 + ( i + nStartIndex - 7 ) / 7 + 1 ),
(float)(this.Width), REG_HEIGHT );
g.DrawString( strDraw, myFont, brDraw, recRegion, sfDraw );
}
}
private void frmSprite_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
Draw( g );
}
为了窗体能方便的退出,我加了一个NotifyIcon和ContextMenu来处理,具体如下。
private System.Windows.Forms.NotifyIcon ntfSprite;
private System.Windows.Forms.ContextMenu mnuContext;
private System.Windows.Forms.MenuItem mnuExit;
private void mnuExit_Click(object sender, System.EventArgs e)
{
this.Close();
}
本来以为自己的窗体放在Desktop之前,会影响窗体下Desktop的某些操作,但事实,这一点根本不用担心,因为.Net框架已经替你做了,因此你不用再调用API来传递消息。
如果想要所显示的窗体能够随意拖动,这可以参看我另外一篇文章:
http://blog.csdn.net/knight94/archive/2006/04/14/663089.aspx
以上的代码只是做了简单的测试,大家可以在我的基础上做扩展,例如调用Api来对当前进程作一些隐藏,设置窗体的起始位置,以及一些界面操作之类,放到启动菜单,这些都是可以完成的,我这里就不罗嗦了
以下就把做的步骤列出来,供大家参考。
首先,需要设置窗体样式,这里面要设置的有:
l 设置FormBorderStyle为None;
l 设置TopMost为false;
l 设置ShowInTaskbar为false;
l 为了能穿透桌面,要把BackColor设为White,在把TransparentKey设为White;
这样,窗体的基本设置就完成了,为了显示要画的内容,则需要在窗体的Paint事件中去做,我这里所画的内容是显示当前月的所有天,相当于一个小日历。
private void Draw( Graphics g )
{
const float REG_HEIGHT = 30f;
const float START_POS_X = 0f;
const float START_POS_Y = 0f;
const int BLANK_SPACE_NUM = 5;
// Draw day of week signal
RectangleF recRegion = new RectangleF( START_POS_X, START_POS_Y,
(float)(this.Width), REG_HEIGHT );
const string FORMAT_STRING = "{0}{1}{2}{3}{4}{5}{6}";
string strDraw = string.Format( FORMAT_STRING,
"SUN".PadLeft( BLANK_SPACE_NUM, ' ' ),
"MON".PadLeft( BLANK_SPACE_NUM, ' ' ),
"TUE".PadLeft( BLANK_SPACE_NUM, ' ' ),
"WED".PadLeft( BLANK_SPACE_NUM, ' ' ),
"THU".PadLeft( BLANK_SPACE_NUM, ' ' ),
"FRI".PadLeft( BLANK_SPACE_NUM, ' ' ),
"SAT".PadLeft( BLANK_SPACE_NUM, ' ' ) );
Font myFont = new Font( "宋体", 11, FontStyle.Bold );
StringFormat sfDraw = new StringFormat();
sfDraw.Alignment = StringAlignment.Near;
sfDraw.LineAlignment = StringAlignment.Far;
Brush brDraw = new SolidBrush( Color.Wheat );
g.DrawString( strDraw, myFont, brDraw, recRegion, sfDraw );
DateTime dtFirstDate = DateTime.Now.AddDays( 1 - DateTime.Now.Day );
int nStartIndex = (int)(dtFirstDate.DayOfWeek);
nStartIndex++;
TimeSpan tsDays = dtFirstDate.AddMonths( 1 ) - dtFirstDate;
// Draw every day in this month
strDraw = "";
int i = 0;
for( ; i < tsDays.Days; i++ )
{
switch( dtFirstDate.AddDays( i ).DayOfWeek )
{
case DayOfWeek.Sunday:
case DayOfWeek.Monday:
case DayOfWeek.Tuesday:
case DayOfWeek.Wednesday:
case DayOfWeek.Thursday:
case DayOfWeek.Friday:
strDraw += (i+1).ToString().PadLeft( BLANK_SPACE_NUM, ' ');
break;
case DayOfWeek.Saturday:
strDraw += (i+1).ToString().PadLeft( BLANK_SPACE_NUM, ' ');
strDraw = strDraw.PadLeft( BLANK_SPACE_NUM * 7, ' ' );
recRegion = new RectangleF( START_POS_X,
START_POS_Y + REG_HEIGHT * ( 1 + ( (i+1) + nStartIndex - 7 ) / 7 ),
(float)(this.Width), REG_HEIGHT );
g.DrawString( strDraw, myFont, brDraw, recRegion, sfDraw );
strDraw = "";
break;
}
}
if( strDraw != "" )
{
strDraw = strDraw.PadRight( BLANK_SPACE_NUM * 7, ' ' );
recRegion = new RectangleF( START_POS_X,
START_POS_Y + REG_HEIGHT * ( 1 + ( i + nStartIndex - 7 ) / 7 + 1 ),
(float)(this.Width), REG_HEIGHT );
g.DrawString( strDraw, myFont, brDraw, recRegion, sfDraw );
}
}
private void frmSprite_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
Draw( g );
}
为了窗体能方便的退出,我加了一个NotifyIcon和ContextMenu来处理,具体如下。
private System.Windows.Forms.NotifyIcon ntfSprite;
private System.Windows.Forms.ContextMenu mnuContext;
private System.Windows.Forms.MenuItem mnuExit;
private void mnuExit_Click(object sender, System.EventArgs e)
{
this.Close();
}
本来以为自己的窗体放在Desktop之前,会影响窗体下Desktop的某些操作,但事实,这一点根本不用担心,因为.Net框架已经替你做了,因此你不用再调用API来传递消息。
如果想要所显示的窗体能够随意拖动,这可以参看我另外一篇文章:
http://blog.csdn.net/knight94/archive/2006/04/14/663089.aspx
以上的代码只是做了简单的测试,大家可以在我的基础上做扩展,例如调用Api来对当前进程作一些隐藏,设置窗体的起始位置,以及一些界面操作之类,放到启动菜单,这些都是可以完成的,我这里就不罗嗦了
相关文章推荐
- 如何用C#做一个类似于桌面插件的程序
- [愚翁专栏]如何用C#做一个类似于桌面插件的程序
- C# 如何使自己的程序在“显示桌面”时不最小化
- [愚翁专栏]如何用C#做一个悬浮窗口程序
- 如何在网页中打开一个本地桌面程序
- C# 只开启一个程序,如果第二次打开则自动将第一个程序显示到桌面
- C#中如何防止一个程序运行多个副本(转载)
- C# winform 程序中如何限制一个文本框中只输入数字和字母(撤消键可以用)
- 如何构造一个C#语言的爬虫蜘蛛程序
- C#如何让同一个窗口只能打开一次和一个程序只能同时打开一个
- 如何构造一个C#语言的爬虫程序
- 如何构造一个C#语言的爬虫蜘蛛程序
- C# 如何使自己的程序在“显示桌面”时不最小化
- C#建立了一个windows程序,如何防止多个程序实例运行?
- [VB.NET]如何把一个c#程序转变为VB.NET
- c# Winform 如何实现程序只能同时运行一个实例
- C#如何判断我的程序已经有一个实例正在运行
- 如何在C#中启动一个外部程序?
- 【C#】如何让多个或全部窗口使用同一个图标(icon),减小程序体积
- 如何构造一个C#语言的爬虫蜘蛛程序