How to create a custom ToolBar in Visual Studio

As this previous post on how to Collapse all projects in the Solution Explorer shows, it is sometimes necessary to add custom ToolBars to the Visual Studio IDE. This post will show you how to do it…

1.- Create a new Tool Bar

Just go to Tools –> Customize, you will find a new window like this one:

image

 

Click on the ToolBars tab, and then in the “New” button. It will ask for the name of the new ToolBar, in our case, the name was: “Macros”. Just type it and press return.

 

Now, your new ToolBar appears in the list on your left. Be sure to check it, so it will appear in the VisualStudio IDE (you can make it a floating ToolBar or dock it into the upper space for toolbars, whatever you want).

 

 

2.- Add a new button to the ToolBar

Go to Tools –> Customize again, but this time click on the “Commands” tab, it´s something like this:

image

 

You have Command Categories on your left, and all the commands belonging to the selected category on your right.

 

To create a new button for one of that commands, just Drag&Drop the desired command to your new ToolBar. Easy as that.

 

3.- Customize the appearance of the button

Again, go to Tools –> Customize –> Commands Tab.

This time, click on the “Rearrange Commands” button. A new window will show with all the customizing options for your menus and toolbars. Just like this one:

image

In this window, you can customize many things, like button order, appearance, icons, texts, whatever.

To customize your new ToolBar, just select the “ToolBar” radio button and your recently created ToolBar in the combo box of your right.

The list on the bottom-left part of the windows will show all the buttons the toolbar contains, and on the bottom-right part you have customizing buttons: add, delete, move up and down and modify.

This last option allows you to change button text (Name), icons, and all that stuff.

Hope you liked it.

Collapse All Projects in the Solution Explorer (Visual Studio)

If you work in large projects usually, you can end with up to 30, 40 , 50 projects or more inside a single solution.

If that´s your case, it is sometimes a pain in the ass work with the solution explorer. In addition to that, Visual Studio sometimes expands the full solution when opens it. How much time have you wasted clicking project by project just to get a tiny, collapsed solution?

No more!

Thanks to Edwin Evans we have a simple VB Macro that collapses the entire solution. You can find the article here.

Just go to Tools -> Macros -> New Macro Project, rename it as you like, and paste the VB code there. Afterwards, you can create a custom ToolBar in the VisualStudio IDE and add there you new macro as a button.

Et voilá, one click collapse for your entire solution!

I´ve tried it and It works, at least in Visual Studio 2008. I´ll post another article today on how to customize your toolbar… keep reading!

PS: To your comfort, I paste here Edwin Evans code:


   Sub CollapseAll()

        ' Get the the Solution Explorer tree

        Dim UIHSolutionExplorer As UIHierarchy

        UIHSolutionExplorer = DTE.Windows.Item( _

            Constants.vsext_wk_SProjectWindow).Object()

        ' Check if there is any open solution

        If (UIHSolutionExplorer.UIHierarchyItems.Count = 0) Then

            ' MsgBox("Nothing to collapse. You must have an open solution.")

            Return

        End If

        ' Get the top node (the name of the solution)

        Dim UIHSolutionRootNode As UIHierarchyItem

        UIHSolutionRootNode = UIHSolutionExplorer.UIHierarchyItems.Item(1)

        ' Collapse each project node

        Dim UIHItem As UIHierarchyItem

        For Each UIHItem In UIHSolutionRootNode.UIHierarchyItems

            UIHItem.UIHierarchyItems.Expanded = False

        Next

        ' Select the solution node, or else when you click

        ' on the solution window

        ' scrollbar, it will synchronize the open document

        ' with the tree and pop

        ' out the corresponding node which is probably not what you want.

        UIHSolutionRootNode.Select(vsUISelectionType.vsUISelectionTypeSelect)

    End Sub






God bless the inet

Taking a tour around the report on this blog, at Google Analytics, I´ve seen that readers come from very different places. We have many visits from:

Kuala Lumpur, Hanoi, San-Ch'Ung, Oslo, Tampere, Bangalore, Teheran, Ankara, Moscow, Stuttgart, Paris, London, Edimburgh, Madrid, Edmonton, Vancouver, San Francisco, Chicago, New York, Ithaca, Montreal, Mexico City, San Salvador, Buenos Aires, Santiago de Chile, Rio de Janeiro, Adelaide, Melbourne, Auckland, St. Petersburg...

and many many other places.

Thanks to all for reading!

Less than a 15% of the 50.000 visits we have had in this time, come from Spanish spoken countries. So I´ll have to write more in english or at least to translate posts!

Best FREE icon set ever

There are thousands of free icon collections out there. Most of them are oldies or full of spam and popups.

Today, I´ve discovered the best free icons web site Ive seen.

http://www.iconarchive.com

Mostly because:

* It has thousands of icons
* They are categorized
* The download links aren´t one thousands clicks away
* Most icons are pretty new, with an excellent quality and HiRes

Be careful with the copyright of some of them if you are going to use them in your projects.

Enjoy!

Making a PropertyGrid´s property expandable, in one second

The PropertyGrid control is one of the most useful controls in the .Net framework. As you probably know, it uses reflection to guess all the public properties of an object, showing them in a user-friendly interface where you can see and change property values.




The wonderful thing about this control is that it automatically creates the user interface and behaves correctly for ReadOnly properties, multiple object selections, anykind of datatype, specific user interfaces for data types (like combos, ColorPickers, DateTimePicker), etc... The list of features is almost endless.

Someone asked me today how to take advantage of another of it´s features: Expandable Properties.

If you don´t know exactly what I´m talking about, let me introduce it with the following example:

public class Car

{

...

private int mLength;

public int Length

{

get{return mLength;}

set{mLength = value;}

}


private Environment mEnv;

public Environment Env

{

get{return mEnv;}

set{mEnv = value;}

}

...

}


And now, somewhere else you use that class, putting it into a PropertyGrid, so you can inspect and change it´s contents:


Car mCar = new Car();

this.propertyGrid1.SelectedObject = mCar;


The property grid will behave correctly for the "Length" property, allowing you to change it´s value and detecting if the value entered is an "int". BUT, what happens with the "Env" property? It is not a basic DataType. It´s not a default complex type of the FrameWork.

By default, the PropertyGrid will only show the string description of the object Env (the return value of the ToSring() method, which can be overriden), making it read only. If only we could make the PropertyGrid treat that object as an expandable property, allowing us to see it´s internals...

Easy as shit! Add this to the definition of the property:


[TypeConverter(typeof(ExpandableObjectConverter))]

public Environment Env
{
get{return mEnv;}
set{mEnv = value;}
}


This way, you tell the PropertyGrid it should treat that object that way, and it will add at it´s left a Plus/Minus sign allowing you to expand the object. Easy, isn´t it?

Note: You have to include a "#using System.ComponentModel" to make this work.


iPhone vs HTC vs Piedra


Hoy he visto un par de cositas en inet que me han hecho mucha gracia... (gracias George ;)


La primera, una viñeta de nuestro querido Dr. Maligno, que graba sus mejores momentos con su HTC... je je


La segunda, una comparativa vista aqui entre el maravilloso iPhone y una piedra, recogida eso sí en uno de los jardines más famosos de San Francisco:





Juas !

De discos duros multimedia y otras lindezas

Preface: Últimamente me estaba planteando la adquisición de un disco duro multimedia de esos. Para mí, es muy importante que tenga las siguientes características:
1.- Que reproduzcan TODOS los archivos. Me repatea poner un vídeo y que diga "codec no soportado".
2.- Que tenga soporte FullHD, compatible con TODOS los archivos, y que lo mueva con fluidez.
3.- Viendo la programación que hay, lo de que grabe de la tele, no es una opción que me interese demasiado.
4.- Que tenga soporte para Audio digital 5.1.

El otro día, me calenté en el MediaMarkt, y me llevé a casa la única unidad que parecía no abierta de la oferta de la semana: un Emtec Movie Pro Q800 de 500 Gb, con soporte para FullHD 720p y 1080i (que no 1080p), usb, lan, etc etc, por 259 pavos (normalmente costaba 300). Lo que mola de este cacharro es que (aunque yo no le doy mucha imporancia) puede grabar de la tele, y lleva receptor TDT integrado, por lo que puede grabar del TDT.
Pues bien, como no estaba nada seguro de lo que había hecho, antes siquiera de abrir la caja, me metí en foros como este (30 páginas nada menos) para ver un poco... Y sinceramente, flipé con la cantidad de problemas que estaba teniendo la gente con los Emtec estos:

* Manuales penosos
* Cuelgues a todas horas,
* Archivos que no se ven
* Subtitulos mal sincronizados y con errores
* Firmware upgrades que empeoran las cosas en lugar de arreglarlas
* Lentitud por todas partes
* Muchos problemas para pasar los archivos grabados de la tele a un ordenador, como un tipo que se encontró una película dividida en miles de fragmentos separados...
* Infierno a la hora de configurarle un adaptador WiFi usb...
* Mandos a distancia que interaccionan incluso con el lavavajillas...

Además de todo esto, no soporta ficheros mkv y encima me entero que su software esta basado en Linux (lo que me faltaba ;), así que lo devolví y empecé a mirar alternativas.

Ya estaba casi convencido por un Conceptronic con soporte 1080p real, que parece va muy bien, cuando leo que está a punto de salir DivX7, que dicen va a estar basado internamente en Matroska, y que va a hacer que todos estos cacharros tengan que cambiar.

Conclusión 1:
Por mucho que estos bichos han avanzado, me temo que han de pasar unos cuantos años para que el mercado se estabilice. Quizá si algún día bajan de precio y pasan a costar 50 euros en lugar de 250, nos dé igual que se nos quede obsoleto y tengamos que tirarlo a la basura, pero por el momento, no me apetece gastar casi 50.000 pelas para que me dure 6 meses.
Conclusión 2:
He optado por dejar en la parte de atras de la tele un cable HDMI, y cuando quiera ver una peli en FullHD, usar el portátil. Al final, es una opción más interesante. Por el módico precio de tener que esperar a que Windows arranque, siempre voy a estar seguro de que mi PC va a reproducir el archivo. Además, mi portátil tiene salida HDMI y mando a distancia (que funciona con el Media Player Classic), así que mejor que mejor. Decir que la conexión HDMI ha mejorado mucho con respecto a las anteriores salidas VGA o DVI, ya que basta con conectar el cable en caliente, para que Vista reconozca el dispositivo (como si fuera USB) y active la salida por la pantalla Ext. con la configuración que le hayas puesto (FullHD, o lo que sea). ¿Ubuntu es capaz de hacer esto? ;) je je... kidding.
Conclusión 3:
Otra opción interesante, si no tienes portátil, son los nuevos desktops Studio de dell, que son muy fashion (por lo que vuestras mujeres no se quejarán de verlos al lado de la tele). Además, hay alguno económico y chiquitín, pueden llevar Blu-ray (algo que es una grave carencia de los discos multimedia), y os aseguráis que va a poder mover FullHD sin problemas. Estos no se si llevan mando a distancia (me da que no).
Reflexión Final:
Estos cacharrillos nacieron como algo bastante sencillo. Poco a poco, los clientes han ido demandando más y más cosas, como HDD, WiFi, USB, seguro que pronto pondran Blu-ray, etc etc etc.
Si te fijas, cuantas más funcionalidades traen, más se parecen a un PC. Entonces, ¿por qué no usar un PC directamente? Es que he flipado al ver a gente que, tras tres meses de leer foros, han conseguido meterle un software al cacharro para poder navegar por internet (usando el mando a distancia!!), a través de la conexión WiFi que también tardaron tres meses en configurar. En fin, sin comentarios...
Lo que está claro es que, una cosa es que Emtec fabrique un aparatillo para reproducir tres videos, y otra que, con un chip Sigma, y un software propio basado en Linux, quieran hacer un PC entero. ¿Por qué digo esto? Muy sencillo:
Si a Microsoft ya le cuesta que sus S.O. no presenten problemas, con miles y miles de ingenieros trabajando en ellos, ¿como lo hará Emtec? Si, ya se que el S.O. de un disco multimedia no es Windows, pero a medida que se van añadiendo cosas y más cosas, se va acercando a él. Y el software es VITAL para que el producto funcione bien. Está claro que las 30 páginas del foro que he puesto arriba, con cientos de problemas relacionados con este producto, refrendan lo que digo.
Lo que me resulta gracioso es ver a gente que con el tiempo se han convertido en auténticos magos de estos tipos de hardware (toquiteando configuraciones internas en binario), y que luego afirman "no tener mucha idea de informática", cuando alguien les sugiere usar un programa para algo. Y digo yo... ¿no hubiera sido mejor dedicar esos miles de horas a aprender informática o a usar un PC que a convertirse en el Master de un aparato que dentro de 2 años ya no existirá?
En fin chavalotes, "up to you", pero hasta que el FullHD no esté más extendido, o hasta que no bajen mucho de precio, yo no me compraría un disco multimedia.
Salu2!

Alarm problems on Windows Mobile 6 devices (HTC Touch)

Last week, I had to take a plane quite early. I woke up at 5:15 in the morning, so I set up an alarm in my HTC Touch. Since then, every f****n day my mobile woke me up at the same hour, no matter what alarm configuration I set.

I tried to disable all alarms, change the ringtones, set different alarms at different hours, everything... Nothing worked, the mobile continued ringing at 5:15.

After searching a little bit, I found that some other people is having the same problem, and I also found some workarounds and solutions:

Workarounds:

1.- Of course, you can switch off your mobile at night, what would be indeed healthy ;)
2.- You can also deactivate all the sounds in your mobile, but the alarm will still switch your mobile light on, and vibrate if the alarm was configured so.
3.- You can of course change your mobile hour every night, to bypass the alarm activation time, something quite stupid, I guess.

Solutions:

1.- Of course, before anything else, try a soft-reset.
2.- I read that sometines, this is fixed doing a Sync with your PC, but that was not my case. Try it anyway, just in case.
3.- You always have the HARD-RESET solution, but you will loose all your configurations, programs, calendar, everything. Though you can sync before your reset, it´s not something I like.

4.- The GOOD ONE: Get MemMaid, a must for any PDA owner. Run it.

MemMaid scans your mobile and shows many many information. The second tab in MemMaid (with the draw of a clock) shows the Notification Queue of your PDA. Every notification programmed in your system is included here: calendar notifications, alarms, tasks, whatever.

Don´t know why, but the "alarm problem" comes when the alarms don´t get deleted from this queue.

Just go to the "Classic Time Based" node of the tree, ans search for "Windows\clock.exe" entries. These are the alarm entries. When you select one, you will see it´s description in the bottom part, with the starting hour for the alarm. Just search the alarms you want to delete, select them and click "Delete".

That´s it. ¡¡¡Now I can finally sleep!!!

Note: You will have to set MemMaid in "non protected mode", at the settings screen.

Label on top of a PictureBox with transparent backcolor

It´s quite usual to need a label to be drawn in top of a PictureBox with a transparent backcolor.

In normal circumstances, setting the BackColor of the Label to "Transparent" would suffice, but when the label is on top of a PictureBox it doesn´t work as expected, as it draws parent´s backcolor as background, not the picture.

To make the label be drawn properly, it must be in the list of Controls of the PictureBox, what is not achieved by normal drag&dropping the the design view.

So, you would need to make the change manually, for example, in the constructor of the form:

public CTOR()
{
InitializeComponent();
...
this.Controls.Remove(label);
this.pictureBox.Controls.Add(label);
}

Et Voilá!

UVAtlas. D3DXCreateTextureGutterHelper fails with some Meshes

I finally found the solution to a problem that was driving me nuts.

D3DXCreateTextureGutterHelper (or the constructor of TextureGutterHelper, if on MDX) throws an "Invalid Call" exception with certain meshes.

I came to a situation where the method worked for a Mesh generated by D3DXCreateUVAtlas, but failed for the (aparently) SAME mesh created by me:

* Same number of vertices/faces
* Same attribute table
* Same vertex format
* Same Mesh Options
* Same declarations
* Same indices at IndexBuffer
* SAME EVERYTHING

Then, what was the cause?

My meshes have 2 or more different sets of TexCoords. One of them to address the UVAtlas, and others for other kind of textures. Aparently, D3DXCreateTextureGutterHelper will fail if the coordinates addressing the UVAtlas are not in the 1st set of TexCoords.

In my case, UVAtlas TexCoords are always in the 2nd set of TexCoords. That´s why it was failing.

Workaround: create a temp Mesh and copy the UVAtlas coordinates to the first set. Then, the method will succeed.

PS To the Microsoft DirectX Team:

The work done with all the UVAtlas functions is priceless. They are really useful, but please, document things like this a little bit.

This kind of problems are very easy to work around when known, but finding the cause by brute-force investigation can take hours and hours.

Instalar aplicación Compact Framework/Windows Mobile en 4 pasos

Últimamente, en mis pocos ratos libres, estoy dedicando tiempo a estudiar el Compact Framework y el desarrollo para dispositivos móbiles, trasteando con DirectX Mobile, WinForms y todo lo que se me ocurre.

El caso es que quería que un programilla bastante útil que he terminado apareciera en la lista de programas instalados, para poder añadirlo al menú de acceso rápido de mi HTC Touch.

Para conseguir esto, hay que crear un pequeño instalador que, en lugar de símplemente copiar la aplicación al dispositivo móvil, efectúe todo el registro habitual de un proceso de instalación. Ésto se puede hacer con un instalador "User Friendly", con ventanitas y demás, o con la variante más rápida, pero menos elegante, que usa ficheros CAB. Por motivos de rapidez iremos por ésta última vía.

La tarea es muy sencilla y rápida, así que voy a explicarla en cuatro pasos:

1.- En la solución donde tengas tu proyecto para Compact Framework, añade un nuevo proyecto escogiendo: Add -> New Project. Después, escoge la categoría "Other Project Types" -> "Setup and Deployment" -> "SmartDevice CAB Project".

2.- Si hacéis "click" en el nuevo proyecto, podrás especificar en sus propiedades el nombre del producto, propietario, etc, etc. Si hacéis "right click", aparecerá un menú contextual, donde podréis elegir: "View -> File System". Se abrirá una pestaña en la ventana principal de Visual Studio. Ésta contiene los contenidos del sistema de ficheros que queremos dejar en la máquina donde se va a instalar nuestra aplicación.

3.- Seleccionamos "Application Folder" en la mitad izda. de esta pestaña, y en la mitad dcha, hacemos "right click" y seleccionamos: Add -> Project Output. Se abrirá una ventanita donde podrás elegir (en el ComboBox de arriba) qué otro proyecto de la solución será el que queremos instalar. Escogéis el que queráis, dejáis marcada la opción "Primary Output" y pulsáis en Aceptar.

4.- Hacéis "right click" sobre el nuevo proyecto de setup y pulsais sobre "Build". Si todo va bien, en la carpeta de salida del proyecto encontraréis el nuevo y flamante CAB de instalación.


Así de fácil.

VisibleChanged Event, missing in the Compact Framework

If you need to do something in the VisibleChanged event of a form or control, using the Compact Framework, you´ll see that this event is missing.

You can easily fix this shadowing the Visible property with a newer one, and firing the event by yourself. Just like this:

public event System.EventHandler VisibleChanged;
public new bool Visible
{
get { return base.Visible; }
set
{
if (base.Visible != value)
{
base.Visible = value;
if (VisibleChanged != null)
VisibleChanged(this, EventArgs.Empty);
}
}
}