PDA

Ver la Versión Completa : Manejo de características de Windows 7


_cero_
20-08-2011, 11:22:26
Como están todos, hace tiempo hice una pregunta, que fue “Creación de jumplist en Windows 7 (http://www.clubdelphi.com/foros/showthread.php?t=65536)”, como el win en ese entonces era relativamente nuevo, no había información en club Delphi (al menos no hasta donde busque), y esta característica no me urgía, pues simplemente abandone, pero aun así las ideas que incluían jumplist me seguían rondando por la cabeza y como tuve un par de días semi libres, ps decidí meterme y responderme a mí mismo, solo que preferí hacer otro hilo, en forma de tutorial sobre todas las nuevas características que nos trae el win 7 y de cómo manipularlas desde el buen amigo builder (esto es algo que debí haber hecho desde que salió el win 7, pero el tiempo me faltaba), bueno manos a la obra.

1 agrupación de los botones en la barra de tareas.
http://www.megapix.com/?p=1KQQFG7Y.jpg

Como ya sabrán en Windows 7 los botones de una misma aplicación se agrupan en uno solo, pero ¿Cómo es que Windows 7 identifica cada aplicación y la separa debidamente, incluso ejecutando barias instancias de una misma aplicación? La respuesta es, que cada aplicación consta de un identificador la cual es una cadena de formato libre de 128 caracteres, en la cual podemos introducir el nombre de la empresa, nombre y versión de la aplicación y cualquier otra cosa que se nos apetezca, si no es establecida por nosotros, el sistema le asignara una determinada por el identificador de proceso y el nombre de la aplicación, para establecer esta cadena contamos con el api “SetCurrentProcessExplicitAppUserModelID”, para el caso de un identificador de aplicación y “SHGetPropertyStoreForWindow” para el cambio del ID de una ventana. Una vez explicado esto procedo a dejar algo de código y el correspondiente ejemplo subido a MU.

Forma de uso de SetCurrentProcessExplicitAppUserModelID

SetCurrentProcessExplicitAppUserModelID( L"Identificador.MiAplicacion.MiVercion" );
Forma de uso de SHGetPropertyStoreForWindow

//Hay que tener en cuenta que “PKEY_AppUserModel_ID” está ya definida en “PropKey.h”,
//pero la pongo porque muchas veces hay problemas al compilar
PROPERTYKEY PKEY_AppUserModel_ID;
CLSIDFromString( L"{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}", &PKEY_AppUserModel_ID.fmtid );
PKEY_AppUserModel_ID.pid = 6;

PROPVARIANT pv;
pv.vt = VT_LPWSTR;
pv.pwszVal = L"Identificador.MiAplicacion.MiVercion";

IPropertyStore* pps;
SHGetPropertyStoreForWindow( this->Handle, IID_PPV_ARGS( &pps ) );
pps->SetValue( PKEY_AppUserModel_ID, pv );
pps->Commit(); Ejemplo: http://www.megaupload.com/?d=2T69EHMR

_cero_
20-08-2011, 11:29:54
2 iconos superpuestos y barras de progreso.
http://www.megapix.com/?p=OO6VT132.jpg
La mejor forma de usar estas características de forma nativa es con la clase “ITaskbarList3”, es realmente simple lo único que hay que hacer es crear un puntero de este objeto e instanciarlo con “CoCreateInstance” una función para inicializar objetos con un CLSID especifico, no hay mucho más que explicar ya que todos sabemos cómo funcionan las barras de progreso y los iconos así que vamos directo al código.

Código para superponer un icono

//Creamos e inicializamos el objeto ITaskbarList3
ITaskbarList3* itl;
CoCreateInstance( CLSID_TaskbarList, NULL, CLSCTX_ALL, IID_ITaskbarList3, (void**)&itl );

//Cargamos el icono desde el imagelist
static int ind;
ind = ind >= 1 ? 0 : 1;

TIcon* ico = new TIcon;
ima1->GetIcon( ind, ico );

//Sobreponemos el icono
itl->SetOverlayIcon( this->Handle, ico->Handle, L"Descripcion" );
Código para ver el progreso en la barra de tareas

//Creamos e inicializamos el objeto ITaskbarList3
ITaskbarList3* itl;
CoCreateInstance( CLSID_TaskbarList, NULL, CLSCTX_ALL, IID_ITaskbarList3, (void**)&itl );

//Mostramos un progreso de 86 en un máximo de 100
itl->SetProgressValue( this->Handle, 86, 100 );

//Cambiamos de modo TBPF_NORMAL a TBPF_ERROR, la barra cambia a rojo
itl->SetProgressState( this->Handle, TBPF_ERROR );


Ejemplo: http://www.megaupload.com/?d=FBHQDL0V

_cero_
20-08-2011, 11:38:36
3 barra de herramientas miniatura (botones en el preview).
http://www.megapix.com/?p=XKG2LLGN.jpg

A mi parecer esta es una característica muy útil, con esto puedes colocar hasta 6 botones (según la MSDN, no probé yo), que te servirán como un mini control remoto que te permite ejecutar X función de tu aplicación todo desde el preview, con lo que le ahorras al usuario un par de clicks y cambiar completamente a tu aplicación. En este caso se complica un poco más ya que tendremos que gestionar los mensajes de tipo “WM_COMMAND” y según el índice será tu acción. Al igual que con las características anteriores usaremos la clase “ITaskbarList3” y la estructura “THUMBBUTTON” para crear la mini-barra, y el puntero “Application->OnMessage” para la gestión de los mensajes.

Creación de la barra

TIcon* ico = new TIcon;
ima1->GetIcon( 0, ico );

//Creamos 2 botones
THUMBBUTTON bb[2];
bb[0].dwMask = THB_ICON | THB_TOOLTIP | THB_FLAGS; //Incluimos las banderas que determinan como se verá nuestro botón
bb[0].iId = 0; //Id que identificara nuestro botón al recibir los mensajes
bb[0].hIcon = ico->Handle; //Icono de nuestro botón
wcscpy(bb[0].szTip, L"Boton 1"); //Hint de nuestro botón
bb[0].dwFlags = THBF_ENABLED; //Incluimos las banderas del estado de nuestro botón

TIcon* ico2 = new TIcon;
ima1->GetIcon( 1, ico2 );

bb[1].dwMask = THB_ICON | THB_TOOLTIP | THB_FLAGS;
bb[1].iId = 1;
bb[1].hIcon = ico2->Handle;
wcscpy(bb[1].szTip, L"Boton 2");
bb[1].dwFlags = THBF_DISABLED; //Nótese que deshabilitamos el botón

//Creamos nuestra barra con el Handle de nuestra ventana, el número de botones, y la estructura THUMBBUTTON
itl->ThumbBarAddButtons( this->Handle, 2, bb );
Gestión de los mensajes

switch ( Msg.message ) {
case WM_COMMAND: {
if ( HIWORD( Msg.wParam ) == THBN_CLICKED) {
if ( LOWORD( Msg.wParam ) == 0) {
MessageBoxA(Handle, "click boton 0", "", MB_ICONINFORMATION);

//Editamos el botón 1
bb[1].dwFlags = THBF_ENABLED;
bb[1].dwMask = THB_ICON | THB_TOOLTIP | THB_FLAGS;
itl->ThumbBarUpdateButtons( this->Handle, 2, bb );
}
else if ( LOWORD( Msg.wParam ) == 1 ) {
MessageBoxA(Handle, "click boton 1", "", MB_ICONINFORMATION);
bb[1].dwFlags = THBF_DISABLED;
itl->ThumbBarUpdateButtons( this->Handle, 2, bb );
}
}
break
;
}
}

Ejemplo: http://www.megaupload.com/?d=8XMQ0WQL

_cero_
20-08-2011, 11:45:19
4 Jump List.
http://www.megapix.com/?p=ODK1H4HI.jpg
Esta es la característica más útil que encontré en Windows 7, y la razón de ser de este mini tutorial, es la parte que me costó entender más y aun no creo entenderla del todo, pero básicamente, las jump list son listas de accesos directos que se despliegan al hacer click derecho sobre un icono de una aplicación, estos accesos directos pueden iniciar determinados archivos, o nuestra/ otra aplicación con ciertos parámetros, parámetros que manejaremos nosotros, y que doy por supuesto que cualquiera ha manejado antes así que solo pondré el código para crear una jumplist simple que constara de un acceso y una categoría, si más adelante le descubro una que otra curiosidad ps la pondré en este mismo lugar.

PROPERTYKEY PKEY_Title;
CLSIDFromString( L"{F29F85E0-4FF9-1068-AB91-08002B27B3D9}", &PKEY_Title.fmtid );
PKEY_Title.pid = 2;

UINT cMinSlots;
ICustomDestinationList *pcdl;
IObjectCollection *poc;
IObjectArray *poaRemoved;
IObjectArray * poa;
IPropertyStore *pps;
IShellLink *psl;

CoCreateInstance( CLSID_DestinationList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &pcdl ) );
pcdl->BeginList( &cMinSlots, IID_PPV_ARGS( &poaRemoved ) );
CoCreateInstance( CLSID_EnumerableObjectCollection, NULL, CLSCTX_INPROC, IID_PPV_ARGS( &poc ) );
CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &psl ) );
psl->SetPath( Application->ExeName.c_str() );
psl->SetArguments( L"/Parametro" );

PROPVARIANT propvar;
propvar.vt = VT_LPWSTR;
propvar.pwszVal = L"Titulo";
psl->QueryInterface( IID_PPV_ARGS( &pps ) );
pps->SetValue( PKEY_Title, propvar );
pps->Commit();
pps->Release();
PropVariantClear( &propvar );
poc->AddObject( psl );
poc->QueryInterface( IID_PPV_ARGS( &poa ) );
pcdl->AppendCategory( L"Categoria Personalizada", poa );
poa->Release();
psl->Release();
poc->Release();
poaRemoved->Release();
pcdl->CommitList();
pcdl->Release();

Ejemplo: http://www.megaupload.com/?d=OEY75RO8

Pd1. Lamento que este mini tuto termine tan abruptamente sin una explicación extensa de las Jump List y sus posibilidades, la cuestión es que yo mismo no he visto todo, sin mencionar que se me acabo el día que decidí dedicarle a este tema, así que si alguien extiende este tema bienvenido sea. Nos vemos

ecfisa
20-08-2011, 14:12:16
Hola _cero_

Muy agradecido por tu aporte.

Un saludo. :)