[轉貼]如何由trayicon取得所屬window handle及iconid

有關於C/C++的語法, 程式等
回覆文章
頭像
tim
文章: 1318
註冊時間: 2008年 11月 26日, 00:49

[轉貼]如何由trayicon取得所屬window handle及iconid

文章 tim » 2008年 11月 27日, 16:41

技術參考 codeproject:
http://www.codeproject.com/shell/ctrayiconposition.asp

使用方式

代碼: 選擇全部

     
      HRESULT res= S_FALSE; 
     
      HWND hWndTray = GetTrayNotifyWnd(); 
      if (hWndTray == NULL) 
      { 
        return S_FALSE; 
      } 
     
      //now we have to get an ID of the parent process for system tray 
      DWORD dwTrayProcessID = -1; 
      GetWindowThreadProcessId(hWndTray, &dwTrayProcessID); 
      if(dwTrayProcessID <= 0) 
      { 
        return S_FALSE; 
      } 
     
      HANDLE hTrayProc = OpenProcess(PROCESS_ALL_ACCESS, 0, dwTrayProcessID); 
      if(hTrayProc == NULL) 
      { 
        return S_FALSE; 
      } 
     
       
     
      int iButtonsCount = ::SendMessage(hWndTray, TB_BUTTONCOUNT, 0, 0); 
       
      //We want to get data from another process - it's not possible to just send messages like TB_GETBUTTON with a localy 
      //allocated buffer for return data. Pointer to localy allocated data has no usefull meaning in a context of another 
      //process (since Win95) - so we need to allocate some memory inside Tray process. 
      //We allocate sizeof(TBBUTTON) bytes of memory - because TBBUTTON is the biggest structure we will fetch. But this buffer 
      //will be also used to get smaller pieces of data like RECT structures. 
     
      LPVOID lpData = VirtualAllocEx(hTrayProc, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE); 
      if( lpData == NULL || iButtonsCount < 1 ) 
      { 
        CloseHandle(hTrayProc); 
        return S_FALSE; 
      } 
     
      for(int iButton=0; iButton<iButtonsCount; iButton++) 
      { 
        DWORD dwBytesRead = -1; 
        TBBUTTON buttonData; 
        ::SendMessage(hWndTray, TB_GETBUTTON, iButton, (LPARAM)lpData); 
        ReadProcessMemory(hTrayProc, lpData, &buttonData, sizeof(TBBUTTON), &dwBytesRead); 
        if(dwBytesRead < sizeof(TBBUTTON)) 
        { 
          continue; 
        } 
     
        //now let's read extra data associated with each button: there will be a HWND of the window that created an icon and icon ID 
        DWORD dwExtraData[2] = { 0,0 }; 
        ReadProcessMemory(hTrayProc, (LPVOID)buttonData.dwData, dwExtraData, sizeof(dwExtraData), &dwBytesRead); 
        if(dwBytesRead < sizeof(dwExtraData)) 
        { 
          continue; 
        } 
     
     
        // get the window handle and iconid from trayicon , these are two identity key to find out the tray icon. 
        HWND hWndOfIconOwner = (HWND) dwExtraData[0]; 
        int  iIconId     = (int)  dwExtraData[1];     
     
        // we can also get the ProcessID from window handle by GetWindowThreadProcessId API. 
        DWORD dwProcessId = 0; 
        GetWindowThreadProcessId(hWndOfIconOwner,&dwProcessId); 
     
        // we can do some thing here. 
        // res = S_OK; or res = S_FALSE; 
     
      } 
     
      VirtualFreeEx(hTrayProc, lpData, NULL, MEM_RELEASE); 
      CloseHandle(hTrayProc); 
     
      return res; 
多多留言, 整理文章, 把經驗累積下來.....

回覆文章