Archive for the ‘C++ Builder’ Category

Capturar sólo números en C++ Builder

junio 22, 2009

En ocasiones necesitamos validar que en un control TEdit el usuario sólo pueda teclear números. Lo que hay que hacer es poner el siguiente código en el evento OnKeyPress de nuestro TEdit.

void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key)
{
if (!((Key >= ‘0’ && Key <= '9') || Key == '\b'))     Key = 0; } [/sourcecode] Lo que hace este código es ignorar la tecla pulsada si dicha tecla no está dentro del rango de 0 a 9 y tampoco es el backspace (retroceso). Si queremos que los números estén alineados a la derecha, el truco es no utilizar un TEdit, sino un control TMemo haciendolo del tamaño deseado y seleccionando la opción taRightJustify en la propiedad Alignment e indicando el número máximo de caracteres en la propiedad MaxLength.

Anuncios

Agregar y borrar usuarios de Firebird desde C++ builder

febrero 23, 2009

Agregar usuario

En la pestaña InterBase Admin de C++ builder 6 existe el componente TIBSecurityService, este componente sirve para agregar o borrar usuarios de un servidor de base de datos Firebird, así como para mostrar o modificar su información.

Suponiendo que dejamos la contraseña por default del usuario sysdba de Firebird y tenemos en un formulario de C++ Builder 6 (llamado Form1) un componente TButton llamado Button1 y 4 componentes TEdit llamados e_usuario, e_nombre, e_apellido y e_clave respectivamente, podríamos agregar un componente TIBSecurityService llamado IBSecurityService1 y poner el siguiente código en el evento OnClick de Button1 para agregar un usuario al servidor Firebird con los datos que contengan los TEdit.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  IBSecurityService1->Params->Values["user_name"]="sysdba";
  IBSecurityService1->Params->Values["password"]="masterkey";

  IBSecurityService1->Active = true;
  try
     {
      IBSecurityService1->UserName = e_usuario->Text;
      IBSecurityService1->FirstName = e_nombre->Text;
      IBSecurityService1->LastName = e_apellido->Text;
      IBSecurityService1->Password = e_clave->Text;
      IBSecurityService1->AddUser();
     }
  __finally
           {
            IBSecurityService1->Active = false;
           }
}

Notese que para indicar el usuario y password con el que se conectará el componente TIBSecurityService se usó

IBSecurityService1->Params->Values[“user_name”]=”sysdba”;
IBSecurityService1->Params->Values[“password”]=”masterkey”;

y no:

IBSecurityService1->Params->Add(“user_name = sysdba”);
IBSecurityService1->Params->Add(“password = masterkey”);

Ya que marcaría un error como “SPB Constant Unknown

Con esto queda agregado el usuario, pero falta hacer los grants para darle permisos de consulta (grant select), inserción (grant insert), borrado (grant delete) y actualización (grant update) sobre las tablas de la base de datos deseada.

Otorgar grants al usuario

Para esto, crearemos un stored procedure (procedimiento almacenado) en la base de datos.

El stored procedure (que llamaremos sp_Grants) otorgará todos los grants a un usuario sobre una tabla determinada; recibirá como parámetros el usuario y el nombre de la tabla.


/* Este procedure otorga todos los permisos al usuario que recibe como parámetro
   sobre la tabla que recibe como parámetro */

set term !! ;
create procedure sp_Grants(s_tabla varchar(65), s_usuario varchar(8))
as
  begin
        execute statement 'grant all on ' || :s_tabla || ' to ' || :s_usuario;
  end !!
set term ; !!

Agregamos a nuestro formulario un componente TIBDatabase llamado IBDatabase1 y un componente TIBStoredProc llamado IBSP_grants. En la propiedad Database del TIBStoredProc ponemos IBDatabase1 y en la propiedad StoredProcName SP_GRANTS (que es el nombre del stored procedure que creamos en la base de datos).

Por último agregamos un componente TListBox al que llamaremos lb_tablas. Lo que haremos será conectarnos a la base de datos, obtener los nombres de todas las tablas y pasarlos al ListBox, después iremos recorriendo el ListBox para otorgar todos los grants sobre todas las tablas al usuario llamando a nuestro stored procedure.

Basta con agregar el siguiente código al final del código que pusimos anteriormente en el evento OnClick del TButton llamado Button1.

En el ejemplo nuestra base de datos se llama prueba.fdb y se encuentra en el directorio llamado prueba de la unidad c:

 // Asigna la ruta a la base de datos
 IBDatabase1->Params->Values["user_name"]="sysdba";
 IBDatabase1->Params->Values["password"]="masterkey";
 IBDatabase1->DatabaseName = "c:\\prueba\\prueba.fdb";

 // Hace la conexión a la base de datos
 IBDatabase1->Connected=true;

 // Pasa los nombres de las tablas de la base de datos al ListBox
 IBDatabase1->GetTableNames(lb_tablas->Items,False);

 // Se desconecta de la base de datos
 IBDatabase1->Connected=false;

 for (int i_x=0; i_x<lb_tablas->Items->Count; i_x++)
     {
      IBSP_grants->ParamByName("s_tabla")->AsString = Trim(lb_tablas->Items->Strings[i_x]);
      IBSP_grants->ParamByName("s_usuario")->AsString = e_usuario->Text;
      IBSP_grants->ExecProc();
      lb_tablas->ItemIndex++;
     }
 lb_tablas->Clear();

Si queremos que no se vea el ListBox sólo debemos poner false en su propiedad Visible

Borrar usuario

Agregamos un componente TButton al que llamaremos Button2 y en su evento OnClick pondremos el siguiente código


void __fastcall TForm1::Button2Click(TObject *Sender)
{
  IBSecurityService1->Params->Values["user_name"]="sysdba";
  IBSecurityService1->Params->Values["password"]="masterkey";

  IBSecurityService1->Active = true;
  try
     {
      IBSecurityService1->UserName = e_usuario->Text;     
      IBSecurityService1->DeleteUser();
     }
  __finally
           {
            IBSecurityService1->Active = false;
           }
}

Nota: En el post la macro de wordpress muestra finally, pero debe ser __finally

Convertir una cadena a double en c++ builder

febrero 9, 2009

La siguiente función recibe una cadena, elimina de la misma todos los caracteres que no sean números y regresa un double.

Acepta el caracter – al principio de la cadena para indicar números negativos y un punto para separar decimales (sólo se acepta el primer punto que contenga la cadena)

Ejemplo:  Si la función recibe la cadena “5-A-6200″, regresará un double cuyo valor será 56200.

Si la cadena no se puede convertir a un número, la función regresa el número cero.

double __fastcall TForm1::ConvierteANumero(String s_cadena)
{
String s_aux=””;
bool bl_negativo=false;

// Si la cadena que recibe está vacia, regresa 0
if (s_cadena==””)
s_aux=”0″;
else
{
// Checa el primer caracter para ver si es el signo menos
if (s_cadena.SubString(1,1)==”-“)
bl_negativo=true;

// Va recorriendo la cadena que recibe y pasando a s_aux sólo los números y el punto
for (int i_x=1;i_x <=s_cadena.Length();i_x++) { if (s_cadena.SubString(i_x,1)>= ‘0’ && s_cadena.SubString(i_x,1)<= '9') s_aux=s_aux+s_cadena.SubString(i_x,1); else { // Si el caracter es un punto, verifica que no exista ya un punto en la cadena if (s_cadena.SubString(i_x,1) == '.' && s_aux.Pos('.')==0) s_aux=s_aux+s_cadena.SubString(i_x,1); } } } if (bl_negativo) s_aux="-"+s_aux; // Si la cadena resultante está vacia, segnifica que s_cadena no contenía ningún número, sólo caracteres. así que se convierte a 0 if (s_aux.IsEmpty()) s_aux="0"; else if (s_aux.Length()==1 && !(s_aux >= ‘0’ && s_aux <= '9')) s_aux="0"; return s_aux.ToDouble(); } [/sourcecode]

Capturar en mayúsculas en un objeto TMemo

enero 14, 2009

En C++ Builder 6, los objetos TEdit tienen una propiedad llamada CharCase en la que podemos seleccionar la opción ecUpperCase para obligar a que se capture en mayúsculas en ese objeto sin importar si el usuario selecciona minúsculas en su teclado.

Los objetos TMemo no cuentan con esa opción, si queremos obtener un efecto equivalente a poner ecUpperCase en la propiedad CharCase de los objetos TEdit, podemos poner el siguiente código en el evento OnKeyPress del TMemo:


switch (Key)
            {
             case 'ñ':
                      Key = 'Ñ';
                      break;
             case 'á':
                      Key = 'Á';
                      break;
             case 'é':
                      Key = 'É';
                      break;
             case 'í':
                      Key = 'Í';
                      break;
             case 'ó':
                      Key = 'Ó';
                      break;
             case 'ú':
                      Key = 'Ú';
                      break;
             default :
                      Key = UpCase(Key);
            }