ToASCII - C#

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by QJHoly, 24 Aug 2009.

  1. QJHoly

    QJHoly New Member

    Joined:
    28 Nov 2007
    Messages:
    13
    Likes Received:
    1
    Reputations:
    0
    У меня есть окно в которое нужно посылать через функцию PostMessage строки текста, но проблема в том что например если я посылаю строку "ПРИВЕТ" то приходит "привет" либо "ghbdtn" в зависимости от расклада клавиатуры в окне. например если мне нужен символ ) приходит 9.
     
  2. flacs

    flacs Member

    Joined:
    28 Jan 2009
    Messages:
    81
    Likes Received:
    31
    Reputations:
    6
    на 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;
    
    
    Переписать на С# я думаю не составит труда.
     
    #2 flacs, 24 Aug 2009
    Last edited: 24 Aug 2009
  3. QJHoly

    QJHoly New Member

    Joined:
    28 Nov 2007
    Messages:
    13
    Likes Received:
    1
    Reputations:
    0
    Я раньше изучал delphi только на простом уровне. Word shl 16 - не понятно что это + как вообще используется в переменной or или and.
     
    #3 QJHoly, 25 Aug 2009
    Last edited: 25 Aug 2009
  4. flacs

    flacs Member

    Joined:
    28 Jan 2009
    Messages:
    81
    Likes Received:
    31
    Reputations:
    6
    shl - логический сдвиг влево (на с++ = <<)
    shr - соответвенно вправо (>>)

    Word shl 16 = word << 16
     
  5. QJHoly

    QJHoly New Member

    Joined:
    28 Nov 2007
    Messages:
    13
    Likes Received:
    1
    Reputations:
    0
    Я про то что вообще за тип Word и зачем делать сдвиг?
     
  6. VARVAR

    VARVAR New Member

    Joined:
    3 Jun 2005
    Messages:
    39
    Likes Received:
    1
    Reputations:
    0
    Короче надо с кодировкой разбираться

    MSDN class

    System.Text.Encoding
     
  7. QJHoly

    QJHoly New Member

    Joined:
    28 Nov 2007
    Messages:
    13
    Likes Received:
    1
    Reputations:
    0
    Я вот начал переводить только не очень получается. Можете не много помочь тут сказано что к операндам типа 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);
            }
    
     
  8. W!z@rD

    W!z@rD Борец за русский язык

    Joined:
    12 Feb 2006
    Messages:
    973
    Likes Received:
    290
    Reputations:
    43
    лучше бы промолчал. Херню несешь


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

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

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

    QJHoly New Member

    Joined:
    28 Nov 2007
    Messages:
    13
    Likes Received:
    1
    Reputations:
    0
    Вот класс который я составил:
    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;
    
     
    #9 QJHoly, 27 Aug 2009
    Last edited: 28 Aug 2009