powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / WinAPI - перевести код из 32-bit в 64-bit
18 сообщений из 18, страница 1 из 1
WinAPI - перевести код из 32-bit в 64-bit
    #40031190
HOME_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго дня господа !

Обращаюсь не по теме - но WinApi он един и он ВСЕГДА !!!!
А господа дельфисты более глубоко осведомлены

Необходимо привести 32-bit код WinAPI (VBA - Excel) к 64-bit WinApi (VBA - Excel)
Просмотрел массу сайтов (в том числе и порнографического характера) - не могу добиться результата
Основное непонимание в определении размерности типа и выделении памяти

Вот первоисточник - логическая суть в блокноте написать слово и нажать Enter
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
Const VK_H = 72
Const VK_E = 69
Const VK_L = 76
Const VK_O = 79
Const VK_ENTER = &HD
Const KEYEVENTF_KEYUP = &H2
Const INPUT_MOUSE = 0
Const INPUT_KEYBOARD = 1
Const INPUT_HARDWARE = 2

Private Type MOUSEINPUT
  dx As Long
  dy As Long
  mouseData As Long
  dwFlags As Long
  time As Long
  dwExtraInfo As Long   -- здесь изменение до 8 б LongPtr
End Type

Private Type KEYBDINPUT
  wVk As Integer
  wScan As Integer
  dwFlags As Long
  time As Long
  dwExtraInfo As Long   -- здесь изменение до 8 б  LongPtr
End Type

Private Type HARDWAREINPUT
  uMsg As Long
  wParamL As Integer
  wParamH As Integer
End Type

Private Type GENERALINPUT
  dwType As Long
  xi(0 To 23) As Byte    - здесь память вероятно должна быть увеличена до 31
End Type

Private Declare Function SendInput Lib "user32.dll" (ByVal nInputs As Long, pInputs As GENERALINPUT, ByVal cbSize As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Sub Test()
  Shell "NotePad.EXE", 1
  SendKey VK_H
  SendKey VK_E
  SendKey VK_L
  SendKey VK_L
  SendKey VK_O
  SendKey VK_ENTER
  SendKey VK_H
  SendKey VK_E
  SendKey VK_L
  SendKey VK_L
  SendKey VK_O
End Sub
Private Sub SendKey(bKey As Byte)
  Dim GInput(0 To 1) As GENERALINPUT
  Dim KInput As KEYBDINPUT
  KInput.wVk = bKey  'the key we're going to press
  KInput.dwFlags = 0 'press the key
  'copy the structure into the input array's buffer.
  GInput(0).dwType = INPUT_KEYBOARD   ' keyboard input hello
  CopyMemory GInput(0).xi(0), KInput, Len(KInput)
  'do the same as above, but for releasing the key
  KInput.wVk = bKey  ' the key we're going to realease
  KInput.dwFlags = KEYEVENTF_KEYUP  ' release the key
  GInput(1).dwType = INPUT_KEYBOARD  ' keyboard input
  CopyMemory GInput(1).xi(0), KInput, Len(KInput)
  'send the input now
  Call SendInput(2, GInput(0), Len(GInput(0)))
End Sub



Ошибки в неверном описании структуры и выделении памяти,
Не смогли бы на WinApi Delphi описать нечто подобное
Попытаюсь по результатам перевести код на VB

Заранее благодарен !
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031192
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031231
HOME_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник


IntPtr - пробывал аналогичное - не фига
В документации рекомендуют LongPtr

Если у Вас Office 2016 x 64 попытайтесь
Excel -> Alt - F11 -> Insert Module -> Вставить вышеизложенный код -> F5
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031257
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Microsoft прикольный, в двух редакциях одного и того же ЯП использует несовместимые типы данных с одинаковыми названиями.
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031293
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HOME_X,

Код: vbnet
1.
  xi(0 To 23) As Byte    - здесь память вероятно должна быть увеличена до 31


Кстати, почему до 31-то, если размер одного указателя увеличивается на 4 байта?.. До 27 же, не?
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031296
HOME_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
Microsoft прикольный, в двух редакциях одного и того же ЯП использует несовместимые типы данных с одинаковыми названиями.


Да не однозначно как-то и главное НЕ хочет работать

Не смогли бы прояснить зачем используется прием CopyMemory
Почему бы не описать изначально необходимый тип и нужным образом не инициализировать
прямо в элементах массива

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
Private Type KEYBDINPUT
  wVk As Integer
  wScan As Integer
  dwFlags As Long
  time As Long
  dwExtraInfo As Long   
End Type


Private Type GENERALINPUT
  dwType As Long
  xi as KEYBDINPUT
End Type

 Dim GInput(0 To 1) As GENERALINPUT

 GInput(0).dwType = 
 GInput(0).xi.wVk = 
 GInput(0).xi.wScan =

 GInput(1).dwType = 
 GInput(1).xi.wVk = 
 GInput(1).xi.wScan =



Но так не работает и под 32 bit
Или GENERALINPUT - фиксирован по длине для SendInput
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031297
HOME_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
HOME_X,

Код: vbnet
1.
  xi(0 To 23) As Byte    - здесь память вероятно должна быть увеличена до 31


Кстати, почему до 31-то, если размер одного указателя увеличивается на 4 байта?.. До 27 же, не?



Там аналогичный подтип для MOUSE

Private Type MOUSEINPUT
dx As Long
dy As Long
mouseData As Long
dwFlags As Long
time As Long
dwExtraInfo As Long -- здесь изменение до 8 б LongPtr
End Type

Отвечу что изначально пробывал до 27 B - тоже ничего не получилось
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031301
HOME_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
HOME_X,

Код: vbnet
1.
  xi(0 To 23) As Byte    - здесь память вероятно должна быть увеличена до 31


Кстати, почему до 31-то, если размер одного указателя увеличивается на 4 байта?.. До 27 же, не?


Изначально зарезервировано 24 элемента это вероятно по максимальной размерности возможного типа
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
Private Type MOUSEINPUT
  dx As Long
  dy As Long
  mouseData As Long
  dwFlags As Long
  time As Long
  dwExtraInfo As Long   -- здесь изменение до 8 б LongPtr
End Type



Long в подтипе MOUSEINPUT = 4*6 = 24

получается это размер можно взять любой MAX(=100) а CopyMemory ограничит длину и обеспечит перенос данных
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031381
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HOME_X
Long в подтипе MOUSEINPUT = 4*6 = 24

Я может чего-то не понимаю, но для x64: 4 * 5 + 8 - у меня упорно получается 28, а не 32...
HOME_X
получается это размер можно взять любой MAX(=100) а CopyMemory ограничит длину и обеспечит перенос данных

Я не знаю как хранятся элементы в массивах VBA.
Но что-то мне подсказывает, что при неправильно выбранном xi в этом массиве
Код: vbnet
1.
Dim GInput(0 To 1) As GENERALINPUT

поедут поля, т.е. присваивание
Код: vbnet
1.
GInput(1).dwType = INPUT_KEYBOARD  ' keyboard input

запишет данные куда-то в рандомное место.
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031446
Flashpoke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Посмотри тут в JwaWinUser.pas.
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031455
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
del
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031463
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HOME_X, господа дельфисты более глубоко осведомлены ))

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
Const VK_H = 72
Const VK_E = 69
Const VK_L = 76
Const VK_O = 79
Const VK_ENTER = &HD
Const KEYEVENTF_KEYUP = &H2
Const INPUT_MOUSE = 0
Const INPUT_KEYBOARD = 1
Const INPUT_HARDWARE = 2
'Const KEYEVENTF_UNICODE = 4

Private Type GENERAL_KEYBDINPUT  ' x64 > 40
  Itype As LongPtr       ' GENERALINPUT.Itype ' 8
  wVk As Integer         ' 2 ' 10
  wScan As Integer       ' 2 ' 12
  dwFlags As Long        ' 4 ' 16
  time As LongPtr        ' 8 ' 24
  dwExtraInfo As LongPtr ' 8 ' 32
  zRound As LongPtr      ' 8 ' 40
End Type

Private Declare PtrSafe Function SendInput Lib "user32.dll" (ByVal nInputs As Long, pInputs As GENERAL_KEYBDINPUT, ByVal cbSize As Long) As Long
Sub Test()
  Shell "NotePad.EXE", 1
  SendKey VK_H
  SendKey VK_E
  SendKey VK_L
  SendKey VK_L
  SendKey VK_O
  SendKey VK_ENTER
  SendKey VK_H
  SendKey VK_E
  SendKey VK_L
  SendKey VK_L
  SendKey VK_O
End Sub
Private Sub SendKey(bKey As Byte)
  Dim GkInput(0 To 1) As GENERAL_KEYBDINPUT
  '
  GkInput(0).Itype = INPUT_KEYBOARD
  GkInput(0).wVk = bKey
  GkInput(0).wScan = 0
  GkInput(0).dwFlags = 0
  GkInput(0).time = 0
  GkInput(0).dwExtraInfo = 0
  '
  GkInput(1).Itype = INPUT_KEYBOARD
  GkInput(1).wVk = bKey
  GkInput(1).wScan = 0
  GkInput(1).dwFlags = KEYEVENTF_KEYUP
  GkInput(1).time = 0
  GkInput(1).dwExtraInfo = 0
  '
  SendInput 2, GkInput(0), 40
End Sub

...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031502
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bred eFeM,

А откуда ты взял эту структуру?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
Private Type GENERAL_KEYBDINPUT  ' x64 > 40
  Itype As LongPtr       ' GENERALINPUT.Itype ' 8
  wVk As Integer         ' 2 ' 10
  wScan As Integer       ' 2 ' 12
  dwFlags As Long        ' 4 ' 16
  time As LongPtr        ' 8 ' 24
  dwExtraInfo As LongPtr ' 8 ' 32
  zRound As LongPtr      ' 8 ' 40
End Type


Потому что вот здесь ( https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-keybdinput ) она описана совершенно иначе (часть про KEYBDINPUT):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
typedef struct tagKEYBDINPUT {
  WORD      wVk;
  WORD      wScan;
  DWORD     dwFlags;
  DWORD     time;
  ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT, *LPKEYBDINPUT;
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031507
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
alekcvp
Bred eFeM,

А откуда ты взял эту структуру?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
Private Type GENERAL_KEYBDINPUT  ' x64 > 40
  Itype As LongPtr       ' GENERALINPUT.Itype ' 8
  wVk As Integer         ' 2 ' 10
  wScan As Integer       ' 2 ' 12
  dwFlags As Long        ' 4 ' 16
  time As LongPtr        ' 8 ' 24
  dwExtraInfo As LongPtr ' 8 ' 32
  zRound As LongPtr      ' 8 ' 40
End Type



Потому что вот здесь ( https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-keybdinput ) она описана совершенно иначе (часть про KEYBDINPUT):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
typedef struct tagKEYBDINPUT {
  WORD      wVk;
  WORD      wScan;
  DWORD     dwFlags;
  DWORD     time;
  ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT, *LPKEYBDINPUT;


судя по всему, сруктура ТС просто развёрнута
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031523
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp , откуда ты взял эту структуру?

GENERAL_KEYBDINPUT как-бы намекает, что это уже нужная 'сборка' структур GENERALINPUT и KEYBDINPUT
чтобы не делать лишних телодвижений, например, с CopyMemory.

Наибольший размер из KEYBDINPUT, HARDWAREINPUT, MOUSEINPUT имеет MOUSEINPUT. Значит GENERALINPUT.xi должен быть не меньше. Но вместо просто массива, размечаем там нужные поля для нашего случая (KEYBDINPUT) и дополнительные - для расширения общей структуры до нужного размера.
Правильнее для x64 будет, наверное, так:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Private Type GENERAL_KEYBDINPUT  ' x64 > 40
  Itype As Long                  ' 4 ' 4 '  GENERALINPUT.Itype
  Itype_RoundTo8Byte As Long     ' 4 ' 8 '
  '--------------------------------------'  KEYBDINPUT
  wVk As Integer                 ' 2 ' 10   GENERALINPUT.xi ->
  wScan As Integer               ' 2 ' 12
  dwFlags As Long                ' 4 ' 16
  time As Long                   ' 4 ' 20
  time_RoundTo8Byte As Long      ' 4 ' 24
  dwExtraInfo As LongPtr         ' 8 ' 32
  '--------------------------------------'
  RoundToMOUSEINPUT As LongPtr   ' 8 ' 40  <- GENERALINPUT.xi
End Type


и под x32:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Private Type GENERAL_KEYBDINPUT  ' x32 > 28
  Itype As Long                  ' 4 ' 4 '  GENERALINPUT.Itype
  '--------------------------------------'  KEYBDINPUT
  wVk As Integer                 ' 2 ' 6    GENERALINPUT.xi ->
  wScan As Integer               ' 2 ' 8
  dwFlags As Long                ' 4 ' 12
  time As Long                   ' 4 ' 16
  dwExtraInfo As Long            ' 4 ' 20
  '--------------------------------------'
  RoundToMOUSEINPUT_A As Long    ' 4 ' 24
  RoundToMOUSEINPUT_B As Long    ' 4 ' 28  <- GENERALINPUT.xi
End Type


А можно всё это сделать и лаконичнее:
Код: vbnet
1.
2.
3.
4.
5.
Private Declare PtrSafe Function keybd_event Lib "user32.dll" (ByVal bVk As Long, ByVal bScan As Long, ByVal dwFlags As Long ByVal, dwExtraInfo As LongPtr) As Long
Private Sub SendKey(bKey As Byte)
  keybd_event bKey, 0, 0, 0
  keybd_event bKey, 0, KEYEVENTF_KEYUP, 0
End Sub

...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031549
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bred eFeM,
Код: vbnet
1.
2.
3.
  time As Long                   ' 4 ' 20
  time_RoundTo8Byte As Long      ' 4 ' 24
  dwExtraInfo As LongPtr         ' 8 ' 32


time_RoundTo8Byte - почему до 8, если оно везде 4?..
И тогда для KEYBOARD 'dwExtraInfo' должно уехать.
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031634
HOME_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

Читаю - ищу - пробую !

Спасибо за активное участие господа

Вопрос - относительно Африки
Нельзя ли из DELPHI (иди используя ИСХОДНИКИ DELPHI)
подсмотреть/ОТЛОВИТЬ структуру и размерность типа 64 типа ?

Спасибо
...
Рейтинг: 0 / 0
WinAPI - перевести код из 32-bit в 64-bit
    #40031684
HOME_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bred eFeM,

Большое Вам спасибо !
Оба варианта прекрасно работают !

Насчет совмещения структур здесь вывод очевиден
Насчет time As LongPtr здесь нужно быть жестким экстраСЕКСОМ

Нашел еще и китайско - тайваньскую интерпретацию структуры там dwFlags As LongPtr

Но как бы не много было китайцев - Ваш вариант работает

"Теперь я засну спокойно......"
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / WinAPI - перевести код из 32-bit в 64-bit
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]