TVM_SELECTITEM по SysTreeView32 не перерисовывает диалог - C#

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Есть диалоговое окно с SysTreeView32. Если щелкнуть по его элементу (в данном случае, "Солнце") лк мышки, этот элемент благополучно выделится вместе с "чекбоксом", при этом перерисовываются все элементы в диалоге (т.е по Spy++ все они создаются при загрузке диалога, а потом просто те или иные включаются/выключаются. Но при отправке TVM_SELECTITEM элементу SysTreeView32, элемент в дереве выделяется (но "чекбокс" не отжимается), элементы диалога не перерисовываются. По запрошенному TVM_GETITEMRECT элемента, а затем WM_LBUTTONDOWN-WM_LBUTTONUP в этой точке - результат тот же. Я пробовал отжимать этот "чекбокс" элемента, меняя и записывая TVITEMEX, но (как я понял), это просто пририсовывает галку этому "чекбоксу" - и всё. Возможно, не то делал. Вопрос: как отжимать правильно элементы дерева, чтобы диалог перерисовывался, менял видимость окон диалога, понимал, что то или оное окно относится в данном случае к выбранному элементу дерева (источнику освещения) ?
                IntPtr treeItemSun = IntPtr.Zero, treeItemEye = IntPtr.Zero;
                TreeView.SearchItem(TConList[0].hWnd, "Солнце", out treeItemSun);
                TreeView.SelectItem(TConList[0].hWnd, treeItemSun); //вариант 1
                us32.RECT rectItemSun = TreeView.GetItemRect(TConList[0].hWnd, treeItemSun);
                us32.SendClickPostMsg(TConList[0].hWnd, rectItemSun.Left, rectItemSun.Top); //вариант 2
под катом вызываемые функции
        public static string GetItemText(IntPtr procHandle, IntPtr hwndTreeView, IntPtr hwndItem)
        {
            TVITEMEX item = new TVITEMEX();
            item.hItem = hwndItem; //hTreeViewItemChange;
            item.mask = (uint)(TVIF.TVIF_HANDLE | TVIF.TVIF_CHILDREN | TVIF.TVIF_TEXT);
            item.cchTextMax = 1024;
            item.pszText = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)item.cchTextMax, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // node text pointer
                                                                                                                                     //Marshal.AllocHGlobal(TreeItem.cchTextMax); //new wchar_t[260];
            byte[] data = getBytes(item);
 
            uint dwSize = (uint)data.Length;
            IntPtr allocMemAddress = VirtualAllocEx(procHandle, IntPtr.Zero, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // TVITEM pointer
 
            uint nSize = dwSize;
            UIntPtr bytesWritten;
            bool successWrite = WriteProcessMemory(procHandle, allocMemAddress, data, nSize, out bytesWritten);
 
            var sm = us32.SendMessage(hwndTreeView, us32.TVM_GETITEMW, IntPtr.Zero, allocMemAddress);
 
            UIntPtr bytesRead;
            bool successRead = ReadProcessMemory(procHandle, allocMemAddress, data, nSize, out bytesRead);
 
            UIntPtr bytesReadText;
            byte[] nodeText = new byte[item.cchTextMax];
            bool successReadText = ReadProcessMemory(procHandle, item.pszText, nodeText, (uint)item.cchTextMax, out bytesReadText);
 
            bool success1 = VirtualFreeEx(procHandle, allocMemAddress, dwSize, MEM_DECOMMIT);
            bool success2 = VirtualFreeEx(procHandle, item.pszText, (uint)item.cchTextMax, MEM_DECOMMIT);
 
            var item2 = fromBytes<TVITEMEX>(data);
 
            String name = Encoding.Unicode.GetString(nodeText);
 
            int x = name.IndexOf('\0');
            if (x >= 0)
                name = name.Substring(0, x);
 
            return name;
        }
 
        private static IntPtr GetProcHandle(IntPtr hwnd)
        {
            int ProcessId;
            GetWindowThreadProcessId(hwnd, out ProcessId);
            // handle of the process with the required privileges
            IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, ProcessId);
            return procHandle;
        }
 
        public static string GetItemText(IntPtr hwndTreeView, IntPtr hwndItem)
        {
            return GetItemText(GetProcHandle(hwndTreeView), hwndTreeView, hwndItem);
        }
 
        private static bool SearchItemHelper(IntPtr procHandle, IntPtr hwndTreeView, string caption, IntPtr CurItem, out IntPtr foundItem)
        {
            foundItem = IntPtr.Zero;
            if (CurItem.ToInt32() != 0)
            {
                string nodetext = GetItemText(hwndTreeView, CurItem);
                if (nodetext == caption)
                {
                    foundItem = CurItem;
                    return true;
                }
                IntPtr treeItem, sItem;
                treeItem = us32.SendMessage(hwndTreeView, us32.TVM_GETNEXTITEM, TreeView.TreeViewConst.TVGN_NEXT, (int)CurItem);
                if (SearchItemHelper(procHandle, hwndTreeView, caption, treeItem, out sItem) == true)
                {
                    foundItem = sItem;
                    return true;
                }
                treeItem = us32.SendMessage(hwndTreeView, us32.TVM_GETNEXTITEM, TreeView.TreeViewConst.TVGN_CHILD, (int)CurItem);
                if (SearchItemHelper(procHandle, hwndTreeView, caption, treeItem, out sItem) == true)
                {
                    foundItem = sItem;
                    return true;
                }
            }
            return false;
        }
 
        public static bool SearchItem(IntPtr hwndTreeView, string caption, out IntPtr hwndItem)
        {
            IntPtr procHandle = GetProcHandle(hwndTreeView);
            IntPtr RootItem = us32.SendMessage(hwndTreeView,us32.TVM_GETNEXTITEM, new IntPtr(TreeViewConst.TVGN_ROOT), new System.IntPtr(0));
            return SearchItemHelper(procHandle, hwndTreeView, caption, RootItem, out hwndItem);
        }
 
        public static bool SelectItem(IntPtr hwnd, IntPtr treeItem)
        {
            bool fRet;
            if (unchecked((int)(long)us32.SendMessage(hwnd, us32.TVM_SELECTITEM, new IntPtr(TreeViewConst.TVGN_CARET | TreeViewConst.TVSI_NOSINGLEEXPAND), treeItem)) != 0)
            {
                fRet = true;
            }
            else
            {
                fRet = unchecked((int)(long)us32.SendMessage(hwnd, us32.TVM_SELECTITEM, new IntPtr(TreeViewConst.TVGN_CARET), treeItem)) != 0;
            }
 
            return fRet;
        }
 
        public static us32.RECT GetItemRect(IntPtr hwndTreeView, IntPtr hwndItem)
        {
            int ProcessId;
            GetWindowThreadProcessId(hwndTreeView, out ProcessId);
            // handle of the process with the required privileges
            IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, ProcessId);
 
            us32.RECT rect1 = new us32.RECT();
            byte[] data = getBytes(rect1);
            byte[] data2 = getBytes(hwndItem);
 
            uint dwSize = (uint)data.Length;
            IntPtr allocMemAddress = VirtualAllocEx(procHandle, IntPtr.Zero, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // TVITEM pointer
 
            uint nSize = (uint)data2.Length;
            UIntPtr bytesWritten;
            bool successWrite = WriteProcessMemory(procHandle, allocMemAddress, data2/**/, nSize, out bytesWritten);
 
            var sm = us32.SendMessage(hwndTreeView, us32.TVM_GETITEMRECT, /*IntPtr.Zero*/(IntPtr)1, allocMemAddress);
            //us32.SendMessage(TConList[0].hWnd, us32.TVM_GETITEMRECT, true, ref rect1)
            UIntPtr bytesRead;
            bool successRead = ReadProcessMemory(procHandle, allocMemAddress, data, /*nSize*/dwSize, out bytesRead);
 
            bool success1 = VirtualFreeEx(procHandle, allocMemAddress, dwSize, MEM_DECOMMIT);
 
            var item2 = fromBytes<us32.RECT>(data);
            us32.RECT rect2 = (us32.RECT)item2;
            return rect2;
        }
 
        public static void SendClickPostMsg(IntPtr hWnd, int posX, int posY)
        {
            us32.PostMessage(hWnd, us32.WM_LBUTTONDOWN, 0x0001, (int)((posY << 16) | (posX & 0xFFFF)));
            us32.PostMessage(hWnd, us32.WM_LBUTTONUP, 0x0001, (int)((posY << 16) | (posX & 0xFFFF)));
        }
попытки с TVITEMEX:
        public static void OnCheckBox(IntPtr hwndTreeView, IntPtr hwndItem)
        {
            int ProcessId;
            GetWindowThreadProcessId(hwndTreeView, out ProcessId);
            // handle of the process with the required privileges
            IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, ProcessId);
 
            TVITEMEX item2 = new TVITEMEX();
            /*change*/
            item2.hItem = hwndItem;
            item2.mask = (uint)(TVIF.TVIF_HANDLE | TVIF.TVIF_IMAGE | TVIF.TVIF_SELECTEDIMAGE | TVIF.TVIF_STATE);
            item2.stateMask = TreeViewConst.TVIS_STATEIMAGEMASK ;
            item2.iSelectedImage = 3; //баловство
            item2.iImage = 3;
            item2.state = 8194;//даёт результат // item2.state | TreeViewConst.TVIS_SELECTED | TreeViewConst.TVIS_EXPANDED;
 
            byte[] data2 = getBytes(item2);
            uint dwSize2 = (uint)data2.Length;
            IntPtr allocMemAddress2 = VirtualAllocEx(procHandle, IntPtr.Zero, dwSize2, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // TVITEM pointer
            uint nSize2 = dwSize2;
            UIntPtr bytesWritten2;
            bool successWrite2 = WriteProcessMemory(procHandle, allocMemAddress2, data2, nSize2, out bytesWritten2);
 
            us32.SendMessage(hwndTreeView, us32.TVM_SETITEMW, IntPtr.Zero, allocMemAddress2);
 
            bool success3 = VirtualFreeEx(procHandle, allocMemAddress2, dwSize2, MEM_DECOMMIT);
        }
А вот сообщения из Spy++, если "вручную" кликать ЛК по SysTreeView32:
<000008> 000B03B4 S WM_PAINT hdc:00000000 [wParam:00000000 lParam:00000000] <000009> 000B03B4 R WM_PAINT <000010> 000B03B4 S WM_MOUSEACTIVATE hwndTopLevel:0004100A nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN [wParam:0004100A lParam:02010001] <000011> 000B03B4 R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE <000012> 000B03B4 P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:68 yPos:52 [wParam:00000001 lParam:00340044] <000013> 000B03B4 S WM_GETDLGCODE wParam:00000000 lParam:00000000 <000014> 000B03B4 R WM_GETDLGCODE fuDlgCodeLGC_WANTARROWS | DLGC_WANTCHARS <000015> 000B03B4 P WM_LBUTTONUP fwKeys:0000 xPos:68 yPos:52 [wParam:00000000 lParam:00340044] <000016> 000B03B4 S WM_CAPTURECHANGED hwndNewCapture:00000000 [wParam:00000000 lParam:00000000] <000017> 000B03B4 R WM_CAPTURECHANGED <000018> 000B03B4 S TVM_HITTEST lpht:0012D714 [wParam:00000000 lParam:0012D714] <000019> 000B03B4 R TVM_HITTEST hItem:09D38120 <000020> 000B03B4 S TVM_SETITEMA pitem:0012D674 [wParam:00000000 lParam:0012D674] <000021> 000B03B4 R TVM_SETITEMA nRet:1 <000022> 000B03B4 S TVM_EXPAND flag:TVE_EXPAND hitem:09D37F40 [wParam:00000002 lParam:09D37F40] <000023> 000B03B4 R TVM_EXPAND fSucceeded:True <000024> 000B03B4 S TVM_GETITEMA pitem:0012D690 [wParam:00000000 lParam:0012D690] <000025> 000B03B4 R TVM_GETITEMA fSucceeded:True <000026> 000B03B4 S TVM_SETITEMA pitem:0012D674 [wParam:00000000 lParam:0012D674] <000027> 000B03B4 R TVM_SETITEMA nRet:1 <000028> 000B03B4 S TVM_EXPAND flag:TVE_EXPAND hitem:09D36280 [wParam:00000002 lParam:09D36280] <000029> 000B03B4 R TVM_EXPAND fSucceeded:False <000030> 000B03B4 S TVM_GETITEMA pitem:0012D690 [wParam:00000000 lParam:0012D690] <000031> 000B03B4 R TVM_GETITEMA fSucceeded:True <000032> 000B03B4 S TVM_SETITEMA pitem:0012D674 [wParam:00000000 lParam:0012D674] <000033> 000B03B4 R TVM_SETITEMA nRet:1 <000034> 000B03B4 S TVM_EXPAND flag:TVE_EXPAND hitem:09D392A0 [wParam:00000002 lParam:09D392A0] <000035> 000B03B4 R TVM_EXPAND fSucceeded:False <000036> 000B03B4 S TVM_SETITEMA pitem:0012D674 [wParam:00000000 lParam:0012D674] <000037> 000B03B4 R TVM_SETITEMA nRet:1 <000038> 000B03B4 S TVM_SETITEMA pitem:0012D674 [wParam:00000000 lParam:0012D674] <000039> 000B03B4 R TVM_SETITEMA nRet:1 <000040> 000B03B4 S TVM_GETITEMA pitem:0012D6B0 [wParam:00000000 lParam:0012D6B0] <000041> 000B03B4 R TVM_GETITEMA fSucceeded:True <000042> 000B03B4 S TVM_SELECTITEM flag:TVGN_CARET hitem:09D38120 [wParam:00000009 lParam:09D38120] <000043> 000B03B4 R TVM_SELECTITEM fSucceeded:True <000044> 000B03B4 S TVM_SETITEMA pitem:0012D698 [wParam:00000000 lParam:0012D698] <000045> 000B03B4 R TVM_SETITEMA nRet:1 <000046> 000B03B4 S TVM_SETITEMA pitem:0012D698 [wParam:00000000 lParam:0012D698] <000047> 000B03B4 R TVM_SETITEMA nRet:1 <000048> 000B03B4 S WM_PAINT hdc:00000000 [wParam:00000000 lParam:00000000] <000049> 000B03B4 S WM_NCPAINT hrgn:00000001 [wParam:00000001 lParam:00000000] <000050> 000B03B4 R WM_NCPAINT <000051> 000B03B4 R WM_PAINT <000052> 000B03B4 S WM_NOTIFY idCtrl:721844 pnmh:0012DDBC [wParam:000B03B4 lParam:0012DDBC] <000053> 000B03B4 R WM_NOTIFY <000054> 000B03B4 S WM_GETOBJECT dwFlags:00000000 dwObjId:FFFFFFF4 [wParam:00000000 lParam:FFFFFFF4] <000055> 000B03B4 R WM_GETOBJECT dwRet:00000000
При аналогичном управлении деревом в другом диалоге всё срабатывает, программа понимает, что элементы диалога относятся к той или иной ветви дерева (у них меняются "заголовки" рядом). Но там всё просто, при открытии диалога окна загружаются, но дальше их видимость не меняется. Тут же поведение не понятное. Помогите, пожалуйста.

Решение задачи: «TVM_SELECTITEM по SysTreeView32 не перерисовывает диалог»

textual
Листинг программы
            bool success1 = VirtualFreeEx(procHandle, allocMemAddress, 0, MEM_RELEASE);

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 3.846 из 5
Похожие ответы