Модераторы: gambit, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Получить название икнонок в трее 
V
    Опции темы
Torgovec
Дата 29.6.2009, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 8.11.2005

Репутация: нет
Всего: нет



Доброго времени суток!
Пытаюсь циклом пробежаться по иконкам в трее и получить их названия таким вот способом
Код

    static class WinApi {

        public const int WM_USER = 0x0400;

        public const int TB_HIDEBUTTON = WM_USER + 4;

        private const int TB_DELETEBUTTON = WM_USER + 22;
        public const int TB_BUTTONCOUNT = WM_USER + 24;
        public const int TB_GETBUTTONINFO = WM_USER + 63;

        public const int TBIF_IMAGE = 0x0001;
        public const int TBIF_TEXT = 0x0002;
        public const int TBIF_STATE = 0x0004;
        public const int TBIF_STYLE = 0x0008;
        public const int TBIF_LPARAM = 0x0010;
        public const int TBIF_COMMAND = 0x0020;
        public const int TBIF_SIZE = 0x0040;
        public const uint TBIF_BYINDEX = 0x80000000;



        [StructLayout(LayoutKind.Sequential)]
        public struct TBBUTTONINFO {
            public uint cbSize;
            public uint dwMask;
            public int idCommand;
            public int iImage;
            public byte fsState;
            public byte fsStyle;
            public short cx;
            public IntPtr lParam;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string lpszText;
            public int cchText;
        }

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool RedrawWindow(IntPtr hWnd, IntPtr lprcUpdate,
                          IntPtr hrgnUpdate, uint flags);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);


        public static void ShowTaskbarButtons() {
            IntPtr window = GetNotifyWindow();
            int count = (int)SendMessage(window, TB_BUTTONCOUNT, IntPtr.Zero, IntPtr.Zero); // Получаю кол-во значков в трее
            char[] chArray = new char[500];
            string s = new string(chArray);

            TBBUTTONINFO tbi = new TBBUTTONINFO(); // Создаю структуру, куда хочу получать данные о значках
            tbi.dwMask   = TBIF_BYINDEX | TBIF_TEXT;
            tbi.cbSize   = (uint)Marshal.SizeOf(tbi);
            tbi.lpszText = s;
            tbi.cchText = 500;


            for (int i = 0; i < count; i++) {

                SendMessage(window, TB_GETBUTTONINFO, i, ref tbi); // После этого падает explorer 
                //SendMessage(window, true, i, showButtons); // Вот это работает нормально
            }
        }


       private static IntPtr GetNotifyWindow() {
            IntPtr shellTrayHwnd = FindWindow("Shell_TrayWnd", null);
            IntPtr trayNotifyHwnd = FindWindowEx(shellTrayHwnd, IntPtr.Zero, "TrayNotifyWnd", null);
            IntPtr sysPagerHwnd = FindWindowEx(trayNotifyHwnd, IntPtr.Zero, "SysPager", null);
            return FindWindowEx(sysPagerHwnd, IntPtr.Zero, "ToolbarWindow32", null);
        }
    }


При запуске explorer валится, структура tbi остается пустой. Прошу помочь разобраться с проблемой.


Это сообщение отредактировал(а) Torgovec - 29.6.2009, 16:06
PM MAIL   Вверх
Partizan
Дата 29.6.2009, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 9
Всего: 67



Torgovec, pinvoke говорит, что определение структуры TBBUTTONINFO должно выглядеть так:

Код

 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
    public struct TBBUTTONINFO
    {
        public int cbSize;
        public int dwMask;
        public int idCommand;
        public int iImage;
        public byte fsState;
        public byte fsStyle;
        public short cx;
        public IntPtr lParam;
        public IntPtr pszText;
        public int cchText;
    }



--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Torgovec
Дата 30.6.2009, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 8.11.2005

Репутация: нет
Всего: нет



Изменил определение структуры по вашей рекомендации и добавил функции чтения памяти из другого процесса.
В итоге структура заполняется, но к сожалению названия значков я так и не вижу :-( - поля "pszText" и "cchText" всегда равны нулю, остальные поля структуры успешно заполняются, а explorer больше не валится. Привожу полный код класса:
Код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace SingleInst2 {
    static class WinApi {

        public const uint TBIF_IMAGE = 0x0001;
        public const uint TBIF_TEXT = 0x0002;
        public const uint TBIF_STATE = 0x0004;
        public const uint TBIF_STYLE = 0x0008;
        public const uint TBIF_LPARAM = 0x0010;
        public const uint TBIF_COMMAND = 0x0020;
        public const uint TBIF_SIZE = 0x0040;
        public const uint TBIF_BYINDEX = 0x80000000;

        const uint WM_USER = 1024;
        const uint TB_HIDEBUTTON = (WM_USER + 4);
        const uint TB_BUTTONCOUNT = (WM_USER + 24);
        const uint TB_GETBUTTON = (WM_USER + 23);
        const uint TB_GETITEMRECT = (WM_USER + 29);
        const uint TB_DELETEBUTTON = (WM_USER + 22);
        const uint TB_GETBUTTONTEXT = (WM_USER + 45);
        const uint TBSTATE_HIDDEN = 0x08;
        const uint PROCESS_ALL_ACCESS = 0x1F0FFF;
        const uint MEM_COMMIT = 0x1000;
        const uint MEM_RELEASE = 0x8000;
        const uint PAGE_READWRITE = 0x04;

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct TBBUTTONINFO {
            public int cbSize;
            public int dwMask;
            public int idCommand;
            public int iImage;
            public byte fsState;
            public byte fsStyle;
            public short cx;
            public IntPtr lParam;
            public IntPtr pszText;
            public int cchText;
        }

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool RedrawWindow(IntPtr hWnd, IntPtr lprcUpdate,
                          IntPtr hrgnUpdate, uint flags);

        public static readonly int WM_SHOWFIRSTINSTANCE = RegisterWindowMessage("WM_SHOWFIRSTINSTANCE");

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, bool lParam);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, IntPtr lParam);

        [DllImport("user32")]
        public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

        [DllImport("user32")]
        public static extern int RegisterWindowMessage(string message);

        [DllImport("user32.dll")]
        public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        [DllImport("user32.dll")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern IntPtr OpenProcess(uint dwDesiredAccess, Int32 bInheritHandle, Int32 dwProcessId);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, Int32 dwSize, uint flAllocationType, uint flProtect);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern Int32 VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, Int32 dwSize, uint dwFreeType);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern Int32 GetWindowThreadProcessId(IntPtr hWnd, out Int32 lpdwProcessId);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern Int32 CloseHandle(IntPtr hObject);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] lpBuffer, Int32 nSize, out Int32 lpNumberOfBytesRead);

        public static void ShowToFront(string windowName) {
            IntPtr window = FindWindow(null, windowName);
            ShowWindow(window, 1);
            SetForegroundWindow(window);
        }


        public static void ShowTaskbarButtons(bool showButtons) {
            IntPtr hTrayWnd = GetNotifyWindow();
            int count = (int)SendMessage(hTrayWnd, TB_BUTTONCOUNT, IntPtr.Zero, IntPtr.Zero);

            Int32 dwTrayProcessID = -1;
            // получаем ID процесса таскбара
            GetWindowThreadProcessId(hTrayWnd, out dwTrayProcessID);
            if (dwTrayProcessID <= 0) { return; }

            TBBUTTONINFO tbbi = new TBBUTTONINFO();

            // открываем процесс на чтение\запись
            IntPtr hTrayProc = OpenProcess(PROCESS_ALL_ACCESS, 0, dwTrayProcessID);
            if (hTrayProc == IntPtr.Zero) { return; }

            Int32 dwBytesRead = -1;
            byte[] byteBuffer = new byte[Marshal.SizeOf(tbbi.GetType())];

            // создаем переменную в другом процессе    
            IntPtr lpData = VirtualAllocEx(hTrayProc, IntPtr.Zero, Marshal.SizeOf(tbbi.GetType()), MEM_COMMIT, PAGE_READWRITE);
            if (lpData == IntPtr.Zero) { CloseHandle(hTrayProc); return; }

            for (int i = 0; i < count; i++) {
                SendMessage(hTrayWnd, TB_GETBUTTON, i, lpData);

                // Читаем данные из другого процесса
                ReadProcessMemory(hTrayProc, lpData, byteBuffer, Marshal.SizeOf(tbbi.GetType()), out dwBytesRead);

                if (dwBytesRead < Marshal.SizeOf(tbbi.GetType())) { continue; }
                IntPtr ptrOut = Marshal.AllocHGlobal(Marshal.SizeOf(tbbi.GetType()));
                Marshal.Copy(byteBuffer, 0, ptrOut, byteBuffer.Length);

                // Получаем данные в структуру
                tbbi = (TBBUTTONINFO)Marshal.PtrToStructure(ptrOut, typeof(TBBUTTONINFO));
            }

            VirtualFreeEx(hTrayProc, lpData, 0, MEM_RELEASE);
            CloseHandle(hTrayProc);
        }
    }
}


В отладчике на 142 строке у меня установлен breakpoint и я вижу что поля tbbi.pszText и tbbi.cchText в процессе прохождения цикла остаются неизменными.

Это сообщение отредактировал(а) Torgovec - 30.6.2009, 14:21
PM MAIL   Вверх
Partizan
Дата 2.7.2009, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 9
Всего: 67



Torgovec, что Вы имеете ввиду, говоря "получить название иконок в трее"? что такое "название иконок"?


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Torgovec
Дата 23.7.2009, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 8.11.2005

Репутация: нет
Всего: нет



Partizan
Быть может неправильно выразился, я имел ввиду подписи к значкам программ расположенных в tray (тот текст, который отображается при наведении мышкой на иконку ). В итоге я изменил SendMessage(hTrayWnd, TB_GETBUTTON, i, lpData) на SendMessage(hTrayWnd, TB_GETBUTTONTEXT, i, lpData).

Изначально код у меня был такой:
Код

            for (int i = 0; i < count; i++) {
                SendMessage(hTrayWnd, TB_GETBUTTON, i, lpData);

                // Читаем данные из другого процесса
                ReadProcessMemory(hTrayProc, lpData, byteBuffer, Marshal.SizeOf(tbbi.GetType()), out dwBytesRead);

                if (dwBytesRead < Marshal.SizeOf(tbbi.GetType())) { continue; }
                IntPtr ptrOut = Marshal.AllocHGlobal(Marshal.SizeOf(tbbi.GetType()));
                Marshal.Copy(byteBuffer, 0, ptrOut, byteBuffer.Length);

                // Получаем данные в структуру
                tbbi = (TBBUTTONINFO)Marshal.PtrToStructure(ptrOut, typeof(TBBUTTONINFO));

.............
            }

но пришлось изменить на 
Код

            for (int i = 0; i < count; i++) {
                SendMessage(hTrayWnd, TB_GETBUTTONTEXT, i, lpData);
                // Читаем данные из другого процесса
                ReadProcessMemory(hTrayProc, lpData, byteBuffer, nBuff, out dwBytesRead);

                if (dwBytesRead < 1000) { continue; }
                IntPtr ptrOut = Marshal.AllocHGlobal(nBuff);
                Marshal.Copy(byteBuffer, 0, ptrOut, byteBuffer.Length);

                // Получаем данные в структуру
                sCheckerSign = "";
                sCheckerSign = (String)Marshal.PtrToStringAnsi(ptrOut, nBuff);
.............
            }

т.к. структуру tbbi мне так и не удалось заполнить.

Это сообщение отредактировал(а) Torgovec - 23.7.2009, 11:19
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Разработка Windows Forms | Следующая тема »


 




[ Время генерации скрипта: 0.1078 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.