Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Lekim

#231
hola

No entiendo porqué quieres usar API para cambiar el estilo de las cabeceras de un Listview cuando vb.net ya ofrece medios para ello.

ListView.DrawColumnHeader Event



Código (vbnet) [Seleccionar]
Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ListView1.View = View.Details
        ListView1.Columns.Add("Header1", 100)
        ListView1.Columns.Add("Header2", 100)
        ListView1.Items.Add("Item1")
        ListView1.Items(0).SubItems.Add("SubItem1")
        ListView1.Items.Add("Item2")
        ListView1.Items(1).SubItems.Add("SubItem2")
        ListView1.OwnerDraw = True

    End Sub

    Private Sub ListView1_DrawColumnHeader(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
        '//Rectángulos para el Bacground
        Try
            'Rectángulo inferior
            e.Graphics.FillRectangle(Brushes.Black, e.Bounds)
            'Rectángulo superior (Se superpone sobre el rectángulo anterior y es más pequeño)
            Dim RectPoint As New Point(e.Bounds.X + 1, e.Bounds.Y + 1)
            Dim RectSize As New Size(New Point(e.Bounds.Width - 2, e.Bounds.Height - 2))
            Dim Rect As New Rectangle(RectPoint, RectSize)
            e.Graphics.FillRectangle(Brushes.White, Rect)
        Finally
        End Try


        '//Dibuja el texto (Se superpone a los rectángulos anteriores o imagen de fondo)
        Dim sf As New StringFormat()
        Try
            Select Case e.Header.TextAlign
                Case HorizontalAlignment.Center
                    sf.Alignment = StringAlignment.Center
                Case HorizontalAlignment.Right
                    sf.Alignment = StringAlignment.Far
            End Select

            Dim headerFont As New Font("Helvetica", 10, FontStyle.Bold)
            Try
                e.Graphics.DrawString(e.Header.Text, headerFont, Brushes.Black, _
                                      New Point(e.Bounds.X + 5, e.Bounds.Y + 1), sf)
            Finally
                headerFont.Dispose()
            End Try

        Finally
            sf.Dispose()
        End Try

     
    End Sub

    Private Sub ListView1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewItemEventArgs) Handles ListView1.DrawItem
        e.DrawDefault = True
    End Sub
End Class


Los cambios se asignan por capas primero estableces lo que sería el 'Background' mediante FillRectangle, si creas otro FillRectangle éste se coloca en la parte superior del anterior en el mismo orden en el que se nombra en el código. Y por último la representación del texto. Si escribes la referéncia al texto antes que aplicar el rectángulo entonces no se verá el texto.

También puedes aplicar una imagen en lugar FillRectangle:

Código (vbnet) [Seleccionar]
       
   Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ListView1.View = View.Details
        ListView1.Columns.Add("Header1", 100)
        ListView1.Columns.Add("Header2", 100)
        ListView1.Items.Add("Item1")
        ListView1.Items(0).SubItems.Add("SubItem1")
        ListView1.Items.Add("Item2")
        ListView1.Items(1).SubItems.Add("SubItem2")
        ListView1.OwnerDraw = True

    End Sub

    Private Sub ListView1_DrawColumnHeader(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
     
        '//Dibuja una imagen
        Dim imagen As Image
        imagen = Image.FromFile("C:\Documents and Settings\Administrador\Mis documentos\columnHeader.png")
        e.Graphics.DrawImage(imagen, e.Bounds)


        '//Dibuja el texto (Se superpone a los rectángulos anteriores o imagen de fondo)
        Dim sf As New StringFormat()
        Try
            Select Case e.Header.TextAlign
                Case HorizontalAlignment.Center
                    sf.Alignment = StringAlignment.Center
                Case HorizontalAlignment.Right
                    sf.Alignment = StringAlignment.Far
            End Select

            Dim headerFont As New Font("Helvetica", 10, FontStyle.Bold)
            Try
                e.Graphics.DrawString(e.Header.Text, headerFont, Brushes.Black, _
                                      New Point(e.Bounds.X + 5, e.Bounds.Y + 1), sf)
            Finally
                headerFont.Dispose()
            End Try

        Finally
            sf.Dispose()
        End Try

     
    End Sub

    Private Sub ListView1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewItemEventArgs) Handles ListView1.DrawItem
        e.DrawDefault = True 'No quitar esto. A no ser que apliques una personalización para este evento. DrawDefault dibujará los valores por defecto.
    End Sub
End Class



#232
Hola

Gracias por comentar la actualización que has hecho para que fuera compatible con Acces 2010  ;-)

Creo que se puede simplificar el código obteniendo la tabla mediante una función y luego con la tabla haces lo que te de la gana.

He modificado la función que puse en el comentario anterior. Aquí no se obtiene sólo un elemento de una tabla sino toda la tabla entera para luego en otro evento hacer lo que se quiera con ella:

[FUNCIÓN PARA OBTENER TABLA ACCES]
Código (vbnet) [Seleccionar]
#Region "Lectura de base de dato ACCES ver. 12.0"
Module modGetDateTable

   Public Function LeerDatosTabla(ByVal PathFileMDB As String, ByVal NombreTabla As String) As DataTable
       Dim query As String = "SELECT * FROM " & NombreTabla
       Dim MDBConnString_ As String = "Provider=Microsoft.ACE.OLEDB.12.0;data source=" & PathFileMDB & ";"
       Dim DataSet_ As New DataSet       '//Caché de memoria interno de datos
       Dim Connection As System.Data.OleDb.OleDbConnection = New System.Data.OleDb.OleDbConnection(MDBConnString_)       '//Conexión con la base de datos
       Dim Resultado As String = Nothing
       Dim Tabla As DataTable = Nothing
       Try
           Connection.Open()                                                                           '//Abre la clase de datos
           Dim cmd As New System.Data.OleDb.OleDbCommand(query, Connection)                             '//Instrucción SQL
           Dim DataAdapter As New System.Data.OleDb.OleDbDataAdapter(cmd)
           DataAdapter.Fill(DataSet_, NombreTabla)                                                     '//Adapta la tabla (fila, columnas) al DataSet
           Connection.Close()                                                                          '//Cierra conexión
           Tabla = DataSet_.Tables(NombreTabla)                                       'Crea una tabla e introduce los datos del DataSet

       Catch ex As Exception
           MessageBox.Show(ex.Message)
       End Try
       Return Tabla
   End Function
End Module
#End Region


Ejemplo se uso:
Código (vbnet) [Seleccionar]

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       Dim PhatFileMDB As String = System.Windows.Forms.Application.StartupPath & "\Datos.accdb"
       Dim dtTable As DataTable = LeerDatosTabla(PhatFileMDB, "L1")
       Try
           For Each dtrow As DataRow In dtTable.Rows
               ListBox1.Items.Add(dtrow.Item(0))
           Next
       Catch ex As Exception
           MessageBox.Show(ex.Message)
       End Try
   End Sub


Por otro lado yo no quitaría Try/Catch

Código (vbnet) [Seleccionar]
  Try '//Intenta ejecutar el siguiente código
           '1...Código
           '2...Código
           '3....
       Catch ex As Exception   '//si se produce una excepción
           '//Muestra un mensaje por ejemplo, Cierra la aplicación o puedes no poner nada
       End Try '//Fin de intento




[MODIFICACIÓN DE TU CÓDIGO]
En un principio dijiste:
después comparo esos dos valores si son iguales

Entiendo que lo que quieres es comparar las filas de unas tablas y comprobar que las dos NO tienen coincidencias ¿no?

He realizado otra forma  ya que, pueden haber coincidencias pero no estar en el mismo lugar es decir: {A, B, C} y {N, M, A} tienen en común A

Código (vbnet) [Seleccionar]
   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       Dim Mydir As String = System.Windows.Forms.Application.StartupPath & "\" & "\Datos.accdb"

       Try  '//Intenta ejectuar el código
           '//Importa las tablas
           Dim Tabla1 As DataTable = LeerDatosTabla(Mydir, "L1")
           Dim Tabla2 As DataTable = LeerDatosTabla(Mydir, "L2")
           Dim Columna As Integer = 0 '//columna que va a comparar

           '//compara las tablas (independientemente de su orden) ej: A= {X,Y,Z}  B= {Y,N,S} HayCoincidencias devuelve  TRUE EN 'Y'
           Dim ListItems1 As New List(Of String), ListItems2 As New List(Of String)
           '//Introduce los elementos de la columna 0 en las listas ListItems1 y ListItems2
           For Each dtRow As DataRow In Tabla1.Rows
               ListItems1.Add(dtRow(Columna))
           Next
           For Each dtRow As DataRow In Tabla2.Rows
               ListItems2.Add(dtRow(Columna))
           Next

           '//Comprueba  las coincidencias
           Dim HayCoincidencia As Boolean = False
           Dim Coincidencias As String = Nothing
           If ListItems1.Count = ListItems2.Count Then
               Dim Int As Integer = -1
               For Each Elemento As String In ListItems2
                   Int += 1
                   If ListItems1.Contains(Elemento) = True Then
                       HayCoincidencia = True
                       If Coincidencias = "" Then
                           Coincidencias &= String.Format("- {0}", Elemento)
                       Else
                           Coincidencias &= String.Format("{0}- {1}", Environment.NewLine, Elemento)
                       End If
                   End If
               Next
           Else
               MessageBox.Show("Las listas no tiene el mismo número de elementos.", "Atención", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
           End If
           '//Lanza mensaje
           If HayCoincidencia Then
               MessageBox.Show(String.Format("Hay coincidencias: {0}{1}", Environment.NewLine, Coincidencias), _
                               "Atención", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
           Else
               MessageBox.Show("No hay coincidencias.", "Información", MessageBoxButtons.OK, MessageBoxIcon.Information)
           End If

           Me.Close()
       Catch ex As Exception  '//Si se produce una excepción"
           Me.Close() 'cierra
       End Try '//Fin de intento

   End Sub


Como ves llamando a la función LeerDatosTabla se obtiene el DataTable  y luego desde el evento de un botón por ejemplo puedes obtener la tabla y luego hacer lo que quieras, si no, es un lío tremendo. Así es más cómodo.

En un principio y para ahorrar código usé Lista1.Except(Lista2) para obtener una lista de elementos en los que no son iguales. Pero lo que interesaba es obtener los elementos que SI son iguales. En su lugar he usado Lista1.Contains(A) que devuelve TRUE si existe el elemento A en  la lista.

Estoy seguro que debe de haber alguna función o funciones NET para comparar listas que ahorre código pero como no la conozco lo he hecho a la cuenta de la vieja XD.




Otra cosa para la próxima puedes usar la lista de GeSHi que puedes ver en este foro cuando editas un comentario para pegar código y sea más legible.

[code=vbnet]...CÓDIGO...[/code]

Y por último decirte que este foro es para VB5 o VB6 y no para NET. Ya hay uno para net  ;)

http://foro.elhacker.net/net-b62.0/

Sl2s




#233
Hola

Antes de nada comentarte que no dispongo de Office 2010 ni archivos *.accdb. Pero he realizado este programa para leer archivos *.mdb y  supongo que el programa será capaz de leer los primeros. Ya me dirás.

Se trata de una función llamada LeerDatosTabla. Esta función devuelve un valor de un lugar concreto de una tabla de una base de datos. Se llama de la siguiente manera:


LeerDatosTabla("E:\Database1.accdb", NOMBRE DE TABLA, FILA, COLUMNA, NúmeroDeFilas, NúmeroDeColumnas)

Donde NúmeroDeFilas y  NúmeroDeColumnas devuelven el número de filas y columnas de la tabla. Es necesario que declares estas variables como 'integer' antes de llamar a la función como se muestra en el siguiente ejemplo. Claro que si no lo quieres puedes modificar el código.Tu mismo.


EJEMPLO:
Código (vbnet) [Seleccionar]



Public Class Form1
   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
   End Sub

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       Dim NúmeroDeFilas As Integer = Nothing          '//Variable para introducir el número de filas de la tabla
       Dim NúmeroDeColumnas As Integer = Nothing       '//Variable para introducir el número de columnas de la tabla
       Try
           Dim Valor1 As String = LeerDatosTabla("C:\Carpeta\Database1.accdb", "L1", 1, 0, NúmeroDeFilas, NúmeroDeColumnas) '//Devuelve el valor1
           Dim Valor2 As String = LeerDatosTabla("C:\Carpeta\Database1.accdb", "L2", 1, 0, NúmeroDeFilas, NúmeroDeColumnas) '//Devuelve el valor2

           If Valor1.Length > 0 And Valor2.Length > 0 Then '//Comprueba que Valor1 y Valor2 contienen alguna cadena
               If Valor1.Equals(Valor2) Then 'compara
                   MessageBox.Show("Hay coincidencia", "Información", MessageBoxButtons.OK, MessageBoxIcon.Information)
               End If
           End If

           'Label1.text = NúmeroDeFilas  
           'Label2.text = NúmeroDeFilas
       Catch ex As Exception
           MessageBox.Show(ex.Message)
       End Try
   End Sub

End Class
#Region "Lectura de base de datos"
Module modGetDateTable
   ''' <summary>
   ''' OBTIENE DATOS DE UNA BASE DE DATOS ACCESS
   ''' </summary>
   ''' <param name="PathFileMDB"></param>
   ''' <param name="NombreTabla"></param>
   ''' <param name="nFila"></param>
   ''' <param name="nColumna"></param>
   ''' <param name="file_Count"></param>
   ''' <param name="Column_count"></param>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Public Function LeerDatosTabla(ByVal PathFileMDB As String, _
                                  ByVal NombreTabla As String, _
                                  ByVal nFila As Integer, _
                                  ByVal nColumna As Integer, _
                                  ByRef file_Count As Integer, _
                                  ByRef Column_count As Integer) As String
       Dim query As String = "SELECT * FROM " & NombreTabla
       Dim MDBConnString_ As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & PathFileMDB & ";"
       Dim DataSet_ As New DataSet       '//Caché de memoria interno de datos
       Dim Connection As System.Data.OleDb.OleDbConnection = New System.Data.OleDb.OleDbConnection(MDBConnString_)       '//Conexión con la base de datos
       Dim Resultado As String = Nothing
       Try
           Connection.Open()                                                                           '//Abre la clase de datos
           Dim cmd As New System.Data.OleDb.OleDbCommand(query, Connection)                             '//Instrucción SQL
           Dim DataAdapter As New System.Data.OleDb.OleDbDataAdapter(cmd)
           DataAdapter.Fill(DataSet_, NombreTabla)                                                     '//Adapta la tabla (fila, columnas) al DataSet
           Connection.Close()                                                                          '//Cierra conexión

           Dim Tabla As DataTable = DataSet_.Tables(NombreTabla)                                       'Crea una tabla e introduce los datos del DataSet
           Dim NumRows As Integer = Tabla.Rows.Count                                                   '//Obtiene el número de filas de la tabla

           file_Count = NumRows                                                                        '//Devuelve Número de filas de la tabla
           Column_count = Tabla.Columns.Count
           Resultado = Tabla.Rows(nFila).Item(nColumna)
       Catch ex As Exception
           MessageBox.Show(ex.Message)
       End Try
       Return Resultado
   End Function
End Module
#End Region




[EJEMPLO SIMPLE]
A veces con las funciones metidas en un módulo y  con el Byval y el ByRef pueden ser confusas. Aquí te dejo un ejemplo sencillo de lectura dentro de un botón, para que lo veas más claro:

- Necesitas meter un ListBox y un Button

Código (vbnet) [Seleccionar]

   Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

       Dim PathMDB As String = "C:\Carpeta\Database1.accdb"                                            '//Nombre de la tabla
       Dim NombreTabla As String = "Direcciones"                                       '//La tabla se llama "Direcciones"

       Dim query As String = "SELECT * FROM " & NombreTabla
       Dim MDBConnString_ As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & PathMDB & ";"
       Dim DataSet_ As New DataSet                                                    '//Caché de memoria interno de datos
       Dim Connection As System.Data.OleDb.OleDbConnection = New System.Data.OleDb.OleDbConnection(MDBConnString_)        '//Conexión con la base de datos
       Connection.Open()                                                              '//Abre la clase de datos
       Dim cmd As New System.Data.OleDb.OleDbCommand(query, Connection)                                 '//Instrucción SQL
       Dim DataAdapter As New System.Data.OleDb.OleDbDataAdapter(cmd)
       DataAdapter.Fill(DataSet_, NombreTabla)                                        '//Adapta la tabla (fila, columnas) al DataSet
       Connection.Close()                                                             '//Cierra conexión

       Dim Tabla As DataTable = DataSet_.Tables(NombreTabla)                           '//Crea una tabla e introduce los datos del DataSet
       Dim NumRows As Integer = Tabla.Rows.Count                                       '//Obtiene el número de filas de la tabla
       For Each Filas As DataRow In Tabla.Rows
           Dim Columna As Integer = 0                                                  '//La primera columna de la tabla
           ListBox1.Items.Add(Filas.Item(Columna))                                     '//Devuelve las filas de la primera columna
       Next

       '//Forma selectiva
       'Label1.Text = Tabla.Rows(FILA).Item(COLUMNA)
   End Sub


Lo que hace este código es meter todos los elementos de la primera fila de una tabla en un ListBox

[LECTURA DE ARCHIVOS XLS O XLSX]
Si quieres leer archivos XLS (Excel) solo tienes que reemplazar:
Código (vbnet) [Seleccionar]
Dim MDBConnString_ As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & PathFileMDB & ";"

por esta otra línea:

Código (vbnet) [Seleccionar]
Dim MDBConnString_ As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & PathFileMDB & ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=0'"

Y como nombre de tabla:

Código (vbnet) [Seleccionar]
[Hoja1$]

Ejemplo:
Código (vbnet) [Seleccionar]
   Dim NúmeroDeFilas As Integer = Nothing          '//Variable para introducir el número de filas de la tabla
        Dim NúmeroDeColumnas As Integer = Nothing       '//Variable para introducir el número de columnas de la tabla
        Dim Valor1 As String = LeerDatosTabla("C:\Carpeta\Libro1.xls", "[Hoja1$]", 1, 0, NúmeroDeFilas, NúmeroDeColumnas) '//Devuelve el valor1
        Me.Text = Valor1


Sldos
#234
Foro Libre / Re: Debate elecciones 2015
2 Diciembre 2015, 16:46 PM
En resumen, pienso que...

El valor de las partes(Podemos, Ciudadanos, PSOE, etc) será inferior al resto(PP) y que la suma de las partes (Podemos, Ciudadanos, PSOE, etc) será superior al resto.

Espero estar equivocado, pero creo que será así.
#235
Hola

España es el país de los pillos, los tramposos, los estafadores, y los listillos... :¬¬

Los/as empresarios/as españoles/as,  se han sacado de la manga una forma de conseguir trabajadores/as GRATIS y se llama 'Convenio de Prácticas (becarios)'. Vale no es nuevo pero enseguida entenderás porqué lo digo.

Ya no les basta con contratar a trabajadores con 'mínima discapacidad' (si estás en silla de ruedas no les vales), para beneficiarse de ayudas y bonificaciones. Con trabajadores que lo mismo tienen una quemadura con secuelas o un poco de sordera. En fin buscan trabajadores que puedan cumplir y que tengan alguna 'tara' los suficientemente importante como para que disponga de un certificado  de discapacidad, pero que sea la más mínima posible y así poder beneficiarse de su contratación.




Ahora la moda es el Convenio de Prácticas. Durante hace un mes, más o menos, me estoy encontrando ofertas de empleo bastante a menudo demandando trabajadores dispuestos a trabajar por convenio, es decir SIN CONTRATO.

Existe el Convenio de Prácticas y Contrato de Prácticas. El primero es sin contrato  y el segundo es con contrato y sueldo.

Curiosamente se está demandando mucho para trabajos de baja cualificación. Por favor, ¿becario para mozo de almacén? No se si reír o llorar. Así que yo voy a la universidad y estudio por ejemplo...periodismo, y me contratan de becario para preparar pedidos en un almacén, o descargar y cargar camiones. Alucino en colores

Pues a esto hemos llegado.

NO ACEPTÉIS ESTOS TRABAJOS sin no cumplís los requisitos que ahora mencionaré, pues si no es así, te están tomando el pelo.



Requisitos para poder realizar un convenio de prácticas
- Estar matriculado en una Universidad o un centro de formación autorizado para la firma de convenios de prácticas con empresas.
- Que la actividad de las prácticas esté relacionada con la formación del estudiante.
- Haber superado el 50% de los créditos necesarios para obtener la titulación.
- Si se trata de prácticas curriculares (incluidas en el plan de estudios), el estudiante debe estar matriculado en la asignatura vinculada a esas prácticas.
- No tener relación contractual alguna con la empresa o institución en la que se vayan a realizar las prácticas.


OJO  :rolleyes:
Que la actividad de las prácticas esté relacionada con la formación del estudiante.

Fuente:
primerempleo


En definitiva, ¿Tienes más de cuarenta? Pues se pasan por el forro de los huevos toda tu experiencia, tus títulos  (mira que me dieron la vara con lo de la ESO y el Bachillerato, lo tengo ¿y para qué?) . Se pasan por el forro todo, lo que quieren es ahorrarse dinerito y se les ocurre la brillante idea de contratar a estudiantes de Universidad, sin contrato y puede que sin pagar, porque aunque deban puede que no lo hagan.


Luego importan el black friday para incentivar el consumo, porque quieren que compremos pero no que cobremos.

Si no cobramos, no compramos, si cobramos poco, compramos poco, así de simple.

¡Que no te tomen el pelo!

Se nota que estoy enfadado ¿no? pues sí , y mucho.





#236
Hola
Como no te contesta nadie...

Prueba esto:
¿Cómo uso una Lista de difusión?

"Una Lista de difusión es una lista de destinatarios que queda guardada. Cuando usas esta lista, puedes volver a difundir un mensaje a los mismos destinatarios sin tener que seleccionarlos de nuevo uno por uno."

Sl2s
#237
Hola

¡Enhorabuena por el proyecto!

Ya está en google XD


https://www.google.es/webhp?source=search_app&gfe_rd=cr&ei=x5AlVrTHMNOCiAaT8oW4AQ&gws_rd=ssl#q=elektrokit

Por cierto, no se de donde sacas el tiempo... :P Veo muchas horas ahí sin dormir.


¿No hay nada para girar la pantalla y que funcione en XP? Encontré varios códigos que funcionan en Vista y posterior pero no en XP.



#238
Hi

Lo que intento es lo siguiente:
-Obtengo código fuente de una página y lo cargo en A
-Cargo la página en el Webbrowser:  WB.DocumentText= A
-Cuando cargue la página llama al evento ReadWeb
-ReadWeb obtiene datos en modo lista y lo Carga en una variable List
-Desde Button_Click llamo a la clase  e intento obtener dicha lista.

Problema: No puedo obtener dicha lista.

Código (vbnet) [Seleccionar]
Class clsGetDataWeb
   Dim Lista As New List(Of String)
   Dim WB As New WebBrowser
   Dim strUrl As String = "http://www...."
   Dim WebSource As String = Nothing


   Public Sub GetDataWeb()

       '//OBTIENE EL CÓDIGO FUENTE DE LA PÁGINA
       Try
           WebSource = GetWebSource(strUrl) 'Obtiene el código de la página
       Catch ex As Exception
           MessageBox.Show(ex.Message)
           Exit Sub
       End Try

       'LLama al evento DocumentCompletes
       AddHandler WB.DocumentCompleted, AddressOf WB_DocumentCompleted

       'Carga el código html en WB
       WB.ScriptErrorsSuppressed = True
       WB.DocumentText = WebSource


   End Sub
   Private Sub WB_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs)
           ReadWeb(WB)
   End Sub
   Private Sub ReadWeb(ByVal WBrowser As WebBrowser)
       Dim document As System.Windows.Forms.HtmlDocument = WBrowser.Document
       Dim doc As HtmlDocument = WBrowser.Document
       Dim divs As HtmlElementCollection = doc.GetElementsByTagName("td")
       Lista.Clear()
       For Each div As HtmlElement In divs
           If div.GetAttribute("classname") = "Canción" Then Lista.Add(div.InnerText)
       Next
       Lista= Lista.Distinct.ToList
   End Sub

   Private Function GetWebSource(ByVal strUrl As String) As String
          ...AQUÍ CÓDIGO PARA OBTENER EL CÓDIGO FUENTE DE LA PÁGINA WEB
Return CódigoFuente
   End Function

   Public ReadOnly Property ParameterNames() As IEnumerable(Of String)
       Get
           Return New List(Of String)(Lista)
       End Get
   End Property

End Class

#End Region



Y desde el un evento click:

Código (vbnet) [Seleccionar]
'//Llamo a
Dim ClassDW As New clsGetDataWeb
       ClassDW.GetDataWeb()
       For Each N As String In ClassDW.ParameterNames
           ListBox1.Items.Add(n)
       Next



He constatado por puntos de interrupción que el código de la página lo obtiene y la lista también. Creo que el problema tiene relación con Evento DocumentCompleted y la propiedad Get

parace como si se estableciese la propiedad antes de que se obtenga la lista

Gracias

[SOLUCIONADO]

Era lo que yo pensaba  :-\

Se carga la propiedad antes de que se obtenga la lista. Para solucionarlo he añadido un simple código de espera
Código (vbnet) [Seleccionar]
   Public ReadOnly Property ParameterNames() As System.Collections.Generic.ICollection(Of String)
       Get

           While [LISTA].Count = 0
               My.Application.DoEvents()
           End While

           Return New List(Of String)([LISTA])
       End Get
   End Property

#239
Otra forma de cambiar el estilo de una ventana...

Código (vbnet) [Seleccionar]
Public Class Form1
    Const WS_VSCROLL As Integer = &H200000
    Const WS_HSCROLL As Integer = &H100000
    Const WS_DISABLED As Integer = &H8000000

    Enum Style_Window
        FLAT = &H0
        NOBORDER_3D = &H400000 '3d sin bordes
        NOTITLEBAR = &H40000 'con bordes sin barra de título
        FLAT_3D = &H800000 'Flat style con línea externa
        BORDER_NOTITLEBAR_SCROLLBAR = &HBEBC20 'con bordes sin barra de título con ScrollBAr
        NOBUTTONSBAR = &HC00000 'sin botones en la barra y no redimensionable
        NOBUTTONSBAR_RESIZABLE = &HC50000 'sin botones en la barra y  redimensionable
        TYPE_MSGBOX = &HC89500 'solo boton cerrar no redimensionable (tipo msgbox)
        TYPE_MSGBOX_NOMIN = &HC99500 'Cerrar + max no redimensionable (tipo msgbox)
        TYPE_MSGBOX_NOMAX = &HCA0000 'Cerrar + min no redimensionable (tipo msgbox)
        TYPE_MSGBOX_ALLBUTTONS = &HCB0000 'todo no redimensionable
        ONLY_CLOSEBUTTON = &HCC0000 'Solo botón Cerrar redimensionable
        ONLY_CLOSE_MAX = &HCD0000 'Cerrar + max redimensionable
        ONLY_CLOSE_MIN = &HCE0000 'Cerrar + min redimensionable
        ALLBUTTONS_RESIZABLE = &HCF0000  'redimensionable
        SCROLLBARS = WS_VSCROLL + WS_HSCROLL
    End Enum
    Enum ExStyle_Window
        BIGBORDER = &H200  'borde ancho
        NORMAL_TITLE_LEFT = &H0 'título a la izquierda
        NORMAL_TITLE_RIGHT = &H1000  'título a la derecha
        INVERT_TITLE_LEFT = &H405000  'Invertido con título a la izquierda
        INVERT_TITLE_RIGHT = &H400000  'Invertido con título a la derecha
        TOOLWINDOW_BIGBORDER_TITLELEFT = &H102390 'Tool window con título a la izquierda y borde grueso
        TOOLWINDOW_BIGBORDER_TITLERIGHT = &H103390 'Tool window con título a la derecha y borde grueso
        TOOLWINDOW_TITLELEFT = &H102490 'Tool window Invertido con título a la izquierda y borde fino
        TOOLWINDOW_TITLERIGHT = &H103490 'Tool window invertido con título a la derecha y borde fino
        TOOLWINDOWS_INVERT_TITLELEFT = &H401080 'Tool window Invertido con título a la izquierda y borde fino
        TOOLWINDOWS_INVERT_TITLERIGHT = &H400180 'Tool window invertido con título a la derecha y borde fino
        TOOLWINDOWS_INVERT_BIGBORDER_TITLELEFT = &H403390 'Tool window Invertido con título a la izquierda y borde grueso
        TOOLWINDOWS_INVERT_BIGBORDER_TITLERIGHT = &H400290 'Tool window invertido con título a la derecha y borde grueso
    End Enum
    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            'cp.Style = cp.Style Or Style_Window.SCROLLBARS
            cp.ExStyle = ExStyle_Window.TOOLWINDOWS_INVERT_TITLERIGHT
            Return cp
        End Get
    End Property
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    End Sub
End Class
#240
Está genial no sabía esa propiedad de Environtment  ;-)

Lo testearé en 64bits más tarde, porque el ratón se quedó sin pilas y estoy recargando y el ratón con teclado numérico es un palo.

sl2s



TESTEADO EN 64BITS

Bueno, ya lo he testeado funciona perfecto y no da ningún error.

Hay que tener en cuenta que el nombre que usé al declarar la función del API es irrelevante. Yo puedo poner VivaLaPepa y funcionaría igual:

Código (vbnet) [Seleccionar]
 <System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="GetWindowLongA", SetLastError:=True)> _
   Private Function VivaLaPepa(ByVal hWnd As IntPtr, _
                                         <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.I4)> ByVal nIndex As Integer) As Integer
   End Function


Lo importante es el punto de entrada GetWindowLongA. Si no establezco el punto de entrada como ocurre por ejemplo en SetWindowPos entonces NO puedo hacer la llamada con otro nombre que no sea SetWindowPos, pues este mismo nombre va actuar como punto de entrada.

Ahora bien, he importado las entradas de USER32.DLL tando en X86 com x64 (Windows 7 64bits) y he encontrado dos  entradas distintas que no se encuentran e x86. Estas son las entradas en User32.dll:

x86
1916  197 00017D64 GetWindowLongA
1919  19A 00019938 GetWindowLongW


x64

1916  197 00017D64 GetWindowLongA
1917  198 00016050 GetWindowLongPtrA
1918  199 0001B970 GetWindowLongPtrW
1919  19A 00019938 GetWindowLongW


Importar Apis


Sin embargo si uso la entrada GetWindowLongPtrA (en sistema de 64bits) o GetWindowLongPtr aparece el siguiente error:

Unable to find an entry point named 'GetWindowLongPtrA' in DLL 'user32.dll

Así no entiendo lo del MSDN. Además pone que para que sea compatible con 32bit y 64bits y ya era compatible con 32bits usando GetWindowLong normal y punto de entrada  GetWindowLongA. Ahora se también que sigue siendo compatible también a 64bits.

Y otro detalle importate. Como he mencionado en 32bits no existen las entradadas GetWindowLongPtrA y GetWindowLongPtrW ¿Por qué dice
To write code that is compatible with both 32-bit ? si dichas entradas no existen en 32 bits XD. No se puede que sea para Windows 8 o posterior o desde lenguaje C


Lo de Environment.Is64BitOperatingSystem ya me ha resultado útil y lo he añadido al código de Importar Apis  ;D. Me va genial para determinar que ProgramFiles usar.

Sl2s

[NUEVO DATO SOBRE ESTE TEMA]

Dandole vueltas al asunto y viendo que Elektro a usado la siguiente convención de llamada para GetWindoLong:
Código (vbnet) [Seleccionar]
<SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist",justification:="Code-Analysis is 32-Bit so it only checks for the entrypoint in the user32.dll of the Win32 API.")><DllImport("user32.dll", EntryPoint:="GetWindowLongPtr", SetLastError:=True)>Public Shared Function GetWindowLongPtr(ByVal hwnd As IntPtr,          <MarshalAs(UnmanagedType.I4)> ByVal nIndex As WindowLongFlags) As IntPtrEnd Function

Me he preguntado ¿Y si mi apliación se está ejecutando con compatibilidad en X86 o como si se ejecutara en X86?

Así que me he dirigido a la configuración de mi proyecto haciendo doble click en My Project  en el Explorador de soluciones y en 'Compilar'
he visto que ponía CPU Destino = X86  y lo he cambiado a X64. He cambiado la llamada a GetWindowLong usando el punto de control GetWindowLongPtrA y sin suprimir errores:

Código (vbnet) [Seleccionar]
 <DllImport("user32.dll", EntryPoint:="GetWindowLongPtrA", SetLastError:=True)> _
   Public Function GetWindowLong(ByVal hwnd As IntPtr, _
    <MarshalAs(UnmanagedType.I4)> ByVal nIndex As Integer) As IntPtr
   End Function


Y NO me da error. Encuentra el punto de entrada  y el programa funciona perfecdtamente. Vuelvo a cambiar a  CPU Destino = X86 y denuevo me dice que no encuentra el punto de entrada.

Entonces llego a la conclusión que la llamada debe hacerse según como compiles el programa y no en el hecho que se ejecute en 32bits o 64bits. De modo que si lo compilo para 64bits y CPU Destino = X64 y llamo al punto de entrada GetWindowLongPtrA sólo será compatible con 64bits. Sin embargo si hago la llamada al punto de entrada GetWindowLongA es compatible en ambos.