Crear un gráfico de barras con UniGUI

A continuación veremos cómo crear un proyecto con UniGUI que incorpore gráficos de barras, líneas, etc. Si han utilizado en sus programas el componente tChart, se darán cuenta de lo parecido que es utilizar su componente equivalente llamado tUniChart, para ello primeramente creamos un nuevo proyecto, después arrastramos los componentes UniGUI al form Main, creamos sus series de datos con valores aleatorios y lo ejecutamos sobre un navegador tecleando http://localhost:8077.
Para aquellos que no sepan cómo se instala uniGUI, les recomiendo el siguiente post de Emilio Pérez

Vamos a ver en detalle todos los pasos anteriores:
Abrimos nuestro Delphi Tokyo 10.2 y creamos un nuevo proyecto, desde New – Other
y seleccionamos UniGUI for Delphi

En la siguiente pantalla seleccionamos “Application Wizard”.
Se abrirá un asistente para indicar qué tipo de proyecto queremos crear.


Tenemos varias opciones: Crear un módulo ISAPI (se genera un archivo dll que se ejecuta desde un Internet Information Server), un Standalone Server (permite su ejecución en la propia máquina) o un Windows Service Application.
En este caso, como estamos en la fase de desarrollo, seleccionamos Standalone Server y pulsamos el botón OK.
En el caso de que seleccionemos la opción del módulo ISAPI para IIS, tendríamos que copiar el archivo dll generado a la carpeta adecuada dentro del IIS y reiniciar el servicio de IIS para que la vuelva a cargar, ya que Windows mantiene las dll en memoria y si no lo  reinicias no las actualiza.


En este momento tendremos el esqueleto de un proyecto típico de UniGUI con 3 units: Main, MainModule y ServerModule.


A continuación desde el inspector de objetos seleccionamos los siguientes:
 tUniStringList tUniChart, y un tUniButton
y los colocamos de la forma que indica la siguiente figura:
En el tUniStringList colocaremos los valores aleatorios de las 2 series numéricas asociadas al componente tUniChart.


Para crear una serie clickeamos sobre el componente tUniChart y en el Inspector de objetos localizamos la propiedad SeriesList y hacemos clic sobre el icono de los 3 puntos que está en esa misma celda.
Se nos abrirá una ventana, después seleccionamos el icono marcado en rojo en la figura de abajo, con el fin de crear una nueva serie (Serie1) en la que definiremos el estilo del gráfico (Si es de líneas, de barras, circular, etc.)
Repetiremos lo mismo para crear otra serie (Serie2).


Cerramos la ventana.
Y con todo lo comentado anteriormente habremos acabado la parte de definición de la interfaz; seguidamente vamos a la parte de la codificación, que es muy sencilla.

CODIFICACIÓN:


Tenemos que rellenar las celdas del componente UniStringList con valores aleatorios, para luego leerlas y crear el gráfico de barras con los valores de una columna y el gráfico de línea con los valores de la otra columna.
Hacemos clic sobre el botón tUnibutton y en el evento asociado llamado onClic tecleamos lo siguiente:




procedure TMainForm.UniButton1Click(Sender: TObject);

var

  I : Integer;

  Val : Double;

  Head : string;

Begin

// INICIALIZAMOS LOS VALORES ALEATORIOS DE LAS CELDAS

// DEL STRINGRID

 

  for I := 0 to 10 do

  begin

    UniStringGrid1.Cells[0,I]:=IntToStr(100+i);

    UniStringGrid1.Cells[1,I]:=IntToStr(Random(100)+50);

  end;

 

// BORRAMOS LOS VALORES DE LAS SERIES

  Series1.Clear;

  Series2.Clear;

 

// CREAMOS LOS VALORES DE LAS SERIES

  for I := 0 to UniStringGrid1.RowCount-1 do

  begin

    if UniStringGrid1.Cells[0,I]='' then Break;

    Val:=StrToFloatDef(UniStringGrid1.Cells[1,I], 0.0);

    Head:=UniStringGrid1.Cells[0,I];

    Series1.Add(Val+Random(100), Head);

    Series2.Add(Val+Random(100), Head);

  end;

end;

Y en principio eso es todo, ahora toca compilar y ejecutar el proyecto como hacemos con cualquier aplicación Delphi, la diferencia es que como es una aplicación orientada a la Web necesitamos abrir un navegador (Chrome, Explorer, Mozilla, etc.), tecleando
Por defecto el servidor web escucha en el puerto 8077, aunque lo podemos cambiar desde la propiedad del form ServerModule-Port
Una vez abierto el navegador y después de pulsar el botón ACEPTAR en la ventana en la que nos da las gracias por utilizar UniGUI, veremos la página que hemos creado con Delphi Tokyo.

Pulsamos el botón INICIAR y si todo ha ido bien veremos el resultado de la ejecución de nuestro código.

Hasta el próximo post

Javier Pareja
blogdelphimagic@blogspot.com

Descuento del 30% hasta el próximo lunes

Me ha llegado esta comunicación sobre un descuento del 30% en productos de Embarcadero sólo hasta el próximo Lunes 22 de Enero de 2018, que espero sea de vuestro interés...

Weekend Sale - Save 30% when you buy ONLINE!
The best developers know having the right tools will help them create their best code more quickly, with fewer bugs, and better design. Start realizing your potential now with our most popular editions at a special discount. Valid until 21 January 2018.
You can also take advantage of this offer via your local reseller (details below) and you have up until Monday 22nd January until 11am CET.
Why You Need Enterprise:
RAD Studio Enterprise is our most popular edition for mobile app developers and building client/server applications.
Create multi-tier applications. Convert your existing code to REST API endpoints with RAD Server.
Go MOBILE. Includes cross-platform capabilities to reach your users' mobile devices with natively compiled code.
Remote Database Connectivity
Includes RAD Server Deployment License, a €5000 Value
Buy Online from Embarcadero
Buy from local Reseller
*For terms and conditions click here
Need Data Modeling? Choose Architect
Our Architect Edition includes all of Enterprise's features plus powerful ER/Studio Developer Edition database modeling and design capabilities.
On a Tight Budget? Start with Professional
Pro is our most popular version for independent developers. It's a great starting point for developers who create primarily Windows applications.

CodeRage XII en Español: 15 y 16 de Febrero



CODERAGE, la mejor conferencia online de desarrolladores,  ahora en español.

Tendrá lugar los días:
  1. Vie., 16 de Feb. de 2018 16:00 - 21:00 CET
Una oportunidad única para ampliar tus conocimientos como programador / analista
en tecnologías RAD de la mano de expertos y MVP de embarcadero.

Las sesiones tratarán sobre:
Tecnologías RAD:
FireDAC, FireMonkey, FireUI, VCL, DataSnap, RAD Server, REST Clients, InterBase, Enterprise Connectors
Mejores Prácticas:
Unit Testing, Writing SOLID Code, Dependency Injection, Clean Code, Exception Handling, Multithreading, Patterns and Practices, Refactoring, Tools and Tips
Tecnologías Emergentes:
Working in the Cloud, REST Services, Microservices, Blockchain, Cryptography, Clustering, Artificial Intelligence / Neural Networks / Deep Learning, Internet of Things (IoT), Single Board Computers (SBC), Wearables, Embedded systems, Automation, Sensors, Robotics
Tendencias de la Industria:
Software as a Service, Working with Audio and Video, Business Side of Software, Technical Partners, Component Libraries, Latest Open Source, MVP Projects, Cool Apps, Case Studies

Para registrarte como asistente pulsa aquí.

Si quieres inscribirte como expositor pulsa aquí.



Cerrar aplicaciones innecesarias de Windows

Muchos de vosotros habréis comprobado que existen muchas aplicaciones de Windows que se instalan sin que el usuario lo permita, me refiero a las que se ven cuando se pulsa el icono "Windows".


como ven hay varias aplicaciones: "noticias", "mapas", "cocina", "juegos", "xbox", etc..., algunas se pueden desinstalar pulsando Uninstall


Pero otras no hay forma.

Cuando un PC desempeña su tarea en entornos empresariales, estas apps se deberían eliminar y para ello la solución que he encontrado es utilizar Powershell del siguiente modo:

1) Hacer clic con el botón derecho del ratón sobre el icono Windows.
2) Desde el menú Ejecutar teclear: powershell
3) Para ver la lista de aplicaciones instaladas teclear: 

Get-AppxPackage | Select Name, PackageFullName





4)Para desinstalar una aplicación teclear:

Get-AppxPackage *NombreDeLaAplicacion* | Remove-AppxPackage

Aquí tenéis los comandos para eliminar la mayoría de ellas:

#Uninstall 3D Builder
Get-AppxPackage *3dbuilder* | Remove-AppxPackage

#Uninstall Camera:
Get-AppxPackage *windowscamera* | Remove-AppxPackage

#Uninstall Get Skype:
Get-AppxPackage *skypeapp* | Remove-AppxPackage

#Uninstall Groove Music:
Get-AppxPackage *zunemusic* | Remove-AppxPackage

#Uninstall Maps:
Get-AppxPackage *windowsmaps* | Remove-AppxPackage

#Uninstall Microsoft Solitaire Collection:
Get-AppxPackage *solitairecollection* | Remove-AppxPackage

#Uninstall Money:
Get-AppxPackage *bingfinance* | Remove-AppxPackage

#Uninstall Movies & TV:
Get-AppxPackage *zunevideo* | Remove-AppxPackage

#Uninstall News:
Get-AppxPackage *bingnews* | Remove-AppxPackage

#Uninstall OneNote:
Get-AppxPackage *onenote* | Remove-AppxPackage

#Uninstall People:
Get-AppxPackage *people* | Remove-AppxPackage

#Uninstall Phone Companion:
Get-AppxPackage *windowsphone* | Remove-AppxPackage

#Uninstall Photos:
Get-AppxPackage *photos* | Remove-AppxPackage

#Uninstall Sports:
Get-AppxPackage *bingsports* | Remove-AppxPackage

#Uninstall Weather:
Get-AppxPackage *bingweather* | Remove-AppxPackage

#Uninstall Xbox:
Get-AppxPackage *xboxapp* | Remove-AppxPackage

#Uninstall Sway (Office):
Get-AppxPackage *Office.Sway* | Remove-AppxPackage

#UPDATE 2 - New Apps
#Uninstall Twitter:
Get-AppxPackage *Twitter* | Remove-AppxPackage

#Uninstall TuneInRadio
Get-AppxPackage *TuneInRadio* | Remove-AppxPackage

#Uninstall Netflix
Get-AppxPackage *Netflix* | Remove-AppxPackage


Para ejecutar fácilmente las instrucciones anteriores: seleccionarlas todas, después hacer Ctrl+V, y luego pegarlas en la ventana de Powershell (no hace falta ir una a una)


Imagen


Si más adelante queréis reinstalar estas apps tan sólo tenéis que teclear desde la consola de Powershell lo siguiente:

Get-AppxPackage -AllUsers| Foreach {Add-AppxPackage -DisableDevelopmentMode -Register "$($_.InstallLocation)\AppXManifest.xml"}






Detener procesos y servicios con Delphi

Resultado de imagen de imagen de cerrar procesos

Examinando los procesos que se estaban ejecutando en mi PC, me dí cuenta que muchos de ellos no servían para nada y lo único que hacían era consumir ciclos de CPU y tiempo de trabajo de disco duro, ocupaban memoria disponible y utilizaban internet para enviar y recibir datos, consumiendo un ancho de banda que es limitado.

Ya sé que desde el Administrador de tareas se pueden finalizar uno a uno, pero me dije ¿por qué no hacer un programa que me los finalice a todos pulsando un botón? y me puse a ello.

Pensé que lo mejor era dividirlo en dos módulos, uno sería un fichero de texto donde colocaría los nombres de los procesos y servicios y otro sería el programa en sí, de tal forma que cuando se iniciase haría lo siguiente:

1) Leer el fichero "ProcesosACerrar.txt"con los nombres de procesos y servicios línea a línea.
2) Después identificaría si es un programa o un servicio, leyendo el carácter que hay antes de la coma.
3) Por último lo detendría mediante la llamada al procedimiento StopProceso o StopService

El fichero "ProcesosACerrar.txt" sería por ejemplo como sigue:

S,Spooler
S,KinectManagement
S,igfxcuiservice1.0.0.0
S,AdobeARMservice
P,ACDaemon.exe
P,ACService.exe
P,jucheck.exe

A continuación os copio el ejecutable que he desarrollado.


USES
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, tlhelp32, winsvc;

// funciones del programa

FUNCTION TForm1.GetToken(Cadena, Separador: ansiSTRING; Token: Integer): ansiSTRING;
{
  Cadena     es el string en el que buscar el token
  Separador  es el string que separa cada token
  Token      es el número de token que buscamos
}
BEGIN
  Cadena := Cadena + Separador;
  WHILE Token > 1 DO
    BEGIN
      Delete(Cadena, 1, AnsiPos(Separador, Cadena));
      Dec(Token);
    END;
  Result := Copy(Cadena, 1, AnsiPos(Separador, Cadena) - Length(Separador));
END;

PROCEDURE TForm1.Button10Click(Sender: TObject);
VAR
  lista: tstringlist;
  i: Integer;
  linea, tipo, ProcesoOServicio, dato: STRING;
BEGIN
memo1.lines.clear;
  IF FileExists('C:\ProcesosACerrar.txt', true) THEN
    BEGIN
      lista := tstringlist.CREATE;
      TRY
        lista.loadfromfile('C:\ProcesosACerrar.txt');
        FOR i := 0 TO lista.Count - 1 DO
          BEGIN
            linea := trim(lista.strings[i]);
            IF linea <> '' THEN
              BEGIN
                // linea es p.ej si es un proceso :   P,notepad.exe
                // linea es p.ej si es un servicio :  S,spooler

                tipo := GetToken(trim(lista.strings[i]), ',', 1);
                //tipo puede ser P o S
                ProcesoOServicio := GetToken(linea, ',', 2);
                //ProcesoOServicio es el nombre del proceso o servicio
                IF tipo = 'P' THEN
                  StopProceso(ProcesoOServicio);
                IF tipo = 'S' THEN
                  StopService(ProcesoOServicio);
              END;
          END;
      FINALLY
        lista.free;
      END;
    END
  ELSE
    showmessage(' no se encuentra el archivo ' + 'C:\ProcesosACerrar.txt')
END;


PROCEDURE TForm1.StopService(nombre: STRING);
VAR
  ServiceControlManager: SC_HANDLE;
  Service: SC_HANDLE;
  ServiceStatus: SERVICE_STATUS;
  Resultado: boolean;
BEGIN
  ServiceControlManager := OpenSCManager(NIL, NIL, SC_MANAGER_CONNECT);
  IF ServiceControlManager <> 0 THEN
    BEGIN
      Service := OpenService(ServiceControlManager, PChar(nombre), SERVICE_ALL_ACCESS);
      IF Service <> 0 THEN
        BEGIN
          IF QueryServiceStatus(Service, ServiceStatus) THEN
            BEGIN
              IF ServiceStatus.dwCurrentState <> SERVICE_STOPPED THEN
                BEGIN
                  Resultado := ControlService(Service, SERVICE_CONTROL_STOP, ServiceStatus);
                  IF Resultado THEN
                    Memo1.lines.add('Servicio ' + nombre + ' detenido')
                  ELSE
                    Memo1.lines.add(' Error al parar el servicio ' + nombre);
                END;
            END;
          CloseServiceHandle(Service);
        END;
      CloseServiceHandle(ServiceControlManager);
    END;
END;


FUNCTION TForm1.StopProceso(nombre: STRING): boolean;
VAR
  ModuleEntry: TModuleEntry32;
  ProcessEntry: TProcessEntry32;
  hSnapshot, hProcess: Cardinal;
BEGIN
  Result := False;
  ModuleEntry.dwSize := SizeOf(TModuleEntry32);
  ProcessEntry.dwSize := SizeOf(TProcessEntry32);
  hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  IF Process32First(hSnapshot, ProcessEntry) THEN
    REPEAT
      IF (lstrcmpi(PChar(nombre), @ProcessEntry.szExeFile) = 0) THEN
        BEGIN
          hProcess := OpenProcess(PROCESS_TERMINATE, False, ProcessEntry.th32processid);
          Result := TerminateProcess(hProcess, 0);
          IF Result THEN
            Memo1.lines.add(nombre + ' - ' + 'Cerrado')
          ELSE
            Memo1.lines.add(nombre + ' - ' + 'Error al cerrar.');

          CloseHandle(hProcess);
        END;
    UNTIL NOT Process32Next(hSnapshot, ProcessEntry);
  CloseHandle(hSnapshot);
END;

Después de haber ejecutado el programa si accedemos al Administrador de tareas de Windows se ve que el consumo de CPU, memoria, disco, ethernet ha disminuido, en mi caso he conseguido cerrar 30 procesos de los 68 que tenía, un 44% de recursos ociosos del sistema y la verdad es que se nota al trabajar con el PC, ahora parece que va "más ligero", las aplicaciones se abren antes y al navegar por internet me da la impresión que las páginas se abren más rápido.
Un detalle que hay que tener en cuenta, es que el ejecutable se debe iniciar como Administrador de la máquina (clic con el botón derecho sobre el programa y en el menú emergente activar el menú "Ejecutar como Administrador", ya que se necesita un usuario con los máximos privilegios para cerrar programas y servicios.