|
231
|
Programación / .NET (C#, VB.NET, ASP) / Re: Listview header modificado en listview vbnet
|
en: 12 Diciembre 2015, 18:22 pm
|
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 EventPublic 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: 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
|
Programación / .NET (C#, VB.NET, ASP) / Re: Leer secuencialmente dos tablas de un archivo creado en vb.net 2010
|
en: 3 Diciembre 2015, 15:06 pm
|
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]#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: 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 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 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] 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
|
Programación / .NET (C#, VB.NET, ASP) / Re: Leer secuencialmente dos tablas de un archivo creado en vb.net 2010
|
en: 2 Diciembre 2015, 19:33 pm
|
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: 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 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: Dim MDBConnString_ As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & PathFileMDB & ";"
por esta otra línea: 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: [Hoja1$]
Ejemplo: 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
|
Foros Generales / Foro Libre / Re: Debate elecciones 2015
|
en: 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
|
Foros Generales / Foro Libre / Convenio de Prácticas el nuevo timoempleo
|
en: 2 Diciembre 2015, 12:34 pm
|
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 Que la actividad de las prácticas esté relacionada con la formación del estudiante.Fuente: primerempleoEn 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.
|
|
|
238
|
Programación / .NET (C#, VB.NET, ASP) / Clase y propiedades con Webbrowser
|
en: 29 Noviembre 2015, 14:25 pm
|
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. 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: '//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 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
|
Programación / .NET (C#, VB.NET, ASP) / Re: Cambiar estilo de las ventanas (invertir, quitar botones, bloquear, etc)
|
en: 29 Noviembre 2015, 00:24 am
|
Otra forma de cambiar el estilo de una ventana... 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
|
Programación / .NET (C#, VB.NET, ASP) / Re: Cambiar estilo de las ventanas (invertir, quitar botones, bloquear, etc)
|
en: 28 Noviembre 2015, 05:18 am
|
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 64BITSBueno, 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: <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: x861916 197 00017D64 GetWindowLongA 1919 19A 00019938 GetWindowLongW x641916 197 00017D64 GetWindowLongA 1917 198 00016050 GetWindowLongPtrA 1918 199 0001B970 GetWindowLongPtrW 1919 19A 00019938 GetWindowLongW Importar ApisSin 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 . 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: <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: <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.
|
|
|
|
|
|
|