Сейчас на сайте

Сейчас 5 гостей онлайн

Поиск

Tag Cloud

Twitter oAuth и Cod... Баллада о г... сихи лирик... стихи лири... Динамическ... Домашняя с... Использова... Использова... Отправка с... Создание ф... Шепот посл... TinyMCE в Rails стихи лири... Быстрая ра... Пишем собс... Создание с... Установка ... Ностальгия... Москва-Бел... стихи лири... Стихи про п... Крылья сти... Создание п... Простой по... Создание п... Одинокий в... Гражданин ... Несчастный... Сонет стих... Отрезок ст... Врагу не сд... Предчувств... Поиск в ст... Использова... Смерть дву... Использова... Как сделат... Как сделат... Облако тег... Южная сере... Программна... Codeigniter в де... CodeIgniter: фор... проверка в... стихи лири... WEB fetcher(scrappe... Простой Twitt... стихи твор... стихи лири... Проверка п... Создание и ... Побег с Сол... Отправка SMS... MS VSTO 2007/Infusio... Установка R... Fckeditor в при... Степные тр... моя любовь. К твоим оз... Сомкнуть л... чтоб отдат... вот – вот ... еще не расс... Снег тишина и лу... и мира пово... что мой пос... Лишь ты. И т... ты любима ты чиста. Экспорт да... Я пью до дн... что нам теп... -Наш первый... Социальные... Социальные... Спит в можж... Воздух про... Стены рожденные ... эхо умрет. Неотправле... стихи лири... Он порезал... Боясь шагн... не осталос... Услышать з... Программир...

Создание программы - MySQL DatabaseBrowser PDF Печать E-mail
31.05.2011 02:39

Сейчас использование баз данных, в то числе и удаленных стало обычной и повседневной практикой. Очень часто используется и СУБД MySQL – свободной распространяемая система управления базами данных. В основном она используется для малых и средних предприятий, где успешно решает многие задачи. Ее бесплатность, доступность, стабильность в работе и прочие характеристики позволяет говорить об это СУБД как о массовой альтернативе таких баз как InterBase или SyBase. Последние версии этой программы, существенно расширяющие ее возможности предлагают решение многих проблем, с которым сталкиваются как администратор баз данных, так и обычный пользователь.

Однако, существуют так же и проблемы при работе с Windows, как обязательное наличие драйверов ODBC для MySQL, если СУБД работает в этой среде. Стандартный клиент для MySQL не является удобным в настоящее время, так как является консольной программой. Опять же, требуется как минимум наличие установленной копии программы MySQL сервер на компьютере пользователя. Просмотр данных и простое редактирование также в стандартном клиенте не отвечает современным требованиям к интерфейсу. Решение целого ряда повседневных задач, предполагает стандартизацию пользовательского интерфейса и создание удобного юзабилити.

Поэтому мы пришли к необходимости создания собственного клиентского приложения.

В начале мы создаем шаблон проекта. Для этого мы в Visual Studio выбираем «MFC APPWizard» и вводим название проекта «Myslqlone» . Далее, «Шаге1» выбираем «Single Document». В «Шаге2» и в «Шаге3» не меняем ничего,
в «Шаге 4» отключаем «Printing and Print Preview» и переключаем радиобокс на «Internet Explorer Rebars”. В «Шаге 5» выбираем из 2 радиобоксов «Windows Explorer». На конец, в «Шаге 6» нажимаем кнопку «Finish». Выбранный нами тип проекта приложения наиболее полно отвечает решению поставленной задачи. В нем находятся изначально 2 удобных класса, «CleftView”, который
является потомком класса «CtreeCtrl» в нашем случае, «CmysqloneView», который в свою очередь наследует от «ClistView», что очень удобно и ускоряет процесс разработки проекта. Оба эти класса могут использовать возможности
контролов ClistCtrl и CtreeCTrl, от которых они порождены. Данные обстоятельства в последствии будут нами постоянно использоваться в этом проекте.Все дальнейшие действия разбиты на этапы и описываются здесь ниже.


1. Копируем 2 файла в папку проекта: «libmysql.dll» и «libmysql.lib» из папки MySQL Server 4.1/lib/. Затем подключаем к проекту файл «libmysql.lib». Нам потребуется этий файлы для обеспечения работы программы и доступа к MySQL API функциям. Мы будем использовать MySQL C API функции,
как наиболее стабильно работающие и обеспечивающие полный сервис.

2. Затем копируем все заголовочные файлы из директории MySQL Server 4.1/include/ все заголовочные файлы в директориюVC /include/ Visual Studio.
Это также необходимо для создания и компиляции проекта.

3. Подключаем в файл “mysql.h” к файлу «stdafx.h» :
#include "mysql.h"

4. Создаем переменную класса CImageList m_TreeImages в классе
«CleftView.cpp» Она будет использована для создания списка картинок, которые будут в свою очередь использованы в создаваемом объекте типа CtreeCtrl.

5. Создаем в файле ресурсов новый ресурс.


6. Создаем в классе «CleftView.cpp» новый метод void FillTree():
void CLeftView::FillTree()
{
CTreeCtrl & m_tree = GetTreeCtrl();
m_tree.DeleteAllItems();

m_tree.SetImageList(&m_TreeImages, TVSIL_NORMAL);


HTREEITEM hRoot;

CMysqloneDoc* pDoc = GetDocument();

for (int i = 0; i < pDoc->m_available_bases.GetSize(); i++)
{
hRoot = m_tree.InsertItem(pDoc->m_available_bases[i], 0, 1);
}


}

7. Создаем в методе класса «CleftView.cpp» :OnInitialUpdate()
объект класса CimageList:

m_TreeImages.Create(IDB_BITMAP1, 16, 1, RGB(255, 255, 255));
Это создает список пиктограмм для CtreeCtrl

8. Добавляем в этот же класс метод OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) для обработки события смены элементов списка.

9. Вставляем в этот метод такой код:

void CLeftView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

CTreeCtrl & m_tree = GetTreeCtrl();
CMysqloneDoc* pDoc = GetDocument();
if (!pDoc->connected) {return;}
pDoc->current_table = "";
HTREEITEM nodSelected = m_tree.GetSelectedItem();

if (nodSelected>=0) {

CString strSelected=m_tree.GetItemText(nodSelected);
GetDocument()->SetTitle(strSelected);
}


HTREEITEM parent;
parent = m_tree.GetParentItem (nodSelected);
if (parent) {
pDoc->current_table = m_tree.GetItemText (nodSelected);

pDoc->UpdateAllViews (this);
return;
}



HTREEITEM child;
while (child = m_tree.GetChildItem (nodSelected)) {
m_tree.DeleteItem (child);
}



CString base_name = m_tree.GetItemText (nodSelected);
pDoc->current_base = base_name;

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);
MYSQL_RES * my_res;
MYSQL_ROW row;
CString sql;

mysql_select_db (mysql, base_name.GetBuffer(125));
if (mysql_query (mysql, "SHOW TABLES")) {
AfxMessageBox ("Query SHOW databases failed");
return;
}
my_res = mysql_store_result(mysql);
while (row = mysql_fetch_row (my_res)) {
char buffer[255];
strcpy (buffer, row[0]);
m_tree.InsertItem (_T(buffer), nodSelected);
}
mysql_free_result (my_res);


*pResult = 0;
}


10.
Добавляем новый ресурс – диалоговое окно. Туда вставляем 3 поля редактирования, одному из них в стилях проставляем стиль: «password» . Далее мы заходи в Class Wizard и создаем новый класс для данного диалога. Назовем его «CLoginDlg». Он будет наследоваться от класса CDialog. Далее к каждому из полей редактирования создаем переменные типа Cstring. Это будут переменные этого класса для ввода данных по соединению с MySQL сервером.

11. Затем мы создаем переменную типа MYSQL mysql для класса «CmysqloneApp.cpp», это класс приложения. Эта переменная будет использоваться нами далее везде в программе для доступа к функциям MySQL.
Затем создаем в этом же классе новый метод для соединения с сервером баз данных типа BOOL ConnectToDb(). Вот его код:


BOOL CMysqloneApp::ConnectToDb()
{
CLoginDlg dlg;

while (dlg.DoModal()== IDOK) {
if(!mysql_init(&mysql)){AfxMessageBox ("Can't make initialization to mysql server!");}
if(mysql_real_connect(&mysql,dlg.m_host, dlg.m_login,dlg.m_password,NULL,0,NULL,0)){
return TRUE;
}
}
return FALSE;

}
В этом методе вызывается диалоговое окно CloginDlg, чтобы считать введенные пользователем данные и выполнить соединение с MySQL сервером. Данные пользователя хранятся в специальном файле, с расширением «.lgn», который предоставляет администратор. Ниже приводится код метода подключения к серверу баз данных:
void CLoginDlg::OnBnClickedLogin()
{
UpdateData();

char login[35];
char password[25];
char host[255];
FILE *file;
bool valid_login = false;

if( m_login =="")
{
AfxMessageBox("You must provide a username and password or click Cancel!");
return;
}
if( m_password =="")
{
AfxMessageBox("Invalid login entered");
return;
}


if( m_host =="")
{
AfxMessageBox("Enter host name, please");
return;
}

try {

file = fopen("database.lgn", "r");


while( !feof(file) )
{

fscanf(file, "%s", login);


if( strcmp((LPCTSTR)m_login, login) == 0 )
{

fscanf(file, "%s", password);


if( strcmp((LPCTSTR)m_password, password) == 0 )
{
valid_login = true;
}
else
valid_login = false;
}
}
if( valid_login == true )
OnOK();
else
{
AfxMessageBox("Invalid entry data entered! Please try again");

}

fclose(file);
}
catch(...)
{
AfxMessageBox("Could not validate entered information to connect with MySQL database");
}

UpdateData(FALSE);

}


12.
Подключаем заголовочный файл класса «CloginDlg.cpp» – «LoginDlg.h» к
к файлу класса «CMysqloneApp»-«mysqlone.cpp»

#include "LoginDlg.h"

13.
Создаем еще один метод для этого же класса типа void ExecuteSQL(CString sql). Он будет использоваться для выполнения запросов к MySQL серверу.
Вот его код:

void CMysqloneApp::ExecuteSQL(CString sql)
{

mysql_query (&mysql, sql);

}

Он также будет использоваться повсеместно в работе программы.

14. Затем мы создаем новые переменные для класса «CmysqloneDoc.cpp»
CStringArray m_available_bases; //текстовой массив списка доступных .//баз.
CString current_base; //переменная строкового типа для имени текущей //базы
CString current_table; //строковая переменная для имени текущей таблицы
bool connected;// переменная булевого типа для состояния соединения с //MySQL сервером.

15. На конец, вставляем следующий код вызова метода ConnectToDb() в
«CMysqloneApp»-«mysqlone.cpp» в метод InitInstance():

SetRegistryKey(_T("MySQLOne- MySQL Database Browser"));

LoadStdProfileSettings(); // Load standard INI file options (including MRU)

//После этих строк.

if (!ConnectToDb()) {
AfxMessageBox ("Could not connect to base\nQuitting");
return FALSE;
}

Метод ConnectToDb() будет вызываться при запуске программы, а поскольку он булевого типа, то про возращении этим методом FALSE программа не будет работать.
Теперь добавим еще один метод, который будет выбирать базу данных для дальнейшего использования.


void CMysqloneApp::ChangeCurrentBase(CString newBaseName)
{
mysql_select_db (&mysql, newBaseName);
}

16.
Далее мы переходим в класс «CleftView.cpp» и через Class Wizard добавляем туда метод OnUpdate. Это один из поддерживаемых представлением методов, который нам нужно переопределить таким образом:

void CLeftView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{

CTreeCtrl & m_tree = GetTreeCtrl();
CMysqloneDoc* pDoc = GetDocument();
if (!pDoc->connected) {
m_tree.DeleteAllItems();
return;
}
FeelTree();

}


17. Затем мы переходим снова к класс «CmysqloneDoc.cpp» и переопределяем метод OnNewDocument():


BOOL CMysqloneDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;

current_table = "";

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);
MYSQL_RES * my_res;
MYSQL_ROW row;
if (mysql_query (mysql, "SHOW databases")) {
AfxMessageBox ("Query SHOW databases failed");
return TRUE;
}
my_res = mysql_store_result(mysql);
int num = mysql_num_rows (my_res);

m_available_bases.RemoveAll();
while (row = mysql_fetch_row (my_res)) {
m_available_bases.Add (row[0]);
}

mysql_free_result (my_res);
current_base = "";
return TRUE;

}


18.
Теперь переходим в класс «CmysqloneView.cpp», где добавляем в метод этого класса OnInitialUpdate() следующий код для создания объекта типа ClistCTrl и задания его стилей отображения.

void CMysqloneView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
CListCtrl &m_list = GetListCtrl();
m_list.ModifyStyle(NULL, LVS_REPORT);
m_list.SetExtendedStyle (LVS_EX_GRIDLINES );


}


19.
Далее мы идем снова в Class Wizard и там добавляем в класс «CmysqloneView.cpp» метод OnUpdate и помещаем туда такой код:

void CMysqloneView::OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/)
{
CListCtrl &m_list = GetListCtrl();
CMysqloneDoc* pDoc = GetDocument();

if (!pDoc->connected) {
m_list.DeleteAllItems ();
while(m_list.DeleteColumn(0));
return;
}
if (pDoc->current_table == "") return;
m_list.DeleteAllItems();
while(m_list.DeleteColumn(0));

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);
MYSQL_RES * my_res;
MYSQL_ROW row;
CString sql;
sql="SHOW COLUMNS IN ";
sql += pDoc->current_table;
mysql_query (mysql, sql);
my_res = mysql_store_result (mysql);
int i = 0;
int counter = 0;
while (row = mysql_fetch_row (my_res)) {
m_list.InsertColumn (i, row[0], LVCFMT_LEFT, 100);
i++;
}
counter = i;
mysql_free_result (my_res);


sql = "SELECT * FROM ";
sql += pDoc->current_table;
mysql_query (mysql, sql);
my_res = mysql_store_result (mysql);
i = 0;
LVITEM item;
item.mask = LVIF_TEXT;
while (row = mysql_fetch_row (my_res)) {
item.iItem = i;
item.iSubItem = 0;
item.pszText = row[0];
m_list.InsertItem (&item);
for (int z = 1; z < counter; z++) {
item.iSubItem = z;
item.pszText = row[z];
m_list.SetItem (&item);
}

i++;
}

}


Этот метод будет использоваться для отображения в правой части окна структуры данных, полученных в результате запросе к базе данных.
Фактически, это и будет главное просмотровое окно программы, отображающие данные и структуру таблиц баз данных.


20. Теперь мы снова идем во вкладку «Resources» и добавляем новый ресурс – диалоговое окно. Это окно будет использоваться для создания новой базы данных. Мы вводим туда новое текстовое поле типа CEdit и СStatic, для создания текстового заголовка: «New Database Name». Создаем в Class Wizarde новый класс «CNewDatabaseDlg». К текстовому полю CEdit подключаем переменную типа CString - «m_newdatabase». Эта переменная для задания нового имени вновь создаваемой базы данных.

21. Переопределяем метод этого класса OnOK() для исполнения запроса к MySQL серверу по созданию новой базы.

void CNewDatabase::OnOK()
{
UpdateData(TRUE);
CString sql="CREATE DATABASE ";
sql +=m_newdatabase;
((CMysqloneApp*)AfxGetApp())->ExecuteSQL (sql);

CDialog::OnOK();
}


22.
Подключаем заголовочный файл нового диалогового «CreateNewTableDlg.h» к классу «CleftView.срр» для последующей обработки командой меню.


23. Теперь переходим опять во вкладку «Resources» и добавляем новое диалоговое окно. На этот раз в нем будет окно для исполнения запросов к базе данных. Мы добавляем туда следующие контролы: ССombox – сюда мы будем вводить SQL запрос, CListBox - это будет форма для отображения списка доступных нам баз данных и CListCtrl - в нем будут отображаться результаты SQL запросов. Итак, мы создаем 2 переменных класса:
CListBox m_listbox и CListCtrl m_list.

24. Затем мы добавляем новый метод к этому классу диалога- void AddStr(). Этот метод будет получать строковую переменную, введенную в CComboBox . Далее код этого метода:

void CSqlQueryDlg::AddStr()
{

CComboBox *Box;

Box = (CComboBox *)(this->GetDlgItem(IDC_COMBO1));

Box->AddString(m_sql);
}



25. Теперь нам необходимо заполнить список базами данных, которыей находятся в данный момент на сервере MySQL. Для этого мы подключаем и переопределяем метод OnInitDialog(). В нем мы заполняем список CListBox, который буджет показываться при запуске этого окна.

BOOL CSqlQueryDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// TODO: Add extra initialization here
MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);
MYSQL_RES * my_res;
MYSQL_ROW row;
CString data_sql="SHOW DATABASES";
((CMysqloneApp*)AfxGetApp())->ExecuteSQL (data_sql);

my_res = mysql_store_result(mysql);
while (row = mysql_fetch_row (my_res)) {
char buffer[255];
strcpy (buffer, row[0]);
m_listbox.AddString(_T(buffer));
}

mysql_free_result (my_res);

return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}


26.
Затем, мы переопределяем метод OnOK() у этого класса, чтобы выполнить SQL запрос.


void CSqlQueryDlg::OnOK()
{
UpdateData();

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

CString basename;
m_listbox.GetText (m_listbox.GetCurSel(), basename);
((CMysqloneApp*)AfxGetApp())->ChangeCurrentBase (basename);
((CMysqloneApp*)AfxGetApp())->ExecuteSQL (m_sql);

m_list.DeleteAllItems ();


while(m_list.DeleteColumn(0));
MYSQL_RES * my_res;
MYSQL_ROW row;
mysql_query (mysql, m_sql);
my_res = mysql_store_result (mysql);

int cols = mysql_num_fields (my_res);
int counter ;
for (counter = 0; counter < cols; counter++) {
m_list.InsertColumn (counter, "Data", LVCFMT_LEFT, 50);
}

counter = cols;
LVITEM item;
item.mask = LVIF_TEXT;
int i = 0;
while (row = mysql_fetch_row (my_res)) {
item.iItem = i;
item.iSubItem = 0;
item.pszText = row[0];
m_list.InsertItem (&item);
for (int z = 1; z < counter; z++) {
item.iSubItem = z;
item.pszText = row[z];
m_list.SetItem (&item);
}

i++;

}

mysql_free_result (my_res);


//CDialog::OnOK();
}

Заметим, что последняя строка кода закомментирована, чтобы OnOk() не закрывал это окно по завершению работы.

27. Теперь добавим новую кнопку в это диалоговое окно и переименуем ее

заголовок в «Clear» и затем создадим для нее обработчик. Этот метод будет

очищать переменную CListCtrl m_list после исполнения запроса к базе данных.

Код метода ниже по тексту.

 

void CSqlQueryDlg::OnClear()

{

m_list.DeleteAllItems ();

UpdateData(FALSE);

}

28. На конец, мы снова подключаем заголовочный файл данного класса диалогового окна «CListCtrl m_list.h» к классу «CleftView.срр» для последующей обработки командой меню.

29. Снова переходим во вкладку «Resources» и добавляем новое диалоговое окно. В этом случае это будет окно для удаления базе данных, которые доступны нам . Мы добавляем сюда 2 контрола: CStatic, в который вводим следующий текст: «Database Name» и CListBox m_listbox, в котором список баз данных будет отображаться. Затем мы добавляем и переопределяем метод класса OnInitDialog, в котором список баз будет заполняться.

BOOL CDeleteDatabaseDlg::OnInitDialog()

{

CDialog::OnInitDialog();

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

MYSQL_RES * my_res;

MYSQL_ROW row;

CString data_sql="SHOW DATABASES";

((CMysqloneApp*)AfxGetApp())->ExecuteSQL (data_sql);

my_res = mysql_store_result(mysql);

while (row = mysql_fetch_row (my_res)) {

char buffer[255];

strcpy (buffer, row[0]);

m_listbox.AddString(_T(buffer));

}

mysql_free_result (my_res);

return TRUE; // return TRUE unless you set the focus to a control

// EXCEPTION: OCX Property Pages should return FALSE

}

Строка запроса будет отображаться в MessageBox, чтобы видеть совершаемое действие.

30. Затем мы переопределяем метод класса OnOk() для исполнения

собственно запроса к базе данных. Вот его код:

void CDeleteDatabaseDlg::OnOK()

{

UpdateData(TRUE);

CString item;

int index=m_listbox.GetCurSel();

m_listbox.GetText(index,item);

CString sql="DROP DATABASE ";

sql +=item;

m_delete=sql;

AfxMessageBox(m_delete);

((CMysqloneApp*)AfxGetApp())->ExecuteSQL (sql);

CDialog::OnOK();

}

31. Опять же, подключаем «DeleteDatabaseDlg.h» файл заголовка к классу «CLeftView.cpp» для использования в обработчике меню.

32. Теперь мы идем опять во вкладку «Resources» и там находим в папке «Menu» ресурс меню проекта - «IDR_MAINFRAME». Мы удаляем все стандартные опции меню, за исключением «Exit» и создаем свои пункты меню и идентификаторы для них. Получаются такие команды меню и идентификаторы:

«Сreate New Table» (ID_NEW_DATABASE), «MySQL Query»( ID_MYSQL_QUERY), «Drop Database»( ID_DATA_DROPDATABASE) и

«See Last Insert/Alter SQL Query»( ID_DATA_SEELASTSQLQUERY). Эта опция меню будет описана позднее. Затем мы создаем для них обработчики в классе «CLeftView.cpp». Далее их полный код:

void CLeftView::OnNewDatabase()

{

CNewDatabase dlg;

if (dlg.DoModal() == IDOK )

{

CTreeCtrl & m_tree = GetTreeCtrl();

HTREEITEM hitem = m_tree.InsertItem(dlg.m_newdatabase, TVI_ROOT);

m_tree.SelectItem(hitem);

}

}

void CLeftView::OnDataDropdatabase()

{

CDeleteDatabaseDlg dlg;

if (dlg.DoModal() == IDOK )

{

CTreeCtrl & m_tree = GetTreeCtrl();

HTREEITEM hitem = m_tree.GetSelectedItem();

CString selected=m_tree.GetItemText(hitem);

m_tree.DeleteItem(hitem);

}

}

void CLeftView::OnNewTable()

{

CCreateNewTableDlg dlg;

if (dlg.DoModal() == IDOK )

{

CTreeCtrl & m_tree = GetTreeCtrl();

HTREEITEM hitem = m_tree.GetSelectedItem();

HTREEITEM childitem=m_tree.GetChildItem(hitem);

childitem = m_tree.InsertItem(dlg.m_newtable, TVI_FIRST);

m_tree.SelectItem(childitem);

}

}

void CLeftView::OnMysqlQuery()

{

CSqlQueryDlg dlg;

if (dlg.DoModal() == IDOK ){

dlg.OnOK();

}

}

void CLeftView::OnDataSeelastsqlquery()

{

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

const char* last_query;

CString noresult;

CString temp;

last_query=mysql_info(mysql);

temp=(CString)last_query;

if (temp=="NULL") {

noresult="No any SQL request was done till now";

AfxMessageBox(noresult);

}

else {

AfxMessageBox(temp);

}

}

На последнем методе остановимся подробнее. Остальные обработчики команд меню используют описанные выше диалоговые классы. А этот метод служит для получения информации о последнем запросе типа INSERT/ALTER к базе данных. Такая информация полезна при коллективной работе с сервером баз данных, так как наиболее быстро позволяет видеть последние изменения данных без необходимости исполнения запросов к таблице.

33. Теперь перейдем во вкладку «Resources» и выбираем «IDD_ABOUTBOX». Там мы добавляем 4 новых контрола типа Cstatic и распологаем их горизонтально, один над другим. Далее мы вводим в качестве заголовков «MySQL Host Name» и «MySQL Protocol Version» в оба верхних контрола. Первый нижний контрол мы переименовываем в

«IDC_INFO» и удаляем текст из него. Затем мы подключаем к нему переменную типа CString mysql_info. Во втором нижнем котроле мы убираем также весь текст в заголовке и подключаем к нему переменную типа int mysql_version. Обе эти переменные буду использоваться для

отображения информации в окне диалога «About».

34. Затем мы переопределяем метод OnAppAbout() этого класса для вызова 2 методов MySQL С API, которые в свою очередь выдадут ифнормацию о типе MySQL cсервера и его версии.

void CMysqloneApp::OnAppAbout()

{

CAboutDlg aboutDlg;

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

const char* host_info="";

int ver;

host_info=mysql_get_host_info(mysql);

ver=mysql_get_proto_info(mysql);

aboutDlg.mysql_info=(CString)host_info;

aboutDlg.mysql_version=ver;

aboutDlg.DoModal();

}

35. В меню “Help” добавляем новый пункт – “MySQL Info”

Здесь будет появляется модальное диалоговое окно, в котором

будет отображаться статус MySQL сервера. Для этого мы добавим туда еще в ресурсах новое диалоговое окно и назовем его «IDD_MYSQLINFODLG». Туда введем 5 новых элементов управления типа CStatic. Одно поле назовем «MySQL Server Status», а другие поля будут связаны с переменными типа CString и в последствии будут использоваться для отображения данных.

Далее переопределяем метод OnInitDialog() этого диалогового окна и вводим туда такой код:

BOOL CMySQLInfoDlg::OnInitDialog()

{

CDialog::OnInitDialog();

const char* result="";

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

result=mysql_stat(mysql);

CString temp=(CString)result;

m_mysqlinfo=temp;

UpdateData(FALSE);

return TRUE; // return TRUE unless you set the focus to a control

// EXCEPTION: OCX Property Pages should return FALSE

}

После добавляем обработчик в меню класса CMainFraime:

void CMainFrame::OnHelpMysqlinfo()

{

CMySQLInfoDlg dlg;

if (dlg.DoModal() == IDOK )

{

dlg.OnBnClickedExit();

}

}

36. Далее мы переходим снова редактор ресурсов, находим главное меню окна и добавляем туда новый пункт «Send E-Mail»

Затем подключаем его обработчик к классу CMysqloneDoc, редактируя его карту сообщений таким образом:

BEGIN_MESSAGE_MAP(CMysqloneDoc, CDocument)

//{{AFX_MSG_MAP(CMysqloneDoc)

// NOTE - the ClassWizard will add and remove mapping macros here.

// DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG_MAP

ON_COMMAND(ID_FILE_SEND_MAIL, OnFileSendMail)

ON_UPDATE_COMMAND_UI(ID_FILE_SEND_MAIL, OnUpdateFileSendMail)

END_MESSAGE_MAP()

Это позволит нам слать сообщения по электронной почте прямо из программы.

37. Снова возвращаемся в редактор ресурсов, к главному меню и вставляем туда такой пункт «Data Optimization». Обработчик для него ставим в классе CLeftView.

void CLeftView::OnDataDataoptimization()

{

CTreeCtrl & m_tree = GetTreeCtrl();

HTREEITEM hitem = m_tree.GetSelectedItem();

HTREEITEM childitem=m_tree.GetChildItem(hitem);

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

CMysqloneDoc* pDoc = GetDocument();

CString base_name=m_tree.GetItemText(hitem);

CString strSelected=m_tree.GetItemText(childitem);

pDoc->current_base=base_name;

CString sql="OPTIMIZE TABLE ";

mysql_select_db(mysql,base_name.GetBuffer(255));

sql+=strSelected;

((CMysqloneApp*)AfxGetApp())->ExecuteSQL (sql);

pDoc->UpdateAllViews (NULL);

}

Здесь мы сможем легко производить оптимизацию выбранной таблицы базы.

38. . Снова возвращаемся в редактор ресурсов, к главному меню и вставляем туда такой пункт «Empty All Data». Обработчик для него ставим в классе также CLeftView.

void CLeftView::OnDataCreatenewtable()

{

CCreateNewTableDlg dlg;

if (dlg.DoModal() == IDOK )

{

CTreeCtrl & m_tree = GetTreeCtrl();

HTREEITEM hitem = m_tree.GetSelectedItem();

HTREEITEM childitem=m_tree.GetChildItem(hitem);

// childitem = m_tree.InsertItem(dlg.m_newtable, TVI_FIRST);

m_tree.SelectItem(childitem);

}

}

void CLeftView::OnDataEmptyalldata()

{

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

CTreeCtrl & m_tree = GetTreeCtrl();

CString sql="DELETE FROM ";

HTREEITEM nodSelected = m_tree.GetSelectedItem();

if (nodSelected>=0) {

CString strSelected=m_tree.GetItemText(nodSelected);

sql +=strSelected;

AfxMessageBox("Are you sure to wish to delete ALL data from "+ strSelected,MB_OKCANCEL|MB_ICONQUESTION );

((CMysqloneApp*)AfxGetApp())->ExecuteSQL (sql);

m_tree.DeleteItem(nodSelected);

}

}

Мы очищаем таблицу от данных при помощи этой команды меню.

На конец, запускаем программу и послу успешной компиляции мы получим диалоговое окно для ввода информации. Затем мы увидим список

баз в виде дерева и таблицы, которые можно просмотреть структуру и сами данные в таблицах баз данных. С помощью

команд меню можно создать и удалить базу, выполнить любой SQL запрос к любой таблице (при наличии у пользователя необходимых полномочий ), послать сообщение электронной почты, посмотреть последние обновления.

Таким образом, мы получили программу, с помощью которой можно выполнять базовый набор операций сервером MySQL и при этом не требуется поддержка и настройка ODBC драйвера. В дальнейшем проект может быть значительно расширен и улучшен.

Исходный код программы.

#include "afxwin.h"

#if !defined(AFX_DELETEDATABASEDLG_H__16ACDEC0_DE9D_11D9_A8EF_929CCA0FC15A__INCLUDED_)

#define AFX_DELETEDATABASEDLG_H__16ACDEC0_DE9D_11D9_A8EF_929CCA0FC15A__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// DeleteDatabaseDlg.h : header file

//

/////////////////////////////////////////////////////////////////////////////

// CDeleteDatabaseDlg dialog

class CDeleteDatabaseDlg : public CDialog

{

// Construction

public:

CDeleteDatabaseDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data

//{{AFX_DATA(CDeleteDatabaseDlg)

enum { IDD = IDD_DIALOG4 };

//}}AFX_DATA

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CDeleteDatabaseDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

// Implementation

protected:

// Generated message map functions

//{{AFX_MSG(CDeleteDatabaseDlg)

virtual void OnOK();

virtual void OnCancel();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

public:

virtual BOOL OnInitDialog();

CListBox m_listbox;

CString m_delete;

};

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DELETEDATABASEDLG_H__16ACDEC0_DE9D_11D9_A8EF_929CCA0FC15A__INCLUDED_)

// DeleteDatabaseDlg.cpp : implementation file

//

#include "stdafx.h"

#include "mysqlone.h"

#include "DeleteDatabaseDlg.h"

#include ".\deletedatabasedlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CDeleteDatabaseDlg dialog

CDeleteDatabaseDlg::CDeleteDatabaseDlg(CWnd* pParent /*=NULL*/)

: CDialog(CDeleteDatabaseDlg::IDD, pParent)

, m_delete(_T(""))

{

//{{AFX_DATA_INIT(CDeleteDatabaseDlg)

m_delete = _T("");

//}}AFX_DATA_INIT

}

void CDeleteDatabaseDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CDeleteDatabaseDlg)

//}}AFX_DATA_MAP

DDX_Control(pDX, IDC_LIST1, m_listbox);

}

BEGIN_MESSAGE_MAP(CDeleteDatabaseDlg, CDialog)

//{{AFX_MSG_MAP(CDeleteDatabaseDlg)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CDeleteDatabaseDlg message handlers

BOOL CDeleteDatabaseDlg::OnInitDialog()

{

CDialog::OnInitDialog();

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

MYSQL_RES * my_res;

MYSQL_ROW row;

CString data_sql="SHOW DATABASES";

((CMysqloneApp*)AfxGetApp())->ExecuteSQL (data_sql);

my_res = mysql_store_result(mysql);

while (row = mysql_fetch_row (my_res)) {

char buffer[255];

strcpy (buffer, row[0]);

m_listbox.AddString(_T(buffer));

}

mysql_free_result (my_res);

return TRUE; // return TRUE unless you set the focus to a control

// EXCEPTION: OCX Property Pages should return FALSE

}

void CDeleteDatabaseDlg::OnOK()

{

UpdateData(TRUE);

CString item;

int index=m_listbox.GetCurSel();

m_listbox.GetText(index,item);

CString sql="DROP DATABASE ";

sql +=item;

m_delete=sql;

AfxMessageBox(m_delete,MB_ICONWARNING);

((CMysqloneApp*)AfxGetApp())->ExecuteSQL (sql);

CDialog::OnOK();

}

void CDeleteDatabaseDlg::OnCancel()

{

// TODO: Add extra cleanup here

CDialog::OnCancel();

}

// LeftView.h : interface of the CLeftView class

//

/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_LEFTVIEW_H__58E6318E_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

#define AFX_LEFTVIEW_H__58E6318E_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

class CMysqloneDoc;

class CLeftView : public CTreeView

{

protected: // create from serialization only

CLeftView();

DECLARE_DYNCREATE(CLeftView)

// Attributes

public:

CMysqloneDoc* GetDocument();

// Operations

public:

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CLeftView)

public:

virtual void OnDraw(CDC* pDC); // overridden to draw this view

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

protected:

virtual void OnInitialUpdate(); // called first time after construct

virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);

//}}AFX_VIRTUAL

// Implementation

public:

CImageList m_TreeImages;

void FillTree();

virtual ~CLeftView();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

protected:

// Generated message map functions

protected:

//{{AFX_MSG(CLeftView)

afx_msg void OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult);

afx_msg void OnDataDropdatabase();

afx_msg void OnNewTable();

afx_msg void OnMysqlQuery();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

public:

afx_msg void OnNewDatabase();

afx_msg void OnDataSeelastsqlquery();

afx_msg void OnDataCreatenewtable();

afx_msg void OnDataEmptyalldata();

afx_msg void OnDataDataoptimization();

afx_msg void OnDataSearchdatain();

};

#ifndef _DEBUG // debug version in LeftView.cpp

inline CMysqloneDoc* CLeftView::GetDocument()

{ return (CMysqloneDoc*)m_pDocument; }

#endif

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_LEFTVIEW_H__58E6318E_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

// LeftView.cpp : implementation of the CLeftView class

//

#include "stdafx.h"

#include "mysqlone.h"

#include "NewDatabase.h"

#include "CreateNewTableDlg.h"

#include "DeleteDatabaseDlg.h"

#include "SqlQueryDlg.h"

#include "mysqloneDoc.h"

#include "LeftView.h"

#include "mysqloneView.h"

#include ".\leftview.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CLeftView

IMPLEMENT_DYNCREATE(CLeftView, CTreeView)

BEGIN_MESSAGE_MAP(CLeftView, CTreeView)

//{{AFX_MSG_MAP(CLeftView)

ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)

ON_COMMAND(ID_DATA_DROPDATABASE, OnDataDropdatabase)

ON_COMMAND(ID_NEW_TABLE, OnNewTable)

ON_COMMAND(ID_MYSQL_QUERY, OnMysqlQuery)

//}}AFX_MSG_MAP

ON_COMMAND(ID_NEW_DATABASE, OnNewDatabase)

ON_COMMAND(ID_DATA_SEELASTSQLQUERY, OnDataSeelastsqlquery)

ON_COMMAND(ID_DATA_CREATENEWTABLE, OnDataCreatenewtable)

ON_COMMAND(ID_DATA_EMPTYALLDATA, OnDataEmptyalldata)

ON_COMMAND(ID_DATA_DATAOPTIMIZATION, OnDataDataoptimization)

ON_COMMAND(ID_DATA_SEARCHDATAIN, OnDataSearchdatain)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CLeftView construction/destruction

CLeftView::CLeftView()

{

// TODO: add construction code here

}

CLeftView::~CLeftView()

{

}

BOOL CLeftView::PreCreateWindow(CREATESTRUCT& cs)

{

// TODO: Modify the Window class or styles here by modifying

// the CREATESTRUCT cs

return CTreeView::PreCreateWindow(cs);

}

/////////////////////////////////////////////////////////////////////////////

// CLeftView drawing

void CLeftView::OnDraw(CDC* pDC)

{

CMysqloneDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

}

void CLeftView::OnInitialUpdate()

{

CTreeView::OnInitialUpdate();

//FillTree();

m_TreeImages.Create(IDB_BITMAP1, 16, 1, RGB(255, 255, 255));

}

/////////////////////////////////////////////////////////////////////////////

// CLeftView diagnostics

#ifdef _DEBUG

void CLeftView::AssertValid() const

{

CTreeView::AssertValid();

}

void CLeftView::Dump(CDumpContext& dc) const

{

CTreeView::Dump(dc);

}

CMysqloneDoc* CLeftView::GetDocument() // non-debug version is inline

{

ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMysqloneDoc)));

return (CMysqloneDoc*)m_pDocument;

}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

// CLeftView message handlers

void CLeftView::FillTree()

{

CTreeCtrl & m_tree = GetTreeCtrl();

m_tree.DeleteAllItems();

m_tree.SetImageList(&m_TreeImages, TVSIL_NORMAL);

HTREEITEM hRoot;

CMysqloneDoc* pDoc = GetDocument();

for (int i = 0; i < pDoc->m_available_bases.GetSize(); i++)

{

hRoot = m_tree.InsertItem(pDoc->m_available_bases[i], 0, 1);

}

}

void CLeftView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)

{

// TODO: Add your specialized code here and/or call the base class

CTreeCtrl & m_tree = GetTreeCtrl();

CMysqloneDoc* pDoc = GetDocument();

if (!pDoc->connected) {

m_tree.DeleteAllItems();

return;

}

FillTree();

}

void CLeftView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)

{

NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

CTreeCtrl & m_tree = GetTreeCtrl();

CMysqloneDoc* pDoc = GetDocument();

if (!pDoc->connected) {return;}

pDoc->current_table = "";

HTREEITEM nodSelected = m_tree.GetSelectedItem();

if (nodSelected>=0) {

CString strSelected=m_tree.GetItemText(nodSelected);

GetDocument()->SetTitle(strSelected);

}

HTREEITEM parent;

parent = m_tree.GetParentItem (nodSelected);

if (parent) {

pDoc->current_table = m_tree.GetItemText (nodSelected);

pDoc->UpdateAllViews (this);

return;

}

HTREEITEM child;

while (child = m_tree.GetChildItem (nodSelected)) {

m_tree.DeleteItem (child);

}

CString base_name = m_tree.GetItemText (nodSelected);

pDoc->current_base = base_name;

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

MYSQL_RES * my_res;

MYSQL_ROW row;

CString sql;

mysql_select_db (mysql, base_name.GetBuffer(255));

if (mysql_query (mysql, "SHOW TABLES")) {

AfxMessageBox ("Query SHOW databases failed");

return;

}

my_res = mysql_store_result(mysql);

while (row = mysql_fetch_row (my_res)) {

char buffer[255];

strcpy (buffer, row[0]);

m_tree.InsertItem (_T(buffer), nodSelected);

}

mysql_free_result (my_res);

*pResult = 0;

}

void CLeftView::OnNewDatabase()

{

CNewDatabase dlg;

if (dlg.DoModal() == IDOK )

{

CTreeCtrl & m_tree = GetTreeCtrl();

HTREEITEM hitem = m_tree.InsertItem(dlg.m_newdatabase, TVI_ROOT);

m_tree.SelectItem(hitem);

}

}

void CLeftView::OnDataDropdatabase()

{

CDeleteDatabaseDlg dlg;

if (dlg.DoModal() == IDOK )

{

CTreeCtrl & m_tree = GetTreeCtrl();

HTREEITEM hitem = m_tree.GetSelectedItem();

CString selected=m_tree.GetItemText(hitem);

m_tree.DeleteItem(hitem);

}

}

void CLeftView::OnNewTable()

{

CCreateNewTableDlg dlg;

if (dlg.DoModal() == IDOK )

{

CTreeCtrl & m_tree = GetTreeCtrl();

HTREEITEM hitem = m_tree.GetSelectedItem();

HTREEITEM childitem=m_tree.GetChildItem(hitem);

// childitem = m_tree.InsertItem(dlg.m_newtable, TVI_FIRST);

m_tree.SelectItem(childitem);

}

}

void CLeftView::OnMysqlQuery()

{

CSqlQueryDlg dlg;

if (dlg.DoModal() == IDOK ){

dlg.OnOK();

}

}

void CLeftView::OnDataSeelastsqlquery()

{

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

const char* last_query;

CString noresult;

CString temp;

last_query=mysql_info(mysql);

temp=(CString)last_query;

if (temp=="NULL") {

noresult="No any SQL request was done till now";

AfxMessageBox(noresult,MB_ICONINFORMATION);

}

else {

AfxMessageBox(temp,MB_ICONINFORMATION);

}

}

void CLeftView::OnDataCreatenewtable()

{

CCreateNewTableDlg dlg;

if (dlg.DoModal() == IDOK )

{

CTreeCtrl & m_tree = GetTreeCtrl();

HTREEITEM hitem = m_tree.GetSelectedItem();

HTREEITEM childitem=m_tree.GetChildItem(hitem);

// childitem = m_tree.InsertItem(dlg.m_newtable, TVI_FIRST);

m_tree.SelectItem(childitem);

}

}

void CLeftView::OnDataEmptyalldata()

{

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

CTreeCtrl & m_tree = GetTreeCtrl();

CString sql="DELETE FROM ";

HTREEITEM nodSelected = m_tree.GetSelectedItem();

if (nodSelected>=0) {

CString strSelected=m_tree.GetItemText(nodSelected);

sql +=strSelected;

AfxMessageBox("Are you sure to wish to delete ALL data from "+ strSelected,MB_OKCANCEL|MB_ICONQUESTION );

((CMysqloneApp*)AfxGetApp())->ExecuteSQL (sql);

m_tree.DeleteItem(nodSelected);

}

}

void CLeftView::OnDataDataoptimization()

{

CTreeCtrl & m_tree = GetTreeCtrl();

HTREEITEM hitem = m_tree.GetSelectedItem();

HTREEITEM childitem=m_tree.GetChildItem(hitem);

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

CMysqloneDoc* pDoc = GetDocument();

CString base_name=m_tree.GetItemText(hitem);

CString strSelected=m_tree.GetItemText(childitem);

pDoc->current_base=base_name;

CString sql="OPTIMIZE TABLE ";

mysql_select_db(mysql,base_name.GetBuffer(255));

sql+=strSelected;

((CMysqloneApp*)AfxGetApp())->ExecuteSQL (sql);

pDoc->UpdateAllViews (NULL);

}

void CLeftView::OnDataSearchdatain()

{

CMysqloneDoc* pDoc = GetDocument();

pDoc->current_table = "";

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

MYSQL_RES * my_res;

MYSQL_ROW row;

CTreeCtrl & m_tree = GetTreeCtrl();

HTREEITEM hitem = m_tree.GetSelectedItem();

HTREEITEM childitem=m_tree.GetChildItem(hitem);

CString base_name=m_tree.GetItemText(hitem);

CString strSelected=m_tree.GetItemText(childitem);

pDoc->current_base=base_name;

CString sql="SELECT * FROM ";

sql+=base_name;

mysql_select_db (mysql, base_name.GetBuffer(255));

if (mysql_query (mysql, sql)) {

CString error=mysql_error(mysql);

AfxMessageBox (error);

return;

}

my_res = mysql_store_result(mysql);

}

#if !defined(AFX_LOGINDLG_H__58E63196_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

#define AFX_LOGINDLG_H__58E63196_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// LoginDlg.h : header file

//

/////////////////////////////////////////////////////////////////////////////

// CLoginDlg dialog

class CLoginDlg : public CDialog

{

// Construction

public:

CLoginDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data

//{{AFX_DATA(CLoginDlg)

enum { IDD = IDD_LOGINDLG };

CString m_login;

CString m_password;

CString m_host;

//}}AFX_DATA

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CLoginDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

// Implementation

protected:

// Generated message map functions

//{{AFX_MSG(CLoginDlg)

// NOTE: the ClassWizard will add member functions here

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

public:

afx_msg void OnBnClickedLogin();

};

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_LOGINDLG_H__58E63196_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

// LoginDlg.cpp : implementation file

//

#include "stdafx.h"

#include "mysqlone.h"

#include "LoginDlg.h"

#include ".\logindlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CLoginDlg dialog

CLoginDlg::CLoginDlg(CWnd* pParent /*=NULL*/)

: CDialog(CLoginDlg::IDD, pParent)

{

//{{AFX_DATA_INIT(CLoginDlg)

m_login = _T("");

m_password = _T("");

m_host = _T("");

//}}AFX_DATA_INIT

}

void CLoginDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CLoginDlg)

DDX_Text(pDX, IDC_EDIT1, m_login);

DDX_Text(pDX, IDC_EDIT2, m_password);

DDX_Text(pDX, IDC_EDIT3, m_host);

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CLoginDlg, CDialog)

//{{AFX_MSG_MAP(CLoginDlg)

// NOTE: the ClassWizard will add message map macros here

//}}AFX_MSG_MAP

ON_BN_CLICKED(IDC_LOGIN, OnBnClickedLogin)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CLoginDlg message handlers

void CLoginDlg::OnBnClickedLogin()

{

UpdateData();

char login[35];

char password[25];

char host[255];

FILE *file;

bool valid_login = false;

if( m_login =="")

{

AfxMessageBox("You must provide a username and password or click Cancel!");

return;

}

if( m_password =="")

{

AfxMessageBox("Invalid login entered");

return;

}

if( m_host =="")

{

AfxMessageBox("Enter host name, please");

return;

}

try {

file = fopen("database.lgn", "r");

while( !feof(file) )

{

fscanf(file, "%s", login);

if( strcmp((LPCTSTR)m_login, login) == 0 )

{

fscanf(file, "%s", password);

if( strcmp((LPCTSTR)m_password, password) == 0 )

{

valid_login = true;

}

else

valid_login = false;

}

}

if( valid_login == true )

OnOK();

else

{

AfxMessageBox("Invalid entry data entered! Please try again");

}

fclose(file);

}

catch(...)

{

AfxMessageBox("Could not validate entered information to connect with MySQL database");

}

UpdateData(FALSE);

}

// MainFrm.h : interface of the CMainFrame class

//

/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_MAINFRM_H__58E63188_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

#define AFX_MAINFRM_H__58E63188_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_

#if _MSC_VER > 1000

#pragma once

class CLeftView;

#endif // _MSC_VER > 1000

class CMysqloneView;

class CMainFrame : public CFrameWnd

{

protected: // create from serialization only

CMainFrame();

DECLARE_DYNCREATE(CMainFrame)

// Attributes

protected:

CSplitterWnd m_wndSplitter;

public:

// Operations

public:

CStatusBar m_wndStatusBar;

CToolBar m_wndToolBar;

CReBar m_rebar;

CDialogBar m_wndDlgBar;

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CMainFrame)

public:

virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

//}}AFX_VIRTUAL

// Implementation

public:

virtual ~CMainFrame();

CMysqloneView* GetRightPane();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

protected: // control bar embedded members

// Generated message map functions

protected:

//{{AFX_MSG(CMainFrame)

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

//}}AFX_MSG

afx_msg void OnUpdateViewStyles(CCmdUI* pCmdUI);

afx_msg void OnViewStyle(UINT nCommandID);

DECLARE_MESSAGE_MAP()

public:

afx_msg void OnHelpGotomysqlsite();

afx_msg void OnNewConnection();

afx_msg void OnCloseConnection();

afx_msg void OnHelpMysqlinfo();

};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MAINFRM_H__58E63188_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

// MainFrm.cpp : implementation of the CMainFrame class

//

#include "stdafx.h"

#include "mysqlone.h"

#include "MainFrm.h"

#include "LeftView.h"

#include "mysqloneView.h"

#include "SqlQueryDlg.h"

#include "NewDatabase.h"

#include "MySQLInfoDlg.h"

#include ".\mainfrm.h"

#include "mysqlonedoc.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

//{{AFX_MSG_MAP(CMainFrame)

ON_WM_CREATE()

ON_COMMAND(ID_NEW_CONNECTION, OnNewConnection)

ON_COMMAND(ID_CLOSE_CONNECTION, OnCloseConnection)

ON_COMMAND(ID_HELP_GOTOMYSQLSITE, OnHelpGotomysqlsite)

//}}AFX_MSG_MAP

ON_UPDATE_COMMAND_UI_RANGE(AFX_ID_VIEW_MINIMUM, AFX_ID_VIEW_MAXIMUM, OnUpdateViewStyles)

ON_COMMAND_RANGE(AFX_ID_VIEW_MINIMUM, AFX_ID_VIEW_MAXIMUM, OnViewStyle)

ON_COMMAND(ID_HELP_MYSQLINFO, OnHelpMysqlinfo)

END_MESSAGE_MAP()

static UINT indicators[] =

{

ID_SEPARATOR, // status line indicator

ID_INDICATOR_CAPS,

ID_INDICATOR_NUM,

ID_INDICATOR_SCRL,

};

/////////////////////////////////////////////////////////////////////////////

// CMainFrame construction/destruction

CMainFrame::CMainFrame()

{

// TODO: add member initialization code here

}

CMainFrame::~CMainFrame()

{

}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CFrameWnd::OnCreate(lpCreateStruct) == -1)

return -1;

if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP

| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||

!m_wndToolBar.LoadToolBar(IDR_TOOLBAR2))

{

TRACE0("Failed to create toolbar\n");

return -1; // fail to create

}

if (!m_wndStatusBar.Create(this) ||

!m_wndStatusBar.SetIndicators(indicators,

sizeof(indicators)/sizeof(UINT)))

{

TRACE0("Failed to create status bar\n");

return -1; // fail to create

}

// TODO: Delete these three lines if you don't want the toolbar to be dockable

m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

EnableDocking(CBRS_ALIGN_ANY);

DockControlBar(&m_wndToolBar);

return 0;

}

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,

CCreateContext* pContext)

{

// create splitter window

if (!m_wndSplitter.CreateStatic(this, 1, 2))

return FALSE;

if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftView), CSize(200, 100), pContext) ||

!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CMysqloneView), CSize(100, 100), pContext))

{

m_wndSplitter.DestroyWindow();

return FALSE;

}

return TRUE;

}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

{

if( !CFrameWnd::PreCreateWindow(cs) )

return FALSE;

// TODO: Modify the Window class or styles here by modifying

// the CREATESTRUCT cs

return TRUE;

}

/////////////////////////////////////////////////////////////////////////////

// CMainFrame diagnostics

#ifdef _DEBUG

void CMainFrame::AssertValid() const

{

CFrameWnd::AssertValid();

}

void CMainFrame::Dump(CDumpContext& dc) const

{

CFrameWnd::Dump(dc);

}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

// CMainFrame message handlers

CMysqloneView* CMainFrame::GetRightPane()

{

CWnd* pWnd = m_wndSplitter.GetPane(0, 1);

CMysqloneView* pView = DYNAMIC_DOWNCAST(CMysqloneView, pWnd);

return pView;

}

void CMainFrame::OnUpdateViewStyles(CCmdUI* pCmdUI)

{

// TODO: customize or extend this code to handle choices on the

// View menu.

CMysqloneView* pView = GetRightPane();

// if the right-hand pane hasn't been created or isn't a view,

// disable commands in our range

if (pView == NULL)

pCmdUI->Enable(FALSE);

else

{

DWORD dwStyle = pView->GetStyle() & LVS_TYPEMASK;

// if the command is ID_VIEW_LINEUP, only enable command

// when we're in LVS_ICON or LVS_SMALLICON mode

if (pCmdUI->m_nID == ID_VIEW_LINEUP)

{

if (dwStyle == LVS_ICON || dwStyle == LVS_SMALLICON)

pCmdUI->Enable();

else

pCmdUI->Enable(FALSE);

}

else

{

// otherwise, use dots to reflect the style of the view

pCmdUI->Enable();

BOOL bChecked = FALSE;

switch (pCmdUI->m_nID)

{

case ID_VIEW_DETAILS:

bChecked = (dwStyle == LVS_REPORT);

break;

case ID_VIEW_SMALLICON:

bChecked = (dwStyle == LVS_SMALLICON);

break;

case ID_VIEW_LARGEICON:

bChecked = (dwStyle == LVS_ICON);

break;

case ID_VIEW_LIST:

bChecked = (dwStyle == LVS_LIST);

break;

default:

bChecked = FALSE;

break;

}

pCmdUI->SetRadio(bChecked ? 1 : 0);

}

}

}

void CMainFrame::OnViewStyle(UINT nCommandID)

{

// TODO: customize or extend this code to handle choices on the

// View menu.

CMysqloneView* pView = GetRightPane();

// if the right-hand pane has been created and is a CMysqloneView,

// process the menu commands...

if (pView != NULL)

{

DWORD dwStyle = -1;

switch (nCommandID)

{

case ID_VIEW_LINEUP:

{

// ask the list control to snap to grid

CListCtrl& refListCtrl = pView->GetListCtrl();

refListCtrl.Arrange(LVA_SNAPTOGRID);

}

break;

// other commands change the style on the list control

case ID_VIEW_DETAILS:

dwStyle = LVS_REPORT;

break;

case ID_VIEW_SMALLICON:

dwStyle = LVS_SMALLICON;

break;

case ID_VIEW_LARGEICON:

dwStyle = LVS_ICON;

break;

case ID_VIEW_LIST:

dwStyle = LVS_LIST;

break;

}

// change the style; window will repaint automatically

if (dwStyle != -1)

pView->ModifyStyle(LVS_TYPEMASK, dwStyle);

}

}

void CMainFrame::OnNewConnection()

{

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

CMysqloneApp* MyApp=((CMysqloneApp*)AfxGetApp());

MyApp->ConnectToDb();

CMysqloneDoc* pDoc=(CMysqloneDoc*)GetActiveDocument();

pDoc->connected = true;

pDoc->UpdateAllViews (NULL);

}

void CMainFrame::OnCloseConnection()

{

CMysqloneApp* MyApp=((CMysqloneApp*)AfxGetApp());

MyApp->CloseConnectionDb();

CMysqloneDoc* pDoc=(CMysqloneDoc*)GetActiveDocument();

pDoc->connected = false;

pDoc->UpdateAllViews(NULL);

}

void CMainFrame::OnHelpGotomysqlsite()

{

ShellExecute(NULL,"open", "http://www.mysql.com", "", "c:\\", SW_SHOWNORMAL);

}

void CMainFrame::OnHelpMysqlinfo()

{

CMySQLInfoDlg dlg;

if (dlg.DoModal() == IDOK )

{

dlg.OnBnClickedExit();

}

}

// mysqlone.h : main header file for the MYSQLONE application

//

#if !defined(AFX_MYSQLONE_H__58E63184_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

#define AFX_MYSQLONE_H__58E63184_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#ifndef __AFXWIN_H__

#error include 'stdafx.h' before including this file for PCH

#endif

#include "resource.h" // main symbols

/////////////////////////////////////////////////////////////////////////////

// CMysqloneApp:

// See mysqlone.cpp for the implementation of this class

//

class CMysqloneApp : public CWinApp

{

public:

void CloseConnectionDb();

void ExecuteSQL(CString sql);

BOOL ConnectToDb();

MYSQL mysql;

CMysqloneApp();

void ChangeCurrentBase(CString newBaseName);

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CMysqloneApp)

public:

virtual BOOL InitInstance();

//}}AFX_VIRTUAL

// Implementation

//{{AFX_MSG(CMysqloneApp)

afx_msg void OnAppAbout();

// NOTE - the ClassWizard will add and remove member functions here.

// DO NOT EDIT what you see in these blocks of generated code !

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MYSQLONE_H__58E63184_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

// mysqlone.cpp : Defines the class behaviors for the application.

//

#include "stdafx.h"

#include "mysqlone.h"

#include "MainFrm.h"

#include "mysqloneDoc.h"

#include "LeftView.h"

#include "LoginDlg.h"

#include ".\mysqlone.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CMysqloneApp

BEGIN_MESSAGE_MAP(CMysqloneApp, CWinApp)

//{{AFX_MSG_MAP(CMysqloneApp)

ON_COMMAND(ID_APP_ABOUT, OnAppAbout)

// NOTE - the ClassWizard will add and remove mapping macros here.

// DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG_MAP

// Standard file based document commands

ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)

ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CMysqloneApp construction

CMysqloneApp::CMysqloneApp()

{

// TODO: add construction code here,

// Place all significant initialization in InitInstance

}

/////////////////////////////////////////////////////////////////////////////

// The one and only CMysqloneApp object

CMysqloneApp theApp;

/////////////////////////////////////////////////////////////////////////////

// CMysqloneApp initialization

BOOL CMysqloneApp::InitInstance()

{

if (!AfxSocketInit())

{

AfxMessageBox(IDP_SOCKETS_INIT_FAILED);

return FALSE;

}

AfxEnableControlContainer();

// Standard initialization

// If you are not using these features and wish to reduce the size

// of your final executable, you should remove from the following

// the specific initialization routines you do not need.

#ifdef _AFXDLL

Enable3dControls(); // Call this when using MFC in a shared DLL

#else

Enable3dControlsStatic(); // Call this when linking to MFC statically

#endif

// Change the registry key under which our settings are stored.

// TODO: You should modify this string to be something appropriate

// such as the name of your company or organization.

SetRegistryKey(_T("MySQLOne - MySQL Database Browser"));

LoadStdProfileSettings(); // Load standard INI file options (including MRU)

if (!ConnectToDb()) {

AfxMessageBox ("Could not connect to base\nQuitting");

return FALSE;

}

// Register the application's document templates. Document templates

// serve as the connection between documents, frame windows and views.

CSingleDocTemplate* pDocTemplate;

pDocTemplate = new CSingleDocTemplate(

IDR_MAINFRAME,

RUNTIME_CLASS(CMysqloneDoc),

RUNTIME_CLASS(CMainFrame), // main SDI frame window

RUNTIME_CLASS(CLeftView));

AddDocTemplate(pDocTemplate);

// Parse command line for standard shell commands, DDE, file open

CCommandLineInfo cmdInfo;

ParseCommandLine(cmdInfo);

// Dispatch commands specified on the command line

if (!ProcessShellCommand(cmdInfo))

return FALSE;

// The one and only window has been initialized, so show and update it.

m_pMainWnd->ShowWindow(SW_SHOW);

m_pMainWnd->UpdateWindow();

return TRUE;

}

/////////////////////////////////////////////////////////////////////////////

// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog

{

public:

CAboutDlg();

// Dialog Data

//{{AFX_DATA(CAboutDlg)

enum { IDD = IDD_ABOUTBOX };

//}}AFX_DATA

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CAboutDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

// Implementation

protected:

//{{AFX_MSG(CAboutDlg)

// No message handlers

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

public:

CString mysql_info;

int mysql_version;

};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

, mysql_info(_T(""))

, mysql_version(0)

{

//{{AFX_DATA_INIT(CAboutDlg)

//}}AFX_DATA_INIT

}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CAboutDlg)

//}}AFX_DATA_MAP

DDX_Text(pDX, IDC_INFO, mysql_info);

DDX_Text(pDX, IDC_MYSQLVER, mysql_version);

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

//{{AFX_MSG_MAP(CAboutDlg)

// No message handlers

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

// App command to run the dialog

void CMysqloneApp::OnAppAbout()

{

CAboutDlg aboutDlg;

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

const char* host_info="";

int ver;

host_info=mysql_get_host_info(mysql);

ver=mysql_get_proto_info(mysql);

aboutDlg.mysql_info=(CString)host_info;

aboutDlg.mysql_version=ver;

aboutDlg.DoModal();

}

/////////////////////////////////////////////////////////////////////////////

// CMysqloneApp message handlers

BOOL CMysqloneApp::ConnectToDb()

{

CLoginDlg dlg;

while (dlg.DoModal()== IDOK) {

if(!mysql_init(&mysql)){AfxMessageBox ("Can't make initialization to mysql server!");}

if(mysql_real_connect(&mysql,dlg.m_host, dlg.m_login,dlg.m_password,NULL,0,NULL,0)){

return TRUE;

}

}

return FALSE;

}

void CMysqloneApp::ExecuteSQL(CString sql)

{

mysql_query (&mysql, sql);

}

void CMysqloneApp::CloseConnectionDb()

{

mysql_close(&mysql);

}

void CMysqloneApp::ChangeCurrentBase(CString newBaseName)

{

mysql_select_db (&mysql, newBaseName);

}

// mysqloneDoc.h : interface of the CMysqloneDoc class

//

/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_MYSQLONEDOC_H__58E6318A_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

#define AFX_MYSQLONEDOC_H__58E6318A_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

class CMysqloneDoc : public CDocument

{

protected: // create from serialization only

CMysqloneDoc();

DECLARE_DYNCREATE(CMysqloneDoc)

// Attributes

public:

// Operations

public:

CStringArray m_available_bases;

CString current_base;

CString current_table;

bool connected;

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CMysqloneDoc)

public:

virtual BOOL OnNewDocument();

virtual void Serialize(CArchive& ar);

//}}AFX_VIRTUAL

// Implementation

public:

virtual ~CMysqloneDoc();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

protected:

// Generated message map functions

protected:

//{{AFX_MSG(CMysqloneDoc)

// NOTE - the ClassWizard will add and remove member functions here.

// DO NOT EDIT what you see in these blocks of generated code !

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MYSQLONEDOC_H__58E6318A_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

// mysqloneDoc.cpp : implementation of the CMysqloneDoc class

//

#include "stdafx.h"

#include "mysqlone.h"

#include "mysqloneDoc.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CMysqloneDoc

IMPLEMENT_DYNCREATE(CMysqloneDoc, CDocument)

BEGIN_MESSAGE_MAP(CMysqloneDoc, CDocument)

//{{AFX_MSG_MAP(CMysqloneDoc)

// NOTE - the ClassWizard will add and remove mapping macros here.

// DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG_MAP

ON_COMMAND(ID_FILE_SEND_MAIL, OnFileSendMail)

ON_UPDATE_COMMAND_UI(ID_FILE_SEND_MAIL, OnUpdateFileSendMail)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CMysqloneDoc construction/destruction

CMysqloneDoc::CMysqloneDoc()

{

// TODO: add one-time construction code here

}

CMysqloneDoc::~CMysqloneDoc()

{

}

BOOL CMysqloneDoc::OnNewDocument()

{

if (!CDocument::OnNewDocument())

return FALSE;

current_table = "";

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

MYSQL_RES * my_res;

MYSQL_ROW row;

if (mysql_query (mysql, "SHOW databases")) {

AfxMessageBox ("Query SHOW databases failed");

return TRUE;

}

my_res = mysql_store_result(mysql);

int num = mysql_num_rows (my_res);

m_available_bases.RemoveAll();

while (row = mysql_fetch_row (my_res)) {

m_available_bases.Add (row[0]);

}

mysql_free_result (my_res);

current_base = "";

return TRUE;

}

/////////////////////////////////////////////////////////////////////////////

// CMysqloneDoc serialization

void CMysqloneDoc::Serialize(CArchive& ar)

{

if (ar.IsStoring())

{

// TODO: add storing code here

}

else

{

// TODO: add loading code here

}

}

/////////////////////////////////////////////////////////////////////////////

// CMysqloneDoc diagnostics

#ifdef _DEBUG

void CMysqloneDoc::AssertValid() const

{

CDocument::AssertValid();

}

void CMysqloneDoc::Dump(CDumpContext& dc) const

{

CDocument::Dump(dc);

}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

// CMysqloneDoc commands

// mysqloneView.h : interface of the CMysqloneView class

//

/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_MYSQLONEVIEW_H__58E6318C_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

#define AFX_MYSQLONEVIEW_H__58E6318C_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

class CMysqloneView : public CListView

{

protected: // create from serialization only

CMysqloneView();

DECLARE_DYNCREATE(CMysqloneView)

// Attributes

public:

CMysqloneDoc* GetDocument();

// Operations

public:

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CMysqloneView)

public:

virtual void OnDraw(CDC* pDC); // overridden to draw this view

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

protected:

virtual void OnInitialUpdate(); // called first time after construct

virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);

//}}AFX_VIRTUAL

// Implementation

public:

virtual ~CMysqloneView();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

protected:

// Generated message map functions

protected:

//{{AFX_MSG(CMysqloneView)

// NOTE - the ClassWizard will add and remove member functions here.

// DO NOT EDIT what you see in these blocks of generated code !

//}}AFX_MSG

afx_msg void OnStyleChanged(int nStyleType, LPSTYLESTRUCT lpStyleStruct);

DECLARE_MESSAGE_MAP()

};

#ifndef _DEBUG // debug version in mysqloneView.cpp

inline CMysqloneDoc* CMysqloneView::GetDocument()

{ return (CMysqloneDoc*)m_pDocument; }

#endif

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MYSQLONEVIEW_H__58E6318C_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

// mysqloneView.cpp : implementation of the CMysqloneView class

//

#include "stdafx.h"

#include "mysqlone.h"

#include "mysqloneDoc.h"

#include "mysqloneView.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CMysqloneView

IMPLEMENT_DYNCREATE(CMysqloneView, CListView)

BEGIN_MESSAGE_MAP(CMysqloneView, CListView)

//{{AFX_MSG_MAP(CMysqloneView)

// NOTE - the ClassWizard will add and remove mapping macros here.

// DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CMysqloneView construction/destruction

CMysqloneView::CMysqloneView()

{

// TODO: add construction code here

}

CMysqloneView::~CMysqloneView()

{

}

BOOL CMysqloneView::PreCreateWindow(CREATESTRUCT& cs)

{

// TODO: Modify the Window class or styles here by modifying

// the CREATESTRUCT cs

return CListView::PreCreateWindow(cs);

}

/////////////////////////////////////////////////////////////////////////////

// CMysqloneView drawing

void CMysqloneView::OnDraw(CDC* pDC)

{

CMysqloneDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

//CListCtrl& refCtrl = GetListCtrl();

//refCtrl.InsertItem(0, "Item!");

// TODO: add draw code for native data here

}

void CMysqloneView::OnInitialUpdate()

{

CListView::OnInitialUpdate();

CListCtrl &m_list = GetListCtrl();

m_list.ModifyStyle(NULL, LVS_REPORT);

m_list.SetExtendedStyle (LVS_EX_GRIDLINES );

}

/////////////////////////////////////////////////////////////////////////////

// CMysqloneView diagnostics

#ifdef _DEBUG

void CMysqloneView::AssertValid() const

{

CListView::AssertValid();

}

void CMysqloneView::Dump(CDumpContext& dc) const

{

CListView::Dump(dc);

}

CMysqloneDoc* CMysqloneView::GetDocument() // non-debug version is inline

{

ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMysqloneDoc)));

return (CMysqloneDoc*)m_pDocument;

}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

// CMysqloneView message handlers

void CMysqloneView::OnStyleChanged(int nStyleType, LPSTYLESTRUCT lpStyleStruct)

{

Default();

}

void CMysqloneView::OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/)

{

CListCtrl &m_list = GetListCtrl();

CMysqloneDoc* pDoc = GetDocument();

if (!pDoc->connected) {

m_list.DeleteAllItems ();

while(m_list.DeleteColumn(0));

return;

}

if (pDoc->current_table == "") return;

m_list.DeleteAllItems();

while(m_list.DeleteColumn(0));

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

MYSQL_RES * my_res;

MYSQL_ROW row;

CString sql;

sql="SHOW COLUMNS FROM ";

sql += pDoc->current_table;

if (mysql_query (mysql, sql)) {

CString error=mysql_error(mysql);

AfxMessageBox(error);

}

else {

my_res = mysql_store_result (mysql);

int i = 0;

int counter = 0;

while (row = mysql_fetch_row (my_res)) {

m_list.InsertColumn (i, row[0], LVCFMT_LEFT, 100);

i++;

}

counter = i;

mysql_free_result (my_res);

sql = "SELECT * FROM ";

sql += pDoc->current_table;

mysql_query (mysql, sql);

my_res = mysql_store_result (mysql);

i = 0;

LVITEM item;

item.mask = LVIF_TEXT;

while (row = mysql_fetch_row (my_res)) {

item.iItem = i;

item.iSubItem = 0;

item.pszText = row[0];

m_list.InsertItem (&item);

for (int z = 1; z < counter; z++) {

item.iSubItem = z;

item.pszText = row[z];

m_list.SetItem (&item);

}

i++;

}

mysql_free_result (my_res);

}

}

#if !defined(AFX_NEWDATABASE_H__58E63198_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

#define AFX_NEWDATABASE_H__58E63198_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// NewDatabase.h : header file

//

/////////////////////////////////////////////////////////////////////////////

// CNewDatabase dialog

class CNewDatabase : public CDialog

{

// Construction

public:

CNewDatabase(CWnd* pParent = NULL); // standard constructor

// Dialog Data

//{{AFX_DATA(CNewDatabase)

enum { IDD = IDD_DIALOG3 };

CString m_newdatabase;

//}}AFX_DATA

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CNewDatabase)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

// Implementation

protected:

// Generated message map functions

//{{AFX_MSG(CNewDatabase)

virtual void OnOK();

virtual void OnCancel();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_NEWDATABASE_H__58E63198_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

// NewDatabase.cpp : implementation file

//

#include "stdafx.h"

#include "mysqlone.h"

#include "NewDatabase.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CNewDatabase dialog

CNewDatabase::CNewDatabase(CWnd* pParent /*=NULL*/)

: CDialog(CNewDatabase::IDD, pParent)

{

//{{AFX_DATA_INIT(CNewDatabase)

m_newdatabase = _T("");

//}}AFX_DATA_INIT

}

void CNewDatabase::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CNewDatabase)

DDX_Text(pDX, IDC_EDIT1, m_newdatabase);

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CNewDatabase, CDialog)

//{{AFX_MSG_MAP(CNewDatabase)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CNewDatabase message handlers

void CNewDatabase::OnOK()

{

UpdateData(TRUE);

CString sql="CREATE DATABASE ";

sql +=m_newdatabase;

((CMysqloneApp*)AfxGetApp())->ExecuteSQL (sql);

CDialog::OnOK();

}

void CNewDatabase::OnCancel()

{

// TODO: Add extra cleanup here

CDialog::OnCancel();

}

#if !defined(AFX_SQLQUERYDLG_H__58E63197_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

#define AFX_SQLQUERYDLG_H__58E63197_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// CListCtrl m_list. : header file

//

#include "mysqlone.h"

#include "afxwin.h"

#include "afxcmn.h"

/////////////////////////////////////////////////////////////////////////////

// CSqlQueryDlg dialog

class CSqlQueryDlg : public CDialog

{

// Construction

public:

void AddStr();

CSqlQueryDlg(CWnd* pParent = NULL); // standard constructor

virtual void OnOK();

// Dialog Data

//{{AFX_DATA(CSqlQueryDlg)

enum { IDD = IDD_DIALOG2 };

CString m_out;

CString m_sql;

//}}AFX_DATA

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CSqlQueryDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

// Implementation

protected:

// Generated message map functions

//{{AFX_MSG(CSqlQueryDlg)

afx_msg void OnClear();

virtual void OnCancel();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

public:

CListBox m_listbox;

virtual BOOL OnInitDialog();

CListCtrl m_list;

};

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_SQLQUERYDLG_H__58E63197_DD0B_11D9_A8EF_BCC8AEF81D60__INCLUDED_)

// SqlQueryDlg.cpp : implementation file

//

#include "stdafx.h"

#include "mysqlone.h"

#include "SqlQueryDlg.h"

#include ".\sqlquerydlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CSqlQueryDlg dialog

CSqlQueryDlg::CSqlQueryDlg(CWnd* pParent /*=NULL*/)

: CDialog(CSqlQueryDlg::IDD, pParent)

{

//{{AFX_DATA_INIT(CSqlQueryDlg)

m_out = _T("");

m_sql = _T("");

//}}AFX_DATA_INIT

}

void CSqlQueryDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CSqlQueryDlg)

DDX_CBString(pDX, IDC_COMBO1, m_sql);

//}}AFX_DATA_MAP

DDX_Control(pDX, IDC_LIST1, m_listbox);

DDX_Control(pDX, IDC_LIST2, m_list);

}

BEGIN_MESSAGE_MAP(CSqlQueryDlg, CDialog)

//{{AFX_MSG_MAP(CSqlQueryDlg)

ON_BN_CLICKED(IDC_BUTTON1, OnClear)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CSqlQueryDlg message handlers

void CSqlQueryDlg::OnOK()

{

UpdateData();

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

CString basename;

m_listbox.GetText (m_listbox.GetCurSel(), basename);

((CMysqloneApp*)AfxGetApp())->ChangeCurrentBase (basename);

((CMysqloneApp*)AfxGetApp())->ExecuteSQL (m_sql);

m_list.DeleteAllItems ();

while(m_list.DeleteColumn(0));

MYSQL_RES * my_res;

MYSQL_ROW row;

mysql_query (mysql, m_sql);

my_res = mysql_store_result (mysql);

int cols = mysql_num_fields (my_res);

int counter ;

for (counter = 0; counter < cols; counter++) {

m_list.InsertColumn (counter, "Data", LVCFMT_LEFT, 50);

}

counter = cols;

LVITEM item;

item.mask = LVIF_TEXT;

int i = 0;

while (row = mysql_fetch_row (my_res)) {

item.iItem = i;

item.iSubItem = 0;

item.pszText = row[0];

m_list.InsertItem (&item);

for (int z = 1; z < counter; z++) {

item.iSubItem = z;

item.pszText = row[z];

m_list.SetItem (&item);

}

i++;

}

mysql_free_result (my_res);

//CDialog::OnOK();

}

void CSqlQueryDlg::OnClear()

{

m_list.DeleteAllItems ();

UpdateData(FALSE);

}

void CSqlQueryDlg::OnCancel()

{

// TODO: Add extra cleanup here

CDialog::OnCancel();

}

void CSqlQueryDlg::AddStr()

{

CComboBox *Box;

Box = (CComboBox *)(this->GetDlgItem(IDC_COMBO1));

Box->AddString(m_sql);

}

BOOL CSqlQueryDlg::OnInitDialog()

{

CDialog::OnInitDialog();

// TODO: Add extra initialization here

MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql);

MYSQL_RES * my_res;

MYSQL_ROW row;

CString data_sql="SHOW DATABASES";

((CMysqloneApp*)AfxGetApp())->ExecuteSQL (data_sql);

my_res = mysql_store_result(mysql);

while (row = mysql_fetch_row (my_res)) {

char buffer[255];

strcpy (buffer, row[0]);

m_listbox.AddString(_T(buffer));

}

mysql_free_result (my_res);

return TRUE; // return TRUE unless you set the focus to a control

// EXCEPTION: OCX Property Pages should return FALSE

}

0
 

Добавить комментарий


Защитный код
Обновить