VB.NET — преобразование функции joyGetDevCaps из VB6 в VB.NET

Я понятия не имею, как мне преобразовать следующий API в VB.NET.

Private Const MAXPNAMELEN As Long = 32&

Private Type JOYCAPS
wMid As Integer
wPid As Integer
szPname As String * MAXPNAMELEN
wXmin As Long
wXmax As Long
wYmin As Long
wYmax As Long
wZmin As Long
wZmax As Long
wNumButtons As Long
wPeriodMin As Long
wPeriodMax As Long
End Type

Private Declare Function joyGetDevCaps Lib "winmm.dll" Alias "joyGetDevCapsA" (ByVal id As Long, lpCaps As JOYCAPS, ByVal uSize As Long) As Long

Я пробовал некоторые преобразователи, но то, что они выдавали, не работало. Если кто-то действительно хорош, может ли он попытаться преобразовать его для меня и показать мне, как его называть? В частности, я не знаю, как создать экземпляр JOYCAPS при передаче его функции.

Я не нашел эту функцию на pinvoke.net.

Спасибо.


person tmighty    schedule 16.12.2012    source источник


Ответы (1)


Я не могу проверить это, но это должно быть простое преобразование:

Private Const MAXPNAMELEN As Integer = 32

<StructLayout(LayoutKind.Sequential)>
Private Structure JOYCAPS
    Public wMid As Short
    Public wPid As Short
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAXPNAMELEN)>
        Public szPname As String
    Public wXmin As Integer
    Public wXmax As Integer
    Public wYmin As Integer
    Public wYmax As Integer
    Public wZmin As Integer
    Public wZmax As Integer
    Public wNumButtons As Integer
    Public wPeriodMin As Integer
    Public wPeriodMax As Integer
End Structure

<DllImport("winmm.dll")>
Private Shared Function joyGetDevCaps(id As IntPtr, ByRef lpCaps As JOYCAPS, uSize As UInteger) As Integer

End Function

Предполагается, что System.Runtime.InteropServices импортируется.

person Ry-♦    schedule 16.12.2012
comment
Вау, спасибо! Не могли бы вы показать мне, как создать экземпляр JOYCAPS при передаче его в функцию? Я предполагаю, что это то, что вы имели в виду, говоря «Обязательно инициализируйте szPname в New StringBuffer с емкостью MAXPNAMELEN». Я не уверен, как мне это сделать. - person tmighty; 16.12.2012
comment
И не могли бы вы рассказать мне, что такое StringBuffer? Вы имели в виду StringBuilder? - person tmighty; 16.12.2012
comment
@tmighty: я действительно имел в виду StringBuilder, и это тоже неправильно :) Я отредактировал его, и теперь он должен работать нормально. Просто Dim caps As New JOYCAPS() для создания экземпляра структуры. - person Ry-♦; 16.12.2012
comment
@minitech Первый параметр функции должен быть размером с указатель. - person GSerg; 16.12.2012
comment
@minitech Спасибо! Но не могли бы вы показать мне пример того, как это на самом деле называется? Это Dim JC As New JOYCAPS : Dim i as integer = JoyGetDevCaps(0, JC, Marshal.SizeOf(JC)) ? - person tmighty; 16.12.2012
comment
@tmighty: выглядит правильно (хотя 0 должен быть IntPtr.Zero); это работает? :) Какой исходный код VB6? - person Ry-♦; 16.12.2012
comment
@minitech Я летаю вслепую здесь ... Кажется, была ошибка в 64-разрядной версии Win7 (не уверен, зависит ли это от Win7 или 64-разрядной версии). joyGetDevCaps никогда не возвращает ‹› JOYERR_NOERROR, даже в VB6. - person tmighty; 16.12.2012
comment
@minitech Однако я использовал Dim JC As JOYCAPS Dim lRet& lRet = joyGetDevCaps(lFirstValidID, JC, Len(JC)) If lRet ‹› JOYERR_NOERROR Then 'У меня это не работает в Windows 7 m_bConnected = True 'просто скажите, что джойстик подключено... JoystickCount кажется допустимым, поэтому мы знаем, сколько кнопок у нас есть Else m_lXMax = ... end if - person tmighty; 16.12.2012
comment
@tmighty: это, вероятно, не удалось в 64-битной Windows, потому что размер указателя был жестко запрограммирован на 32 бита (отсюда здесь IntPtr). Так что вы должны передать lFirstValidID вместо IntPtr.Zero в качестве первого аргумента, я полагаю... - person Ry-♦; 16.12.2012
comment
@minitech Вот мой код для оценки lFirstValidID: Dim iDevCount As Long Dim j As Long Dim ret As Long Dim JI As JOYINFO iDevCount = joyGetNumDevs 'Все устройства, даже кнопки Dim lFirstValidID& lFirstValidID = -1 Do While iDevCount › 0 iDevCount = iDevCount - 1 Если joyGetPos(iDevCount, JI) = JOYERR_NOERROR Then lFirstValidID = iDevCount JoystickCount = JoystickCount + 1 End If Loop Однако и VB6, и VB.NET возвращают для меня lRet = 165, поэтому я предполагаю, что код тот же. - person tmighty; 16.12.2012
comment
Если я отмечу ваш ответ как правильный, эта тема будет закрыта. Я просто подожду минут 15, возможно, кто-то захочет что-то сказать о результате 165 (что мне кажется странным). - person tmighty; 16.12.2012
comment
@tmighty: Что он возвращает в 32-битной Windows? (Или 165 правильно, но это просто кажется произвольным?) - person Ry-♦; 16.12.2012
comment
@minitech в 32-битной Windows (извините, у меня есть только 32-битная XP для тестирования), он возвращает JOYERROR_NOERROR (= 0). 165 — это JOYERROR_ERRPARAMS (что означает неверный дескриптор джойстика). - person tmighty; 16.12.2012
comment
@tmighty: Ха. Я понятия не имею: D У вас есть какая-либо документация, на которую я мог бы взглянуть? - person Ry-♦; 16.12.2012