您的位置:首页 > 其它

QQ消息窗口实现

2009-07-22 22:35 225 查看
【转载】用VC++制作MSN、QQ 的消息提示窗口
2008-05-29 22:54
用过QQ和MSN聊天工具的人都知道,只要好友上线,就会在托盘的位置处显示一个提示窗口,以是拉帘式的,或者是淡入淡出的形式出现;想想何不为自己的程式也加一个漂亮的提示窗口呢?

  一、MSN拉帘式窗口制作

  分三部分:1、窗口的显示;2、窗口的停留;3、窗口的消失;
如果达到这样郊果,系统中要有三个定时器,进行分别控制。定义的定时器如下:

#define ID_TIMER_POP_WINDOW 1
#define ID_TIMER_DISPALY_DELAY 2
#define ID_TIMER_CLOSE_WINDOW 3
  从CWnd 继承一个窗口,当然也可以从CFrameWnd进行派生,这不是主要问题,关键是看你是怎么处理WM_PAINT,WM_MOUSEMOVE,WM_TIMER的消息。一般情况,我从OnPaint()中进行显示图片,在WM_TIMER中处理定时器消息,下面是处里定时器时用到的代码:

CMsgWnd::CMsgWnd()
{
 ...
 SetTimer(ID_TIEMR_POP_WINDOW,20,NULL);
 ...
}

void CMsgWnd::OnTimer(UINT nIDEvent)
{
 static int nHeight=0;
 int cy=GetSystemMetrics(SM_CYSCREEN);
 int cx=GetSystemMetrics(SM_CXSCREEN);
 RECT rect;
 SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);
 int y=rect.bottom-rect.top;
 int x=rect.right-rect.left;
 x=x-WIN_WIDTH;

 switch(nIDEvent)
 {
  case ID_TIMER_POP_WINDOW:
   if(nHeight<=WIN_HEIGHT)
   {
    ++nHeight;
    MoveWindow(x,y-nHeight,WIN_WIDTH,WIN_HEIGHT);
    Invalidate(FALSE);
   }
   else
   
   break;
  case ID_TIMER_CLOSE_WINDOW:
   if(nHeight>=0)
   
   else
   
   break;
  case ID_TIMER_DISPLAY_DELAY:
   KillTimer(ID_TIMER_DISPLAY_DELAY);
   SetTimer(ID_TIMER_CLOSE_WINDOW,20,NULL);
   break;
 }
 CWnd::OnTimer(nIDEvent);
}
  根据你设的定时器的长短来控制窗口的显示过程;

二、QQ淡出淡出显示实现

  其实用到一个API函数:AnimateWindow,下面是这个函数的一些说明:

BOOL AnimateWindow(
 HWND hwnd, // handle to the window to animate
 DWORD dwTime, // duration of animation
 DWORD dwFlags // animation type
);
  上面的函数前两个参数一看就明白,不用说了,最后一个参数dwFlags设置动画窗口的样式:

  各种标志说明:

标志说明
AW_SLIDEUses slide animation. By default, roll animation is used.
This flag is ignored when used with the AW_CENTER flag.
AW_ACTIVATEActivates the window. Do not use this flag with AW_HIDE.
AW_BLENDUses a fade effect. This flag can be used only if hwnd is a top-level window.
AW_HIDEHides the window. By default, the window is shown.
AW_CENTERMakes the window appear to collapse inward if the AW_HIDE flag is used or expand outward
if the AW_HIDE flag is not used.
AW_HOR_POSITIVEAnimate the window from left to right. This flag can be used with roll or slide animation. It is ignored when used with the AW_CENTER flag.
AW_HOR_NEGATIVEAnimate the window from right to left. This flag can be used with roll or slide animation.
It is ignored when used with the AW_CENTER flag.
AW_VER_POSITIVEAnimate the window from top to bottom. This flag can be used with roll or slide animation.
It is ignored when used with the AW_CENTER flag.
AW_VER_NEGATIVEAnimate the window from bottom to top. This flag can be used with roll or slide animation.
It is ignored when used with the AW_CENTER flag.
  以上内容是从MSDN中摘录的,要淡入淡出的效果的话,用到AW_BELND。

  三、控制窗口显示的代码

CMainFrame::OnCreate(…)
  四、关闭的代码

CMainFrame::OnClose(..)
  其实AnimateWindow只是利用了windows本身的方法,如果您要更加有个性的窗口效果,那就得多做写些代码了,一分辛苦,一分收获吧

以上是我转载的,然后我就照着文章的思路写了个模仿QQ消息弹出框的程序:
1.在VS中建一个基于对话框的模板的程序
2.在对话框的属性一栏中,将Tool Window和Topmost置true
3.重写OnInitDialog():
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。

// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
//  执行此操作
SetIcon(m_hIcon, TRUE);			// 设置大图标
SetIcon(m_hIcon, FALSE);		// 设置小图标

// TODO: 在此添加额外的初始化代码
CRect rect,rect2;
::SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);
GetWindowRect(&rect2);
//下面用MoveWindow,不要用SetWindowPos,不然效果不对
MoveWindow(rect.right-rect2.Width(),rect.bottom-rect2.Height(),rect2.Width(),rect2.Height());

ShowWindow(SW_HIDE);
::SetWindowLong(GetSafeHwnd(),GWL_EXSTYLE,WS_EX_TOOLWINDOW);

AnimateWindow(3000,AW_BLEND);//窗口淡化效果

return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: