Files
ShrlAlgoToolkit/ShrlAlgo.Toolkit.Revit/Helpers/KeyIntPtrHelper.cs

681 lines
19 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Interop;
using Autodesk.Windows;
namespace ShrlAlgo.Toolkit.Revit.Helpers;
public class KeyIntPtrHelper
{
public delegate bool CallBack(IntPtr hwnd, int lParam);
public delegate bool EnumWindowsProc(IntPtr hWnd, int lParam);
private static void CompleteMultiSelection()
{
var rvtwindow = ComponentManager.ApplicationWindow;
var list = new List<IntPtr>();
var flag = EnumChildWindows(
rvtwindow,
(hwnd, l) =>
{
var windowText = new StringBuilder(200);
_ = GetWindowText(hwnd, windowText, windowText.Capacity);
var className = new StringBuilder(200);
_ = GetClassName(hwnd, className, className.Capacity);
if (
(
windowText.ToString().Equals("完成", StringComparison.Ordinal)
|| windowText.ToString().Equals("Finish", StringComparison.Ordinal)
) && className.ToString().Contains("Button")
)
{
list.Add(hwnd);
return false;
}
return true;
},
new IntPtr(0)
);
var complete = list.FirstOrDefault();
_ = PostMessage(complete, 245, 0, 0);
}
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
private static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
private static extern bool DeleteObject(IntPtr hObject);
/// <summary>
/// 确定主窗口
/// </summary>
/// <param name="handles"></param>
/// <returns></returns>
private static IntPtr DetermineMainWindow(IReadOnlyList<IntPtr> handles)
{
IntPtr result;
if (handles == null || handles.Count <= 0)
{
result = IntPtr.Zero;
}
else
{
var intPtr = IntPtr.Zero;
if (handles.Count == 1)
{
intPtr = handles[0];
}
else
{
foreach (var intPtr2 in handles)
{
var windowTextLength = GetWindowTextLength(intPtr2);
if (windowTextLength != 0)
{
var stringBuilder = new StringBuilder(windowTextLength);
_ = GetWindowText(intPtr2, stringBuilder, windowTextLength + 1);
if (stringBuilder.ToString().ToLower().Contains("autodesk revit"))
{
intPtr = intPtr2;
break;
}
}
}
}
result = intPtr;
}
return result;
}
[DllImport("user32.dll", CharSet = CharSet.None, ExactSpelling = false)]
private static extern bool EnumChildWindows(IntPtr hwndParent, CallBack lpEnumFunc, IntPtr lParam);
[DllImport("user32.DLL")]
private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);
[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Unicode)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern int GetCurrentThreadId();
[DllImport("user32.dll")]
private static extern int GetKeyboardState(byte[] lpKeyState);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
private static extern int GetKeyNameText(int lParam, [Out] StringBuilder lpString, int nSize);
[DllImport("user32.dll")]
private static extern short GetKeyState(short nVirtKey);
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
private static extern IntPtr GetParent(IntPtr hWnd);
[DllImport("user32.DLL")]
private static extern IntPtr GetShellWindow();
[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, int revert);
[DllImport("user32.dll")]
private static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);
[DllImport("user32.dll")]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
private static extern IntPtr GetWindowLongPtr_1(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpText, int nCount);
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
[DllImport("user32.dll")]
private static extern bool IsChild(IntPtr hWndParent, IntPtr hWnd);
[DllImport("user32.DLL")]
private static extern bool IsWindowVisible(IntPtr hWnd);
/// <summary>
/// 键盘事件
/// </summary>
/// <param name="bVk">虚拟键值查询虚拟键值表</param>
/// <param name="bScan">扫描不设置为0</param>
/// <param name="dwFlags">按键状态选项按下为0如果为松开 则设置成2KEYEVENT_KEYUP</param>
/// <param name="dwExtraInfo">,一般为0</param>
[DllImport("user32.dll")]
private static extern void keybdEvent(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
/// <summary>
/// 虚拟按钮
/// </summary>
/// <param name="uCode"></param>
/// <param name="uMapType"></param>
/// <returns></returns>
[DllImport("user32.dll")]
private static extern uint MapVirtualKey(uint uCode, uint uMapType);
[DllImport("user32.dll")]
private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
/// <summary>
///发送消息
/// </summary>
/// <param name="hWnd"></param>
/// <param name="msg"></param>
/// <param name="wParam"></param>
/// <param name="lParam"></param>
/// <example>
/// <para>Press.PostMessage(_revit_window, (uint)Press.KEYBOARD_MSG.WM_KEYDOWN, (uint)System.Windows.Forms.Keys.Escape, 0);</para>
/// <para>Press.PostMessage(_revit_window, (uint)Press.KEYBOARD_MSG.WM_KEYDOWN, (uint)System.Windows.Forms.Keys.Escape, 0);</para></example>
/// <returns></returns>
[DllImport("user32.dll")]
private static extern bool PostMessage(IntPtr hWnd, uint msg, uint wParam, uint lParam);
[DllImport("user32.dll")]
private static extern IntPtr SetActiveWindow(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool SetWindowText(IntPtr hWnd, string lpString);
/// <summary>
/// 显示窗口
/// </summary>
/// <param name="hWnd"></param>
/// <param name="nCmdShow">0隐藏窗口1恢复窗口大小2最小化窗口3最大化窗口</param>
/// <returns></returns>
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
private static extern int ToUnicode(
int wVirtKey,
int wScanCode,
byte[] lpKeyState,
[MarshalAs(UnmanagedType.LPWStr)][Out] StringBuilder pwszBuff,
int cchBuff,
int wFlags
);
/// <summary>
/// 执行Esc两次退出Revit选择
/// </summary>
public static void RaiseEscTwice()
{
SetForegroundWindow(ComponentManager.ApplicationWindow);
keybdEvent(27, 0, 0, 0);
keybdEvent(27, 0, 2, 0);
//keybdEvent(0x1B, 0, 0, 0);
//keybdEvent(0x1B, 0, 0, 0);
}
/// <summary>
/// 查找内容
/// </summary>
/// <param name="hwndParent"></param>
/// <param name="hwndChildAfter"></param>
/// <param name="lpszClass"></param>
/// <param name="lpszWindow"></param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindowEx(
IntPtr hwndParent,
IntPtr hwndChildAfter,
string lpszClass,
string lpszWindow
);
public static IntPtr GetMainWindow(int pid)
{
var shellWindow = GetShellWindow();
var windowsForPid = new List<IntPtr>();
_ = EnumWindows(
(hWnd, _) =>
{
if (hWnd == shellWindow) { }
else
{
if (!IsWindowVisible(hWnd))
{
return true;
}
GetWindowThreadProcessId(hWnd, out var num);
if (num != (ulong)pid)
{
return true;
}
var parent = GetParent(hWnd);
if (parent == IntPtr.Zero)
{
windowsForPid.Add(hWnd);
}
}
return true;
},
0
);
return DetermineMainWindow(windowsForPid);
}
public static IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex)
{
return IntPtr.Size == 8 ? GetWindowLongPtr_1(hWnd, nIndex) : new IntPtr(GetWindowLong(hWnd, nIndex));
}
public static void HideWindow(string winName)
{
var parenthWndldsl = FindWindow(null, winName);
if (!parenthWndldsl.Equals(IntPtr.Zero))
{
_ = ShowWindow(parenthWndldsl, 0);
}
}
public static bool IsVisible(string winName)
{
var parenthWndldsl = FindWindow(null, winName);
return !parenthWndldsl.Equals(IntPtr.Zero);
}
/// <summary>
/// 提交一系列按钮
/// </summary>
/// <param name="revitHandle"></param>
/// <param name="command">快捷键命令</param>
public static void Keys(IntPtr revitHandle, string command)
{
//IntPtr revitHandle = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
foreach (var letter in command)
{
OneKey(revitHandle, letter);
}
}
/// <summary>
/// 提交单个按键
/// </summary>
/// <param name="handle">窗口句柄</param>
/// <param name="letter"></param>
public static void OneKey(IntPtr handle, char letter)
{
var scanCode = MapVirtualKey(letter, (uint)MvkMapType.VkeyToScancode);
var keyDownCode = (uint)WhKeyboardLparam.Keydown | (scanCode << 16);
var keyUpCode = (uint)WhKeyboardLparam.Keyup | (scanCode << 16);
PostMessage(handle, (uint)KeyboardMsg.WmKeydown, letter, keyDownCode);
PostMessage(handle, (uint)KeyboardMsg.WmKeyup, letter, keyUpCode);
}
public static bool RestoreWindow(IntPtr hWnd)
{
return ShowWindow(hWnd, 1);
}
public static void SendKeys(IntPtr proc, byte bVk)
{
SetActiveWindow(proc);
SetForegroundWindow(proc);
//keybd_event(27, 0, 0, 0);
//keybd_event(27, 0, 2, 0);
keybdEvent(bVk, 0, 0, 0);
keybdEvent(bVk, 0, 2, 0);
keybdEvent(bVk, 0, 0, 0);
keybdEvent(bVk, 0, 2, 0);
}
public static void SetAsOwner(IntPtr mainHandler, Window childWindow)
{
new WindowInteropHelper(childWindow).Owner = mainHandler;
}
public static void ShowAndActive(string winname)
{
var parenthWndldsl = FindWindow(null, winname);
if (!parenthWndldsl.Equals(IntPtr.Zero))
{
ShowWindow(parenthWndldsl, 1);
SetActiveWindow(parenthWndldsl);
}
}
/// <summary>
/// 键盘消息
/// </summary>
public enum KeyboardMsg : uint
{
WmKeydown = 0x100,
WmKeyup = 0x101
}
private enum MvkMapType : uint
{
VkeyToScancode = 0,
ScancodeToVkey = 1,
VkeyToChar = 2,
ScancodeToLrVkey = 3
}
private enum WhKeyboardLparam : uint
{
Keydown = 0x00000001,
Keyup = 0xC0000001
}
#region Win32 API Hook
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
private const int VbWH_MOUSE_LL = 14;
private const int VbWM_LBUTTONDOWN = 0x0201;
private static IntPtr _hookID = IntPtr.Zero;
private static IntPtr SetHook(HookProc proc)
{
using var curProcess = Process.GetCurrentProcess();
using var curModule = curProcess.MainModule;
return SetWindowsHookEx(VbWH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
}
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr MouseHookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)VbWM_LBUTTONDOWN)
{
MessageBox.Show("Left button down");
CompleteMultiSelection();
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
public static void MouseLeftButtonAction(Action action)
{
_hookID = SetHook(MouseHookCallback);
action();
UnhookWindowsHookEx(_hookID);
}
#endregion
#region Keys
public const byte VbKey0 = 48;
public const byte VbKey1 = 49;
public const byte VbKey2 = 50;
public const byte VbKey3 = 51;
public const byte VbKey4 = 52;
public const byte VbKey5 = 53;
public const byte VbKey6 = 54;
public const byte VbKey7 = 55;
public const byte VbKey8 = 56;
public const byte VbKey9 = 57;
public const byte VbKeyA = 65;
public const byte VbKeyAdd = 107;
public const byte VbKeyAlt = 18;
public const byte VbKeyB = 66;
public const byte VbKeyBack = 8;
public const byte VbKeyC = 67;
public const byte VbKeyCancel = 3;
public const byte VbKeyCapital = 20;
public const byte VbKeyClear = 12;
public const byte VbKeyControl = 17;
public const byte VbKeyD = 68;
public const byte VbKeyDecimal = 110;
public const byte VbKeyDelete = 46;
public const byte VbKeyDivide = 111;
public const byte VbKeyDown = 40;
public const byte VbKeyE = 69;
public const byte VbKeyEnd = 35;
public const byte VbKeyEscape = 27;
public const byte VbKeyExecute = 43;
public const byte VbKeyF = 70;
public const byte VbKeyF1 = 112;
public const byte VbKeyF10 = 121;
public const byte VbKeyF11 = 122;
public const byte VbKeyF12 = 123;
public const byte VbKeyF2 = 113;
public const byte VbKeyF3 = 114;
public const byte VbKeyF4 = 115;
public const byte VbKeyF5 = 116;
public const byte VbKeyF6 = 117;
public const byte VbKeyF7 = 118;
public const byte VbKeyF8 = 119;
public const byte VbKeyF9 = 120;
public const byte VbKeyG = 71;
public const byte VbKeyH = 72;
public const byte VbKeyHelp = 47;
public const byte VbKeyHome = 36;
public const byte VbKeyI = 73;
public const byte VbKeyJ = 74;
public const byte VbKeyK = 75;
public const byte VbKeyL = 76;
public const byte VbKeyLButton = 1;
public const byte VbKeyLeft = 37;
public const byte VbKeyM = 77;
public const byte VbKeyMButton = 4;
public const byte VbKeyMenu = 18;
public const byte VbKeyMultiply = 106;
public const byte VbKeyN = 78;
public const byte VbKeyNumlock = 144;
public const byte VbKeyNumpad0 = 96;
public const byte VbKeyNumpad1 = 97;
public const byte VbKeyNumpad2 = 98;
public const byte VbKeyNumpad3 = 99;
public const byte VbKeyNumpad4 = 100;
public const byte VbKeyNumpad5 = 101;
public const byte VbKeyNumpad6 = 102;
public const byte VbKeyNumpad7 = 103;
public const byte VbKeyNumpad8 = 104;
public const byte VbKeyNumpad9 = 105;
public const byte VbKeyO = 79;
public const byte VbKeyP = 80;
public const byte VbKeyPageUp = 33;
public const byte VbKeyPause = 19;
public const byte VbKeyPrint = 42;
public const byte VbKeyQ = 81;
public const byte VbKeyR = 82;
public const byte VbKeyRButton = 2;
public const byte VbKeyReturn = 13;
public const byte VbKeyRight = 39;
public const byte VbKeyS = 83;
public const byte VbKeySelect = 41;
public const byte VbKeySeparator = 108;
public const byte VbKeyShift = 16;
public const byte VbKeySnapshot = 44;
public const byte VbKeySpace = 32;
public const byte VbKeySubtract = 109;
public const byte VbKeyT = 84;
public const byte VbKeyTab = 9;
public const byte VbKeyU = 85;
public const byte VbKeyUp = 38;
public const byte VbKeyV = 86;
public const byte VbKeyW = 87;
public const byte VbKeyX = 88;
public const byte VbKeyY = 89;
public const byte VbKeyZ = 90;
public const int WmChar = 258;
public const int WmClick = 245;
public const int WmClose = 16;
public const int WmDeadchar = 259;
public const int WmKeydown = 256;
public const int WmKeyup = 257;
public const int WmLbuttondblclk = 515;
public const int WmLbuttondown = 513;
public const int WmLbuttonup = 514;
public const int WmMbuttondblclk = 521;
public const int WmMbuttondown = 519;
public const int WmMbuttonup = 520;
public const int WmMousehwheel = 526;
public const int WmMousemove = 512;
public const int WmMousewheel = 522;
public const int WmRbuttondblclk = 518;
public const int WmRbuttonup = 517;
public const int WmSyschar = 262;
public const int WmSysdeadchar = 263;
public const int WmSyskeydown = 260;
public const int WmSyskeyup = 261;
public const int WmXbuttondblclk = 525;
public const int WmXbuttondown = 523;
public const int WmXbuttonup = 524;
#endregion
}