private int IndexToCommand(int idx) { TBBUTTON button = new TBBUTTON(); PInvoke.SendMessage(BreadcrumbController.Handle, TB_GETBUTTON, (IntPtr)idx, ref button); return(button.idCommand); }
private TrayItem GetTrayItem(int i, IntPtr hBuffer, IntPtr hProcess, IntPtr toolbarHwnd) { TBBUTTON tbButton = new TBBUTTON(); TrayItem trayItem = new TrayItem(); IntPtr hTBButton = Marshal.AllocHGlobal(Marshal.SizeOf(tbButton)); IntPtr hTrayItem = Marshal.AllocHGlobal(Marshal.SizeOf(trayItem)); IntPtr msgSuccess = SendMessage(toolbarHwnd, (int)TB.GETBUTTON, (IntPtr)i, hBuffer); if (ReadProcessMemory(hProcess, hBuffer, hTBButton, Marshal.SizeOf(tbButton), out _)) { tbButton = (TBBUTTON)Marshal.PtrToStructure(hTBButton, typeof(TBBUTTON)); if (tbButton.dwData != UIntPtr.Zero) { if (ReadProcessMemory(hProcess, tbButton.dwData, hTrayItem, Marshal.SizeOf(trayItem), out _)) { trayItem = (TrayItem)Marshal.PtrToStructure(hTrayItem, typeof(TrayItem)); CairoLogger.Instance.Debug( $"ExplorerTrayService: Got tray item: {trayItem.szIconText}"); } } } return(trayItem); }
private static bool GetMicrophoneInUseStatus() { var toolBarWindowHandle = GetToolbarWindowHandle(); if (toolBarWindowHandle == IntPtr.Zero) { return(false); } UInt32 count = User32.SendMessage(toolBarWindowHandle, TB.BUTTONCOUNT, 0, 0); var microphoneInUse = false; for (int i = 0; i < count; i++) { TBBUTTON tbButton = new TBBUTTON(); string text = String.Empty; IntPtr ipWindowHandle = IntPtr.Zero; bool b = GetTBButton(toolBarWindowHandle, i, ref tbButton, ref text, ref ipWindowHandle); if (b) { if (text.Contains("is using your microphone")) { microphoneInUse = true; break; } } } return(microphoneInUse); }
public static unsafe bool GetToolbarButton(IntPtr hToolbar, int i, ref TBBUTTON tbButton) { // One page const int BUFFER_SIZE = 0x1000; byte[] localBuffer = new byte[BUFFER_SIZE]; UInt32 processId = 0; UInt32 threadId = WinAPI.GetWindowThreadProcessId(hToolbar, out processId); IntPtr hProcess = WinAPI.OpenProcess((int)WinAPI.ProcessAccessFlags.All, false, processId); if (hProcess == IntPtr.Zero) { throw new ArgumentException("OpenProcess failed"); } IntPtr ipRemoteBuffer = WinAPI.VirtualAllocEx(hProcess, IntPtr.Zero, BUFFER_SIZE, WinAPI.AllocationType.Commit, WinAPI.MemoryProtection.ExecuteReadWrite); if (ipRemoteBuffer == IntPtr.Zero) { throw new ArgumentException("VirtualAllocEx failed"); } // TBButton fixed(TBBUTTON *pTBButton = &tbButton) { IntPtr ipTBButton = new IntPtr(pTBButton); int b = (int)WinAPI.SendMessage(hToolbar, (int)WinAPI.ToolbarMessage.TB_GETBUTTON, (IntPtr)i, ipRemoteBuffer); if (b == 0) { throw new ArgumentException("SendMessage TB_GETBUTTON failed"); } // this is fixed int ipBytesRead = 0; bool b2 = WinAPI.ReadProcessMemory(hProcess, ipRemoteBuffer, ipTBButton, sizeof(TBBUTTON), out ipBytesRead); if (!b2) { throw new ArgumentException("ReadProcessMemory failed"); } } WinAPI.VirtualFreeEx( hProcess, ipRemoteBuffer, 0, WinAPI.AllocationType.Release); WinAPI.CloseHandle(hProcess); return(true); }
protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); //设置imgList SendMessage(this.Handle, 0x430, IntPtr.Zero, imgList.Handle);//TB_SETIMAGELIST //准备添加按钮 int btnStructSize = Marshal.SizeOf(typeof(TBBUTTON)); SendMessage(this.Handle, 0x41E, new IntPtr(btnStructSize), IntPtr.Zero);//TB_BUTTONSTRUCTSIZE,必须在添加按钮前 //构建按钮信息 TBBUTTON btnStruct = new TBBUTTON { //iBitmap = 0, //idCommand = 0, fsState = 0x4, //TBSTATE_ENABLED iString = SendMessage(this.Handle, 0x44D, 0, this.Text + '\0') //TB_ADDSTRING }; if (this.isToggleMode) { btnStruct.fsStyle = 0x2; } //BTNS_CHECK。作为切换按钮时 IntPtr btnStructStart = IntPtr.Zero; try { btnStructStart = Marshal.AllocHGlobal(btnStructSize); //在非托管区创建一个指针 Marshal.StructureToPtr(btnStruct, btnStructStart, true); //把结构体塞到上述指针 //添加按钮 SendMessage(this.Handle, 0x444, new IntPtr(1) /*按钮数量*/, btnStructStart);//TB_ADDBUTTONS。从指针取按钮信息 //设置按钮尺寸刚好为ToolBar尺寸 AdjustButtonSize(); } finally { if (btnStructStart != IntPtr.Zero) { Marshal.FreeHGlobal(btnStructStart); } } }
public static ApplicationWindow GetNthApplicationWindowOnNotificationArea(IntPtr notificationAreaHwnd, int i) { var tbButton = new TBBUTTON(); var text = string.Empty; var ipWindowHandle = IntPtr.Zero; NotificationAreaWindow notificationAreaWindow; var b = User32.GetTBButton(notificationAreaHwnd, i, ref tbButton, ref text, ref ipWindowHandle, out notificationAreaWindow); if (!b) { return(null); } //if (!User32.KeepWindowHandleInAltTabList(notificationAreaWindow.MainWindowHandle)) //return null; /*if (hash.Contains(notificationAreaWindow.MainWindowHandle)) * return null; * hash.Add(notificationAreaWindow.MainWindowHandle);*/ uint processId = 0; User32.GetWindowThreadProcessId(notificationAreaWindow.MainWindowHandle, out processId); if (processId == 0) { return(null); } if (processId == App.ProcessId) { return(null); } var fileName = User32.GetWindowModuleFileNameFromHandle(notificationAreaWindow.MainWindowHandle); if (fileName.ToLower().EndsWith("explorer.exe")) { return(null); } var window = new ApplicationWindow((int)processId, fileName, notificationAreaWindow); return(window); }
private void Ping(object sender, ElapsedEventArgs e) { // var process = Process.GetProcessesByName("Pandora").First(); var _ToolbarWindowHandle = GetSystemTrayHandle(); uint count = User32.SendMessage(_ToolbarWindowHandle, TB.BUTTONCOUNT, 0, 0); for (int i = 0; i < count; i++) { TBBUTTON tbButton = new TBBUTTON(); string text = string.Empty; IntPtr ipWindowHandle = IntPtr.Zero; bool b = GetTBButton(_ToolbarWindowHandle, i, ref tbButton, ref text, ref ipWindowHandle); if (text.StartsWith("Pandora")) { UpdateCurrentSong(text); } } }
public static extern void SendMessage(IntPtr hWnd, int msg, int wParam, ref TBBUTTON lParam);
//タスクトレイアイコンのクリック処理 public static bool ClickTasktrayIcon(string tooltip) { const string TRAY_WINDOW = "Shell_TrayWnd"; const string TRAY_NOTIFYWINDOW = "TrayNotifyWnd"; const string TRAY_PAGER = "SysPager"; const string TOOLBAR_CONTROL = "ToolbarWindow32"; //タスクバーのハンドル取得 var taskbarWin = FindWindow(TRAY_WINDOW, null); if (taskbarWin.Equals(IntPtr.Zero)) return false; //通知領域のハンドル取得 var trayWin = FindWindowEx(taskbarWin, IntPtr.Zero, TRAY_NOTIFYWINDOW, null); if (trayWin.Equals(IntPtr.Zero)) return false; //SysPagerの有無確認。(XP/2000はSysPagerあり) var tempWin = FindWindowEx(trayWin, IntPtr.Zero, TRAY_PAGER, null); if (tempWin.Equals(IntPtr.Zero)) tempWin = trayWin; //タスクトレイがツールバーで出来ているか確認 // → ツールバーでなければ終了 var toolWin = FindWindowEx(tempWin, IntPtr.Zero, TOOLBAR_CONTROL, null); if (toolWin.Equals(IntPtr.Zero)) return false; //タスクトレイのプロセス(Explorer)を取得し、外部から参照するために開く int expPid = 0; GetWindowThreadProcessId(toolWin, out expPid); var hProc = OpenProcess(ProcessAccess.VMOperation | ProcessAccess.VMRead | ProcessAccess.VMWrite, false, expPid); if (hProc.Equals(IntPtr.Zero)) return false; //プロセスを閉じるためにtry-finally try { var tbButtonLocal = new TBBUTTON(); //本プロセス内のタスクバーボタン情報作成(サイズ特定でのみ使用) //Explorer内のタスクバーボタン格納メモリ確保 var ptbSysButton = VirtualAllocEx(hProc, IntPtr.Zero, (IntPtr)Marshal.SizeOf(tbButtonLocal), AllocationTypes.Reserve | AllocationTypes.Commit, MemoryProtectionTypes.ReadWrite); if (ptbSysButton.Equals(IntPtr.Zero)) return false; //メモリ確保失敗 try { var tbButtonInfoLocal = new TBBUTTONINFO(); //本プロセス内ツールバーボタン詳細情報作成 //Explorer内のタスクバーボタン詳細情報格納メモリ確保 var ptbSysInfo = VirtualAllocEx(hProc, IntPtr.Zero, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), AllocationTypes.Reserve | AllocationTypes.Commit, MemoryProtectionTypes.ReadWrite); if (ptbSysInfo.Equals(IntPtr.Zero)) return false; //メモリ確保失敗 try { const int titleSize = 256; //Tooltip文字列長 var title = ""; //Tooltip文字列 //共有メモリにTooltip読込メモリ確保 var pszTitle = Marshal.AllocCoTaskMem(titleSize); if (pszTitle.Equals(IntPtr.Zero)) return false; //メモリ確保失敗 try { //Explorer内にTooltip読込メモリ確保 var pszSysTitle = VirtualAllocEx(hProc, IntPtr.Zero, (IntPtr)titleSize, AllocationTypes.Reserve | AllocationTypes.Commit, MemoryProtectionTypes.ReadWrite); if (pszSysTitle.Equals(IntPtr.Zero)) return false; //メモリ確保失敗 try { //通知領域ボタン数取得 var iCount = (int)SendMessage(toolWin, (int)Sm_Message.TB_BUTTONCOUNT, new IntPtr(0), new IntPtr(0)); //左から順に情報取得 for (var i = 0; i < iCount; i++) { var dwBytes = 0; //読み書きバイト数 var tbButtonLocal2 = new TBBUTTON(); //ボタン情報 var tbButtonInfoLocal2 = new TBBUTTONINFO(); //ボタン詳細情報 //共有メモリにボタン情報読込メモリ確保 var ptrLocal = Marshal.AllocCoTaskMem(Marshal.SizeOf(tbButtonLocal)); if (ptrLocal.Equals(IntPtr.Zero)) return false; //メモリ確保失敗 try { Marshal.StructureToPtr(tbButtonLocal, ptrLocal, true); //共有メモリ初期化 //ボタン情報取得(idCommandを取得するため) SendMessage( toolWin, (int)Sm_Message.TB_GETBUTTON, new IntPtr(i), ptbSysButton); //Explorer内のメモリを共有メモリに読み込み ReadProcessMemory( hProc, ptbSysButton, ptrLocal, (IntPtr)Marshal.SizeOf(tbButtonLocal), out dwBytes); //共有メモリの内容を構造体に変換 tbButtonLocal2 = (TBBUTTON)Marshal.PtrToStructure( ptrLocal, typeof(TBBUTTON)); } finally { Marshal.FreeCoTaskMem(ptrLocal); //共有メモリ解放 } //ボタン詳細情報を取得するためのマスク等を設定 tbButtonInfoLocal.cbSize = Marshal.SizeOf(tbButtonInfoLocal); tbButtonInfoLocal.dwMask = (int)(ToolbarButtonMask.TBIF_COMMAND | ToolbarButtonMask.TBIF_LPARAM | ToolbarButtonMask.TBIF_TEXT); tbButtonInfoLocal.pszText = pszSysTitle; //Tooltip書き込み先領域 tbButtonInfoLocal.cchText = titleSize; //マスク設定等をExplorerのメモリへ書き込み WriteProcessMemory( hProc, ptbSysInfo, ref tbButtonInfoLocal, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), out dwBytes); //ボタン詳細情報取得 SendMessage( toolWin, (int)Sm_Message.TB_GETBUTTONINFO, tbButtonLocal2.idCommand, ptbSysInfo); //共有メモリにボタン詳細情報を読み込む領域確保 var ptrInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(tbButtonInfoLocal)); if (ptrInfo.Equals(IntPtr.Zero)) return false; //共有メモリ確保失敗 try { Marshal.StructureToPtr(tbButtonInfoLocal, ptrInfo, true); //共有メモリ初期化 //Explorer内のメモリを共有メモリに読み込み ReadProcessMemory( hProc, ptbSysInfo, ptrInfo, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), out dwBytes); //共有メモリの内容を構造体に変換 tbButtonInfoLocal2 = (TBBUTTONINFO)Marshal.PtrToStructure( ptrInfo, typeof(TBBUTTONINFO)); } finally { Marshal.FreeCoTaskMem(ptrInfo); //共有メモリ解放 } //Tooltipの内容をExplorer内のメモリから共有メモリへ読込 ReadProcessMemory(hProc, pszSysTitle, pszTitle, (IntPtr)titleSize, out dwBytes); //ローカル変数へ変換 title = Marshal.PtrToStringAnsi(pszTitle, titleSize); //Tooltipが指定文字列を含んでいればクリック if (title.Contains(tooltip)) { //PostMessageでクリックを送るために、ボタン詳細情報のlParamでポイントされているTRAYNOTIFY情報が必要 var tNotify = new TRAYNOTIFY(); var tNotify2 = new TRAYNOTIFY(); //共有メモリ確保 var ptNotify = Marshal.AllocCoTaskMem(Marshal.SizeOf(tNotify)); if (ptNotify.Equals(IntPtr.Zero)) return false; //メモリ確保失敗 try { Marshal.StructureToPtr(tNotify, ptNotify, true); //初期化 //lParamのメモリを読込 ReadProcessMemory( hProc, tbButtonInfoLocal2.lParam, ptNotify, (IntPtr)Marshal.SizeOf(tNotify), out dwBytes); //構造体へ変換 tNotify2 = (TRAYNOTIFY) Marshal.PtrToStructure( ptNotify, typeof(TRAYNOTIFY)); } finally { Marshal.FreeCoTaskMem(ptNotify); //共有メモリ解放 } //クリックするためには通知領域がアクティブでなければならない SetForegroundWindow(tNotify2.hWnd); //左クリック PostMessage(tNotify2.hWnd, tNotify2.uCallbackMessage, (IntPtr)tNotify2.uID, (IntPtr)PM_Message.WM_LBUTTONDOWN); PostMessage(tNotify2.hWnd, tNotify2.uCallbackMessage, (IntPtr)tNotify2.uID, (IntPtr)PM_Message.WM_LBUTTONUP); return true; } } return false; //該当なし } finally { VirtualFreeEx(hProc, pszSysTitle, (IntPtr)titleSize, MemoryFreeTypes.Release); //メモリ解放 } } finally { Marshal.FreeCoTaskMem(pszTitle); //共有メモリ解放 } } finally { VirtualFreeEx(hProc, ptbSysInfo, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), MemoryFreeTypes.Release); //メモリ解放 } } finally { VirtualFreeEx(hProc, ptbSysButton, (IntPtr)Marshal.SizeOf(tbButtonLocal), MemoryFreeTypes.Release); //メモリ解放 } } finally { CloseHandle(hProc); //Explorerのプロセス閉じる } }
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, ref TBBUTTON lParam);
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, out TBBUTTON lpBuffer, int dwSize, out int lpNumberOfBytesRead);
// TODO-Linux: Implement if needed public static int SendMessage(IntPtr hWnd, int msg, int wParam, ref TBBUTTON lParam) { Console.WriteLine("Warning using unimplemented method SendMessage"); return 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; } } Kernel32.VirtualFreeEx( hProcess, ipRemoteBuffer, UIntPtr.Zero, MemAllocationType.RELEASE); Kernel32.CloseHandle(hProcess); return(true); }
//タスクトレイアイコンのクリック処理 public static bool ClickTasktrayIcon(string tooltip) { const string TRAY_WINDOW = "Shell_TrayWnd"; const string TRAY_NOTIFYWINDOW = "TrayNotifyWnd"; const string TRAY_PAGER = "SysPager"; const string TOOLBAR_CONTROL = "ToolbarWindow32"; //タスクバーのハンドル取得 var taskbarWin = FindWindow(TRAY_WINDOW, null); if (taskbarWin.Equals(IntPtr.Zero)) { return(false); } //通知領域のハンドル取得 var trayWin = FindWindowEx(taskbarWin, IntPtr.Zero, TRAY_NOTIFYWINDOW, null); if (trayWin.Equals(IntPtr.Zero)) { return(false); } //SysPagerの有無確認。(XP/2000はSysPagerあり) var tempWin = FindWindowEx(trayWin, IntPtr.Zero, TRAY_PAGER, null); if (tempWin.Equals(IntPtr.Zero)) { tempWin = trayWin; } //タスクトレイがツールバーで出来ているか確認 // → ツールバーでなければ終了 var toolWin = FindWindowEx(tempWin, IntPtr.Zero, TOOLBAR_CONTROL, null); if (toolWin.Equals(IntPtr.Zero)) { return(false); } //タスクトレイのプロセス(Explorer)を取得し、外部から参照するために開く int expPid = 0; GetWindowThreadProcessId(toolWin, out expPid); var hProc = OpenProcess(ProcessAccess.VMOperation | ProcessAccess.VMRead | ProcessAccess.VMWrite, false, expPid); if (hProc.Equals(IntPtr.Zero)) { return(false); } //プロセスを閉じるためにtry-finally try { var tbButtonLocal = new TBBUTTON(); //本プロセス内のタスクバーボタン情報作成(サイズ特定でのみ使用) //Explorer内のタスクバーボタン格納メモリ確保 var ptbSysButton = VirtualAllocEx(hProc, IntPtr.Zero, (IntPtr)Marshal.SizeOf(tbButtonLocal), AllocationTypes.Reserve | AllocationTypes.Commit, MemoryProtectionTypes.ReadWrite); if (ptbSysButton.Equals(IntPtr.Zero)) { return(false); //メモリ確保失敗 } try { var tbButtonInfoLocal = new TBBUTTONINFO(); //本プロセス内ツールバーボタン詳細情報作成 //Explorer内のタスクバーボタン詳細情報格納メモリ確保 var ptbSysInfo = VirtualAllocEx(hProc, IntPtr.Zero, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), AllocationTypes.Reserve | AllocationTypes.Commit, MemoryProtectionTypes.ReadWrite); if (ptbSysInfo.Equals(IntPtr.Zero)) { return(false); //メモリ確保失敗 } try { const int titleSize = 256; //Tooltip文字列長 var title = ""; //Tooltip文字列 //共有メモリにTooltip読込メモリ確保 var pszTitle = Marshal.AllocCoTaskMem(titleSize); if (pszTitle.Equals(IntPtr.Zero)) { return(false); //メモリ確保失敗 } try { //Explorer内にTooltip読込メモリ確保 var pszSysTitle = VirtualAllocEx(hProc, IntPtr.Zero, (IntPtr)titleSize, AllocationTypes.Reserve | AllocationTypes.Commit, MemoryProtectionTypes.ReadWrite); if (pszSysTitle.Equals(IntPtr.Zero)) { return(false); //メモリ確保失敗 } try { //通知領域ボタン数取得 var iCount = (int)SendMessage(toolWin, (int)Sm_Message.TB_BUTTONCOUNT, new IntPtr(0), new IntPtr(0)); //左から順に情報取得 for (var i = 0; i < iCount; i++) { var dwBytes = 0; //読み書きバイト数 var tbButtonLocal2 = new TBBUTTON(); //ボタン情報 var tbButtonInfoLocal2 = new TBBUTTONINFO(); //ボタン詳細情報 //共有メモリにボタン情報読込メモリ確保 var ptrLocal = Marshal.AllocCoTaskMem(Marshal.SizeOf(tbButtonLocal)); if (ptrLocal.Equals(IntPtr.Zero)) { return(false); //メモリ確保失敗 } try { Marshal.StructureToPtr(tbButtonLocal, ptrLocal, true); //共有メモリ初期化 //ボタン情報取得(idCommandを取得するため) SendMessage( toolWin, (int)Sm_Message.TB_GETBUTTON, new IntPtr(i), ptbSysButton); //Explorer内のメモリを共有メモリに読み込み ReadProcessMemory( hProc, ptbSysButton, ptrLocal, (IntPtr)Marshal.SizeOf(tbButtonLocal), out dwBytes); //共有メモリの内容を構造体に変換 tbButtonLocal2 = (TBBUTTON)Marshal.PtrToStructure( ptrLocal, typeof(TBBUTTON)); } finally { Marshal.FreeCoTaskMem(ptrLocal); //共有メモリ解放 } //ボタン詳細情報を取得するためのマスク等を設定 tbButtonInfoLocal.cbSize = Marshal.SizeOf(tbButtonInfoLocal); tbButtonInfoLocal.dwMask = (int)(ToolbarButtonMask.TBIF_COMMAND | ToolbarButtonMask.TBIF_LPARAM | ToolbarButtonMask.TBIF_TEXT); tbButtonInfoLocal.pszText = pszSysTitle; //Tooltip書き込み先領域 tbButtonInfoLocal.cchText = titleSize; //マスク設定等をExplorerのメモリへ書き込み WriteProcessMemory( hProc, ptbSysInfo, ref tbButtonInfoLocal, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), out dwBytes); //ボタン詳細情報取得 SendMessage( toolWin, (int)Sm_Message.TB_GETBUTTONINFO, tbButtonLocal2.idCommand, ptbSysInfo); //共有メモリにボタン詳細情報を読み込む領域確保 var ptrInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(tbButtonInfoLocal)); if (ptrInfo.Equals(IntPtr.Zero)) { return(false); //共有メモリ確保失敗 } try { Marshal.StructureToPtr(tbButtonInfoLocal, ptrInfo, true); //共有メモリ初期化 //Explorer内のメモリを共有メモリに読み込み ReadProcessMemory( hProc, ptbSysInfo, ptrInfo, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), out dwBytes); //共有メモリの内容を構造体に変換 tbButtonInfoLocal2 = (TBBUTTONINFO)Marshal.PtrToStructure( ptrInfo, typeof(TBBUTTONINFO)); } finally { Marshal.FreeCoTaskMem(ptrInfo); //共有メモリ解放 } //Tooltipの内容をExplorer内のメモリから共有メモリへ読込 ReadProcessMemory(hProc, pszSysTitle, pszTitle, (IntPtr)titleSize, out dwBytes); //ローカル変数へ変換 title = Marshal.PtrToStringAnsi(pszTitle, titleSize); //Tooltipが指定文字列を含んでいればクリック if (title.Contains(tooltip)) { //PostMessageでクリックを送るために、ボタン詳細情報のlParamでポイントされているTRAYNOTIFY情報が必要 var tNotify = new TRAYNOTIFY(); var tNotify2 = new TRAYNOTIFY(); //共有メモリ確保 var ptNotify = Marshal.AllocCoTaskMem(Marshal.SizeOf(tNotify)); if (ptNotify.Equals(IntPtr.Zero)) { return(false); //メモリ確保失敗 } try { Marshal.StructureToPtr(tNotify, ptNotify, true); //初期化 //lParamのメモリを読込 ReadProcessMemory( hProc, tbButtonInfoLocal2.lParam, ptNotify, (IntPtr)Marshal.SizeOf(tNotify), out dwBytes); //構造体へ変換 tNotify2 = (TRAYNOTIFY) Marshal.PtrToStructure( ptNotify, typeof(TRAYNOTIFY)); } finally { Marshal.FreeCoTaskMem(ptNotify); //共有メモリ解放 } //クリックするためには通知領域がアクティブでなければならない SetForegroundWindow(tNotify2.hWnd); //左クリック PostMessage(tNotify2.hWnd, tNotify2.uCallbackMessage, (IntPtr)tNotify2.uID, (IntPtr)PM_Message.WM_LBUTTONDOWN); PostMessage(tNotify2.hWnd, tNotify2.uCallbackMessage, (IntPtr)tNotify2.uID, (IntPtr)PM_Message.WM_LBUTTONUP); return(true); } } return(false); //該当なし } finally { VirtualFreeEx(hProc, pszSysTitle, (IntPtr)titleSize, MemoryFreeTypes.Release); //メモリ解放 } } finally { Marshal.FreeCoTaskMem(pszTitle); //共有メモリ解放 } } finally { VirtualFreeEx(hProc, ptbSysInfo, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), MemoryFreeTypes.Release); //メモリ解放 } } finally { VirtualFreeEx(hProc, ptbSysButton, (IntPtr)Marshal.SizeOf(tbButtonLocal), MemoryFreeTypes.Release); //メモリ解放 } } finally { CloseHandle(hProc); //Explorerのプロセス閉じる } }
public static unsafe bool GetTBButton(IntPtr hToolbar, int i, ref TBBUTTON tbButton, ref string text, ref IntPtr ipWindowHandle, out NotificationAreaWindow notificationAreaWindow) { notificationAreaWindow = new NotificationAreaWindow(); // One page const int BUFFER_SIZE = 0x1000; var localBuffer = new byte[BUFFER_SIZE]; uint processId = 0; uint threadId = User32.GetWindowThreadProcessId(hToolbar, out processId); var hProcess = Kernel32.OpenProcess(ProcessRights.ALL_ACCESS, false, processId); if (hProcess == IntPtr.Zero) { Debug.Assert(false); return(false); } var 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) { var ipTbButton = new IntPtr(pTbButton); var b = (int)User32.SendMessage(hToolbar, TB.GETBUTTON, (IntPtr)i, ipRemoteBuffer); if (b == 0) { Debug.Assert(false); return(false); } var dwBytesRead = 0; var ipBytesRead = new IntPtr(&dwBytesRead); var 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) { var ipLocalBuffer = new IntPtr(pLocalBuffer); var chars = (int)User32.SendMessage(hToolbar, TB.GETBUTTONTEXTW, (IntPtr)tbButton.idCommand, ipRemoteBuffer); if (chars == -1) { Debug.Assert(false); return(false); } var dwBytesRead = 0; var ipBytesRead = new IntPtr(&dwBytesRead); var 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; } } // window handle fixed(byte *pLocalBuffer = localBuffer) { var ipLocalBuffer = new IntPtr(pLocalBuffer); var dwBytesRead = 0; var ipBytesRead = new IntPtr(&dwBytesRead); var ipRemoteData = tbButton.dwData; var b4 = Kernel32.ReadProcessMemory( hProcess, ipRemoteData, ipLocalBuffer, new UIntPtr(4), ipBytesRead); if (!b4) { Debug.Assert(false); return(false); } if (dwBytesRead != 4) { Debug.Assert(false); return(false); } var iWindowHandle = BitConverter.ToInt32(localBuffer, 0); if (iWindowHandle == -1) { Debug.Assert(false); } //return false; } ipWindowHandle = new IntPtr(iWindowHandle); } var rect = default(RECT); uint dwTrayProcessID = 0; GetWindowThreadProcessId(hToolbar, out dwTrayProcessID); if (dwTrayProcessID <= 0) { return(false); } var hTrayProc = Kernel32.OpenProcess(PROCESS_ALL_ACCESS, 0, dwTrayProcessID); if (hTrayProc == IntPtr.Zero) { return(false); } var lpData = Kernel32.VirtualAllocEx(hTrayProc, IntPtr.Zero, Marshal.SizeOf(tbButton.GetType()), MEM_COMMIT, PAGE_READWRITE); if (lpData == IntPtr.Zero) { Kernel32.CloseHandle(hTrayProc); return(false); } // Show tray icon if hidden //if ((tbButton.fsState & (byte)TBSTATE_HIDDEN) == (byte)TBSTATE_HIDDEN) SendMessage(hToolbar, TB_HIDEBUTTON, tbButton.idCommand, 1); // Get rectangle of tray icon var dwBytesRead2 = -1; var rectNotifyIcon = new RECT(0, 0, 0, 0); var byteBuffer3 = new byte[Marshal.SizeOf(rectNotifyIcon.GetType())]; SendMessage(hToolbar, TB.GETITEMRECT, tbButton.idCommand, lpData); Kernel32.ReadProcessMemory(hTrayProc, lpData, byteBuffer3, Marshal.SizeOf(rectNotifyIcon.GetType()), out dwBytesRead2); if (dwBytesRead2 < Marshal.SizeOf(rectNotifyIcon.GetType())) { return(false); } var ptrOut2 = Marshal.AllocHGlobal(Marshal.SizeOf(rectNotifyIcon.GetType())); Marshal.Copy(byteBuffer3, 0, ptrOut2, byteBuffer3.Length); rectNotifyIcon = (RECT)Marshal.PtrToStructure(ptrOut2, typeof(RECT)); //MapWindowPoints(hToolbar, IntPtr.Zero, ref rectNotifyIcon, 2); // Display coordinates var c = GetRect(hToolbar); System.Diagnostics.Debug.Print("{4} ICONS COORDINATES ARE: Top: {0}, Left: {1}, Bottom: {2}, Right: {3}", rectNotifyIcon.Top - c.Top, rectNotifyIcon.Left - c.Left, (rectNotifyIcon.Bottom - c.Bottom) + rectNotifyIcon.Height, rectNotifyIcon.Right - c.Right, text); Kernel32.VirtualFreeEx(hTrayProc, lpData, UIntPtr.Zero, MEM_RELEASE); Kernel32.CloseHandle(hTrayProc); rect = new RECT( rectNotifyIcon.Left - c.Left, rectNotifyIcon.Top - c.Top, rectNotifyIcon.Right - c.Right, (rectNotifyIcon.Bottom - c.Bottom) + rectNotifyIcon.Height); Kernel32.VirtualFreeEx( hProcess, ipRemoteBuffer, UIntPtr.Zero, MemAllocationType.RELEASE); Kernel32.CloseHandle(hProcess); notificationAreaWindow = new NotificationAreaWindow() { TBBUTTON = tbButton, MainWindowHandle = ipWindowHandle, ToolBarIconHandle = hToolbar, Text = text, RECT = rect }; return(true); }
protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); //设置imgList SendMessage(this.Handle, 0x430, IntPtr.Zero, imgList.Handle);//TB_SETIMAGELIST //准备添加按钮 int btnStructSize = Marshal.SizeOf(typeof(TBBUTTON)); SendMessage(this.Handle, 0x41E, new IntPtr(btnStructSize), IntPtr.Zero);//TB_BUTTONSTRUCTSIZE,必须在添加按钮前 //构建按钮信息 TBBUTTON btnStruct = new TBBUTTON { //iBitmap = 0, //idCommand = 0, fsState = 0x4, //TBSTATE_ENABLED iString = SendMessage(this.Handle, 0x44D, 0, this.Text + '\0')//TB_ADDSTRING }; if (this.isToggleMode) { btnStruct.fsStyle = 0x2; }//BTNS_CHECK。作为切换按钮时 IntPtr btnStructStart = IntPtr.Zero; try { btnStructStart = Marshal.AllocHGlobal(btnStructSize);//在非托管区创建一个指针 Marshal.StructureToPtr(btnStruct, btnStructStart, true);//把结构体塞到上述指针 //添加按钮 SendMessage(this.Handle, 0x444, new IntPtr(1)/*按钮数量*/, btnStructStart);//TB_ADDBUTTONS。从指针取按钮信息 //设置按钮尺寸刚好为ToolBar尺寸 AdjustButtonSize(); } finally { if (btnStructStart != IntPtr.Zero) { Marshal.FreeHGlobal(btnStructStart); } } }