2008-11-05 8 views
7

क्या सिस्ट्रे तक पहुंचने के लिए कोई तरीका है (सी # में)? मैं एक अधिसूचना आइकन बनाने के बारे में बात नहीं कर रहा हूं। मैं ट्रे में वस्तुओं के माध्यम से पुन: प्रयास करना चाहता हूं (मुझे प्रक्रियाओं के माध्यम से अनुमान लगाया जाएगा, लेकिन मुझे नहीं पता कि ट्रे में वास्तव में क्या है और यह केवल एक प्रक्रिया क्या है) और यह भी मेरे आइकन के साथ आइटम का प्रतिनिधित्व करने के लिए अपने यूईसिस्ट्रे एक्सेस

उत्तर

5

Win32 इंटरऑप के बारे में आप कैसा महसूस करते हैं? मुझे C/Win32 code मिला जो आपके लिए चाल कर सकता है। (असल में, यह एक दिलचस्प समस्या की तरह दिखता है, इसलिए मैं इसे खुद से निपटने का प्रयास कर सकता हूं, अभी नहीं)।

hHook=SetWindowsHookEx(WH_CALLWNDPROC,HOOKPROC(MsgProc), 
     hInstance,dwExplorerThreadId);
तब संदेश पंप हुक दौरान

:

NotifyWnd = FindWindowEx(SysTray, 0, "TrayNotifyWnd", 0);

फिर वह अपने संदेश पंप पर एक हुक सेट:

जादू है कि वह सिस्टम ट्रे की खिड़की के लिए एक संभाल हो जाता है प्रतीत होता है कॉलबैक, उसे खिड़की के बारे में कुछ सूचक डेटा का संदर्भ मिलता है:

TWDataT* twd=(TWDataT*)GetWindowLong(NotifyWnd,0);

रहस्य - निर्भरता दर्शक, कि DPA_GetPtr है, जो एक गतिशील सूचक सरणी से डेटा प्राप्त के साथ मेरी जाँच के अनुसार

 pTWIconDataT p=COMCTL32_332(twd->iconsInfo,i);

COMCTL32_332 Comctl32.dll की 332 क्रमसूचक के लिए GetProcAddress और अंकों के साथ परिभाषित किया गया है: y फिर अपने पाश है। मैं दृश्यों के पीछे क्या चल रहा हूं उससे परिचित नहीं हूं, लेकिन यह पूरी तरह से सवाल से बाहर नहीं लगता है।

मैं इसे थोड़ा सा खेलना चाहता हूं, लेकिन उम्मीद है कि यह आपको शुरू करने के लिए एक अच्छी जगह है। :)

1

माथीस राउन का पागल चयन (डेल्फी सी # के लिए) Tray Icons सूचीबद्ध कर सकता है।

और वहाँ एक कमांडलाइन उपकरण है: Windows System Tray Scan Utility

मैं भी लिखा है (जारी नहीं) डेल्फी (नहीं Delphi.NET) में अपने खुद के कार्यक्रम, madCollection, जो ट्रे आइकन, प्रक्रिया नाम, टूलटिप्स और पता चलता का उपयोग नहीं अन्य जानकारी लेकिन यह सही नहीं है। ऐसे कुछ आइकन हैं जो प्रदर्शित नहीं कर सकते हैं (भले ही यह अन्य जानकारी सूचीबद्ध करता हो), और यह विंडोज 9एक्स के तहत किसी भी आइकन को प्रदर्शित नहीं कर सकता है। मैंने Vista के तहत बिल्कुल इसका परीक्षण नहीं किया है।

1

Windows 2000 में, सिस्टम ट्रे आइकन एक सादे उपकरण पट्टी नियंत्रण (विंडो वर्ग "ToolbarWindow32") जो "TrayNotifyWnd" खिड़की का एक बच्चा है, तो आप इसे इस तरह TB_BUTTONCOUNT और TB_GETBUTTON के रूप में उपकरण पट्टी संदेश भेज सकते हैं कर रहे हैं ।

आपको सावधान होने की जरूरत है, हालांकि: इस तरह के TB_GETBUTTON के रूप में संदेशों जो जिसमें परिणाम स्टोर करने के लिए एक बफर के लिए सूचक की आवश्यकता की जरूरत है कि को बफर सिसट्रे प्रक्रिया ही में हो। इसके लिए आवश्यक है कि आपके पास सही अनुमतियां हों, और आप मेमोरी आवंटित करने के लिए VirtualAllocEx का उपयोग करें।

मैंने इसे XP या Vista पर नहीं देखा है। मुझे उम्मीद है कि चीजें बदल गई हैं।

0

विंडोज 2000/एक्सपी में इसे हासिल करना पूरी तरह से संभव था। दुर्भाग्य से विंडोज 7 में ऐसा लगता है कि यह अब और संभव नहीं है।

चाल आसान था: आप ट्रे खिड़की संभाल खोजने के लिए:

 static IntPtr GetSystemTrayHandle() 
    { 
     IntPtr hWndTray = FindWindow("Shell_TrayWnd", null); 
     if (hWndTray != IntPtr.Zero) 
     { 
      hWndTray = FindWindowEx(hWndTray, IntPtr.Zero, "TrayNotifyWnd", null); 
      if (hWndTray != IntPtr.Zero) 
      { 
       hWndTray = FindWindowEx(hWndTray, IntPtr.Zero, "SysPager", null); 
       if (hWndTray != IntPtr.Zero) 
       { 
        hWndTray = FindWindowEx(hWndTray, IntPtr.Zero, "ToolbarWindow32", null); 
        return hWndTray; 
       } 
      } 
     } 

     return IntPtr.Zero; 
    } 

के बाद से इस विंडो ToolbarWindow32 है तो आप WinAPI का उपयोग कर बटन भर की गणना करने की है। केवल समस्या यह है कि इस के लिए उपयोग किए गए सभी संरचनाओं लक्ष्य प्रक्रिया पता स्थान में आवंटित किया जाना चाहिए है, तो आप कुछ इस तरह उपयोग करने के लिए है: विंडोज 7 tbButton.dwData बराबर 0 है में दुर्भाग्य से

private static unsafe bool GetTBButton(IntPtr hToolbar, int i, ref TBBUTTON tbButton, ref string text, ref IntPtr ipWindowHandle) 
    { 
     // One page 
     const int BUFFER_SIZE = 0x1000; 

     byte[] localBuffer = new byte[BUFFER_SIZE]; 

     UInt32 processId = 0; 
     UInt32 threadId = User32.GetWindowThreadProcessId(hToolbar, out processId); 

     IntPtr hProcess = Kernel32.OpenProcess(ProcessRights.ALL_ACCESS, false, processId); 
     if (hProcess == IntPtr.Zero) { Debug.Assert(false); return false; } 

     IntPtr ipRemoteBuffer = Kernel32.VirtualAllocEx(
      hProcess, 
      IntPtr.Zero, 
      new UIntPtr(BUFFER_SIZE), 
      MemAllocationType.COMMIT, 
      MemoryProtection.PAGE_READWRITE); 

     if (ipRemoteBuffer == IntPtr.Zero) { Debug.Assert(false); return false; } 

     // TBButton 
     fixed (TBBUTTON* pTBButton = &tbButton) 
     { 
      IntPtr ipTBButton = new IntPtr(pTBButton); 

      int b = (int)User32.SendMessage(hToolbar, TB.GETBUTTON, (IntPtr)i, ipRemoteBuffer); 
      if (b == 0) { Debug.Assert(false); return false; } 

      // this is fixed 
      Int32 dwBytesRead = 0; 
      IntPtr ipBytesRead = new IntPtr(&dwBytesRead); 

      bool b2 = Kernel32.ReadProcessMemory(
       hProcess, 
       ipRemoteBuffer, 
       ipTBButton, 
       new UIntPtr((uint)sizeof(TBBUTTON)), 
       ipBytesRead); 

      if (!b2) { Debug.Assert(false); return false; } 
     } 

     // button text 
     fixed (byte* pLocalBuffer = localBuffer) 
     { 
      IntPtr ipLocalBuffer = new IntPtr(pLocalBuffer); 

      int chars = (int)User32.SendMessage(hToolbar, TB.GETBUTTONTEXTW, (IntPtr)tbButton.idCommand, ipRemoteBuffer); 
      if (chars == -1) { Debug.Assert(false); return false; } 

      // this is fixed 
      Int32 dwBytesRead = 0; 
      IntPtr ipBytesRead = new IntPtr(&dwBytesRead); 

      bool b4 = Kernel32.ReadProcessMemory(
       hProcess, 
       ipRemoteBuffer, 
       ipLocalBuffer, 
       new UIntPtr(BUFFER_SIZE), 
       ipBytesRead); 

      if (!b4) { Debug.Assert(false); return false; } 

      text = Marshal.PtrToStringUni(ipLocalBuffer, chars); 

      if (text == " ") text = String.Empty; 
     } 

, तो आप कर सकते हैं ' NotifyIcon और लक्ष्य प्रक्रिया

के बीच कोई भी संबंध नहीं मिला
संबंधित मुद्दे