Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Mysqlapi
Mysqlapi
El presente articulo muestra paso a paso como crear una peque na aplicaci on en Visual C++ 6.0 con acceso a una base de datos de MySQL, utilizando librer as prove das e incluidas en las distribuciones del motor de base de datos MySQL.
Indice
1. Introducci on 2. Preparar los datos 3. Crear el proyecto 4. Conguraciones y otros detalles 5. La conexi on a MySQL 6. Preparar el di alogo 7. Modicar, Agregar, Eliminar datos 8. Comentarios, conclusiones, recursos , etc..
3 3 4 6 9 13 17 25
1. Introducci on
Las diferentes alternativas que tenemos los desarrolladores para implementar aplicaciones de acceso a base de datos nos hacen pensar dos veces antes de elegir el c omo y con qu e lenguaje nos conectamos a una base de datos. El mismo dilema se presenta al elegir el gestor de base de datos, al principio es tedioso, pero cuando uno empieza a tener conanza no duda en seguir utilizando su gestor favorito. Este tutorial aunque peque no intenta mostrar la puerta al mundo de posibilidades que existe al utilizar Visual C++ como lenguaje de programaci on y MySQL como gestor de datos. Les guiar e paso a paso como deben construir su primera aplicaci on de acceso a base de datos con Visual C++ utilizando las librer as API escritas en C que provee MySQL. Empezaremos alistando los datos sobre un servidor de datos MySQL ya instalado y corriendo para luego crear un proyecto en Visual C++ 6.0 basado en dialogo el cual conguraremos inicialmente para utilizas las librer as API de MySQL y nalmente escribiremos unas cuantas lineas de c odigo.
Listado 1: Script de la tabla que contiene los datos en prueba db.sql 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: CREATE DATABASE prueba_db; USE prueba_db; CREATE TABLE empresas ( RUC char(11) NOT NULL, RazonSocial varchar(80), Direccion varchar(60), Email varchar(50), Web varchar(60), PRIMARY KEY (RUC), KEY RazonSocial (RazonSocial) );
3. Crear el proyecto
Posiblemente usted ya conozca el proceso de crear una aplicaci on basada en di alogo con Visual C++, si es asi entonces contin ue con el siguiente paso.
Bueno... procedemos a crear el proyecto mediante el AppWizard del Visual C++ 6.0, accedemos al men u: File -> New o presionamos la combinaci on [Ctrl] + [N]. Aparecer a un di alogo parecido al de la Im agen 1. Elegimos el tipo de proyecto MFC AppWizard (.exe), para el proyecto eleg el 4
nombre TestMySQL, esto autom aticamente crear a una carpeta con todos los elementos necesarios, es recomendable que esta carpeta est e situada en un lugar estrat egico, por un principio de orden. En el siguiente dialogo elegimos el tipo de aplicaci on Basada en dialogo (Dialog Based). Ya que este es un proyecto cuyo objetivo es demostrar el uso de las librer as API de MySQL solo crearemos un proyecto de ese tipo por que no necesitamos todo el c odigo que genera para las otras aplicaciones, en caso de que tenga que crear proyectos mas grandes puede escoger las otras opciones. Ver Imagen 2. Una aplicaci on Dialog Based b asicamente genera tres clases: una clase derivada de CWinApp que ser a la aplicaci on propiamente dicha, otra clase derivada de CDialog acompa nada de un formulario en blanco para dar rienda suelta a nuestra imaginaci on y otra clase derivada de CDialog que contiene informaci on acerca de la aplicaci on.
Los siguientes di alogos de opciones son irrelevantes a lo que necesitamos as es que click en Finish y nos olvidamos de este asunto de una buena vez. Aparecer a un di alogo que nos informar a lo que estamos generando. Click en OK y con esto terminamos este Paso.
En una instalaci on, por defecto, se instalan las librer as en rutas espec cas:
Archivos de cabecera c:\Archivos de Programa\MySQL\MySQL Server 5.0\include Archivos de librer a (.lib) con informaci on para poder depurar c:\Archivos de Programa\MySQL\MySQL Server 5.0\lib\debug Archivos de librer a (.lib) optimizados c:\Archivos de Programa\MySQL\MySQL Server 5.0\lib\opt
La carpeta debug contiene librer as para compilar nuestro proyecto en el modo Debug y la carpeta opt contiene los archivos para el modo Release. El primer modo (Debug) nos facilita la vida en la etapa de desarrollo pudiendo detectar problemas 6
y errores para poder corregirlos. El segundo modo de compilaci on se utiliza cuando estemos seguros que no hay mas problemas y generamos un ejecutable liviano y listo para el usuario nal; aunque siempre se presenta algun maldito problema que no supimos prevenir. Nota: No es necesario que intalen el servidor de datos completo, es posible que ustedes tengan un servidor MySQL corriendo en alguna otra parte de su red. Para ello pueden copiar las carpetas indicadas arriba desde otra instalaci on o simplemente instalar s olo los Developer Components Dejemos el asunto ah , sigamos con la conguraci on de las rutas. Ahora conguraremos Visual C++ para que agregue estas rutas a su lista de carpetas de busqueda de archivos de inclusi on (Include Files). Entonces debemos acceder a la Conguraci on del Proyecto (Project Settings) y agregar la ruta que corresponde on del Proyecto ir a Menu: Project Ver Im agen 4. Para accede a la Conguraci -Setting o presionar la combinaci on [ALT]+[F7].
De estas carpetas utilizaremos el archivo mysql.h en nuestras futuras aplicaciones, en este archivo estan declaradas las funciones de conexi on que nos proporciona MySQL para C. Al igual que en el caso anterior tambi en tenemos que agregar el directorio de librer as lib. El archivo libmySQL.lib ubicado en esta carpeta nos sirve para enlazar nuestra aplicaci on, Visual C++ se encargar a de enlazar todo para producir un ejecutable. Dentro de las carpetas lib\debug y lib\opt tambien existe el archivo libmySQL.dll el cual debemos copiarlo en la misma carpeta de nuestro 7
ejecutable para que pueda correr sin problemas. Pero debemos elegir el correcto, en este caso tomaremos el de la carpeta lib\debug, por que nuestro proyecto estar a congurado en el modo Debug por defecto. Ver Im agen 5.
Cuando tengan lista una aplicaci on para el usuario nal deber an congurar el proyecto en el modo Release o Lanzamiento e incluir en su distribuci on el archivo libmySQL.dll contenido en la carpeta lib\opt. Antes de compilar deben tambi en congurar las rutas de las librer as hacia la carpeta lib\opt.
Otras conguraciones
Luego de hacer todas las tareas anteriores procedemos a establecer conguraciones adicionales: Carpeta de salida. En la pesta na General de la ventana de Conguraci on del Proyecto ((Project Settings)) en la secci on Output les: escribir OutPut como carpeta de salida. Esto le dice al compilador que los archivos ejecutables que produzca no los mezcle con los archivos intermedios y los bote en un directorio aparte (OutPut). Carpeta de trabajo. La carpeta de trabajo es el lugar que tendr a nuestro programa como carpeta por defecto al ejecutarlo desde el Visual C++ (Working directory). En esta carpeta debemos copiar el archivo libmySQL.dll. Por defecto el valor de esta propiedad esta en blanco. Librer as. En la pesta na Link (de Conguraci on del Proyecto) agregar el texto libmySQL.lib en la secci on Object/Library modules, esta se usa para decirle 8
a compilador que utilice librer as extra al momento del la construcci on nal del ejecutable. Este paso nos evita ver problemas al momento de enlazar el proyecto (Linker Errors).
Archivos de Cabecera
Las declaraciones de las variables y funciones de MySQL C API estan en el archivo mysql.h, debemos declarar la inclusi on de este archivo en Stdafx.h, ver l neas deben escribirse al nal de todas las declaraciones #include listado 2. Estas existentes.
Listado 2: Incluir archivos en Stdafx.h 1: 2: #include <afxsock.h> #include <mysql.h>
Debido a que mysql.h utiliza conexiones de Sockets es necesario tambien incluir el archivo afxsock.h antes de mysql.h para que esten disponibles los Window Sockets.
5. La conexi on a MySQL
En el Paso 2 creamos el proyecto, en el cual habr a notado que se han creado tres clases: CAboutDlg, CTestMySQLApp y CTestMySQLDlg. No tocaremos la primera clase ya que es un dialogo que no cumple otra funci on mas que informar acerca del proyecto. En la clase CTestMySQLApp crearemos la conexi on a la base de datos la que utilizaremos en todo el proyecto, de modo que ser a una conexion global. En la clase CTestMySQLDlg realizaremos una consulta a la tabla empresas de la base de datos prueba db y lo mostraremos en resultado en el control list del dialogo. Ver Im agen 6. Pues manos a la obra, escribiremos nuestras primeras lineas de codigo asegurando la conexi on a la base de datos la cual crearemos en la clase CTestMySQLApp, necesitaremos denir las variables y funciones como se indica en la Tabla 1. En la variable m pLinkDb, que inicialmente ser a NULL (Ver Listado 4), permanecer a la conexi on a MySQL que obtendremos con OpenConnection al iniciar la aplicaci on. La funci on GetConnection nos servir a para el resto de objetos de la 9
Tipo de dato Nombre MYSQL* m pLinkDb MYSQL* GetConnection() bool OpenConnection() int ExitInstance()
Tabla 1: Variables y funciones para la clase CTestMySQLApp aplicaci on que necesiten utilizar una conexion a MySQL (Di alogos, Vistas, Clases, etc.). Podremos acceder a la conexi on desde cualquier parte a trav es de la variable global theApp. Es por eso que la variable m pLinkDb tiene que estar protegida, para evitar utilizarla negligentemente sin que est e inicializada. Ver Listado10 l nea 14. Luego del proceso de agregar las variables y funciones de la Tabla 1. Nuestra clase CTestMySQLApp quedar a como el Listado 3.
Listado 3: Declaraci on de la clase CTestMySQLApp 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: class CTestMySQLApp : public CWinApp { protected: bool OpenConnection(); MYSQL* m_pLinkDb; public: MYSQL* GetConnection(); CTestMySQLApp(); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CTestMySQLApp) public: virtual BOOL InitInstance(); virtual int ExitInstance(); //}}AFX_VIRTUAL // Implementation //{{AFX_MSG(CTestMySQLApp)
//}}AFX_MSG DECLARE_MESSAGE_MAP() };
10
La funci on OpenConnection
Esta funci on es muy importante por que depende de esta si seguimos con el programa o nos salimos de el sin antes mostrar un mensaje de error. OpenConnection debe invocarse desde InitInstance de la Aplicaci on. Ya que necesitamos que la conexi on se establezca al iniciar el programa. En la neas funci on OpenConnection es donde inicializamos la variable m pLinkDb (L 3-4) para luego conectarnos al servidor MySQL con la funci on de la API de neas 11,19). Si ocurre algun error devolvemos MySQL mysql real connect (L false mostrando antes el mensaje de error (L neas 21,27). Ver Listado 5.
Listado 5: Implementaci on de la funci on OpenConnection 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: bool CTestMySQLApp::OpenConnection() { m_pLinkDb = new MYSQL; mysql_init(m_pLinkDb); CString CString CString CString sHost sUser sPassword sDatabase = = = = _T("localhost"); _T("root"); _T(""); _T("prueba_db");
if (!mysql_real_connect( m_pLinkDb, sHost, sUser, sPassword, sDatabase, 3306, // Puerto de conexion NULL, // Unix socket 0)) // Otras opciones del cliente { CString strText; strText.Format("Error: %s" ,mysql_error(m_pLinkDb)); AfxMessageBox(strText); return false; }
11
29: 30:
return true; }
Usted puede guardar y obtener los parametros de conexi on del lugar que guste el registro de Windows por ejemplo, es por eso que he declarado las variables de las l neas 6-9. En la funci on InitInstance invocamos a OpenConnection pero vericamos que el resultado sea el que esperamos, sino retornamos FALSE y asi evitamos que la aplicaci on siga. Ver Listado 6.
Listado 6: Abriendo la conexi on con OpenConnection 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: BOOL CTestMySQLApp::InitInstance() { ... if (!OpenConnection()) { return FALSE; } ... }
Cuando salgamos de la aplicaci on tendremos que cerrar la conexi on. Al salir de una aplicaci on basada en MFC se invoca a la funci on ExitInstance y ah es donde tenemos que escribir el codigo necesario para ello. Ver Listado 7.
Listado 7: Cerrando la conexi on en ExitInstance 1: 2: 3: 4: 5: 6: 7: 8: int CTestMySQLApp::ExitInstance() { if (m_pLinkDb) { mysql_close(m_pLinkDb); } return CWinApp::ExitInstance(); }
Ahora nalmente vamos a la funci on GetConnection, esta funci on nos retornar a un apuntador hacia la conexi on global, antes de retornar dicho apuntador debemos asegurarnos que la conexi on sea valida, para ello se utiliza la macro ASSERT(), esta macro eval ua el parametro, si es FALSE o NULL provoca un fallo. on a la base de datos. Ver Listado 8. Con esto concluimos el asunto de la conexi 12
6. Preparar el di alogo
Desde la vista de recursos en la secci on Dialogs ubicar y abrir el dialogo de la aplicaci on (en nuestro caso es el dialogo que tiene el ID: IDD TESTMYSQL DIALOG) para modicarlo. Agregarle y ubicar los controles hasta que quede como la Imagen 6. A cada uno de los controles le asignaremos un ID como la Tabla 2. En la misma tabla se indica los eventos y funciones que tambien debemos agregar a la clase CTestMySQLDlg.
Nota: Para agregar facilmente una variable relacionada a un control: hacer doble click sobre el manteniendo presionada la tecla [CTRL], luego asignarle el nombre y tipo de variable. El ambito de las variables y funciones ser an creados autom aticamente por el ClassWizard. La funci on OnFind() es invocada cuando el usuario hace click sobre el boton IDC FIND. Asu vez la funci on OnFind() invocar a a LoadData() Ver Listado 9:1518. Tambien tenemos que hacer una llamada a LoadData() desde la funci on OnInitDialog(). Ver Listado 9:10.
13
Tipo de dato Control Evento CListCtrl IDC RESULT CString IDC QUERY void void IDC FIND BN CLICKED
La funci on LoadData() se encargar a de cargar los datos y los ir a volcando en el control IDC RESULT(Ver Listado 10:13-44), pero antes de cargarlos ensamblar a una consulta SQL para ello. La consulta SQL la ejecutaremos a trav es de la conexi on global y contendr a en clausula WHERE una sentencia que nos ayudar aa buscar registros basados en el contenido del control IDC QUERY (Ver Listado 10:511).
Listado 10: La funci on LoadData 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: void CTestMySQLDlg::LoadData() { CWaitCursor x; UpdateData(); CString sql; sql.Format("SELECT ruc,razonsocial \ FROM empresas \ WHERE razonsocial LIKE %s%%",m_sFilter);
14
12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54:
if(mysql_real_query( theApp.GetConnection() ,sql ,sql.GetLength()) == 0 ) { MYSQL_RES* res; if ((res = mysql_store_result(theApp.GetConnection()))) { m_report.DeleteAllItems(); MYSQL_ROW Row; CString sRuc; // Ruc CString sRazSoc; // Razon Social int item = 0; while ((Row = mysql_fetch_row(res))) { sRuc.Format ("%s", Row[0] ? (char*) Row[0] : "NULL"); m_report.InsertItem(item,sRuc); sRazSoc.Format ("%s", Row[1] ? (char*) Row[1] : "NULL"); m_report.SetItemText(item,1,sRazSoc); item++; } mysql_free_result(res); } } else { CString strText; strText.Format("Error: %s" ,mysql_error(theApp.GetConnection())); AfxMessageBox(strText); } }
15
int mysql_real_query( MYSQL *mysql, // enlace a la base de datos const char *query, // Consulta unsigned long length ); // Longitud de la consulta
mysql store result: Retorna todos los registros de la ultima consulta ejecutada a una estructura MYSQL RES. Retorna NULL si no hay resultados que mostrar.
mysql fetch row: Retorna el siguiente registro de una consulta, este m etodo debe ser llamado despu es de mysql store result. Retorna NULL si no hay mas registros.
mysql free result: Libera la memoria ocupada por el resultado de una consulta obtenida mediante mysql store result.
16
Antes de escribir el codigo de las instrucciones de los botones nuevos, tenemos que crear un dialogo para poder dar de alta o modicar un registro en la base de datos. En el dialogo actual s olo muestra dos campos (ruc, razonsocial) pero la tabla empresas tiene 5 (Ver Listado 1). Para ello es di alogo de la Imagen 9, e la clase a este dialogo le puse el ID: IDD EMPRESA y mediante ClassWizard cre relacionada con este: CEmpresaDlg. La clase CEmpresaDlg debe tener las variables, eventos y funciones que se indican en la Tabla 3. Las variables de tipo CString estan elazadas a un control y pueden agregarse utilizando el procedimiento que se indica en la Nota de la Imagen 6. La variable m bIsNew nos servir a como ag para saber si estamos agregando o modicando. En la funci on LoadData() cargaremos los datos en caso de que estemos modicando. Utilizaremos Guardar para actualizar o dar de alta un registro de la base de datos. Las funci on OnOK puede agregarse haciendo doble click en el boton con el ID: IDOK. La funci on OnInitDialog se agrega automaticamente ubicando el mensaje 17
Tipo Variable Variable Variable Variable Variable Variable Funci on Funci on Funci on Funci on
Tipo de dato CString CString CString CString CString bool void bool void BOOL
Control IDC RUC IDC RAZONSOCIAL IDC DIRECCION IDC EMAIL IDC WEB
Nombre m sRUC m sRazonSocial m sDireccion m sEmail m sWeb m bIsNew LoadData() Guardar() OnOK() OnInitDialog()
Ambito public public public public public public protected protected protected protected
Tabla 3: Variables y funciones para la clase CEmpresaDlg WM INITDIALOG desde la pesta na Message Maps del ClassWizard, luego de ubicar el mensaje hacer click en Add Function. Para terminar tenemos que modicar el contructor del dialogo CEmpresaDlg para que nos acepte un parametro CString, donde le pasaremos el RUC en caso de que quisieramos modicar un registro. Luego de todas esas modicaciones, la clase CEmpresaDlg deber a quedar como el Listado 11.
Listado 11: Declaracion de la clase CEmpresaDlg 1: 2: 3: 4: 5: 6: 7: 8: class CEmpresaDlg : public CDialog { // Construction public: CEmpresaDlg(CString sRUC,CWnd* pParent = NULL); // Dialog Data //{{AFX_DATA(CEmpresaDlg)
18
9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37:
enum { IDD = IDD_EMPRESA }; CString m_sRUC; CString m_sRazonSocial; CString m_sDireccion; CString m_sEmail; CString m_sWeb; //}}AFX_DATA bool m_bIsNew; // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CEmpresaDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); //}}AFX_VIRTUAL // Implementation protected: bool Guardar(); void LoadData(); // Generated message map functions //{{AFX_MSG(CEmpresaDlg) virtual BOOL OnInitDialog(); virtual void OnOK(); //}}AFX_MSG DECLARE_MESSAGE_MAP() };
19
m_sRazonSocial = _T(""); m_sDireccion = _T(""); m_sEmail = _T(""); m_sWeb = _T(""); //}}AFX_DATA_INIT m_bIsNew = m_sRUC.IsEmpty() == TRUE; }
La funci on LoadData
La funci on LoadData se parece mucho a la funci on CTestMySQLDlg::LoadData s olo que esta vez carga un solo registro, y se asigna el valor de cada campo a la variable que corresponde en el di alogo. Ver Listado 13. La consulta SQL que estamos ejecutando es SELECT * FROM empresas WHERE ruc = m sRUC. En la funci on OnInitDialog invocaremos a LoadData en caso de que estemos editando un registro. Ver Listado 13.
Listado 13: Funci ones OnInitDialog y LoadData 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: BOOL CEmpresaDlg::OnInitDialog() { CDialog::OnInitDialog(); if (!m_bIsNew) { LoadData(); } return TRUE; } void CEmpresaDlg::LoadData() { CWaitCursor x; UpdateData(); CString sql; sql.Format("SELECT * FROM empresas WHERE ruc = %s",m_sRUC); if(mysql_real_query( theApp.GetConnection() ,sql ,sql.GetLength()) == 0 ) { MYSQL_RES* res; if ((res = mysql_store_result(theApp.GetConnection()))) {
20
29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53:
MYSQL_ROW Row; if((Row = mysql_fetch_row(res))) { m_sRUC = Row[0]; m_sRazonSocial = Row[1]; m_sDireccion = Row[2]; m_sEmail = Row[3]; m_sWeb = Row[4]; UpdateData(FALSE); } mysql_free_result(res); } } else { CString strText; strText.Format("Error: %s" ,mysql_error(theApp.GetConnection())); AfxMessageBox(strText); } }
La funci on Guardar
En la funci on Guardar() ejecutar a el comando SQL INSERT o UPDATE seg un sea el caso. En la linea 19 del Listado 14, antes de ejecutar cualquier consulta, evaluamos el valor de la variable m bIsNew. Si la consulta se ha ejecutado con exito Guardar() devolver a true, y como es invocada desde OnOK el dialogo se cerrar a devolviendo IDOK.
Listado 14: Funci ones Guardar y OnOK 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: void CEmpresaDlg::OnOK() { if (Guardar()) { CDialog::OnOK(); } } bool CEmpresaDlg::Guardar() { CWaitCursor x; UpdateData();
21
15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59:
CString sql; m_sRazonSocial.Replace("",""); if (m_bIsNew) //Nueva Empresa { sql.Format("INSERT INTO empresas \ VALUES (%s,%s,%s,%s,%s)" ,m_sRUC ,m_sRazonSocial ,m_sDireccion ,m_sEmail ,m_sWeb); } else // Modificar Empresa { sql.Format("UPDATE empresas SET RazonSocial = %s, \ Direccion = %s, Email = %s, Web = %s \ WHERE ruc = %s " ,m_sRazonSocial ,m_sDireccion ,m_sEmail ,m_sWeb ,m_sRUC); } if(mysql_real_query( theApp.GetConnection() ,sql ,sql.GetLength()) == 0 ) { return true; } else { CString strText; strText.Format("Error: %s" ,mysql_error(theApp.GetConnection())); AfxMessageBox(strText); return false; } }
nuevos botones de la Imagen 8. El Listado 15 muestra las tres funciones. En el caso de OnModify y OnDel es necesario comprobar que un elemento del control CListCtrl est e seleccionado. Es importante que este declarada la inclusi on del archivo EmpresaDlg.h (#include .EmpresaDlg.h") en el archivo TestMySQLDlg.cpp para poder utilizar la clase CEmpresaDlg.
Listado 15: C odigo para guardar, modicar y eliminar 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: void CTestMySQLDlg::OnNew() { CEmpresaDlg dlg(""); if (dlg.DoModal() == IDOK) { m_report.InsertItem(0,dlg.m_sRUC); m_report.SetItemText(0,1,dlg.m_sRazonSocial); } } void CTestMySQLDlg::OnModify() { POSITION pos = m_report.GetFirstSelectedItemPosition(); if (pos) { int item = m_report.GetNextSelectedItem(pos); CString ruc = m_report.GetItemText(item,0); CEmpresaDlg dlg(ruc); if (dlg.DoModal() == IDOK) { m_report.SetItemText(item,0,dlg.m_sRUC); m_report.SetItemText(item,1,dlg.m_sRazonSocial); } } else { MessageBox("Debe seleccionar un item de la lista"); } } void CTestMySQLDlg::OnDel() { POSITION pos = m_report.GetFirstSelectedItemPosition(); if (pos) { int item = m_report.GetNextSelectedItem(pos); CString ruc = m_report.GetItemText(item,0); CString msg = "Realmente desea Eliminar el item seleccionado?"; if (MessageBox(msg,"Eliminar",MB_YESNO|MB_ICONWARNING) == IDYES)
23
43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71:
{ CString sql; sql.Format("DELETE FROM empresas WHERE ruc = %s",ruc); if(mysql_real_query( theApp.GetConnection() ,sql ,sql.GetLength()) == 0 ) { m_report.DeleteItem(item); } else { CString strText; strText.Format("Error: %s" ,mysql_error(theApp.GetConnection())); MessageBox(strText); } } } else { MessageBox("Debe seleccionar un item de la lista"); } }
Finalmente la aplicaci on correr a como se ve en la Imagen 10. Notar an que los botones tienen un icono, es por que he utilizado la clase CImageButton del art culo que esta ubicado en: www.latindevelopers.com/articles/vc/imagebutton/ He modicado la clase CImageButton para que acepte solo una imagen por boton. Ademas tambien le he agregado un temporizador para hacer la busqueda mas interactiva.
24
Por citar un solo ejemplo: las consultas pueden agruparse en una funci on generica que las ejecute. Agradezco a Rosario Bustamante por realizar las correcciones ortogr acas. El Lenguaje de programaci on Visual C++ es una marca y producto de Microsoft Corp. El gestor de base de datos MySQL es producido y distribuido bajo licencia GPL por MySQL AB.
26