比如说系统托盘中有qq,输入法,nordon等,我想得到它们的窗口的hwnd,如何编程实现

解决方案 »

  1.   

    你可以先使用spy获得应用程序的classname或者windowname,然后用FindWindow(...)就可以获得句柄。直接通过系统托盘的方式我不太清楚,不知道那位高手可以提示一下。
      

  2.   

    // 得到任务栏窗口句柄
    HWND  hTaskBarWnd = FindWindow( "Shell_TrayWnd", NULL );// 得到通知区窗口句柄
    HWND  hTrayNotifyWnd = FindWindowEx(
    hTaskBarWnd,
    NULL,
    "TrayNotifyWnd",
    NULL );// 得到系统托盒窗口句柄
    HWND  hTrayClockWnd = FindWindowEx(
    hTrayNotifyWnd,
    NULL,
    "ToolbarWindow32",
    NULL );
      

  3.   

    之后可以用“工具栏”相关API去获得图标数量
      

  4.   

    http://www.codeproject.com/shell/trayposition.asp
      

  5.   

    CTrayToolBar::CTrayToolBar()
    {
    if(m_handle = ::FindWindow("Shell_TrayWnd",NULL)) if(m_handle = FindWindowEx(m_handle,NULL,"TrayNotifyWnd",NULL))
      if(m_handle = FindWindowEx(m_handle,NULL,"ToolbarWindow32",NULL))
    if(m_handle)
    this->Attach(m_handle);
    else
    m_handle = NULL;}CTrayToolBar::~CTrayToolBar()
    {
    this->Detach();
    }
    BEGIN_MESSAGE_MAP(CTrayToolBar, CToolBarCtrl)
    //{{AFX_MSG_MAP(CTrayToolBar)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CTrayToolBar message handlersvoid CTrayToolBar::ShowAll()
    {
    if(!m_handle) {AfxMessageBox("获取system tray失败!"); return;}    int i = 0;
    while(i < ICON_MAX )
    {
    this->ShowIcon(i,TRUE);
    i++;
    } Refresh();}void CTrayToolBar::ShowIcon(int index ,BOOL bShow)
    {
    if(!m_handle) {AfxMessageBox("获取system tray失败!"); return;}
    //本来这里可以通过index来获得 nID,但是虽然函数成功,但idCommand却是错误的
    /*
    TBBUTTON * ptbbtn= new TBBUTTON;
    this->SendMessage(TB_GETBUTTON,(WPARAM) index,(LPARAM) ptbbtn);
    */
    if(bShow)
         this->PostMessage(TB_HIDEBUTTON, index ,(LPARAM) MAKELONG(FALSE, 0));
    else
         this->PostMessage(TB_HIDEBUTTON, index ,(LPARAM) MAKELONG(TRUE, 0));
     //  delete ptbbtn;
    }void CTrayToolBar::HideAll()
    { if(!m_handle) {AfxMessageBox("获取system tray失败!"); return;}    int i = 0;
    while(i < ICON_MAX )
    {
    this->ShowIcon(i,FALSE);
    i++;
    } Refresh();}void CTrayToolBar::Refresh()
    { NOTIFYICONDATAW Icon;
    Icon.cbSize = sizeof( NOTIFYICONDATAW );
    Icon.hWnd = this->m_hWnd ;
    Icon.uID = 0;
    Icon.uFlags = NIF_MESSAGE | NIF_TIP;
    Icon.uCallbackMessage = WM_USER + 777;
    Icon.hIcon = NULL;
    Shell_NotifyIconW( NIM_ADD , &Icon );
    Shell_NotifyIconW( NIM_DELETE , &Icon );}void CTrayToolBar::DeleteIcon(int index)
    {
    if(!m_handle) {AfxMessageBox("获取system tray失败!"); return;} this->DeleteButton(index);
    Refresh();
    }
    int CTrayToolBar::GetCount()
    {
    if(!m_handle) {AfxMessageBox("获取system tray失败!"); return 0;}
    return this->GetButtonCount();
    }
      

  6.   

    所有的托盘区图标都是在一个窗口中的,这个窗口的窗口类是TrayNotifyWnd.我写了一段代码演示如何得到这个窗口的句柄及如何计算图标数:
    #include "windows.h"
    #include "stdio.h"int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
      // TODO: Place code here.
    HWND  hTaskBarWnd = FindWindow( "Shell_TrayWnd", NULL );
    HWND  hTrayNotifyWnd = FindWindowEx(
    hTaskBarWnd,
    NULL,
    "TrayNotifyWnd",
    NULL );
    HWND  hTrayClockWnd = FindWindowEx(
    hTrayNotifyWnd,
    NULL,
    "TrayClockWClass",
    NULL );
    RECT rectNotify,rectClock;
    GetWindowRect(hTrayNotifyWnd,&rectNotify);
    GetWindowRect(hTrayClockWnd,&rectClock);
    int nIcons=((rectNotify.right-rectNotify.left)-(rectClock.right-rectClock.left))/16;
    char szText[256];
    sprintf(szText,"托盘区图标数:%d",nIcons);
    MessageBox(NULL,szText,"ok",MB_OK);
    return 0;
    }
    这段代码用到了一个托盘区图标的特点:它们都是16×16的小图标.