Просмотр полной версии : ToASCII - C#
У меня есть окно в которое нужно посылать через функцию PostMessage строки текста, но проблема в том что например если я посылаю строку "ПРИВЕТ" то приходит "привет" либо "ghbdtn" в зависимости от расклада клавиатуры в окне. например если мне нужен символ ) приходит 9.
на Delphi
Дело в том, что когда мы посылаем какие то сообщение окну, в данном случае мы отсылаем какой то символ, нужно обязательно воспользоваться функциями MapVirtualKey, OemKeyScan, чтобы потом в lParam, записать нужный нам скан-код клавиши. Следующий код реализует этот механизм, причем учитывается, даже нажатый shift, ctrl
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.
shl - логический сдвиг влево (на с++ = <<)
shr - соответвенно вправо (>>)
Word shl 16 = word << 16
shl - логический сдвиг влево (на с++ = <<)
shr - соответвенно вправо (>>)
Word shl 16 = word << 16
Я про то что вообще за тип Word и зачем делать сдвиг?
Короче надо с кодировкой разбираться
MSDN class
System.Text.Encoding
Я вот начал переводить только не очень получается. Можете не много помочь тут сказано что к операндам типа int нельзя применять && ||.
[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);
}
Короче надо с кодировкой разбираться
MSDN class
System.Text.Encoding
лучше бы промолчал. Херню несешь
Я вот начал переводить только не очень получается. Можете не много помочь тут сказано что к операндам типа int нельзя применять && ||.
ололо, && || -> И, ИЛИ.
нельзя применять -> В сферический вакууме нельзя
немного пишется слитно
Вот класс который я составил:
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# буду выглядеть?
Ctrl:= (ConvKey and $00040000) <> 0;
wParam:= vKey or ScanCode shl 8;
ScanCode:= ConvKey and $000000FF or $FF00;
vBulletin® v3.8.14, Copyright ©2000-2026, vBulletin Solutions, Inc. Перевод: zCarot