Introduction
QuickQuery is the second program I wrote on my own in C++, just to experiment. It was an attempt to make an app that could run queries on any type of database. This code was written using VC6 and has been run on Windows 2000 and XP.
Background
I started off trying to make something that the rest of my company could use. I still use it every now and then, but not much. At the time, I was also trying to learn DirectX programming, so you'll see some of that in here, too. :)
Using the code
QuickQuery uses ODBC to run the queries and the CRecordset
-derived classes from Microsoft's "catsets" source code. These sets are used to get the primary keys and columns of all the tables in the database. There is functionality there that I didn't implement, but that can still be used.
This program uses a CFormView
and switches back and forth between that and a CListView
view. By switching to the ListView, you can see all the tables in a database:
and double-clicking on a table will show you the columns and column types for that table.
This is done by clicking the double-arrow icon on the toolbar. I used this code that I found somewhere in my MSDN to switch views in a function of my app, called SwitchView()
:
CView* CQuickQueryApp::SwitchView(CView* pNewView)
{
CView* pActiveView =
((CFrameWnd*) m_pMainWnd)->GetActiveView();
try
{
#ifndef _WIN32
UINT temp = ::GetWindowWord(pActiveView->m_hWnd, GWW_ID);
::SetWindowWord(pActiveView->m_hWnd, GWW_ID,
::GetWindowWord(pNewView->m_hWnd, GWW_ID));
::SetWindowWord(pNewView->m_hWnd, GWW_ID, temp);
#else
UINT temp = ::GetWindowLong(pActiveView->m_hWnd, GWL_ID);
::SetWindowLong(pActiveView->m_hWnd, GWL_ID,
::GetWindowLong(pNewView->m_hWnd, GWL_ID));
::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);
#endif
pActiveView->ShowWindow(SW_HIDE);
pNewView->ShowWindow(SW_SHOW);
((CFrameWnd*) m_pMainWnd)->SetActiveView(pNewView);
((CFrameWnd*) m_pMainWnd)->RecalcLayout();
pNewView->Invalidate();
}
catch(CException* err)
{
pErrObject->HandleError(err," "," ");
}
catch(...)
{
AfxMessageBox("Unhandled Error ");
}
return pActiveView;
}
There is also a pretty generic 'Find' dialog that lets you search, when a ListView is active. It allows you to search by column. Although it should probably be a modeless dialog, at the time I made this project, I really didn't know how to do that. :)
Queries can be saved, as well as the connection string to your last connection so that when you open a query, it connects you to the right database. Your last connection is also saved in the registry so that when you open QuickQuery, it will connect you to the last connection you had open before shutting down.
void CQuickQueryDoc::Serialize(CArchive& ar)
{
try
{
if (ar.IsStoring())
{
m_view->UpdateData();
ar<<m_view->m_strQuery<<m_view->m_CurrentSource;
}
else
{
if(!m_view)
{
ar>>m_docQuery>>m_docSource;
m_bSerializing = TRUE;
return;
}
ar>>m_view->m_strQuery>>m_view->m_CurrentSource;
AfxGetApp()->WriteProfileString("Database",
"LastDatabase",m_view->m_CurrentSource);
m_view->UpdateData(FALSE);
}
}
catch(CException* err)
{
pErrObject->HandleError(err," "," ");
}
catch(...)
{
AfxMessageBox("Unhandled Error");
}
}
Points of Interest
The 'About' dialog has a simple PictureBox control that I use to display a spinning Direct3D square, with my old company's logo texture-mapped onto the square. This was made using DirectX 8, but I have version 9 now, and it compiles just fine. Maybe even the DirectX code involved in the dialog will help somebody out! (I can hope, can't I?)
As I said, this was my second C++ project, not out of a tutorial, so please don't be too harsh. :)
There is a context-sensitive help file associated with QuickQuery that I never fully finished...so some of it works - some of it doesn't. You'll probably have to change the path to the help file for building purposes.
You are free to do whatever you want with this code. Like I said, it was my very first project, and I had actually forgot about it until I saw it in one of my old folders. If I were to do a project like this over from scratch, I'd use ADO, only using the ODBC function to get the connection string, as I have done since.
Known Issues
When running this program, after shutting down, I see a memory leak in the debug output, but I really have no idea where it is (or much desire to investigate).
This program is a lot larger than it needs to be, mostly because of bitmaps (I hope). There is a bug that occurs sometimes when switching views. Error-handling could be a lot better.
History