У меня есть окно в которое нужно посылать через функцию PostMessage строки текста, но проблема в том что например если я посылаю строку "ПРИВЕТ" то приходит "привет" либо "ghbdtn" в зависимости от расклада клавиатуры в окне. например если мне нужен символ ) приходит 9.
на Delphi Дело в том, что когда мы посылаем какие то сообщение окну, в данном случае мы отсылаем какой то символ, нужно обязательно воспользоваться функциями MapVirtualKey, OemKeyScan, чтобы потом в lParam, записать нужный нам скан-код клавиши. Следующий код реализует этот механизм, причем учитывается, даже нажатый shift, ctrl Code: procedure SendShift(H: HWnd; Down: Boolean); var vKey, ScanCode, wParam: Word; lParam: longint; begin vKey:= $10; ScanCode:= MapVirtualKey(vKey, 0); wParam:= vKey or ScanCode shl 8; lParam:= longint(ScanCode) shl 16 or 1; if not(Down) then lParam:= lParam or $C0000000; SendMessage(H, WM_KEYDOWN, vKey, lParam); end; procedure SendCtrl(H: HWnd; Down: Boolean); var vKey, ScanCode, wParam: Word; lParam: longint; begin vKey:= $11; ScanCode:= MapVirtualKey(vKey, 0); wParam:= vKey or ScanCode shl 8; lParam:= longint(ScanCode) shl 16 or 1; if not(Down) then lParam:= lParam or $C0000000; SendMessage(H, WM_KEYDOWN, vKey, lParam); end; procedure SendKey(H: Hwnd; Key: char); var vKey, ScanCode, wParam: Word; lParam, ConvKey: longint; Shift, Ctrl: boolean; begin ConvKey:= OemKeyScan(ord(Key)); Shift:= (ConvKey and $00020000) <> 0; Ctrl:= (ConvKey and $00040000) <> 0; ScanCode:= ConvKey and $000000FF or $FF00; vKey:= ord(Key); wParam:= vKey; lParam:= longint(ScanCode) shl 16 or 1; if Shift then SendShift(H, true); if Ctrl then SendCtrl(H, true); SendMessage(H, WM_KEYDOWN, vKey, lParam); SendMessage(H, WM_CHAR, vKey, lParam); lParam:= lParam or $C0000000; SendMessage(H, WM_KEYUP, vKey, lParam); if Shift then SendShift(H, false); if Ctrl then SendCtrl(H, false); end; ... В коде procedure SendingString(wnd_target: HWND; s: string); var i: integer; begin for i:=1 to length(s) do SendKey(wnd_target, s[i]); end; Переписать на С# я думаю не составит труда.
Я раньше изучал delphi только на простом уровне. Word shl 16 - не понятно что это + как вообще используется в переменной or или and.
Я вот начал переводить только не очень получается. Можете не много помочь тут сказано что к операндам типа int нельзя применять && ||. Code: [DllImport("user32")] public static extern int OemKeyScan(int wOemChar); [DllImport("user32", EntryPoint = "PostMessageA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] public static extern bool PostMessage(IntPtr hwnd, int wMsg, int wParam, int lParam); static byte ORD(char ch) { return System.Text.Encoding.ASCII.GetBytes(new char[] { ch })[0]; } static char CHR(byte code) { return System.Text.Encoding.ASCII.GetChars(new byte[] { code })[0]; } public static void SendKey(char Key) { ushort ScanCode, vKey, wParam; int lParam, ConvKey; bool Shift, Ctrl; ConvKey = OemKeyScan(ORD(Key)); ScanCode = (ConvKey && 0x000000FF) || 0xFF00; vKey = ORD(Key); wParam = vKey; lParam = (int)ScanCode << 16 || 1; if ((ConvKey && 0x00020000) != 0) SendShift(BotContro1l.mem.WindowHandle, true); if ((ConvKey && 0x00040000) != 0) SendCtrl(BotContro1l.mem.WindowHandle, true); PostMessage(BotContro1l.mem.WindowHandle, WM_KEYDOWN, vKey, lParam); PostMessage(BotContro1l.mem.WindowHandle, WM_CHAR, vKey, lParam); lParam = lParam || 0xC0000000; PostMessage(BotContro1l.mem.WindowHandle, WM_KEYUP, vKey, lParam); if ((ConvKey && 0x00020000) != 0) SendShift(BotContro1l.mem.WindowHandle, false); if ((ConvKey && 0x00040000) != 0) SendCtrl(BotContro1l.mem.WindowHandle, false); }
лучше бы промолчал. Херню несешь ололо, && || -> И, ИЛИ. нельзя применять -> В сферический вакууме нельзя немного пишется слитно
Вот класс который я составил: Code: class KeyboardHook { [DllImport("user32")] public static extern int OemKeyScan(int wOemChar); [DllImport("user32", EntryPoint = "PostMessageA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] public static extern bool PostMessage(IntPtr hwnd, int wMsg, int wParam, int lParam); [DllImport("user32.dll")] static extern uint MapVirtualKey(uint uCode, uint uMapType); static int WM_KEYDOWN = 0x0100; static int WM_KEYUP = 0x0101; static int WM_CHAR = 0x0102; static byte ORD(char ch) { return System.Text.Encoding.ASCII.GetBytes(new char[] { ch })[0]; } public static void SendShift(bool Down) { ushort vKey, ScanCode, wParam; int lParam; vKey = 0x10; ScanCode = MapVirtualKey(vKey, 0); wParam = vKey || ScanCode << 8; lParam = longint(ScanCode) << 16 || 1; if (!Down) { lParam = lParam || 0xC0000000; } PostMessage(BotContro1l.mem.WindowHandle, WM_KEYDOWN, vKey, lParam); } public static void SendCtrl(bool Down) { ushort vKey, ScanCode, wParam; int lParam; vKey = 0x11; ScanCode = MapVirtualKey(vKey, 0); wParam = vKey || ScanCode << 8; lParam = longint(ScanCode) << 16 || 1; if (!Down) { lParam = lParam || 0xC0000000; } PostMessage(BotContro1l.mem.WindowHandle, WM_KEYDOWN, vKey, lParam); } public static void SendKey(char Key) { ushort ScanCode, vKey, wParam; int lParam, ConvKey; bool Shift, Ctrl; ConvKey = OemKeyScan(ORD(Key)); ScanCode = (ConvKey && 0x000000FF) || 0xFF00; vKey = ORD(Key); wParam = vKey; lParam = (int)ScanCode << 16 || 1; if ((ConvKey && 0x00020000) != 0) SendShift(true); if ((ConvKey && 0x00040000) != 0) SendCtrl(true); PostMessage(BotContro1l.mem.WindowHandle, WM_KEYDOWN, vKey, lParam); PostMessage(BotContro1l.mem.WindowHandle, WM_CHAR, vKey, lParam); lParam = lParam || 0xC0000000; PostMessage(BotContro1l.mem.WindowHandle, WM_KEYUP, vKey, lParam); if ((ConvKey && 0x00020000) != 0) SendShift(false); if ((ConvKey && 0x00040000) != 0) SendCtrl(false); } public static void SendString(string s) { for (int i = 1; i != s.Length; i++) { SendKey(s[i]); } } } Проблема в том что Я не понимаю для чего в Deplhi используется в переменных and or и тп. И зачем по битовый снов используется. Кому не трудно распишите. Кто-нибудь может показать как эти строки на C# буду выглядеть? Code: Ctrl:= (ConvKey and $00040000) <> 0; wParam:= vKey or ScanCode shl 8; ScanCode:= ConvKey and $000000FF or $FF00;