- 題名: ツリービューのアイコン取得(32bit→64bit対応)
- 日時: 2014/02/20 11:46:39
- ID: 32169
- この記事の返信元:
- (なし)
- この記事への返信:
- [32170] Re[1]: ツリービューのアイコン取得(32bit→64bit対応)2014/02/20 11:53:13
- ツリーを表示
using System; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Diagnostics; namespace VaultPanelControl { public class VaultPNCTL { [StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Unicode)] public struct TVITEM { public uint mask; public IntPtr hItem; public uint state; public uint stateMask; public IntPtr pszText; public int cchTextMax; public int iImage; public int iSelectedImage; public int cChildren; public IntPtr lParam; public int iIntegral; public uint uStateEx; public IntPtr hwnd; public int iExpandedImage; public int iReserved; } [DllImport("User32.dll", CharSet = CharSet.Unicode)] static extern IntPtr FindWindow(string lpszClass, string lpszWindow); [DllImport("user32.dll")] static extern IntPtr FindWindowEx(IntPtr hWnd, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("User32.dll", CharSet = CharSet.Unicode)] public static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); [DllImport("kernel32.dll")] public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint dwFreeType); [DllImport("kernel32.dll")] public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint lpNumberOfBytesRead); [DllImport("kernel32.dll")] public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint lpNumberOfBytesWritten); [DllImport("kernel32.dll")] public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CloseHandle(IntPtr hObject); [DllImport("kernel32.dll")] static extern void MoveMemory(IntPtr dst, IntPtr src, int size); private static uint PROCESS_VM_OPERATION = 0x00000008; private static uint PROCESS_VM_READ = 0x00000010; private static uint PROCESS_VM_WRITE = 0x00000020; private static uint MEM_RESERVE = 0x2000; private static uint MEM_COMMIT = 0x1000; private static uint MEM_RELEASE = 0x8000; private static uint PAGE_READWRITE = 0x0040; public static int TVM_EXPAND = 0x1102; public static int TV_FIRST = 0x1100; public static int TVM_GETITEM = TV_FIRST + 62; public static int TVM_GETNEXTITEM = 0x110A; public static int TVGN_ROOT = 0x0000; public static int TVGN_NEXT = 0x0001; public static int TVGN_CARET = 0x0009; public static int TVE_EXPAND = 0x1102; public static uint TVIF_TEXT = 0x0001; public static uint TVIS_STATEIMAGEMASK = 0xF000; public static uint TVIF_STATE = 0x0008; static void Main(string[] args) { uint pid = 0x2780; // 相手アプリケーションのプロセスID(直接指定) IntPtr treewindow = (IntPtr)0x80CEC; // ツリーウィンドウのハンドル(直接指定) IntPtr hwindow = (IntPtr)0xE0B66; //親ウィンドウハンドル直接指定 uint result = GetWindowThreadProcessId(hwindow, out pid); Process p = Process.GetProcessById((int)pid); //カレントのハンドル IntPtr lItemWnd = SendMessage(treewindow, TVM_GETNEXTITEM, (IntPtr)TVGN_CARET, IntPtr.Zero); //ツリーを開く SendMessage(treewindow, TVM_EXPAND, (IntPtr)TVE_EXPAND, lItemWnd); //ノードの名称を取得 //相手プロセスのオープン IntPtr pProcessH = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, pid); if (pProcessH.Equals(IntPtr.Zero)) { return; } try { //pszText設定用の文字列領域確保 int MAX_STR = 260; //TVITEM構造体を宣言 初期化 TVITEM tvitem = new TVITEM(); int tvitemSize = Marshal.SizeOf(tvitem); int dwSize = tvitemSize + MAX_STR; //自プロセスの共有メモリ確保 //TVITEM格納分 IntPtr pLocalShared = Marshal.AllocHGlobal(tvitemSize); try { //タイトルバッファ格納分 IntPtr pLocalShared_Buf = Marshal.AllocCoTaskMem(MAX_STR); try { //相手側プロセスの共有メモリ確保 //TVITEM格納分 IntPtr pSysShared = VirtualAllocEx(pProcessH, IntPtr.Zero, (uint)tvitemSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (pSysShared.Equals(IntPtr.Zero)) { return; } try { //タイトルバッファ格納分 IntPtr pSysShared_Buf = VirtualAllocEx(pProcessH, IntPtr.Zero, (uint)MAX_STR, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (pSysShared_Buf.Equals(IntPtr.Zero)) { return; } try { //構造体の初期化 tvitem.mask = TVIF_TEXT | TVIF_STATE; tvitem.hItem = lItemWnd; tvitem.pszText = pSysShared_Buf; tvitem.cchTextMax = MAX_STR; tvitem.stateMask = TVIS_STATEIMAGEMASK; //構造体のポインタを確保したアドレスに移動 Marshal.StructureToPtr(tvitem, pLocalShared, false); //相手プロセス内にTVITEM構造体をコピー uint retWrite = 0; bool bRet = false; bRet = WriteProcessMemory(pProcessH, pSysShared, pLocalShared, tvitemSize, ref retWrite); if (bRet == false) { return; } //SendMessage発行 IntPtr pRet; pRet = SendMessage(treewindow, TVM_GETITEM, IntPtr.Zero, pSysShared); if (pRet == IntPtr.Zero) return; //共有メモリから情報取得 uint retRead = 0; bRet = ReadProcessMemory(pProcessH, pSysShared_Buf, pLocalShared_Buf, MAX_STR, ref retRead); if (bRet == false) return; //状態イメージの取得 ↓↓↓↓↓↓ ここで帰ってくる値が32bitの時と異なります。 bRet = ReadProcessMemory(pProcessH, pSysShared, pLocalShared, tvitemSize, ref retRead); if (bRet == false) return ; TVITEM n_tvitem = (TVITEM)Marshal.PtrToStructure(pLocalShared, typeof(TVITEM)); uint StateIcon = (n_tvitem.state); MessageBox.Show(Marshal.PtrToStringUni(pLocalShared_Buf) + " [Icon:" + StateIcon.ToString("X") + "]"); } finally { //相手プロセス内の共有メモリを解放する VirtualFreeEx(pProcessH, pSysShared_Buf, (uint)tvitemSize, MEM_RELEASE); } } finally { //相手プロセス内の共有メモリを解放する VirtualFreeEx(pProcessH, pSysShared, (uint)MAX_STR, MEM_RELEASE); } } finally { //自プロセス内共有メモリを解放する Marshal.FreeHGlobal(pLocalShared_Buf); } } finally { //自プロセス内共有メモリを解放する Marshal.FreeHGlobal(pLocalShared); } } finally { //相手プロセスのクローズ CloseHandle(pProcessH); }}}}
分類:[.NET]