Из Mfc в Api или как писать на Api?
Вот уже 2ю неделю пытаюсь понять, где же истина? MFC или API?
В общем проблема вот в чем. Уже 3 месяца пишу на MFC и горя не знаю, правда только на форумах говорят что это зло, мол слишком все у них там накручено и если писать что то более или менее серьезное то надо на API и я полностью согласен. Правда есть одна проблема. Я в своих программах (вернее программе) использую базу данных Access.
Обращаюсь я с ней следующим образом
#include <afxdb.h>
CDatabase Db;
CRecordset* Rs;
Db.OpenEx("DBQ=base.mdb;Driver={Microsoft Access Driver (*.mdb)}");
Rs= new CRecordset(&Db);
А потом после коннекта который я делаю при инициализации проекта я могу с помощью SQL обратиться к любому полю любой таблицы базы данных base.mdb следующим образом:
CString s;
s.Format("SELECT surname FROM people ORDER BY id");
Rs->Open(CRecordset::snapshot,s);
while(!Rs->IsEOF())
{
Rs->GetFieldValue(“surname”,s);
m_listPeople.AddStirng(s);
Rs->MoveNext();
}
Rs->Close();
В общем все очень просто.
А как это сделать на API не знаю. Подскажите пожалуйста, или дайте линк где почитать. Как только я научусь обращаться к базе данных я СРАЗУ перейду на API!
И еще если не сложно подскажите как на API сделать диалог с закладками, и что использовать вместо CString, ну в смысле может кроме типа char есть что ни будь по удобнее?
Ой, много вопросов еще вспомнил, но я думаю это будет слишком (а ведь как интересно то на чистом API программировать, я это почувствовал когда начал читать Петзльда).
И еще один вопрос (его я не могу не задать!) – можно ли в программе написанной на чистом API использовать классы?
Здравствуйте отцы, несущие свет в наши темные головы!
А как это сделать на API не знаю. Подскажите пожалуйста, или дайте линк где почитать. Как только я научусь обращаться к базе данных я СРАЗУ перейду на API!
На чистом апи есть много способов обращения к БД вот один с использованием ODBC,пример из MSDN:
Connecting with SQLConnect
SQLConnect is the simplest connection function. It requires a data source name and accepts an optional user ID and password. It works well for applications that hard-code a data source name and do not require a user ID or password. It also works well for applications that want to control their own "look and feel" or that have no user interface. Such applications can build a list of data sources using SQLDataSources, prompt the user for data source, user ID, and password, and then call SQLConnect.
The following example connects to the Northwind database, using a DSN called Northwind, and retrieves all of the first and last name fields from all of the records in the Employees table.
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <stdlib.h>
#include <mbstring.h>
#define MAX_DATA 100
#define MYSQLSUCCESS(rc) ((rc==SQL_SUCCESS)||(rc==SQL_SUCCESS_WITH_INFO))
class direxec
{
RETCODE rc; // ODBC return code
HENV henv; // Environment
HDBC hdbc; // Connection handle
HSTMT hstmt; // Statement handle
unsigned char szData[MAX_DATA]; // Returned data storage
SDWORD cbData; // Output length of data
unsigned char chr_ds_name[SQL_MAX_DSN_LENGTH]; // Data source name
public:
direxec(); // Constructor
void sqlconn(); // Allocate env, stat, and conn
void sqlexec(unsigned char *); // Execute SQL statement
void sqldisconn(); // Free pointers to env, stat, conn,
// and disconnect
void error_out(); // Displays errors
};
// Constructor initializes the string chr_ds_name with the
// data source name.
direxec::direxec()
{
_mbscpy(chr_ds_name,(const unsigned char *)"Northwind");
}
// Allocate environment handle, allocate connection handle,
// connect to data source, and allocate statement handle.
void direxec::sqlconn(void)
{
SQLAllocEnv(&henv);
SQLAllocConnect(henv,&hdbc);
rc=SQLConnect(hdbc,chr_ds_name,SQL_NTS,NULL,0,NULL,0);
// Deallocate handles, display error message, and exit.
if (!MYSQLSUCCESS(rc))
{
SQLFreeEnv(henv);
SQLFreeConnect(hdbc);
error_out();
exit(-1);
}
rc=SQLAllocStmt(hdbc,&hstmt);
}
// Execute SQL command with SQLExecDirect() ODBC API.
void direxec::sqlexec(unsigned char * cmdstr)
{
rc=SQLExecDirect(hstmt,cmdstr,SQL_NTS);
if (!MYSQLSUCCESS(rc)) //Error
{
error_out();
// Deallocate handles and disconnect.
SQLFreeStmt(hstmt,SQL_DROP);
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);
exit(-1);
}
else
{
for (rc=SQLFetch(hstmt); rc == SQL_SUCCESS; rc=SQLFetch(hstmt))
{
SQLGetData(hstmt,1,SQL_C_CHAR,szData,sizeof(szData),&cbData);
// In this example, the data is returned in a messagebox
// for simplicity. However, normally the SQLBindCol() ODBC API
// could be called to bind individual rows of data and assign
// for a rowset.
MessageBox(NULL,(const char *)szData,"ODBC",MB_OK);
}
}
}
// Free the statement handle, disconnect, free the connection handle, and
// free the environment handle.
void direxec::sqldisconn(void)
{
SQLFreeStmt(hstmt,SQL_DROP);
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);
}
// Display error message in a message box that has an OK button.
void direxec::error_out(void)
{
unsigned char szSQLSTATE[10];
SDWORD nErr;
unsigned char msg[SQL_MAX_MESSAGE_LENGTH+1];
SWORD cbmsg;
while(SQLError(0,0,hstmt,szSQLSTATE,&nErr,msg,sizeof(msg),&cbmsg)==
SQL_SUCCESS)
{
wsprintf((char *)szData,"Error:\nSQLSTATE=%s,Native
error=%ld,msg='%s'",
szSQLSTATE,nErr,msg);
MessageBox(NULL,(const char *)szData,"ODBC Error",MB_OK);
}
}
int WINAPI WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
// Declare an instance of the direxec object.
direxec x;
// Allocate handles, and connect.
x.sqlconn();
// Execute SQL command "SELECT first name, last_name FROM employee".
x.sqlexec((UCHAR FAR *)"SELECT first name, last_name FROM employee");
// Free handles, and disconnect.
x.sqldisconn();
// Return success code; example executed successfully.
return (TRUE);
}
И еще если не сложно подскажите как на API сделать диалог с закладками, и что использовать вместо CString, ну в смысле может кроме типа char есть что ни будь по удобнее?
Попробуй использовать STL`овский string
И еще один вопрос (его я не могу не задать!) – можно ли в программе написанной на чистом API использовать классы?
Не только можно но и нужно,на то он и С++.
MSDN лучший проводник в мир чистого апи.
P.S. Изучай так же STL,и может даже WTL позднее,так как все же не так рационально использовать чистый апи как его обертки класссов из данной библиотеки.
Почитай вот http://forum.codenet.ru/showthread.php?threadid=25395
, тут и про подключку к БД есть.
На счет того как писать под WINAPI, в нете есть дофига инфы. Лень искать? Дай мыло скину :)
Почитай для начала firststeps.ru
А вообще, я последнее время полностью соглащаюсь с тем что велосипелы не зачем изобретать, если в этом нету бо льшой необходимости.
Тебя будут ломать и далее)))
А вообще, я последнее время полностью соглащаюсь с тем что велосипелы не зачем изобретать, если в этом нету бо льшой необходимости.
Я не изобретаю велосипед, а делаю свой, под свои нужды, такой, какой он нужен мне.
заранее спасибо.
да, еще хотел спросить на счет wtl, ты ею пользуешься?
да, еще хотел спросить на счет wtl, ты ею пользуешься?
Скрипя зубами пробую:
http://forum.codenet.ru/showthread.php?threadid=25990
Как я не однократно говорил - WINAPI рулит. И говорю так дальше, даже после неоднократных попыток меня обламать.
Почитай вот http://forum.codenet.ru/showthread.php?threadid=25395
, тут и про подключку к БД есть.
На счет того как писать под WINAPI, в нете есть дофига инфы. Лень искать? Дай мыло скину :)
Почитай для начала firststeps.ru
там мне кто то обещал инфу скинуть?
lamermfc @ mail.ru
там мне кто то обещал инфу скинуть?
lamermfc @ mail.ru
Блин, забыл наглушняк, сегодня с работы скину (если не забуду опять :))
Блин, забыл наглушняк, сегодня с работы скину (если не забуду опять :))
А что у тебя конкретно по этому поводу? Не половина ли переведенной MSDN?:)))
Если что-то стоящее на русском скинь и мне пожалуйста. Если не на русском, тогда не надо. MSDN хватает.
Правда если что-то чего в МСДН нету, но на английском тогда тоже скинь))))
Если на японском... не нужно)
Connecting with SQLConnect
SQLConnect is the simplest connection function. It requires a data source name and accepts an optional user ID and password. It works well for applications that hard-code a data source name and do not require a user ID or password. It also works well for applications that want to control their own "look and feel" or that have no user interface. Such applications can build a list of data sources using SQLDataSources, prompt the user for data source, user ID, and password, and then call SQLConnect.
The following example connects to the Northwind database, using a DSN called Northwind, and retrieves all of the first and last name fields from all of the records in the Employees table.
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <stdlib.h>
#include <mbstring.h>
#define MAX_DATA 100
#define MYSQLSUCCESS(rc) ((rc==SQL_SUCCESS)||(rc==SQL_SUCCESS_WITH_INFO))
class direxec
{
RETCODE rc; // ODBC return code
HENV henv; // Environment
HDBC hdbc; // Connection handle
HSTMT hstmt; // Statement handle
unsigned char szData[MAX_DATA]; // Returned data storage
SDWORD cbData; // Output length of data
unsigned char chr_ds_name[SQL_MAX_DSN_LENGTH]; // Data source name
public:
direxec(); // Constructor
void sqlconn(); // Allocate env, stat, and conn
void sqlexec(unsigned char *); // Execute SQL statement
void sqldisconn(); // Free pointers to env, stat, conn,
// and disconnect
void error_out(); // Displays errors
};
// Constructor initializes the string chr_ds_name with the
// data source name.
direxec::direxec()
{
_mbscpy(chr_ds_name,(const unsigned char *)"Northwind");
}
// Allocate environment handle, allocate connection handle,
// connect to data source, and allocate statement handle.
void direxec::sqlconn(void)
{
SQLAllocEnv(&henv);
SQLAllocConnect(henv,&hdbc);
rc=SQLConnect(hdbc,chr_ds_name,SQL_NTS,NULL,0,NULL,0);
// Deallocate handles, display error message, and exit.
if (!MYSQLSUCCESS(rc))
{
SQLFreeEnv(henv);
SQLFreeConnect(hdbc);
error_out();
exit(-1);
}
rc=SQLAllocStmt(hdbc,&hstmt);
}
// Execute SQL command with SQLExecDirect() ODBC API.
void direxec::sqlexec(unsigned char * cmdstr)
{
rc=SQLExecDirect(hstmt,cmdstr,SQL_NTS);
if (!MYSQLSUCCESS(rc)) //Error
{
error_out();
// Deallocate handles and disconnect.
SQLFreeStmt(hstmt,SQL_DROP);
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);
exit(-1);
}
else
{
for (rc=SQLFetch(hstmt); rc == SQL_SUCCESS; rc=SQLFetch(hstmt))
{
SQLGetData(hstmt,1,SQL_C_CHAR,szData,sizeof(szData),&cbData);
// In this example, the data is returned in a messagebox
// for simplicity. However, normally the SQLBindCol() ODBC API
// could be called to bind individual rows of data and assign
// for a rowset.
MessageBox(NULL,(const char *)szData,"ODBC",MB_OK);
}
}
}
// Free the statement handle, disconnect, free the connection handle, and
// free the environment handle.
void direxec::sqldisconn(void)
{
SQLFreeStmt(hstmt,SQL_DROP);
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);
}
// Display error message in a message box that has an OK button.
void direxec::error_out(void)
{
unsigned char szSQLSTATE[10];
SDWORD nErr;
unsigned char msg[SQL_MAX_MESSAGE_LENGTH+1];
SWORD cbmsg;
while(SQLError(0,0,hstmt,szSQLSTATE,&nErr,msg,sizeof(msg),&cbmsg)==
SQL_SUCCESS)
{
wsprintf((char *)szData,"Error:\nSQLSTATE=%s,Native
error=%ld,msg='%s'",
szSQLSTATE,nErr,msg);
MessageBox(NULL,(const char *)szData,"ODBC Error",MB_OK);
}
}
int WINAPI WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
// Declare an instance of the direxec object.
direxec x;
// Allocate handles, and connect.
x.sqlconn();
// Execute SQL command "SELECT first name, last_name FROM employee".
x.sqlexec((UCHAR FAR *)"SELECT first name, last_name FROM employee");
// Free handles, and disconnect.
x.sqldisconn();
// Return success code; example executed successfully.
return (TRUE);
}
Попробуй использовать STL`овский string
Не только можно но и нужно,на то он и С++.
MSDN лучший проводник в мир чистого апи.
P.S. Изучай так же STL,и может даже WTL позднее,так как все же не так рационально использовать чистый апи как его обертки класссов из данной библиотеки.
В принципе работоспособно но с классами как-то навороченно сильно получается.