类似QQ界面的实现
来源:互联网 发布:软件质量工程师 编辑:程序博客网 时间:2024/05/03 22:11
类似QQ界面的实现
流浪狗
下载源代码
一、需求分析:
QQ是现在非常流行的一种及时通讯工具,它以强大的功能和漂亮、友好的界面获得了无数人的喜爱。本程序的目的是为了做出像QQ主界面的程序。
二、功能:
(1)、实现OUTLOOK风格的QQ主界面。
(2)、实现自动隐藏功能。
(3)、实现系统托盘,并动态的更换图标,就像QQ上线时托盘所表现的动态画面。
三、说明:
本程序复用了一些别人写的类,并在此基础上作出了部分修改,以实现本程序的功能,在此向CgfxOutBarCtrl类和CtrayIcon的作者表示感谢。
四、具体实现
(一)、创建一个单文档的应用程序,命命为MyQQ,接下来都选默认选项。
(1)编辑CMainFrame::PreCreateWindow。
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
……
//设置窗口高度和宽度
cs.cx=150;
cs.cy=600;
//去出菜单
cs.hMenu=NULL;
//限定不能改变大小,去出最大化按钮 cs.style&=~(WS_THICKFRAME|WS_MAXIMIZEBOX); } (2)、编辑CMyQQApp::InitInstance在后面添加: //设置窗口文字 和窗口位置 AfxGetMainWnd()->SetWindowText("MyQQ"); AfxGetMainWnd()->SetWindowPos(&CWnd::wndTopMost,400,0,150,600, SWP_SHOWWINDOW); (2)、准备一张图片 (二)、实现QQ界面功能 (1)、准备。准备CgfxOutBarCtrl类(你可以在网上找到)和两张图片,用作大图标和小图标,命名为IDB_IMAGELIST和IDB_SMALL_IMAGELIST。在QQ2005中将NEWFACE文件夹拷贝到当前工程目录下,准备一个声音文件folder.wav。 (2)、将CgfxOutBarCtrl和它要用到的一些类CgfxGroupEdit和CgfxPopupMenu一起导入工程。 (3)、在MainFrm.h中添加包含#include "GfxOutBarCtrl.h",并添加属性CgfxOutBarCtrl wndBar和 CimageList imaLarge, imaSmall (4)、重载CmainFrame的OnCreateClient函数 BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { // TODO: Add your specialized code here and/or call the base class DWORD dwf = CGfxOutBarCtrl::fDragItems| CGfxOutBarCtrl::fEditGroups| CGfxOutBarCtrl::fEditItems| CGfxOutBarCtrl::fRemoveGroups| CGfxOutBarCtrl::fRemoveItems| CGfxOutBarCtrl::fAddGroups| CGfxOutBarCtrl::fAnimation; RECT rect; GetClientRect(&rect); wndBar.Create(WS_CHILD|WS_VISIBLE,rect,this,NULL,dwf); wndBar.SetOwner(this); //此处必须以真彩色显示 imaLarge.Create(40,40,ILC_COLOR24,0,0); imaSmall.Create(16,16,ILC_COLOR24,0,0); //此处由于将QQ里的一百张图片全部加载进内存,所以要耗费很多内存,可以在寻求一个更好的办法 for(int i=1;i<=100;i++) { CBitmap pBitmap; CString str; str.Format("NEWFACE//%d.bmp",i); //加载位图 HBITMAP hBitmap; //定义位图对象句柄 hBitmap=(HBITMAP):: LoadImage ( AfxGetInstanceHandle(), //取得应用程序句柄 str, //位图文件名 IMAGE_BITMAP, //类型为Windows位图 0,0, LR_LOADFROMFILE); if(NULL==hBitmap) { AfxMessageBox("不能打开文件"); return FALSE; } pBitmap.Attach(hBitmap); imaLarge.Add(&pBitmap,RGB(0,0,0)); CBitmap sBitmap; str.Format("NEWFACE//%d_m.bmp",i); //加载位图 hBitmap=(HBITMAP):: LoadImage ( AfxGetInstanceHandle(), //取得应用程序句柄 str, //位图文件名 IMAGE_BITMAP, //类型为Windows位图 0,0, LR_LOADFROMFILE); if(NULL==hBitmap) { AfxMessageBox("不能打开文件"); return FALSE; } sBitmap.Attach(hBitmap); imaSmall.Add(&sBitmap,RGB(0,0,0)); } wndBar.SetImageList(&imaLarge, CGfxOutBarCtrl::fLargeIcon); wndBar.SetImageList(&imaSmall, CGfxOutBarCtrl::fSmallIcon); wndBar.SetAnimationTickCount(10); wndBar.SetAnimSelHighlight(200); wndBar.SetIfQueryRemove(true); wndBar.AddFolder("我的好友", 0); wndBar.AddFolder("陌生人", 1); wndBar.AddFolder("黑名单", 2); wndBar.InsertItem(0, 0, "午夜", 0, 0); wndBar.InsertItem(0, 1, "浪子", 1, 0); wndBar.InsertItem(0, 2, "未来之城", 2, 0); wndBar.InsertItem(0, 3, "黑色幽默", 3, 0); wndBar.InsertItem(0, 4, "想飞", 4, 0); ……//这儿省略一部分 wndBar.InsertItem(2, 0, "酒鬼", 80, 0); wndBar.InsertItem(2, 1, "痴人", 81, 0); wndBar.InsertItem(2, 2, "逐梦人", 82, 0); wndBar.InsertItem(2, 3, "陆小凤", 83, 0); wndBar.SetSelFolder(0); return TRUE; } 完成后我们可以编译改程序,但是当点击陌生人时,由于里面没有成员,本不应该出现下拉按钮,但是出现了,当我们点击时,就会发生溢出。所以修改原来的CgfxOutBarCtrl源文件的OnPaint函数: if (l < GetItemCount() - 1 //Modified By jamiandy@163.com //Author:流浪狗 Date:2005Y-05M-13D::12:13 //在此处修改原来的语句,以便使得当item为0时,不出现向下的按钮,防止溢出 //修改if (l < GetItemCount() - 1)为if (l < GetItemCount() - 1&&GetItemCount()!=0) &&GetItemCount()!=0) { ……//此处省略 } else bDownArrow = false; (5)、修改CgfxOutBarCtrl类的OnLButtonDown,在里面适当位置即响应点击FOLDER时的地方添加语句: BOOL r = sndPlaySound("sound//folder.wav",SND_SYNC |SND_NODEFAULT);//播放WAV ASSERT(r); r = sndPlaySound("",SND_ASYNC|SND_NODEFAULT);//停止播放 (6)、在CmainFrame的头文件中,DECLARE_MESSAGE_MAP()上面添加afx_msg long OnOutBarNotify(WPARAM wParam, LPARAM lParam);消息映射,在实现文件中,BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)和END_MESSAGE_MAP()之间加入ON_MESSAGE(WM_OUTBAR_NOTIFY, OnOutBarNotify)。编写代码: long CMainFrame::OnOutBarNotify(WPARAM wParam, LPARAM lParam) { switch (wParam) { case NM_SENDMSG: { int index = (int) lParam; //弹出发送消息对话框 DoMsgDialog(); } return 1; //你可以在此添加你自己的消息,从CGfxOutBarCtrl中发送 } return 0; } 修改CgfxOutBarCtrl中的代码,实现向主框架发送消息,可以用GetOwner()->SendMessage(WM_OUTBAR_NOTIFY, NM_SENDMSG, iHitInternal2)实现,具体情况可以根据需要改变。然后从主框架中处理消息,从而保证用主框架来响应外界的消息。 经过这些,基本的QQ界面实现了,现在编译运行,就可以看到漂亮的界面了。 (三)、实现QQ的自动隐藏。 原理:在检测到窗口靠近屏幕边缘时,移动窗口到屏幕外边,从而实现自动隐藏,当检测到鼠标移近时,将窗口显示出来,从而实现自动弹出,实现过程如下: (1)、在MainFrm.cpp中头部加入: int ScreenX; //屏幕宽度 int ScreenY; //屏幕高度 int alignType; //全局变量,用于记录窗体停靠状态 enum { ALIGN_NONE, //不停靠 ALIGN_TOP, //停靠上边 ALIGN_LEFT, //停靠左边 ALIGN_RIGHT //停靠右边 }; #define NEAR_SIZE 5 //定义自动停靠有效距离 #define NEAR_SIDE 3 //窗体隐藏后在屏幕上保留的像素,以使鼠标可以触及 在OnCreate中加入: ScreenX = GetSystemMetrics(SM_CXSCREEN); ScreenY = GetSystemMetrics(SM_CYSCREEN); SetTimer(WM_TIMER,50,NULL); NearSide(GetSafeHwnd()); (2)、添加NearSide函数 void CMainFrame::NearSide(HWND hWnd) { int change = 0; RECT rect; GetWindowRect(&rect); alignType = ALIGN_NONE; if (rect.left < NEAR_SIZE) { alignType = ALIGN_LEFT; if ((rect.left != 0) && rect.right != NEAR_SIDE) { rect.right -= rect.left; rect.left = 0; change = 1; } } else if (rect.right > ScreenX - NEAR_SIZE) { alignType = ALIGN_RIGHT; if (rect.right != ScreenX && rect.left != ScreenX - NEAR_SIDE) { rect.left += (ScreenX - rect.right); rect.right = ScreenX; change = 1; } } //调整上下 if (rect.top < NEAR_SIZE) { alignType = ALIGN_TOP; if (rect.top != 0 && rect.bottom != NEAR_SIDE) { rect.bottom -= rect.top; rect.top = 0; change = 1; } } if (change) { MoveWindow(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE); } } (3)、重载OnTimer,编辑 void CMainFrame::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default POINT pt; RECT rc; GetCursorPos(&pt); GetWindowRect(&rc); if (!PtInRect(&rc, pt)) //若鼠标不在窗体内,隐藏窗体. { KillTimer(WM_TIMER); HideSide(GetSafeHwnd(),TRUE); } CFrameWnd::OnTimer(nIDEvent); } (4)、添加HideSide,编辑: void CMainFrame::HideSide(HWND hWnd, BOOL hide) { RECT rc; int moves = 4; //动画滚动窗体的步数,如果你觉得不够平滑,可以增大该值. int xStep, yStep; int xEnd, yEnd; int width; int height; register int i; GetWindowRect(&rc); width = rc.right - rc.left; height = rc.bottom - rc.top; //下边判断窗体该如何移动,由停靠方式决定 switch (alignType) { case ALIGN_TOP: { //向上移藏 xStep = 0; xEnd = rc.left; if (hide) { yStep = -rc.bottom / moves; yEnd = -height + NEAR_SIDE; } else { yStep = -rc.top / moves; yEnd = 0; } break; } case ALIGN_LEFT: { //向左移藏 //此处省略,类似向上隐藏 …… break; } case ALIGN_RIGHT: { //向右移藏 //此处省略,类似向上隐藏 …… break; } default: return; } //动画滚动窗体. for (i = 0; i < moves; i++) { rc.left += xStep; rc.top += yStep; SetWindowPos(NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOSENDCHANGING); RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); Sleep(5); } SetWindowPos(NULL, xEnd, yEnd, 0, 0, SWP_NOSIZE); if (!hide) //如果窗体已被显示,设置定时器.监视鼠标. { SetTimer(WM_TIMER, 50, NULL); } } (5)、最后重载OnNcMouseMove,添加代码如下: void CMainFrame::OnNcMouseMove(UINT nHitTest, CPoint point) { RECT rc; GetWindowRect(&rc); if (rc.left < 0 || rc.top < 0 || rc.right > ScreenX) //未显示 { HideSide(GetSafeHwnd(), FALSE); }else { HideSide(GetSafeHwnd(), FALSE); SetTimer(WM_TIMER,50,NULL); } CFrameWnd::OnNcMouseMove(nHitTest, point); } 这样,自动隐藏的功能就实现了,当你把它拖到屏幕边上的时候,就自动消失了,当鼠标移近时,又自动出现。 (四)、托盘程序的实现 (1)、将CtrayIcon(你可以从网上找到它)加入工程。添加两个图标,分别命名为IDI_ONLINE和IDI_OFFLINE,表示交替的两个图标。在MainFrm.h中加入私有变量CTrayIcon m_trayIcon; BOOL IsOnline;在构造函数中对其初始化,m_trayIcon(IDR_TRAYICON),IsOnline=FALSE。在MainFrm.cpp中添加#define WM_MY_TRAY_NOTIFICATION WM_USER+0 (2)、在OnCreate中添加: m_trayIcon.SetNotificationWnd(this, WM_MY_TRAY_NOTIFICATION); m_trayIcon.SetIcon(IDI_ONLINE); SetTimer(2,500,NULL); (3)、修改OnTimer: if(nIDEvent==2) { IsOnline=!IsOnline; m_trayIcon.SetIco(IsOnlineIDI_ONLINE:IDI_OFFLINE); } 这样就可以动态改变图标了。 到此为止,我们要求的所有功能都实现了,现在可以编译运行,修改不正确的地方。效果如图所示:
cs.style&=~(WS_THICKFRAME|WS_MAXIMIZEBOX);
}
(2)、编辑CMyQQApp::InitInstance在后面添加:
//设置窗口文字 和窗口位置
AfxGetMainWnd()->SetWindowText("MyQQ");
AfxGetMainWnd()->SetWindowPos(&CWnd::wndTopMost,400,0,150,600,
SWP_SHOWWINDOW);
(2)、准备一张图片
(二)、实现QQ界面功能
(1)、准备。准备CgfxOutBarCtrl类(你可以在网上找到)和两张图片,用作大图标和小图标,命名为IDB_IMAGELIST和IDB_SMALL_IMAGELIST。在QQ2005中将NEWFACE文件夹拷贝到当前工程目录下,准备一个声音文件folder.wav。
(2)、将CgfxOutBarCtrl和它要用到的一些类CgfxGroupEdit和CgfxPopupMenu一起导入工程。
(3)、在MainFrm.h中添加包含#include "GfxOutBarCtrl.h",并添加属性CgfxOutBarCtrl wndBar和 CimageList imaLarge, imaSmall
(4)、重载CmainFrame的OnCreateClient函数
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// TODO: Add your specialized code here and/or call the base class
DWORD dwf = CGfxOutBarCtrl::fDragItems|
CGfxOutBarCtrl::fEditGroups|
CGfxOutBarCtrl::fEditItems|
CGfxOutBarCtrl::fRemoveGroups|
CGfxOutBarCtrl::fRemoveItems|
CGfxOutBarCtrl::fAddGroups|
CGfxOutBarCtrl::fAnimation;
RECT rect;
GetClientRect(&rect);
wndBar.Create(WS_CHILD|WS_VISIBLE,rect,this,NULL,dwf);
wndBar.SetOwner(this);
//此处必须以真彩色显示
imaLarge.Create(40,40,ILC_COLOR24,0,0);
imaSmall.Create(16,16,ILC_COLOR24,0,0);
//此处由于将QQ里的一百张图片全部加载进内存,所以要耗费很多内存,可以在寻求一个更好的办法
for(int i=1;i<=100;i++)
{
CBitmap pBitmap;
CString str;
str.Format("NEWFACE//%d.bmp",i);
//加载位图
HBITMAP hBitmap; //定义位图对象句柄
hBitmap=(HBITMAP):: LoadImage
( AfxGetInstanceHandle(),
//取得应用程序句柄
str,
//位图文件名
IMAGE_BITMAP,
//类型为Windows位图
0,0,
LR_LOADFROMFILE);
if(NULL==hBitmap)
{
AfxMessageBox("不能打开文件");
return FALSE;
}
pBitmap.Attach(hBitmap);
imaLarge.Add(&pBitmap,RGB(0,0,0));
CBitmap sBitmap;
str.Format("NEWFACE//%d_m.bmp",i);
//加载位图
hBitmap=(HBITMAP):: LoadImage
( AfxGetInstanceHandle(),
//取得应用程序句柄
str,
//位图文件名
IMAGE_BITMAP,
//类型为Windows位图
0,0,
LR_LOADFROMFILE);
if(NULL==hBitmap)
{
AfxMessageBox("不能打开文件");
return FALSE;
}
sBitmap.Attach(hBitmap);
imaSmall.Add(&sBitmap,RGB(0,0,0));
}
wndBar.SetImageList(&imaLarge, CGfxOutBarCtrl::fLargeIcon);
wndBar.SetImageList(&imaSmall, CGfxOutBarCtrl::fSmallIcon);
wndBar.SetAnimationTickCount(10);
wndBar.SetAnimSelHighlight(200);
wndBar.SetIfQueryRemove(true);
wndBar.AddFolder("我的好友", 0);
wndBar.AddFolder("陌生人", 1);
wndBar.AddFolder("黑名单", 2);
wndBar.InsertItem(0, 0, "午夜", 0, 0);
wndBar.InsertItem(0, 1, "浪子", 1, 0);
wndBar.InsertItem(0, 2, "未来之城", 2, 0);
wndBar.InsertItem(0, 3, "黑色幽默", 3, 0);
wndBar.InsertItem(0, 4, "想飞", 4, 0);
……//这儿省略一部分
wndBar.InsertItem(2, 0, "酒鬼", 80, 0);
wndBar.InsertItem(2, 1, "痴人", 81, 0);
wndBar.InsertItem(2, 2, "逐梦人", 82, 0);
wndBar.InsertItem(2, 3, "陆小凤", 83, 0);
wndBar.SetSelFolder(0);
return TRUE;
}
完成后我们可以编译改程序,但是当点击陌生人时,由于里面没有成员,本不应该出现下拉按钮,但是出现了,当我们点击时,就会发生溢出。所以修改原来的CgfxOutBarCtrl源文件的OnPaint函数:
if (l < GetItemCount() - 1
//Modified By jamiandy@163.com
//Author:流浪狗 Date:2005Y-05M-13D::12:13
//在此处修改原来的语句,以便使得当item为0时,不出现向下的按钮,防止溢出
//修改if (l < GetItemCount() - 1)为if (l < GetItemCount() - 1&&GetItemCount()!=0)
&&GetItemCount()!=0)
{
……//此处省略
}
else bDownArrow = false;
(5)、修改CgfxOutBarCtrl类的OnLButtonDown,在里面适当位置即响应点击FOLDER时的地方添加语句:
BOOL r = sndPlaySound("sound//folder.wav",SND_SYNC |SND_NODEFAULT);//播放WAV
ASSERT(r); r = sndPlaySound("",SND_ASYNC|SND_NODEFAULT);//停止播放
(6)、在CmainFrame的头文件中,DECLARE_MESSAGE_MAP()上面添加afx_msg long OnOutBarNotify(WPARAM wParam, LPARAM lParam);消息映射,在实现文件中,BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)和END_MESSAGE_MAP()之间加入ON_MESSAGE(WM_OUTBAR_NOTIFY, OnOutBarNotify)。编写代码:
long CMainFrame::OnOutBarNotify(WPARAM wParam, LPARAM lParam)
{
switch (wParam)
{
case NM_SENDMSG:
{
int index = (int) lParam;
//弹出发送消息对话框
DoMsgDialog();
}
return 1;
//你可以在此添加你自己的消息,从CGfxOutBarCtrl中发送
}
return 0;
}
修改CgfxOutBarCtrl中的代码,实现向主框架发送消息,可以用GetOwner()->SendMessage(WM_OUTBAR_NOTIFY, NM_SENDMSG, iHitInternal2)实现,具体情况可以根据需要改变。然后从主框架中处理消息,从而保证用主框架来响应外界的消息。
经过这些,基本的QQ界面实现了,现在编译运行,就可以看到漂亮的界面了。
(三)、实现QQ的自动隐藏。
原理:在检测到窗口靠近屏幕边缘时,移动窗口到屏幕外边,从而实现自动隐藏,当检测到鼠标移近时,将窗口显示出来,从而实现自动弹出,实现过程如下:
(1)、在MainFrm.cpp中头部加入:
int ScreenX; //屏幕宽度
int ScreenY; //屏幕高度
int alignType; //全局变量,用于记录窗体停靠状态
enum
{
ALIGN_NONE, //不停靠
ALIGN_TOP, //停靠上边
ALIGN_LEFT, //停靠左边
ALIGN_RIGHT //停靠右边
};
#define NEAR_SIZE 5 //定义自动停靠有效距离
#define NEAR_SIDE 3 //窗体隐藏后在屏幕上保留的像素,以使鼠标可以触及
在OnCreate中加入:
ScreenX = GetSystemMetrics(SM_CXSCREEN);
ScreenY = GetSystemMetrics(SM_CYSCREEN);
SetTimer(WM_TIMER,50,NULL);
NearSide(GetSafeHwnd());
(2)、添加NearSide函数
void CMainFrame::NearSide(HWND hWnd)
{
int change = 0;
RECT rect;
GetWindowRect(&rect);
alignType = ALIGN_NONE;
if (rect.left < NEAR_SIZE)
{
alignType = ALIGN_LEFT;
if ((rect.left != 0) && rect.right != NEAR_SIDE)
{
rect.right -= rect.left;
rect.left = 0;
change = 1;
}
}
else if (rect.right > ScreenX - NEAR_SIZE)
{
alignType = ALIGN_RIGHT;
if (rect.right != ScreenX && rect.left != ScreenX - NEAR_SIDE)
{
rect.left += (ScreenX - rect.right);
rect.right = ScreenX;
change = 1;
}
}
//调整上下
if (rect.top < NEAR_SIZE)
{
alignType = ALIGN_TOP;
if (rect.top != 0 && rect.bottom != NEAR_SIDE)
{
rect.bottom -= rect.top;
rect.top = 0;
change = 1;
}
}
if (change)
{
MoveWindow(rect.left, rect.top, rect.right - rect.left,
rect.bottom - rect.top, TRUE);
}
}
(3)、重载OnTimer,编辑
void CMainFrame::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
POINT pt;
RECT rc;
GetCursorPos(&pt);
GetWindowRect(&rc);
if (!PtInRect(&rc, pt)) //若鼠标不在窗体内,隐藏窗体.
{
KillTimer(WM_TIMER);
HideSide(GetSafeHwnd(),TRUE);
}
CFrameWnd::OnTimer(nIDEvent);
}
(4)、添加HideSide,编辑:
void CMainFrame::HideSide(HWND hWnd, BOOL hide)
{
RECT rc;
int moves = 4; //动画滚动窗体的步数,如果你觉得不够平滑,可以增大该值.
int xStep, yStep;
int xEnd, yEnd;
int width;
int height;
register int i;
GetWindowRect(&rc);
width = rc.right - rc.left;
height = rc.bottom - rc.top;
//下边判断窗体该如何移动,由停靠方式决定
switch (alignType)
{
case ALIGN_TOP:
{
//向上移藏
xStep = 0;
xEnd = rc.left;
if (hide)
{
yStep = -rc.bottom / moves;
yEnd = -height + NEAR_SIDE;
}
else
{
yStep = -rc.top / moves;
yEnd = 0;
}
break;
}
case ALIGN_LEFT:
{
//向左移藏
//此处省略,类似向上隐藏
……
break;
}
case ALIGN_RIGHT:
{
//向右移藏
//此处省略,类似向上隐藏
……
break;
}
default:
return;
}
//动画滚动窗体.
for (i = 0; i < moves; i++)
{
rc.left += xStep;
rc.top += yStep;
SetWindowPos(NULL, rc.left, rc.top, 0, 0,
SWP_NOSIZE | SWP_NOSENDCHANGING);
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
Sleep(5);
}
SetWindowPos(NULL, xEnd, yEnd, 0, 0, SWP_NOSIZE);
if (!hide) //如果窗体已被显示,设置定时器.监视鼠标.
{
SetTimer(WM_TIMER, 50, NULL);
}
}
(5)、最后重载OnNcMouseMove,添加代码如下:
void CMainFrame::OnNcMouseMove(UINT nHitTest, CPoint point)
{
RECT rc;
GetWindowRect(&rc);
if (rc.left < 0 || rc.top < 0 || rc.right > ScreenX) //未显示
{
HideSide(GetSafeHwnd(), FALSE);
}else
{
HideSide(GetSafeHwnd(), FALSE);
SetTimer(WM_TIMER,50,NULL);
}
CFrameWnd::OnNcMouseMove(nHitTest, point);
}
这样,自动隐藏的功能就实现了,当你把它拖到屏幕边上的时候,就自动消失了,当鼠标移近时,又自动出现。
(四)、托盘程序的实现
(1)、将CtrayIcon(你可以从网上找到它)加入工程。添加两个图标,分别命名为IDI_ONLINE和IDI_OFFLINE,表示交替的两个图标。在MainFrm.h中加入私有变量CTrayIcon m_trayIcon; BOOL IsOnline;在构造函数中对其初始化,m_trayIcon(IDR_TRAYICON),IsOnline=FALSE。在MainFrm.cpp中添加#define WM_MY_TRAY_NOTIFICATION WM_USER+0
(2)、在OnCreate中添加:
m_trayIcon.SetNotificationWnd(this, WM_MY_TRAY_NOTIFICATION);
m_trayIcon.SetIcon(IDI_ONLINE);
SetTimer(2,500,NULL);
(3)、修改OnTimer:
if(nIDEvent==2)
{
IsOnline=!IsOnline;
m_trayIcon.SetIco(IsOnlineIDI_ONLINE:IDI_OFFLINE);
}
这样就可以动态改变图标了。
到此为止,我们要求的所有功能都实现了,现在可以编译运行,修改不正确的地方。效果如图所示:
- 类似QQ界面的实现
- Android类似QQ同步助手的Tab界面的实现
- 使用ViewPager实现几个界面的切换,类似QQ
- android expandablelistview--实现类似qq界面的效果
- 利用ImageView + fragment 实现类似QQ消息界面的 点击不同按钮 展示不同界面
- 关于类似QQ界面隐藏的问题
- 【转载】类似QQ功能的界面
- 类似QQ展开界面
- 类似QQ聊天界面
- QQ界面的实现
- IOS 实现边滑动边缩放的类似qq主界面的页面切换功能
- IOS 实现边滑动边缩放的类似qq主界面的页面切换功能
- IOS 实现边滑动边缩放的类似qq主界面的页面切换功能
- ExpandableListView实现的简单类似QQ好友界面的可展开下拉列表
- Qt+html+JavaScript实现类似QQ聊天界面的气泡效果
- iOS 类似微信,QQ聊天界面的气泡聊天简单实现Demo
- iOS 类似微信,QQ聊天界面的气泡聊天简单实现Demo
- 利用tabhost实现类似QQ、微信界面
- 网络安全技术与市场分析
- #1 内核学习FAQ大集锦
- 默认首页恶意修改?
- 欧拉
- 手机图片、铃声免费下载终极大法
- 类似QQ界面的实现
- 曲率
- 学术论文各部分的写作要求与写作方法
- 发布源码:高效的Esmtp,带验证,用Socket编写
- JAVA相关基础知识 转自[http://www.blogcn.com]
- PHP5+Apache2在Windows下模块化安装
- .net中判断该应用程序是否已经启动,防止重复启动
- 由于网速的原因最近写的文章老是丢了
- 用脚本实现人工智能的探讨