BrightnessTray.WindowPositioning.GetNotifyIconRectLegacy C# (CSharp) Метод

GetNotifyIconRectLegacy() публичный статический Метод

Returns a rectangle representing the location of the specified NotifyIcon. (Windows Vista and earlier.)
public static GetNotifyIconRectLegacy ( System.Windows.Forms.NotifyIcon notifyicon ) : Rect?
notifyicon System.Windows.Forms.NotifyIcon The NotifyIcon whose location should be returned.
Результат Rect?
        public static Rect? GetNotifyIconRectLegacy(NotifyIcon notifyicon)
        {
            Rect? nirect = null;

            FieldInfo idFieldInfo = notifyicon.GetType().GetField("id", BindingFlags.NonPublic | BindingFlags.Instance);
            int niid = (int)idFieldInfo.GetValue(notifyicon);

            FieldInfo windowFieldInfo = notifyicon.GetType().GetField("window", BindingFlags.NonPublic | BindingFlags.Instance);
            System.Windows.Forms.NativeWindow nativeWindow = (System.Windows.Forms.NativeWindow)windowFieldInfo.GetValue(notifyicon);
            IntPtr nihandle = nativeWindow.Handle;
            if (nihandle == null || nihandle == IntPtr.Zero)
                return null;

            // find the handle of the task bar
            IntPtr taskbarparenthandle = NativeMethods.FindWindow("Shell_TrayWnd", null);

            if (taskbarparenthandle == (IntPtr)null)
                return null;

            // find the handle of the notification area
            IntPtr naparenthandle = NativeMethods.FindWindowEx(taskbarparenthandle, IntPtr.Zero, "TrayNotifyWnd", null);

            if (naparenthandle == (IntPtr)null)
                return null;

            // make a list of toolbars in the notification area (one of them should contain the icon)
            List<IntPtr> natoolbarwindows = NativeMethods.GetChildToolbarWindows(naparenthandle);

            bool found = false;

            for (int i = 0; !found && i < natoolbarwindows.Count; i++)
            {
                IntPtr natoolbarhandle = natoolbarwindows[i];

                // retrieve the number of toolbar buttons (i.e. notify icons)
                int buttoncount = NativeMethods.SendMessage(natoolbarhandle, NativeMethods.TB_BUTTONCOUNT, IntPtr.Zero, IntPtr.Zero).ToInt32();

                // get notification area's process id
                uint naprocessid;
                NativeMethods.GetWindowThreadProcessId(natoolbarhandle, out naprocessid);

                // get handle to notification area's process
                IntPtr naprocesshandle = NativeMethods.OpenProcess(NativeMethods.ProcessAccessFlags.All, false, naprocessid);

                if (naprocesshandle == IntPtr.Zero)
                    return null;

                // allocate enough memory within the notification area's process to store the button info we want
                IntPtr toolbarmemoryptr = NativeMethods.VirtualAllocEx(naprocesshandle, (IntPtr)null, (uint)Marshal.SizeOf(typeof(NativeMethods.TBBUTTON)), NativeMethods.AllocationType.Commit, NativeMethods.MemoryProtection.ReadWrite);

                if (toolbarmemoryptr == IntPtr.Zero)
                    return null;

                try
                {
                    // loop through the toolbar's buttons until we find our notify icon
                    for (int j = 0; !found && j < buttoncount; j++)
                    {
                        int bytesread = -1;

                        // ask the notification area to give us information about the current button
                        NativeMethods.SendMessage(natoolbarhandle, NativeMethods.TB_GETBUTTON, new IntPtr(j), toolbarmemoryptr);

                        // retrieve that information from the notification area's process
                        NativeMethods.TBBUTTON buttoninfo = new NativeMethods.TBBUTTON();
                        NativeMethods.ReadProcessMemory(naprocesshandle, toolbarmemoryptr, out buttoninfo, Marshal.SizeOf(buttoninfo), out bytesread);

                        if (bytesread != Marshal.SizeOf(buttoninfo))
                            return null;

                        if (buttoninfo.dwData == IntPtr.Zero)
                            return null;

                        // the dwData field contains a pointer to information about the notify icon:
                        // the handle of the notify icon (an 4/8 bytes) and the id of the notify icon (4 bytes)
                        IntPtr niinfopointer = buttoninfo.dwData;

                        // read the notify icon handle
                        IntPtr nihandlenew;
                        NativeMethods.ReadProcessMemory(naprocesshandle, niinfopointer, out nihandlenew, Marshal.SizeOf(typeof(IntPtr)), out bytesread);

                        if (bytesread != Marshal.SizeOf(typeof(IntPtr)))
                            return null;

                        // read the notify icon id
                        uint niidnew;
                        NativeMethods.ReadProcessMemory(naprocesshandle, niinfopointer + Marshal.SizeOf(typeof(IntPtr)), out niidnew, Marshal.SizeOf(typeof(uint)), out bytesread);

                        if (bytesread != Marshal.SizeOf(typeof(uint)))
                            return null;

                        // if we've found a match
                        if (nihandlenew == nihandle && niidnew == niid)
                        {
                            // check if the button is hidden: if it is, return the rectangle of the 'show hidden icons' button
                            if ((byte)(buttoninfo.fsState & NativeMethods.TBSTATE_HIDDEN) != 0)
                            {
                                nirect = GetNotifyAreaButtonRectangle();
                            }
                            else
                            {
                                NativeMethods.RECT result = new NativeMethods.RECT();

                                // get the relative rectangle of the toolbar button (notify icon)
                                NativeMethods.SendMessage(natoolbarhandle, NativeMethods.TB_GETITEMRECT, new IntPtr(j), toolbarmemoryptr);

                                NativeMethods.ReadProcessMemory(naprocesshandle, toolbarmemoryptr, out result, Marshal.SizeOf(result), out bytesread);

                                if (bytesread != Marshal.SizeOf(result))
                                    return null;

                                // find where the rectangle lies in relation to the screen
                                NativeMethods.MapWindowPoints(natoolbarhandle, (IntPtr)null, ref result, 2);

                                nirect = result;
                            }

                            found = true;
                        }
                    }
                }
                finally
                {
                    // free memory within process
                    NativeMethods.VirtualFreeEx(naprocesshandle, toolbarmemoryptr, 0, NativeMethods.FreeType.Release);

                    // close handle to process
                    NativeMethods.CloseHandle(naprocesshandle);
                }
            }

            return nirect;
        }