Saturday 11 December 2010

Undervolt en procesadores AMD K10

¿Que es Undervolt?

Basicamente traducido al español es como decir bajo-voltaje

¿Porque Undervolt?

Si tienes un portatil o PC de escritorio y te preocupan las altas temperaturas o si quieres ayudar al planeta, aparte de tener un buen case/caja ventilada puedes conseguir temperaturas de entre 20° o 30° segun tambien la temperatura ambiente

Por ejemplo ahora mismo en mi cuarto con aire acondicionado a 18° los cores del Phenom II X4 que tengo estan a 29°, sin el aire acondicionado estarian como en 40°, que considero que son altas





Bien el programa del que les hablo es de:


K10STAT


La version por ahora es la 1.41, lo descargas y luego descomprimes el contenido del zip a la carpeta que quieras y ejecutas el archivo K10STAT.exe

Asi tengo configurado los estados del procesador con su voltaje, bueno lo he dejado como esta en K10STAT, no he tocado nada ya que considero que esta bien asi





Puedes crear perfiles, obviamente tiene que probar que es mejor para ti, tambien puedes verlo en la barra de tareas





El icono cuadrado verde indica que esta en estado con el voltaje mas bajo, el icono cambia de color segun el voltaje que tengas configurados en los p-states

NOTA: Por defecto la aplicacion no controla el voltaje asi que si hacemos click derecho sobre el icono y clickeas en Enable Clock Control el programa pasa a tomar el control del voltaje

Vamos a configurarlo para que cada vez que inicies el PC o portatil se ejecute el K10STAT con una configuracion determinada para hacerle undervolt al procesador


  1. Crea un acceso direto del ejecutable K10STAT en el escritorio, tan solo haz click derecho sobre el archivo Click en Enviar -> Escritorio (acceso directo)

  2. Click derecho sobre el acceso directo recien creado click en Propiedades

  3. En el cuadro de texto Destino escribe al final de la esa ruta

  4. 3.1 -ClkCtrl:1 -nw -StayOnTray

    C:\RUTA\AL\K10STAT\K10STAT.exe -ClkCtrl:1 -nw -StayOnTray

    NOTA: recuerda que si la ruta tiene espacios debes usar comillas, ejemplo:

    "C:\RU TA\A L\K10 STAT\K10STAT.exe" -ClkCtrl:1 -nw -StayOnTray


  5. Luego Corta&Pega el acceso directo en la carpeta Inicio del Menu Inicio

  6. C:\Users\[USUARIO_AQUI]\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

    NOTA: puede ser distinto en tu PC


  7. Listo!!


Significado de la linea de comandos:

-ClkCtrl:#(0-4) - Enable Clock Control

  • 0: No Control

  • 1: Control clock of each core.

  • 2: Control clock of all cores together (Criterion is most loaded core).

  • 3: Control clock of all cores together (Criterion is average of all cores).

  • 4: Control clock of all cores together (Criterion is least loaded core).


-StayOnTray mostrar icono en la barra de tareas

-nw no mostrar la ventana inicial


Publicado en tttony.blogspot.com

Sunday 28 November 2010

BlueScreenView lector de archivos .dmp

Me he encontrado con esta utilidad llamada BlueScreenView, que la considero primordial para leer los archivos .dmp que se crean cuando hay una pantalla azul ya sea de Windows XP / Wondows Vista / Windows 7 (32 o 64bits)





Descargar BlueScreenView (pagina oficial) y ademas es portable


Publicado en tttony.blogspot.com

Monday 23 August 2010

Convertir codigo de C# a VB.NET y de VB.NET a C#

Existe un utilidad en la web del conocido elGuille que te ayuda a convertir tu codigo de C# a VB.NET y viceversa

Aqui lo puedes encontrar, te bajas el ejecutable y luego te bajas las dos librerias(no se porque no coloco todo junto)

La utilidad no es 100% fiable, todavia le falta por pulir muchas cosas, yo lo uso para convertir los codigos de C# a VB.NET y tiene muchos errores, mas que todo cuando hay comentarios /* ESTE ES UN COMENTARIO EN C# */ que no los parsea bien

Tambien puedes usarlo via web: C# a VB.NET y de VB.NET a C#

Otra buena utilidad online para convertir codigo esta aqui

ACTUALIZACION: 09/08/2011

Me he encontrado una aplicacion online mucho mejor, ya que permite subir un archivo o varios archivos .zip al servidor el cual contenga los archivos .vb para VB.NET o .cs para C# que quieras convertir

http://converter.telerik.com/Default.aspx


Publicado en tttony.blogspot.com

Sunday 22 August 2010

Encriptar contraseñas con MD5 en C# y VB.NET (Obsoleto)

ADVERTENCIA!!! la encriptacion con la funcion md5() es insegura, es mejor usar la encriptacion BCrypt
Para encriptar contraseñas en tu base de datos lo mas comun es usar la ecriptacion MD5

Codigo C#:

public string GetMD5Hash(string input)
{
MD5CryptoServiceProvider x = new MD5CryptoServiceProvider();
byte[] bs = Encoding.UTF8.GetBytes(input);
bs = x.ComputeHash(bs);
StringBuilder s = new StringBuilder();
foreach (byte b in bs)
{
s.Append(b.ToString("x2").ToLower());
}
string password = s.ToString();
return password;
}


Codigo VB.NET:

Public Function GetMD5Hash(input As String) As String

Dim x As New MD5CryptoServiceProvider()
Byte() bs = Encoding.UTF8.GetBytes(input)
bs = x.ComputeHash(bs)
Dim s As New StringBuilder()
For Each b As Byte in bs

s.Append(b.ToString("x2").ToLower())

Next
Dim password As String = s.ToString()
Return password

End Function


Publicado en tttony.blogspot.com

Sistema de login en C# con Access 2007

He mejorado un poco el sistema y ademas lo puedes descargar como archivo de proyecto para VS2010

Sistema de login

Es facil de usar solo tienes que configurarlo dependiendo de como tengas la base de datos de los usuarios

NUEVO: agregada opcion de encriptacion de contraseña con Bcrypt

La contraseña de la base de datos login.accdb es: test

Ejecuta el proyecto pero modo Debug ya que la base de datos login.accdb esta en el directorio Debug e introduce estos datos:


Usuario: prueba
Contraseña: 5555

El codigo esta documentado


ACTUALIZADO 11/11/12


Publicado en tttony.blogspot.com

Manejar errores en C#

Los errores en las aplicaciones son un dolor de cabeza, no sirve de mucho usar:



try
{
// codigo aqui
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}


Es mejor hacer un log, osea escribir en un archivo el error lanzado, en internet me encontre con este

Cada vez que haya una excepcion tienes la opcion de guardar el error en archivo propio .log o al archivo log del sistema



try
{
// codigo aqui
}
catch(Exception ex)
{
if (!ErrorLog.ErrorRoutine(false, ex))
MessageBox.Show("No es posible escribir en el archivo de error");
}


Fuente: http://www.codeproject.com/KB/dotnet/logger.aspx


Publicado en tttony.blogspot.com

Encriptar/Decriptar cadenas con Base64 en C#

Me he encontrado un codigo para encriptar y decriptar cadenas con Base64:


static class EncryptClass
{

// http://www.codeproject.com/KB/cs/Cryptography.aspx

///
/// Encrypt a string using dual encryption method. Return a encrypted cipher Text
///

/// string to be encrypted
/// use hashing? send to for extra secirity
///
public static string Encrypt(string toEncrypt, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

string key = Properties.Settings.Default.SecurityKey; //<-- crealo en tu configuracion

if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);

TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;

ICryptoTransform cTransform = tdes.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
///
/// DeCrypt a string using dual encryption method. Return a DeCrypted clear string
///

/// encrypted string
/// Did you use hashing to encrypt this data? pass true is yes
///
public static string Decrypt(string cipherString, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = {0};

try
{
/*
* La longitud de cadena enritptada con Hashing es de 24
* si es menor de 24 lanza una excepcion, asi que hay que pasar de ella
*/
toEncryptArray = Convert.FromBase64String(cipherString);
}
catch (Exception)
{
return null;
}

string key = Properties.Settings.Default.SecurityKey;

if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);

TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;

ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

tdes.Clear();
return UTF8Encoding.UTF8.GetString(resultArray);
}
}



Creas un valor de configuracion llamado SecurityKey en tu proyecto y le asignas un valor aleatorio

Fuente: http://www.codeproject.com/KB/cs/Cryptography.aspx

Publicado en tttony.blogspot.com

Saturday 21 August 2010

Guardar tamaño de las columnas de un DataGridView en C#

La terea es sencilla, guardar el tamaño de las columnas de un DataGridView

Primero creas en tu configuracion un valor llamado por ej. DataGridViewColumnSize con el tipo System.Collections.Specialized.StringCollection

En el evento FormLoad despues de haber cargado tus datos en el DataGridView coloca este codigo:

/* * Creado por tttony 2010 * http://tttony.blogspot.com/ * * POR FAVOR NO BORRES ESTE COMENTARIO */

// Primera vez
if (Properties.Settings.Default.DataGridViewColumnSize == null)
{
// como es primera vez que inicia entonces colocar todas
// las columnas con el mismo tamaño
colWidth = (dgvLastServices.Width / dgvLastServices.Columns.Count) - (dgvLastServices.Columns.Count);
foreach (DataGridViewColumn col in dgvLastServices.Columns)
{
col.Width = colWidth;
}
}
else
{
StringCollection cols = Properties.Settings.Default.DataGridViewColumnSize;

string[] colsArray = new string[cols.Count];
cols.CopyTo(colsArray, 0);
Array.Sort(colsArray);

for (int i = 0; i < colsArray.Length; ++i)
{
string[] a = colsArray[i].Split(',');
int index = int.Parse(a[3]);
dataGridView1.Columns[index].DisplayIndex = Int16.Parse(a[0]);
dataGridView1.Columns[index].Width = Int16.Parse(a[1]);
dataGridView1.Columns[index].Visible = bool.Parse(a[2]);
}
}


Y en el evento FormClosing del formulario coloca esto:

/* * Creado por tttony 2010 * http://tttony.blogspot.com/ * * POR FAVOR NO BORRES ESTE COMENTARIO */
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
StringCollection stringCollection = new StringCollection();

int i = 0;
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
stringCollection.Add(string.Format(
"{0},{1},{2},{3}",
column.DisplayIndex.ToString("D2"), // Column order fix
column.Width,
column.Visible,
i++));
}

Properties.Settings.Default.DataGridViewColumnSize = stringCollection;
Properties.Settings.Default.Save();
}



Cuando se cierra el formulario se guarda el tamaño y propiedades de las columnas

Fuente: http://www.codeproject.com

Publicado en tttony.blogspot.com

Thursday 19 August 2010

Compactar base de datos Access 2007 en C# y VB.NET

Para compactar una base de datos Access en C#, primero agregas esta referencia a tu solucion:

Microsoft Office 12.0 Access Database Engine Object Library


Y con esta funcion compactas la base de datos

Codigo C#:

/* * Creado por tttony 2010 * http://tttony.blogspot.com/ * * POR FAVOR NO BORRES ESTE COMENTARIO */

public void compact()
{

try
{
/*
* http://techieyogi.blogspot.com/2009/11/how-to-compact-access-2007-database.html
*/
Microsoft.Office.Interop.Access.Dao.DBEngine objDbEngine = new Microsoft.Office.Interop.Access.Dao.DBEngine();

// Archivo temporal no debe existir
string strDbTmp = Application.StartupPath + @"\compacting__.accdb";
// path de la base de datos a compactar
string strDB = @"C:\db\access.accdb";

objDbEngine.CompactDatabase(strDB , strDbTmp, null, null, ";pwd=" + m_dataBasePassword);

if ((new FileInfo(strDbTmp)).Length == (new FileInfo(strDB)).Length)
{
// no fue compactada ya que tiene el mismo tamaño que antes
File.Delete(strDbTmp);
}
else // compactacion exitosa
{
// copia de seguridad IMPORTANTE!!!
File.Copy(strDB, strDB + ".nocompact_" + DateTime.Today.ToString().Replace("/", "_").Substring(0, 10));
// borrar original
File.Delete(m_dataBaseFile);
// mover la db compactada
File.Move(strDbTmp, m_dataBaseFile);
}

}
catch(Exception ex)
{
ErrorToLog(ex);
}

}


Codigo VB.NET:

' * Creado por tttony 2010 * http://tttony.blogspot.com/ * * POR FAVOR NO BORRES ESTE COMENTARIO


Public Sub compact()

Try
'
' * http://techieyogi.blogspot.com/2009/11/how-to-compact-access-2007-database.html
'

Dim objDbEngine As New Microsoft.Office.Interop.Access.Dao.DBEngine()

' Archivo temporal no debe existir
Dim strDbTmp As String = Application.StartupPath + "\compacting__.accdb"
' path de la base de datos a compactar
Dim strDB As String = "C:\db\access.accdb"

objDbEngine.CompactDatabase(strDB, strDbTmp, Nothing, Nothing, ";pwd=" & m_dataBasePassword)

If (New FileInfo(strDbTmp)).Length = (New FileInfo(strDB)).Length Then
' no fue compactada ya que tiene el mismo tamaño que antes
File.Delete(strDbTmp)
Else
' compactacion exitosa
' copia de seguridad IMPORTANTE!!!
File.Copy(strDB, strDB & ".nocompact_" & DateTime.Today.ToString().Replace("/", "_").Substring(0, 10))
' borrar original
File.Delete(m_dataBaseFile)
' mover la db compactada
File.Move(strDbTmp, m_dataBaseFile)

End If
Catch ex As Exception
ErrorToLog(ex)
End Try

End Sub




Publicado en tttony.blogspot.com

Tuesday 17 August 2010

Compilacion condicional en C#

En C# existe algo llamado compilacion condicional (en otros lenguajes tambien existen) que no es mas que definir una variable segun el entorno (Debug, Release) por ej:

/* * Creado por tttony 2010 * http://tttony.blogspot.com/ * * POR FAVOR NO BORRES ESTE COMENTARIO */

#if (DEBUG)

// Esto se mostrara solo en modo depuracion
private void info()
{
Debug.WriteLine("Alguna informacion aqui en modo depuracion (debug)");
}

#endif



En Visual Studio por defecto no puedes elegir el modo de trabajo (Debug o Release), asi que lo activamos en el menu:


Herramientas -> Opciones -> En el panel izq. selecciona Proyectos y soluciones -> General -> En la parte derecha activa la opcion Mostrar configuraciones de generacion avanzadas


Ahora si vas al menu:


Proyecto -> Propiedades de TU_PROYECTO -> Generar


Alli veras que se han activado unos combosBox (Configuracion y Plataforma respectivamente) en la parte de arriba, podras configurar que es lo que quieres en modo debug y modo release



Publicado en tttony.blogspot.com

Monday 16 August 2010

Agregar tu programa al inicio de Windows en C# y VB.NET

Con este codigo puedes iniciar tu aplicacion con Windows:

Codigo C#:

/*
* Creado por tttony 2010
* http://tttony.blogspot.com/
*
* POR FAVOR NO BORRES ESTE COMENTARIO
*/
RegistryKey hklm = Registry.LocalMachine;
hklm = hklm.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
string path = hklm.GetValue(Application.ProductName).ToString();

string thisApp = Application.ExecutablePath.ToUpper();

if (path != thisApp) // No se inicia con windows
{
hklm.SetValue(Application.ProductName, thisApp);
}

hklm.Close();


Codigo VB.NET:

'
' * Creado por tttony 2010
' * http://tttony.blogspot.com/
' *
' * POR FAVOR NO BORRES ESTE COMENTARIO
'

Dim hklm As RegistryKey = Registry.LocalMachine
hklm = hklm.CreateSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run")
Dim path As String = hklm.GetValue(Application.ProductName).ToString()

Dim thisApp As String = Application.ExecutablePath.ToUpper()

If path <> thisApp Then
' No se inicia con windows
hklm.SetValue(Application.ProductName, thisApp)
End If

hklm.Close()




Publicado en tttony.blogspot.com

Guardar configuracion previa en C# y VB.NET

Cada vez que compilas tu programa en C# cambia la version del ensamblado y por consiguiente la aplicacion crea una nueva carpeta:


C:\Documents and Settings\Usuario\Configuración local\Datos de programa\NOMBREPROGRAMA\NOMREDELEJECUTABLE.EXE_Url_2ha3w3vmz3qfzpaloruetfyed\1.0.3880.23525\app.config


Otra compilacion:

C:\Documents and Settings\Usuario\Configuración local\Datos de programa\NOMBREPROGRAMA\NOMREDELEJECUTABLE.EXE_Url_2ha3w3vmz3qfzpaloruetfyed\1.0.3880.24678\app.config


Entonces ahi tendras problemas con la configuracion y tendras que configurar el programa cada vez que lo compiles

Para evitar esto agrega este codigo, normalmente lo agrego en el archivo Program.cs de la solucion:

Codigo C#:

/*
* Importar la ultima configuracion
*/
Version appVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;

// Cambio la version del ensamblado???
// si es asi entonces guardalo
if (Properties.Settings.Default.ApplicationVersion != appVersion.ToString())
{
Properties.Settings.Default.Upgrade(); // <-- aqui importa la configuracion anterior
Properties.Settings.Default.ApplicationVersion = appVersion.ToString();
Properties.Settings.Default.Save();
}



Codigo VB.NET:

'
' * Importar la ultima configuracion
'

Dim appVersion As Version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version

' Cambio la version del ensamblado???
' si es asi entonces guardalo
If Properties.Settings.[Default].ApplicationVersion <> appVersion.ToString() Then
Properties.Settings.[Default].Upgrade()
' <-- aqui importa la configuracion anterior
Properties.Settings.[Default].ApplicationVersion = appVersion.ToString()
Properties.Settings.[Default].Save()
End If


Como veras tendras que agregar un campo de configuracion llamado ApplicationVersion


Publicado en tttony.blogspot.com

BrowserFolder en C# y VB.NET

Necesitado en un BrowserFolder me encontre con este:

Codigo C#:

folderBrowserDialog1.Description = "Buscar el directorio";

// Para tener un directorio de inicio propio debes primero
// asignar a RootFolder = Environment.SpecialFolder.MyComputer
// luego en la siguiente linea escribes el directorio de inicio
// en SelectedPath

folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer;
folderBrowserDialog1.SelectedPath = Application.StartupPath; // <-- Directorio de inicio

if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
txtReportsPath.Text = folderBrowserDialog1.SelectedPath;
}


Codigo VB.NET:

folderBrowserDialog1.Description = "Buscar el directorio"
' Para tener un directorio de inicio propio debes primero
' asignar a RootFolder = Environment.SpecialFolder.MyComputer
' luego en la siguiente linea escribes el directorio de inicio
' en SelectedPath
folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer
folderBrowserDialog1.SelectedPath = Application.StartupPath ' <-- Directorio de inicio
If folderBrowserDialog1.ShowDialog() = DialogResult.OK Then
txtReportsPath.Text = folderBrowserDialog1.SelectedPath
End if


Pues bien o mejor dicho mal, ya que este control no permite ver carpetas en la red, si que malo no???

Buscando en la web, me encontre con la funcion SHBrowseForFolder de la API de Windows, segui buscando y encontre este codigo que tambien venia sin el InitDir, asi que lo modifique:

Codigo C#:

using System;
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WINAPI32
{
/*
* Codigo original de netomatix.com
* http://www.netomatix.com/FolderBrowser.aspx
*
* Modificado para tener un directorio de inicio por: tttony 2010
* http://tttony.blogspot.com/
*
* POR FAVOR NO BORRAR ESTE COMENTARIO
*/
public delegate int BrowseCallbackProc(IntPtr hwnd, int uMsg, IntPtr wParam, IntPtr lParam);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
[ComVisible(true)]
public class BROWSEINFO
{
public IntPtr hwndOwner;
public IntPtr pidlRoot;
public IntPtr pszDisplayName;
public string lpszTitle;
public int ulFlags;
public BrowseCallbackProc lpfn;
public IntPtr lParam;
public int iImage;

}

public class Win32SDK
{
[DllImport("shell32.dll", PreserveSig = true, CharSet = CharSet.Auto)]
public static extern IntPtr SHBrowseForFolder(BROWSEINFO bi);

[DllImport("shell32.dll", PreserveSig = true, CharSet = CharSet.Auto)]
public static extern bool SHGetPathFromIDList(IntPtr pidl, IntPtr pszPath);

[DllImport("shell32.dll", PreserveSig = true, CharSet = CharSet.Auto)]
public static extern int SHGetSpecialFolderLocation(IntPtr hwnd, int csidl, ref IntPtr ppidl);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, string lParam);

}

public enum BrowseForFolderMessages
{
BFFM_ENABLEOK = 0x465,
BFFM_INITIALIZED = 1,
BFFM_IUNKNOWN = 5,
BFFM_SELCHANGED = 2,
BFFM_SETEXPANDED = 0x46a,
BFFM_SETOKTEXT = 0x469,
BFFM_SETSELECTIONA = 0x466,
BFFM_SETSELECTIONW = 0x467,
BFFM_SETSTATUSTEXTA = 0x464,
BFFM_SETSTATUSTEXTW = 0x468,
BFFM_VALIDATEFAILEDA = 3,
BFFM_VALIDATEFAILEDW = 4
}

[Flags, Serializable]
public enum BrowseFlags
{
BIF_DEFAULT = 0x0000,
BIF_BROWSEFORCOMPUTER = 0x1000,
BIF_BROWSEFORPRINTER = 0x2000,
BIF_BROWSEINCLUDEFILES = 0x4000,
BIF_BROWSEINCLUDEURLS = 0x0080,
BIF_DONTGOBELOWDOMAIN = 0x0002,
BIF_EDITBOX = 0x0010,
BIF_NEWDIALOGSTYLE = 0x0040,
BIF_NONEWFOLDERBUTTON = 0x0200,
BIF_RETURNFSANCESTORS = 0x0008,
BIF_RETURNONLYFSDIRS = 0x0001,
BIF_SHAREABLE = 0x8000,
BIF_STATUSTEXT = 0x0004,
BIF_UAHINT = 0x0100,
BIF_VALIDATE = 0x0020,
BIF_NOTRANSLATETARGETS = 0x0400,
}

public class FolderBrowser
{
private string m_strDirectoryPath;
private string m_strTitle;
private string m_strDisplayName;
private BrowseFlags m_Flags;
private string m_initDir = null;

public FolderBrowser()
{
m_Flags = BrowseFlags.BIF_DEFAULT;
m_strTitle = "";
}

public string DirectoryPath
{
get { return this.m_strDirectoryPath; }
}

public string DisplayName
{
get { return this.m_strDisplayName; }
}

public string Title
{
set { this.m_strTitle = value; }
}

public BrowseFlags Flags
{
set { this.m_Flags = value; }
}

public DialogResult ShowDialog()
{
BROWSEINFO bi = new BROWSEINFO();
bi.pszDisplayName = IntPtr.Zero;
//bi.lpfn = IntPtr.Zero;
/*
* InitDir??
*/
bi.lpfn = new BrowseCallbackProc(browserCallBack);
bi.lParam = IntPtr.Zero;
bi.lpszTitle = "Select Folder";
IntPtr idListPtr = IntPtr.Zero;
IntPtr pszPath = IntPtr.Zero;
try
{
if (this.m_strTitle.Length != 0)
{
bi.lpszTitle = this.m_strTitle;
}
bi.ulFlags = (int)this.m_Flags;
bi.pszDisplayName = Marshal.AllocHGlobal(256);
// Call SHBrowseForFolder
idListPtr = Win32SDK.SHBrowseForFolder(bi);

// Check if the user cancelled out of the dialog or not.
if (idListPtr == IntPtr.Zero)
{
return DialogResult.Cancel;
}

// Allocate ncessary memory buffer to receive the folder path.
pszPath = Marshal.AllocHGlobal(256);
// Call SHGetPathFromIDList to get folder path.
bool bRet = Win32SDK.SHGetPathFromIDList(idListPtr, pszPath);
// Convert the returned native poiner to string.
m_strDirectoryPath = Marshal.PtrToStringAuto(pszPath);
this.m_strDisplayName = Marshal.PtrToStringAuto(bi.pszDisplayName);
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
return DialogResult.Abort;
}
finally
{
// Free the memory allocated by shell.
if (idListPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(idListPtr);
}
if (pszPath != IntPtr.Zero)
{
Marshal.FreeHGlobal(pszPath);
}
if (bi != null)
{
Marshal.FreeHGlobal(bi.pszDisplayName);
}
}
return DialogResult.OK;
}

private IntPtr GetStartLocationPath()
{
return IntPtr.Zero;
}

public string InitDir
{
set { this.m_initDir = value; }
}

private int browserCallBack(IntPtr hWnd, int uMsg, IntPtr wParam, IntPtr lParam)
{
if (uMsg == (int)BrowseForFolderMessages.BFFM_INITIALIZED)
{
/*
* Con BFFM_SETSELECTIONW todo bien
*/
Win32SDK.SendMessage(hWnd, (int)BrowseForFolderMessages.BFFM_SETSELECTIONW, 1, this.m_initDir);
}

return 0;
}
}

}


Codigo VB.NET:

Imports System.Diagnostics
Imports System.Collections
Imports System.ComponentModel
Imports System.Drawing
Imports System.Data
Imports System.Windows.Forms
Imports System.Runtime.InteropServices

Namespace WINAPI32
'
' * Codigo original de netomatix.com
' * http://www.netomatix.com/FolderBrowser.aspx
' *
' * Modificado para tener un directorio de inicio por: tttony 2010
' * http://tttony.blogspot.com/
' *
' * POR FAVOR NO BORRAR ESTE COMENTARIO
'

Public Delegate Function BrowseCallbackProc(hwnd As IntPtr, uMsg As Integer, wParam As IntPtr, lParam As IntPtr) As Integer

_
_
Public Class BROWSEINFO
Public hwndOwner As IntPtr
Public pidlRoot As IntPtr
Public pszDisplayName As IntPtr
Public lpszTitle As String
Public ulFlags As Integer
Public lpfn As BrowseCallbackProc
Public lParam As IntPtr
Public iImage As Integer

End Class

Public Class Win32SDK
_
Public Shared Function SHBrowseForFolder(bi As BROWSEINFO) As IntPtr
End Function

_
Public Shared Function SHGetPathFromIDList(pidl As IntPtr, pszPath As IntPtr) As Boolean
End Function

_
Public Shared Function SHGetSpecialFolderLocation(hwnd As IntPtr, csidl As Integer, ByRef ppidl As IntPtr) As Integer
End Function

_
Public Shared Function SendMessage(hWnd As IntPtr, Msg As Integer, wParam As Integer, lParam As String) As IntPtr
End Function

End Class

Public Enum BrowseForFolderMessages
BFFM_ENABLEOK = &H465
BFFM_INITIALIZED = 1
BFFM_IUNKNOWN = 5
BFFM_SELCHANGED = 2
BFFM_SETEXPANDED = &H46a
BFFM_SETOKTEXT = &H469
BFFM_SETSELECTIONA = &H466
BFFM_SETSELECTIONW = &H467
BFFM_SETSTATUSTEXTA = &H464
BFFM_SETSTATUSTEXTW = &H468
BFFM_VALIDATEFAILEDA = 3
BFFM_VALIDATEFAILEDW = 4
End Enum

_
Public Enum BrowseFlags
BIF_DEFAULT = &H0
BIF_BROWSEFORCOMPUTER = &H1000
BIF_BROWSEFORPRINTER = &H2000
BIF_BROWSEINCLUDEFILES = &H4000
BIF_BROWSEINCLUDEURLS = &H80
BIF_DONTGOBELOWDOMAIN = &H2
BIF_EDITBOX = &H10
BIF_NEWDIALOGSTYLE = &H40
BIF_NONEWFOLDERBUTTON = &H200
BIF_RETURNFSANCESTORS = &H8
BIF_RETURNONLYFSDIRS = &H1
BIF_SHAREABLE = &H8000
BIF_STATUSTEXT = &H4
BIF_UAHINT = &H100
BIF_VALIDATE = &H20
BIF_NOTRANSLATETARGETS = &H400
End Enum

Public Class FolderBrowser
Private m_strDirectoryPath As String
Private m_strTitle As String
Private m_strDisplayName As String
Private m_Flags As BrowseFlags
Private m_initDir As String = Nothing

Public Sub New()
m_Flags = BrowseFlags.BIF_DEFAULT
m_strTitle = ""
End Sub

Public ReadOnly Property DirectoryPath() As String
Get
Return Me.m_strDirectoryPath
End Get
End Property

Public ReadOnly Property DisplayName() As String
Get
Return Me.m_strDisplayName
End Get
End Property

Public WriteOnly Property Title() As String
Set
Me.m_strTitle = value
End Set
End Property

Public WriteOnly Property Flags() As BrowseFlags
Set
Me.m_Flags = value
End Set
End Property

Public Function ShowDialog() As DialogResult
Dim bi As New BROWSEINFO()
bi.pszDisplayName = IntPtr.Zero
'bi.lpfn = IntPtr.Zero;
'
' * InitDir??
'

bi.lpfn = New BrowseCallbackProc(AddressOf browserCallBack)
bi.lParam = IntPtr.Zero
bi.lpszTitle = "Select Folder"
Dim idListPtr As IntPtr = IntPtr.Zero
Dim pszPath As IntPtr = IntPtr.Zero
Try
If Me.m_strTitle.Length <> 0 Then
bi.lpszTitle = Me.m_strTitle
End If
bi.ulFlags = CInt(Me.m_Flags)
bi.pszDisplayName = Marshal.AllocHGlobal(256)
' Call SHBrowseForFolder
idListPtr = Win32SDK.SHBrowseForFolder(bi)

' Check if the user cancelled out of the dialog or not.
If idListPtr = IntPtr.Zero Then
Return DialogResult.Cancel
End If

' Allocate ncessary memory buffer to receive the folder path.
pszPath = Marshal.AllocHGlobal(256)
' Call SHGetPathFromIDList to get folder path.
Dim bRet As Boolean = Win32SDK.SHGetPathFromIDList(idListPtr, pszPath)
' Convert the returned native poiner to string.
m_strDirectoryPath = Marshal.PtrToStringAuto(pszPath)
Me.m_strDisplayName = Marshal.PtrToStringAuto(bi.pszDisplayName)
Catch ex As Exception
Trace.WriteLine(ex.Message)
Return DialogResult.Abort
Finally
' Free the memory allocated by shell.
If idListPtr <> IntPtr.Zero Then
Marshal.FreeHGlobal(idListPtr)
End If
If pszPath <> IntPtr.Zero Then
Marshal.FreeHGlobal(pszPath)
End If
If bi IsNot Nothing Then
Marshal.FreeHGlobal(bi.pszDisplayName)
End If
End Try
Return DialogResult.OK
End Function

Private Function GetStartLocationPath() As IntPtr
Return IntPtr.Zero
End Function

Public WriteOnly Property InitDir() As String
Set
Me.m_initDir = value
End Set
End Property

Private Function browserCallBack(hWnd As IntPtr, uMsg As Integer, wParam As IntPtr, lParam As IntPtr) As Integer
If uMsg = CInt(BrowseForFolderMessages.BFFM_INITIALIZED) Then
'
' * Con BFFM_SETSELECTIONW todo bien
'

Win32SDK.SendMessage(hWnd, CInt(BrowseForFolderMessages.BFFM_SETSELECTIONW), 1, Me.m_initDir)
End If

Return 0
End Function
End Class

End Namespace



Como usarlo??

Codigo C#:

FolderBrowser browser = new FolderBrowser();
browser.Title = "Buscar el directorio";
browser.Flags = BrowseFlags.BIF_NEWDIALOGSTYLE | BrowseFlags.BIF_NONEWFOLDERBUTTON;
browser.InitDir = Application.StartupPath; // <-- el directorio de inicio
if (browser.ShowDialog() == DialogResult.OK)
{
txtPath.Text = browser.DirectoryPath;
}


Codigo VB.NET:

Dim browser As New FolderBrowser()
browser.Title = "Buscar el directorio"
browser.Flags = BrowseFlags.BIF_NEWDIALOGSTYLE Or BrowseFlags.BIF_NONEWFOLDERBUTTON
browser.InitDir = Application.StartupPath ' <-- el directorio de inicio
If browser.ShowDialog() = DialogResult.OK Then
txtPath.Text = browser.DirectoryPath
End if



Publicado en tttony.blogspot.com

Wednesday 4 August 2010

Instalar Office 2007 Enterprise desatendido

Buscando en la web me encontre de que existe una manera de instalar el Office 2007 Enterprise de forma desatendida, pues bien segun he leido la unica version que se puede instalar desatendidamente es la version Enterprise:


La forma de hacerlo es configurar el Office mediante este comando:

C:\office2007\setup.exe /admin


Luego de seguir los pasos que te indican alli, al final guardas un archivo en el menu Archivo --> Guardar con la extension desatendido.MSP y usandolo de esta manera:

OJO ESTE METODO NO ME FUNCIONO!!! SIGUE LEYENDO

C:\office2007\setup.exe /adminfile desatendido.msp


Se supone que se deberia de instalar sin preguntar nada, sin embargo no es asi, al ejecutar este ultimo comando te abre la ventana con el boton Continuar osea que no es desatendido.


Pero existe otra manera de hacerlo y es editando el archivo:

Enterprise.WW\config.xml



<Configuration Product="Enterprise">

<Display Level="basic" CompletionNotice="no" SuppressModal="yes" AcceptEula="yes" />

<!-- <Logging Type="standard" Path="%temp%" Template="Microsoft Office Enterprise Setup(*).txt" /> -->

<PIDKEY Value="AQUITUCODIGOSINELGUION" />

<USERNAME Value="PC" />

<COMPANYNAME Value="PC" />

<!-- <INSTALLLOCATION Value="%programfiles%\Microsoft Office" /> -->

<!-- <LIS CACHEACTION="CacheOnly" /> -->

<!-- <SOURCELIST Value="\\server1\share\Office12;\\server2\share\Office12" /> -->

<!-- <DistributionPoint Location="\\server\share\Office12" /> -->

<!-- <OptionState Id="OptionID" State="absent" Children="force" /> -->

<!-- <Setting Id="Reboot" Value="IfNeeded" /> -->

<!-- <Command Path="msiexec.exe" Args="/i \\server\share\my.msi" QuietArg="/q" ChainPosition="after" Execute="install" /> -->

</Configuration>


El archivo esta oculto y ademas no se puede escribir en el asi que primero guardalo por ejemplo en el Escritorio y luego lo copias y reemplazas en el directorio Enterprise.WW

Basicamente lo que se hace es que el modo de presentacion sea el basico:
Display Level="basic"

No avisar cuando termine:
CompletionNotice="no"

Suprimimos el modal:
SuppressModal="yes"

Y aceptamos la licencia:
AcceptEula="yes"



Para ejecutarlo haz lo siguiente:

C:\office2007\setup.exe /config Enterprise.WW\config.xml



NOTA: obviamente cambia el directorio por el tuyo


Publicado en tttony.blogspot.com

Thursday 15 July 2010

Resetear BIOS de una Lenovo 3000 C200




Este post es especifico para la laptop Lenovo 3000 C200, los fabricantes, en este caso Lenovo, proveen en su pagina web un manual de intrucciones paso a paso de como desarmar una laptop

AQUI puedes ingresar el modelo/serie de la laptop y les aparecera el manual detallado de como desarmar la laptop, el link es especifico para Venezuela, si no aparece tu modelo entra en: (la laptop esta descontinuada y no encontraras guias ni manuales en la pagina de Lenovo)

1. lenovo.com
2. Soporte y Descargas
3. Guias y manuales
4. Introduce el modelo/serie de la laptop


Introduccion




En estos dias me he topado con una laptop Lenovo 3000 C200 que te pedia contraseña para iniciar, ni siquiera te deja entrar al BIOS, asi que habia que resetear el BIOS, pero como?

Buscando en la web de lenovo, me lei un manual, que te decia como resetear el BIOS (pagina no disponible) y funciono a la perfeccion, sin necesidad de quitar la pila, tan solo hay que hacer contacto para crear un corto


Pasos para resetear la BIOS



  1. Desconectar la bateria de la portatil
  2. Desconectar el cargador
  3. Debajo, quita la tapa donde estan las memorias y retira las memorias
  4. Ubica esto:




  5. Con un destornillador haz contacto por un rato en esa zona
  6. Listo!!


Publicado en tttony.blogspot.com

Monday 5 July 2010

Problemas con las fechas en Access en C# y VB.NET

Si han tenido problemas para buscar filas con determinadas fechas, la fecha debe ser con este formato: YYYY/MM/DD de lo contrario tendras resultados indeseables como los que he tenido, aqui les dejo esta funcion:

Codigo C#:

// Darle formato a la fecha
private string ToDBDate(DateTime dt)
{
return dt.Year + "/" + dt.Month + "/" + dt.Day;
}


Codigo VB.NET:

' Darle formato a la fecha
Private Function ToDBDate(dt As DateTime) As String

Return dt.Year & "/" & dt.Month & "/" & dt.Day

End Function


EL otro problema que surge es con sentencias BETWEEN

Codigo C#:

string sql = String.Format("SELECT * FROM table1 WHERE datetime BETWEEN #{0} 00:00:00# AND #{1} 23:59:59#", ToDBDate(fromDateTime), ToDBDate(toDateTime));


Codigo VB.NET:

Dim sql As String = String.Format("SELECT * FROM table1 WHERE datetime BETWEEN #{0} 00:00:00# AND #{1} 23:59:59#", ToDBDate(
fromDateTime), ToDBDate(toDateTime))


Asi el resultado sera el que buscas


Publicado en tttony.blogspot.com

Wednesday 12 May 2010

Reacciones en tus posts en Blogger

Para que tus visitantes voten por tus post debes activar las reacciones en tus post, sigue estos pasos:

1. Entra en Blogger
2. Click en Diseño
3. En el Gadget "Entradas del Blog" click en editar
4. Activa la casilla Reacciones
5. Y listo!!!

NOTA: si no te aparecen las casillas para votar en tu post entonces hay que editar la plantilla:

1. Entra en tu cuenta Blogger
2. Click en Diseño
3. Click en Edición HTML y activa Expandir plantillas de artilugios
4. Busca esta linea: (en Firefox Ctrl+F)


<p><dat:post.body/></p>


5. Abajo de esa linea pega este codigo


Publicado en tttony.blogspot.com

Agregar boton AddThis a tu Blogger

Pasos a seguir:

1. Entra en tu cuenta Blogger
2. Click en Diseño
3. Click en Edición HTML y activa Expandir plantillas de artilugios
4. Busca esta linea: (en Firefox Ctrl+F)

<div class="post-footer">

NOTA: También si quieres lo puedes colocar debajo de la linea que dice:
<div class="post-footer-line post-footer-line-1">
pero en mi caso lo tengo con la primera opcion
5. Abajo de esa linea pega este código o si solo quieres que aparezca en cada post pega este código

NOTA IMPORTANTE: en el código debes cambiar el id de AddThis por el tuyo, en el archivo te dice donde es, tan solo reemplaza tttony por el nombre de tu usuario en AddThis

Actualizado: 30/01/11


Publicado en tttony.blogspot.com

Botones para compartir en Blogger

Aqui les tengo unos botones para compartir sus post en las distintas redes sociales, es el mismo que tengo al final de este post:






Pasos a seguir:

1. Entra en tu cuenta Blogger
2. Click en Diseño
3. Click en Editar HTML y activa Expandir plantillas de artilugios
4. Busca esta linea: (en Firefox Ctrl+F)

<div class="post-footer">

NOTA: Tambien si quieres lo puedes colocar debajo de la linea que dice:
<div class="post-footer-line post-footer-line-1">
pero en mi caso lo tengo con la primera opcion
5. Abajo de esa linea pega este codigo o si solo quieres que aparezca en el post pega este codigo
6. Un paso final, coloca este codigo en la parte CSS de la plantilla

.post-footer-shares-buttons img { margin:.3em; }


Fuente: http://sedatkurtulus.blogspot.com/2010/01/simple-share-buttons-for-blogger.html


Publicado en tttony.blogspot.com

Thursday 6 May 2010

Paises y banderas que hablan ingles

Aqui les tengo los paises y banderas que hablan ingles:

Paises donde el idioma ingles es oficial:

Español Inglés
-----------------------------------
Reino Unido United Kingdom
Estados Unidos United States
Australia Australia


Lista de otros paises donde hablan tambien ingles ademas de sus idiomas locales


Español Inglés
---------------------------------------------
Antigua y Barbuda Antigua and Barbuda
Bahamas Bahamas
Barbados Barbados
Belice Belize
Botsuana Botswana
Camerún Cameroon
Canadá Canada
Dominica Dominica
Fiyi Fiji
Gambia Gambia
Ghana Ghana
Granada Grenada
Guyana Guyana
India India
Irlanda Ireland
Jamaica Jamaica
Jordania Jordan
Kenia Kenya
Kiribati Kiribati
Lesoto Lesotho
Liberia Liberia
Malaui Malawi
Malta Malta
Islas Marshall Marshall Islands
Mauricio Mauritius
Estados Federados de Micronesia Federated States of Micronesia
Namibia Namibia
Nauru Nauru
Nueva Zelanda New Zealand
Nigeria Nigeria
Pakistán Pakistan
Palaos Palau
Papúa Nueva Guinea Papua New Guinea
Filipinas Philippines
Ruanda Rwanda
San Cristóbal y Nieves Saint Kitts and Nevis
Santa Lucía Saint Lucia
San Vicente y las Granadinas Saint Vincent and the Grenadines
Samoa Samoa
Seychelles Seychelles
Sierra Leona Sierra Leone
Singapur Singapore
Islas Salomón Solomon Islands
Sudáfrica South Africa
Sudán Sudan
Suazilandia Swaziland
Tanzania Tanzania
Tonga Tonga
Trinidad y Tobago Trinidad and Tobago
Tuvalu Tuvalu
Uganda Uganda
Vanuatu Vanuatu
Zambia Zambia
Zimbabue Zimbabwe


Descargar banderas

Estan en tres formatos: pequeñas, medianas y grandes y son en total 57 paises/banderas


Publicado en tttony.blogspot.com

Tuesday 9 February 2010

TextBox numerico en C# y VB.NET

Codigo C#:

private void TextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!Char.IsDigit(e.KeyChar)) // Si no es numerico
{
// Invalidar la accion
e.Handled = true;
// Enviar el sonido de beep de windows
System.Media.SystemSounds.Beep.Play();
}
}



Codigo VB.NET:

Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs)

If Not Char.IsDigit(e.KeyChar) Then

' Invalidar la accion
e.Handled = true ' Si no es numerico
' Enviar el sonido de beep de windows
System.Media.SystemSounds.Beep.Play()

End if

End Sub




Publicado en tttony.blogspot.com

Solucion al error


La generación SQL dinámica para UpdateCommand no es compatible con SelectCommand, que no devuelve ninguna información de columna de clave.


Este error se produce cuando se esta actualizando un registro que no tiene un campo unico, lo que tienes que hacer es marcar como unico algun campo que normalmente es llamado ID y listo solucionado el problema



Publicado en tttony.blogspot.com

Recuperar datos entre formularios en C# y VB.NET

En VB6.0 era tan sencillo como esto:

'Form2
txtNombre.Text = frmMain.txtNombre.Text

'O usando una variable publica
txtNombre.Text = frmMain.strNombre


En C# es distinto ya que se manejan clases, supongamos que estas en esta situacion, tienes dos formularios: FormUno.cs y FormDos.cs, el formulario FormUno es el primero en iniciar y tienes dos ComboBox en cada formulario llamados ComboBox1 y ComboBox2 pero quieres que en el FormDos en el evento Load cargue los datos de los CombosBoxes del FormUno sin instanciar el formulario porque recuerda que el FormUno inicia primero:

Codigo C#:

// FormUno.cs
public partial class FormUno : Form
{
public static string strCombo1 = "";
public static string strCombo2 = "";

private void ComboBox1_DropDown(object sender, EventArgs e)
{
strCombo1 = ComboBox1.Text;
}

private void ComboBox1_DropDownClosed(object sender, EventArgs e)
{
strCombo1 = ComboBox1.Text;
}
private void ComboBox2_DropDown(object sender, EventArgs e)
{
strCombo2 = ComboBox2.Text;
}

private void ComboBox2_DropDownClosed(object sender, EventArgs e)
{
strCombo2 = ComboBox2.Text;
}

}


Codigo VB.BET:

' FormUno.cs
Public Partial Class FormUno Inherits Form

Public Shared strCombo1 As String = ""
Public Shared strCombo2 As String = ""
Private Sub ComboBox1_DropDown(sender As Object, e As EventArgs)
strCombo1 = ComboBox1.Text
End Sub

Private Sub ComboBox1_DropDownClosed(sender As Object, e As EventArgs)
strCombo1 = ComboBox1.Text
End Sub
Private Sub ComboBox2_DropDown(sender As Object, e As EventArgs)
strCombo2 = ComboBox2.Text
End Sub

Private Sub ComboBox2_DropDownClosed(sender As Object, e As EventArgs)
strCombo2 = ComboBox2.Text
End Sub

End Class


Declarar dos variables publicas y estaticas en la clase para asi acceder directamente a ellas, ademas si los CombosBoxes cambian de Texto hay que declarar los eventos DropDown y DropDownClosed para guardar instantaneamente el texto en la variable y asi quedaria el FormDos:

Codigo C#:

public partial class FormDos : Form
{

private void FormDos_Load(object sender, EventArgs e)
{
/** Sin necesidad de instanciar el FormUno se puede acceder a los datos **/
this.Combo1.Text = FormUno.strCombo1;
this.Combo2.Text = FormUno.strCombo2;
}

}


Codigo VB.NET:

Public Partial Class FormDos Inherits Form

Private Sub FormDos_Load(sender As Object, e As EventArgs)
' Sin necesidad de instanciar el FormUno se puede acceder a los datos
this.Combo1.Text = FormUno.strCombo1
this.Combo2.Text = FormUno.strCombo2
End Sub

End Sub


NOTA: codigos convertidos gracias a esta aplicacion


Publicado en tttony.blogspot.com

Sunday 31 January 2010

Olvídate de jesús ¡Las estrellas te aman!

Bueno como ateo que soy inicio esta nueva seccion de videos e imagenes relaciones con el ateismo, esta vez les mostrare un video que encontre en youtube que aunque es muy corto dice algo que es muy importante:

Olvídate de jesús ¡Las estrellas te aman!




Es verdad olvidate de de Dios, Jesus y todo lo relacionado con la religion porque Dios no te ha creado sino las estrellas...


Publicado en tttony.blogspot.com