C#如何模仿MSN消息提示窗口向上推的的功能?

l25926845 2009-12-31 08:57:32
消息弹出我用的API的AnimateWindow和SetWindowPos方法来显示消息提示窗体,另外还加了一个Timeer来让窗体逐渐消失自动关闭。但是当有多条消息同时显示的时候根据SetWindowPos方法中的属性设定是在同一坐标显示的。请问有没有能判断信息条数然后分开显示的方法?
个人感觉还是SetWindowPos方法中的某个属性设置的问题
...全文
283 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
hualiang_ll 2009-12-31
  • 打赏
  • 举报
回复
我发过和你一样的帖子,你可以看看我发过的帖子,应该这个问题就可以解决了。
m_struggle 2009-12-31
  • 打赏
  • 举报
回复
帮顶
liushengmz 2009-12-31
  • 打赏
  • 举报
回复
我自己写的时候就是通过Timer+窗口操作+队列来实现的,但是效果远没有有MSN的好
  • 打赏
  • 举报
回复
爬Windows窗口看似不可行,消息提示窗口往往显示在一些窗口前面,而不是上面。
  • 打赏
  • 举报
回复
你必须用同一个对象实例来管理消息窗口的弹出、移动、消失,这样它就可以遍历、协调。其它程序只是跟它交互而不是各自弹出消息窗口。
ITJaneLiu 2009-12-31
  • 打赏
  • 举报
回复
帮顶.
l25926845 2009-12-31
  • 打赏
  • 举报
回复
的确,显示窗体和样式什么的都好实现。只是让窗体根据信息数量和先后顺序排队是难点,正在研究中有结果了会发出来。当然有会的人也不要吝惜啊~
deyter 2009-12-31
  • 打赏
  • 举报
回复
用AnimateWindow还不如自己写
就是timer+窗体的操作
l25926845 2009-12-31
  • 打赏
  • 举报
回复
自己顶
l25926845 2009-12-31
  • 打赏
  • 举报
回复
 /// <summary>
/// 清空数据库中未读信息记录
/// </summary>
private void clearUncountMessageCount()
{
Service service = new Service();
int flag = service.updateMessageCount_IN(uId, suId);
if (flag.Equals(-99))
{
CommonCode.CommonMessageBox.failedMessageBox("更新MessageCount失败");
}
}

private void moveUpTimer_Tick(object sender, EventArgs e)
{
switch (this.NextState)
{
case FormMoveState.MoveUp:
this.moveUp(new object());
break;
case FormMoveState.Waiting:
this.moveWait(new object());
break;
case FormMoveState.MoveDown:
this.moveDown(new object());
break;
default:
break;
}
//int a = this.Height - this.moveCount;
//this.label1.Text = a.ToString() + " " + this.Size.Height.ToString() + " " + this.BackgroundImage.Height.ToString();
}

private void moveUp(object sender)
{
if (this.Location.Y != this.EndPoint.Y)
{
moveCount++;
Point tempPoint = new Point();
tempPoint.X = this.Location.X;
tempPoint.Y = this.Location.Y - this.moveHeight;
if (this.useThread)
{
this.SetLocation(tempPoint);
this.SetHeight(this.Height + this.moveHeight);
}
else
{
this.Location = tempPoint;
//为什么要等待两次也就是两像素?因为Form。Height默认最小值为2
if (this.moveCount > 2)
{
this.Height += this.moveHeight;
}
}
this.State = FormMoveState.MoveUp;
}
else
{
this.NextState = FormMoveState.Waiting;
}
}

private void waitingTimer_Tick(object sender, EventArgs e)
{
this.moveWait(new object());
}

private void moveWait(object sender)
{
if (!this.mouseStateTimer.Enabled)
{
this.mouseStateTimer.Enabled = true;
}

if (this.waitedCount < this.waitCount)
{
this.waitedCount++;
this.State = FormMoveState.Waiting;
}
else
{
this.NextState = FormMoveState.MoveDown;
}
}

private void moveDownTimer_Tick(object sender, EventArgs e)
{
this.moveDown(new object());
}

private void moveDown(object sender)
{
if (this.mouseStateTimer.Enabled)
{
this.mouseStateTimer.Enabled = false;
}

if (this.Location != this.StartPoint)
{
Point tempPoint = new Point();
tempPoint.X = this.Location.X;
tempPoint.Y = this.Location.Y + this.moveHeight;
if (this.useThread)
{
this.SetLocation(tempPoint);
this.SetHeight(this.Height - this.moveHeight);
}
else
{
this.Location = tempPoint;
this.Height -= this.moveHeight;
}
this.State = FormMoveState.MoveDown;
}
else
{
if (this.useThread)
{
this.upTimer.Change(-1, -1);
this.CloseWindow();
}
else
{
this.moveUpTimer.Enabled = false;
this.Close();
}
}
}

private void MoveForm_MouseEnter(object sender, EventArgs e)
{
this.mouseEnter = true;
}

private void MoveForm_MouseLeave(object sender, EventArgs e)
{
this.mouseEnter = false;
}

private void mouseState(object sender)
{
if (this.State == FormMoveState.Waiting && this.mouseEnter)
{
this.moveUpTimer.Enabled = false;
}
else
{
this.moveUpTimer.Enabled = true;
}
}

private void MoveForm_FormClosed(object sender, FormClosedEventArgs e)
{
this.Opener.ListMoveForms.Remove(this);
}

private void SetLocation(Point p)
{
if (this.InvokeRequired)
{
this.Invoke(new SetLocationHandler(this.SetLocation), new object[] { p });
}
else
{
this.Location = p;
}
}

private void SetHeight(int height)
{
if (this.InvokeRequired)
{
this.Invoke(new SetHeightHandler(this.SetHeight), new object[] { height });
}
else
{
this.Height = height;
}
}

private void CloseWindow()
{
if (this.InvokeRequired)
{
this.Invoke(new CloseWindowHandler(this.CloseWindow));
}
else
{
this.Close();
}
}

private void moveUpTimer_Tick_1(object sender, EventArgs e)
{
switch (this.NextState)
{
case FormMoveState.MoveUp:
this.moveUp(new object());
break;
case FormMoveState.Waiting:
this.moveWait(new object());
break;
case FormMoveState.MoveDown:
this.moveDown(new object());
break;
default:
break;
}
}

private void mouseStateTimer_Tick_1(object sender, EventArgs e)
{
this.mouseState(new object());
}
}
l25926845 2009-12-31
  • 打赏
  • 举报
回复
    public partial class FrmMessageCount : Form
{
//发送方ID
Guid uId;
//接收方ID
Guid suId;

/// <summary>
/// 滚动开始点
/// </summary>
private Point StartPoint;
/// <summary>
/// 等待次数
/// </summary>
private int waitCount = 50;
/// <summary>
/// 已经等待的次数
/// </summary>
private int waitedCount = 0;

/// <summary>
/// 滚动终点
/// </summary>
private Point EndPoint;

/// <summary>
/// 当前窗体的纵坐标
/// </summary>
public int Y
{
get { return this.EndPoint.Y; }
}

/// <summary>
/// 当前状态
/// </summary>
private FormMoveState State;

/// <summary>
/// 下一个状态
/// </summary>
private FormMoveState NextState;

/// <summary>
/// 窗体距离右边屏幕的距离
/// </summary>
private int marginRight = 50;

/// <summary>
/// 鼠标是否已经悬停
/// </summary>
private bool mouseEnter;

/// <summary>
/// 窗口的打开者
/// </summary>
public FrmMain Opener;

/// <summary>
/// 移动终点与初始点的纵坐标的差,一般等于窗体高度
/// </summary>
private int endHeight = 200;

private delegate void SetLocationHandler(Point p);
private delegate void SetHeightHandler(int height);
private delegate void CloseWindowHandler();

private System.Threading.Timer upTimer;
private System.Threading.Timer waitTimer;
//private System.Threading.Timer downTimer;
//private System.Threading.Timer mouseTimer;

/// <summary>
/// 是否使用 System.Threading.Timer 控件
/// </summary>
private bool useThread = false;

/// <summary>
/// 移动次数
/// </summary>
private int moveCount = 0;

private int moveHeight = 1;

public FrmMessageCount(string userTrueName, int count, Guid userId, Guid sendToUserId)
{
if (this.useThread)
{
this.upTimer = new System.Threading.Timer(new System.Threading.TimerCallback(this.moveUp));
this.waitTimer = new System.Threading.Timer(new System.Threading.TimerCallback(this.moveWait));
//this.downTimer = new System.Threading.Timer(new System.Threading.TimerCallback(this.moveDown));
//this.mouseTimer = new System.Threading.Timer(new System.Threading.TimerCallback(this.mouseState));
}

Control.CheckForIllegalCrossThreadCalls = false;
InitializeComponent();
lblText.Text = userTrueName.ToString() + "给你发送了" + count.ToString() + "条信息";
Ceterlabel();
uId = sendToUserId;
suId = userId;
//窗体弹出的同时开启线程清空数据库中未读记录的信息
Thread t = new Thread(clearUncountMessageCount);
t.Start();
}

private void FrmMessageCount_Load(object sender, EventArgs e)
{
this.lblText.Visible = false;
//置窗口的大小
//this.Width = this.Width;
this.Width = this.BackgroundImage.Width;

this.Height = 2;

//this.endHeight = this.Height;
this.endHeight = this.BackgroundImage.Height;

//this.Height = this.endHeight;
//return;

//获取当前屏幕

Screen currentScreen = Screen.AllScreens[0];

//设置开始位置

this.StartPoint = new Point();
this.StartPoint.X = currentScreen.WorkingArea.Width - this.Width - this.marginRight;
this.StartPoint.Y = this.Opener.TopPointY;
//设置终止位置

this.EndPoint = new Point();
this.EndPoint.X = this.StartPoint.X;
this.EndPoint.Y = this.Opener.TopPointY - this.endHeight;

//设置窗口初始位置
this.Location = this.StartPoint;

//设置moveUpTimer;
if (this.useThread)
{
this.upTimer.Change(10, 50);
}
else
{
this.moveUpTimer.Enabled = true;
}

this.NextState = FormMoveState.MoveUp;
}

//label居中
public void Ceterlabel()
{
this.lblText.Left = (this.Width - lblText.Width) / 2;
this.lblText.Height = (this.Height - lblText.Height) / 2;
}
private void lblText_Resize(object sender, EventArgs e)
{
Ceterlabel();
}


l25926845 2009-12-31
  • 打赏
  • 举报
回复
弄出来了
参考了网上的一个例子,放弃了API的方法,使用了两个timer分别控制鼠标状态和窗体移动。
不过性能上还有待验证。
banyanying 2009-12-31
  • 打赏
  • 举报
回复
学习中

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧