如何做QQ交互界面

大凡用过电脑,上过 的朋友都用过QQ,对QQ的一些交互界面可能垂慕已久,的确,无论是其生动的企鹅形象,还是“滴滴的”消息声音,以及“刷”的菜单等功能,简单单的消息发送,以及快速的回显和众多卡通的QQ头像等铸就了其在 络的良好地位,本人对其研究虽不够透彻,但也做一些探索性的尝试,并简单的实现了比较突出的功能,在s模拟的过程中,主要实现了以下几部分的功能:

  QQ菜单,也称抽屉菜单(也有的叫导航菜单);

  QQ头像的列表显示;

  简易的消息发送模拟;

  简易的上线,隐身模拟;

  悬挂QQ;

  本程序的运行界面如图:

  当然啦,现在的QQ功能强大,如QQ直播,联系人,个人设置等功能,视频聊天等众多强悍功能,本人能力不及,并没有实现!下面,就开始QQ模拟之旅吧!

  一、准备

  在实现QQ界面之前,有一些准备工作,请确定你已经有如下知识:

  1.具备C,C++,VC的初步知识!

  2.具备一定的思考能力!

  3.要有一定的想法

  4.熟悉QQ界面

  5.具备一些软件工具:如Visual C++, Resource Hack(这个可以找到.exe、.dll 文件的资源,包括对话框和控件的属性.

  二、剖析QQ界面

  1.QQ头像和图标

  这是QQ做的特别好的地方,大家如果留心的话会发现QQ附带的功能实在强悍,可以视频聊天,截图,发送文件,记录我的好友等信息,等这些功能全部仅在一个对话框或一个设置框中实现,给人很轻松的感觉,企鹅的形象深入民心,获取关键的图标是很必要的。

  用Resource Hacker对你安装的QQ.exe进行资源导出吧,这样获取的图标文件.ico为你所用,不要再为没有形象ICO而烦恼啦!

  在你的QQ安装目录下面有个QQface,里面有QQ所需要用到的所有QQ头像,如果你不知道的话,也可以直接下载本人的源代码,里面已经将100张QQ头像嵌在里面啦,直接用,不要客气!

  2.登陆界面

  QQ的登陆界面简单易了,风格明朗,本人已尝试做了一个,可以到知识库里下一下看,做的并不好,但长的蛮像的!本人并未实现 络登陆功能,以至很多朋友有被欺骗的感觉,本人在这说明:已经在程序说明部分说明并未实现 络功能,如果对登陆器,或外挂比较感兴趣可以从 络上搜索一些资料,应该有的下载!

  3.登陆时任务栏图标

  这个可能对 速慢的朋友可能会注意到,这又是QQ花心思的地方。

  4.上线时的声音及消息显示时的人物跳动

  任务栏的图标也跟着改变啦,可以近ctrl+alt+z快捷键迅速查看留言啦!

  5.快捷方便的抽屉菜单

  我个人非常欣赏该功能,所以讲解的过程中本人会做最详细的阐述!

  6.发送消息对话框

  消息来时候的很清脆的声音及快速的回显!

  7.在桌面顶端上悬挂QQ

  这使QQ占用很少的桌面空间,值得注意!

  将在下面重点讲述实现3到7功能,并逐一实现!

  三、登陆时任务栏图标的动态显示

   络上关于在任务栏上添加图标的代码说明不少,本人也是参考了书书籍和借签了一部分代码后,并做了以下模拟处理。

  基础部分:

NOTIFYICONDATA nid;

//此处在类中定义

void CMyQQDlg::DisplayInTask()

{

  if(isDisplayInTask)

  {

    //初始化nid

    nid.cbSize = sizeof(NOTIFYICONDATA);

    nid.hWnd =this->m_hWnd;

    nid.uID = IDR_QQMENU;

    nid.uFlags = NIF_ICON | NIF_TIP|NIF_MESSAGE ;

    nid.hIcon = m_hIcon;

    strcpy (nid.szTip, “任务栏图标”);

    nid.uCallbackMessage=WM_DISPLAYTASKICON;

    Shell_NotifyIcon(NIM_ADD,&nid);  

    isDisplayInTask=FALSE;

  }

  else

  {

    Shell_NotifyIcon(NIM_DELETE,&nid);

    isDisplayInTask=true;

  }

}

  关于Shell_NotifyIcon这个函数共有三种操作,分别为NIM_ADD, NIM_MODIFY, NIM_DELETE,为系统函数,大家对这个不熟悉也不要紧,也就是实现在任务栏上显示的功能,在程序的OnInitDialog函数中添加如下代码:

  isDisplayInTask=true;

  DisplayInTask(); //显示到任务栏里面去;

  Sleep(500);

  OnOutline();

  Sleep(500);

  OnHidden();

  Sleep(500);

  OnOutline();

  Sleep(500);

  OnHidden();

  仅仅是个模拟,并没有考虑到程序的具体操作过程,也可以定义一个时间,然后用 KillTime 函数终止也可以!

四、上线时的声音及消息显示时的人物跳动

  本人并未实现人物跳动,并不知道是切换图片,还是更改图片的位置,所以此功能有待各位的指点!

  五、动感十足的抽屉菜单

  我对QQ的这个菜单印象特深,犹其是配的“刷”的声音,充分体验到QQ的生动!下面就详细介绍自己是如何一步步实现的:

  说明:

  在程序的一开始就获得最顶端按钮的位置:

// 将该对话框放置到右上角;

  GetWindowRect(&dlgrect);

  MoveWindow(GetSystemMetrics(SM_CXSCREEN)-dlgrect.Width()-20, 0,

    dlgrect.Width(), dlgrect.Height(), true);

  //

  /

  // 获取得第一个按钮和最后一个按钮的位置

  GetDlgItem(IDC_QQFRIEND)->GetWindowRect(&rect0);

  ScreenToClient(&rect0);

  GetDlgItem(IDC_QQQUN)->GetWindowRect(&rect1);

  ScreenToClient(&rect1);用一个重要的函数分别处理当按下不同铵钮时的反应:void CMyQQDlg::ChangeView()

{

  // 开始对按钮进行各个处理

  if(TopButtonNum!=1&&clicknum==1)

  {

    //

    // QQ好友按钮已经置于最上层

    // 所以无需移动

    // 其余全置于下面

    m_QQothers.MoveWindow(0, rect1.bottom,

      rect0.Width(), rect0.Height(), true);

    m_QQqun.MoveWindow(0, rect1.bottom-rect0.Height(),

      rect0.Width(), rect0.Height(), true);

    //

    // QQ好友

    if(isBigFace)

    {

      m_List1.SetImageList(&m_imagelist2, LVSIL_SMALL);

    }

    else

    {

      m_List1.SetImageList(&m_imagelist1, LVSIL_SMALL);

    }

    m_List1.DeleteAllItems();

    for(int i=1; i

    {

      m_List1.InsertItem(0xffff,””, -1);

      m_List1.InsertItem(0xffff,”

“+myClass[i-1], i);

    }

    m_List1.InsertItem(0xffff,””, -1);

    //

    // 显示该栏目的下的QQ好友, 隐藏其它栏目;

    m_List1.ShowWindow(SW_SHOW);

    m_List2.ShowWindow(SW_HIDE);

    treeCtrl.ShowWindow(SW_HIDE);

    return;

  }

  if(TopButtonNum!=2&&clicknum==2)

  {

    // 先将排在它上面的按钮置上不闻;

    m_QQqun.MoveWindow(0, rect0.bottom,

      rect0.Width(), rect0.Height(), true);

    // 将排在它后面的按钮置后;

    m_QQothers.MoveWindow(0, rect1.bottom,

      rect0.Width(), rect0.Height(), true);

    // 显示该栏目的下的QQ群, 隐藏其它栏目;

    m_List1.ShowWindow(SW_HIDE);

    m_List2.ShowWindow(SW_HIDE);

    treeCtrl.ShowWindow(SW_SHOW);

    return;

  }

  //

  /

  //  另外大家在处理的过程中,可以在QQ好友和最后一个菜单,这里是最近联系人,可以加一个picture控件,将其设置成很细小,且不可视,定制在对话框的最上和最下位置,这样你就可以随时获得你所需要的按钮移向的位置,另外每个按钮的长宽相同,方便啦处理!

  六、发送消息对话框

在这里只讲两部分:

  1.动态产生消息对话框

  2.按Ctrl+Enter键发送消息

  动态产生对话框,一般是先在资源中建立一个对话框模板,用Create函数产生一个对话框实例, 本程序是这样实现的:

void CMyQQDlg::OnDblclkMyFriend(NMHDR* pNMHDR, LRESULT* pResult)

{

  NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

  int m_nCurrentSel = pNMListView->iItem;

  CString str;

  str=m_List1.GetItemText(m_nCurrentSel, NULL);

  

  CQQSendMessage *dlg=new CQQSendMessage;

  dlg->msg=str;

  dlg->Create(IDD_QQ_MESSAGE);

  dlg->SetWindowText(“你正在与”+str+”聊天当中”);

  dlg->SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), false);

  dlg->ShowWindow(SW_SHOW);

  

  *pResult = 0;

}第2个键盘发送可以做如下处理:BOOL CQQSendMessage::PreTranslateMessage(MSG* pMsg)

{

  // TODO: Add your specialized code here and/or call the base class

  if(pMsg->message==WM_KEYDOWN)

  { 

    if(pMsg->wParam==VK_RETURN  &&  GetKeyState(VK_CONTROL)&0x80)

    { 

      {

        //处理发送对话的内容 

        OnSend();

        return  1; 

      }

    } 

  } 

  return CDialog::PreTranslateMessage(pMsg);

}这样你按下Ctrl+Enter键后就会处理OnSend()函数,这样就可以实现快捷键发送消息啦!

  七、在桌面顶端上悬挂QQ

  这样的实现不知道满意不满意,可以用一个时间片,时刻测试鼠标的坐标,并判断它所处的范围,以判断是否悬挂对话框!

  悬挂QQ,并不是让其隐藏而是要留下只剩下一根细线,当鼠标移到这根细线的时候,就立刻反显示!悬挂代码如下:

  LPPOINT pt=new CPoint;

  GetCursorPos(pt);

  CRect rect;

  GetWindowRect(&rect);

  if(rect.PtInRect(*pt))

  {

    if(rect.top

    {

      MoveWindow(rect.left, rect.top,

        dlgrect.Width(), dlgrect.Height(), true);

    }

  }

  else

  {

    if(rect.top

    {

      MoveWindow(rect.left, 0, rect.Width(), 3, true);

    }

  }

  delete pt;

  小结:

  不知道通过上面的讲述,你是否感爱到QQ的巧妙于本人也在学习阶段,所以分析的也不是很到位,但也希望通过这次学习能有所提高,可以与本人联系: xuwenq88@126.com

 

 用过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

    {

      ++nHeight;

      MoveWindow(x,

        y-nHeight,

        WIN_WIDTH,

        WIN_HEIGHT);

      

      Invalidate(FALSE);

    }

    else

    {

      KillTimer(ID_TIMER_POP_WINDOW);

      SetTimer(ID_TIMER_DISPLAY_DELAY,5000,NULL);

    }

    break;

  case ID_TIMER_CLOSE_WINDOW:

    if(nHeight>=0)

    {

      nHeight–;

      MoveWindow(x,

        y-nHeight,

        WIN_WIDTH,

        nHeight);

    }

    else

    {

      KillTimer(ID_TIMER_CLOSE_WINDOW);

      SendMessage(WM_CLOSE);

    }

    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,下面是这个函数的一些说明:

The AnimateWindow function enables you to produce special effects when showing or hiding windows.

There are two types of animation: roll animation and slide animation. BOOL AnimateWindow(

     HWND hwnd, // handle to the window to animate

     DWORD dwTime, // duration of animation

     DWORD dwFlags // animation type

     );

  上面的函数前两个参数一看就明白,不用说了,最后一个参数dwFlags设置动画窗口的样式:

Specifies the type of animation. This parameter can be one or more of the following flags.

  各种标志说明:

  

 

标志

 

说明

 

AW_SLIDE

 

Uses slide animation. By default, roll animation is used.

  This flag is ignored when used with the AW_CENTER flag.

 

AW_ACTIVATE

 

Activates the window. Do not use this flag with AW_HIDE.

 

AW_BLEND

 

Uses a fade effect. This flag can be used only if hwnd is a top-level window.

 

AW_HIDE

 

Hides the window. By default, the window is shown.

 

AW_CENTER

 

Makes 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_POSITIVE

 

Animate 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_NEGATIVE

 

Animate 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_POSITIVE

 

Animate 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_NEGATIVE

 

Animate 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(…)

{

  //…

  AnimateWindow(GetSafeHwnd(),1000,AW_CENTER|AW_BLEND);

  //…

}   

  四、关闭的代码

CMainFrame::OnClose(..)

{

  AnimateWindow(GetSafeHwnd(),1000,AW_HIDE|AW_CENTER|AW_BLEND);

}   

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

  就这写这么多吧,不明白的,一看源码,二查MSDN,三请教高手。

  五、结束语

  其实就MSN的提示窗口来说,如果要从使用复杂一点的背景和效果,那么还有刷新屏幕的问题,应做到无闪刷新.由于时间苍促,不足之处必然有之,同时以上代码也参考了一部分以前 VCKBASE 技术文档,在此表示感谢!

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2013年8月3日
下一篇 2013年8月4日

相关推荐