Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   ToASCII - C# (https://forum.antichat.xyz/showthread.php?t=137130)

QJHoly 24.08.2009 20:48

ToASCII - C#
 
У меня есть окно в которое нужно посылать через функцию PostMessage строки текста, но проблема в том что например если я посылаю строку "ПРИВЕТ" то приходит "привет" либо "ghbdtn" в зависимости от расклада клавиатуры в окне. например если мне нужен символ ) приходит 9.

flacs 24.08.2009 22:26

на 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;

Переписать на С# я думаю не составит труда.

QJHoly 25.08.2009 16:05

Я раньше изучал delphi только на простом уровне. Word shl 16 - не понятно что это + как вообще используется в переменной or или and.

flacs 25.08.2009 17:07

shl - логический сдвиг влево (на с++ = <<)
shr - соответвенно вправо (>>)

Word shl 16 = word << 16

QJHoly 25.08.2009 17:23

Цитата:

Сообщение от flacs
shl - логический сдвиг влево (на с++ = <<)
shr - соответвенно вправо (>>)

Word shl 16 = word << 16

Я про то что вообще за тип Word и зачем делать сдвиг?

VARVAR 25.08.2009 17:48

Короче надо с кодировкой разбираться

MSDN class

System.Text.Encoding

QJHoly 26.08.2009 19:01

Я вот начал переводить только не очень получается. Можете не много помочь тут сказано что к операндам типа 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);
        }


W!z@rD 27.08.2009 06:56

Цитата:

Сообщение от VARVAR
Короче надо с кодировкой разбираться

MSDN class

System.Text.Encoding

лучше бы промолчал. Херню несешь


Цитата:

Сообщение от QJHoly
Я вот начал переводить только не очень получается. Можете не много помочь тут сказано что к операндам типа int нельзя применять && ||.

ололо, && || -> И, ИЛИ.

нельзя применять -> В сферический вакууме нельзя

немного пишется слитно

QJHoly 27.08.2009 18:29

Вот класс который я составил:
Код:

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;



Время: 05:45