Se puede prescindir de todas las funciones API en VB.NET

Iniciado por okik, 24 Junio 2015, 20:41 PM

0 Miembros y 1 Visitante están viendo este tema.

okik

Hola

Soy emigrante de VB6 a .NET, de hecho ya me han echado la "bronca" en varias ocasiones por usar la metodología de VB6 en .NET cuando no era necesario. He visto que se puede prescindir de algunas funciones API de Windows en .NET.  El caso es que no se cuales funciones ya están incluidas en .NET o no.

Una que ahora mismo estoy buscando es el GetCursorPos, para determinar la posición X, Y del puntero en el escritorio.

Llamando así funciona:

Código (vbnet) [Seleccionar]
   
   Structure POINTAPI
       Public X As Integer
       Public Y As Integer
   End Structure
   Private Declare Function GetCursorPos Lib "user32.dll" ( _
   ByRef lpPoint As POINTAPI) As Integer



Pero parace ser que es más de '.NET' ponerlo así:

Código (vbnet) [Seleccionar]
  Public Structure POINTAPI
       Public X As Integer
       Public Y As Integer
   End Structure

 <Runtime.InteropServices.DllImport("user32.dll")> _
   Public Shared Function GetCursorPos(ByRef lpPoint As POINTAPI) As Integer
   End Function


No se, me extrañaría que los de Microsoft, al construir .NET no hubieran establacido funciones internas de .NET para todas funciones incluidas en DLLs de Windows como USER32.DLL. y no tener que hacer estas llamadas.


Saludos y gracias




Pues nada que en dicho caso parece que es lo que digo:

Código (vbnet) [Seleccionar]

'Posición X del cursor en el escritorio
  Me.Text = Cursor.Position.X


Fuente:
https://msdn.microsoft.com/es-es/library/system.windows.forms.cursor.position%28v=vs.110%29.aspx

No entiendo porqué, si como parece estoy en lo cierto, tanta gente postea y fomenta el uso de estas llamadas cuando no son necesarias


Eleкtro

#1
Cita de: okik en 24 Junio 2015, 20:41 PMUna que ahora mismo estoy buscando es el GetCursorPos, para determinar la posición X, Y del puntero en el escritorio.

Tan fácil cómo esto :P:
Código (vbnet) [Seleccionar]
Dim cursorPos As Point = Windows.Forms.Cursor.Position
MessageBox.Show(cursorPos.ToString)





Cita de: okik en 24 Junio 2015, 20:41 PMLlamando así funciona:
Código (vbnet,1) [Seleccionar]

   Private Declare Function GetCursorPos Lib "user32.dll" (ByRef lpPoint As POINTAPI) As Integer


Pero parace ser que es más de '.NET' ponerlo así:
Código (vbnet,1) [Seleccionar]

   <Runtime.InteropServices.DllImport("user32.dll")>
   Public Shared Function GetCursorPos(ByRef lpPoint As POINTAPI) As Integer
   End Function


Quiero resaltar esas lineas y la frase que has dicho "Pero parace ser que es más de '.NET' ponerlo así",
fíjate bien en las diferencias, no es una simple cuestión de sintaxis o estética, es que si sigues declarando las funciones al estilo VB6 en vb.Net, entonces estarás privándote de las "nuevas" mejoras que aportan las funcionalidades de los parámetros del atributo DllImporAttribute.

No sigas usando el tipo de declaración vb6-stylized con el keyword Declare, no aporta nada.




Cita de: okik en 24 Junio 2015, 20:41 PMNo entiendo porqué, si como parece estoy en lo cierto, tanta gente postea y fomenta el uso de estas llamadas cuando no son necesarias

Generalmente suele ser por ignorancia e inexperiencia, otras veces suele ser por que ves un código muy antiguo, tan antiguo que tal vez en este momento las classes de .Net Framework no exponían ningún método para hacerlo sin recurrir a la WinAPI, y en otros casos es por motivos razonables cómo mayor control del comportamiento del código (por ejemplo usar la WinAPI para mover/copiar archivos).

Te lo dije en otro post (creo recordar :-/), los códigos que encuentres en Google la mayoría va a ser morralla de programadores que usan malas prácticas por que no dejan la costumbre de cómo hacian las cosas en VB6, y eso conlleva a acabar no sabiendo nada acerca de las funcionalidades de la librería de clases de .Net Framework. Esto obviamente no siempre es así, he dicho la mayoría.

Saludos








okik

#2
Ok, gracias Elektro

Oye, en confianza, que lo de la "bronca" no me refería a tí , eh  ;)

Bueno la otra forma sería así:

Código (vbnet) [Seleccionar]
   
<DllImport("user32.dll", BestFitMapping:=False, CallingConvention:=CallingConvention.Winapi, CharSet:=CharSet.Unicode, EntryPoint:="user32")> _
   Public Shared Function GetCursorPos(ByRef lpPoint As POINTAPI) As Boolean
   End Function


Y establecer el siguiente Imports:
Código (vbnet) [Seleccionar]
Imports System.Runtime.InteropServices

Evidentemente es lo que dices, aquí puedo establecer los parámentros de la llamada.

Pero quería decir que si funciona o realmente no hace falta establecer nada pues ya vale aunque sea al estilo de VB6, digo yo.




Bueno, sabiéndolo personalmente siempre buscaré la forma de no tener que usar funciones API.



Eleкtro

#3
Cita de: okik en 24 Junio 2015, 21:38 PM
Pero quería decir que si funciona o realmente no hace falta establecer nada pues ya vale aunque sea al estilo de VB6, digo yo.

No pasa nada en realidad, pero aporta menor control cómo por ejemplo no poder especificar si quieres que la función devuelva un código de error o no (siempre que la función ueda devolver un código de error, no todas lo hacen, claro está), y personalmente, lo considero algo muy feo.

Te sugiero leer este artículo en su totalidad:
Walkthrough: Calling Windows APIs (Visual Basic)
CitarThe DllImport attribute provides a second way to call functions in DLLs without type libraries. DllImport is roughly equivalent to using a Declare statement but provides more control over how functions are called.

You can use DllImport with most Windows API calls as long as the call refers to a shared (sometimes called static) method. You cannot use methods that require an instance of a class. Unlike Declare statements, DllImport calls cannot use the MarshalAs attribute.

y los campos/parámetros de:
DllImportAttribute

Saludos