開発環境 Microsoft Visual C++ 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Win32 プロジェクト
プロジェクト名 CsvDirect
アプリケーションの種類 Windows アプリケーション
追加のオプション 空のプロジェクト
文字セット マルチバイト

CsvDirect.cpp
// マルチバイト
#include <Windows.h>
#include <CommCtrl.h>
#include <sqlext.h>
#include <tchar.h>
#include <vector>
#include <string>
#include "resource.h"
 
#define DRIVER _T("Microsoft Text Driver (*.txt; *.csv)")
#define DATABASE _T("C:\\tmp")
#define TABLE _T("09TOCHIG.CSV")
#define TABLE2 _T("09TOCHIG_.CSV")
 
// 型定義
struct ColInfo {	// 列情報
	std::string strName;	// 列名
	SQLSMALLINT datatype;	// データ型
};
typedef std::vector<ColInfo> VecCI;
 
// 関数プロトタイプ宣言
INT_PTR CALLBACK MainDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnInitDialog(HWND hDlg);
void LoadTable(HWND hDlg);
BOOL SaveTable(HWND hDlg);
 
// 外部変数構造体
static struct {
	HWND hList;	// リストビュー
	SQLHENV henv;	// 環境ハンドル
	SQLHDBC hdbc;	// 接続ハンドル
	VecCI vecci;	// 列情報
} g;
 
//==============================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
	// ODBC環境ハンドルの確保
	SQLRETURN rc;	// retcode
	rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &g.henv);
	rc = SQLSetEnvAttr(g.henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
 
	DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, MainDlgProc);
 
	SQLFreeHandle(SQL_HANDLE_ENV, g.henv);
	return 0;
}
 
//------------------------------------------------------------------------------
INT_PTR CALLBACK MainDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	INT_PTR nRet = TRUE;	// メッセージを処理した
 
	switch (uMsg) {
	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDC_SAVE:
			if (SaveTable(hDlg)) {
				MessageBox(hDlg, _T("完了しました。"), _T("報告"), MB_OK);
			}
			break;
		case IDCANCEL:
			EndDialog(hDlg, IDCANCEL);
			break;
		}
		break;
	case WM_INITDIALOG:
		OnInitDialog(hDlg);
		nRet = TRUE;	// SetFocusでフォーカスを設定した場合はFALSE
		break;
	case WM_CLOSE:
		EndDialog(hDlg, 0);
		break;
	case WM_DESTROY:
		SQLDisconnect(g.hdbc);
		SQLFreeHandle(SQL_HANDLE_DBC, g.hdbc);
		break;
	default:
		nRet = FALSE;	// メッセージを処理しなかった
	}
	return nRet;
}
 
//------------------------------------------------------------------------------
void OnInitDialog(HWND hDlg)
{
	// リストビュー拡張スタイル
	g.hList = GetDlgItem(hDlg, IDC_LIST);
	DWORD dwExStyle = ListView_GetExtendedListViewStyle(g.hList);
	dwExStyle |= LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES;
	ListView_SetExtendedListViewStyle(g.hList, dwExStyle);
 
	// テーブルの読み込み
	LoadTable(hDlg);
}
 
//------------------------------------------------------------------------------
void LoadTable(HWND hDlg)
{
	SQLHSTMT hstmt;	// 命令ハンドル
	SQLSMALLINT col;
	SQLSMALLINT n;
	SQLSMALLINT datatype;
	TCHAR buf[256];
	SQLLEN len;
	SQLRETURN rc;	// retcode
 
	// データベースへの接続
	rc = SQLAllocHandle(SQL_HANDLE_DBC, g.henv, &g.hdbc);
	rc = SQLDriverConnect(g.hdbc, NULL,
		(SQLTCHAR *) TEXT("driver={") DRIVER TEXT("}; dbq=") DATABASE,
		SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
	if (!SQL_SUCCEEDED(rc)) {
		return;
	}
 
	// 検索
	rc = SQLAllocHandle(SQL_HANDLE_STMT, g.hdbc, &hstmt);
	rc = SQLExecDirect(hstmt, (SQLTCHAR *) TEXT("select * from ") TABLE, SQL_NTS);
	if (!SQL_SUCCEEDED(rc)) {
		return;
	}
	// 列情報
	LV_COLUMN lvCol;
	lvCol.mask	= LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
	lvCol.fmt	= LVCFMT_LEFT;
	lvCol.cx	= 100;
	rc = SQLNumResultCols(hstmt, &col);
	g.vecci.reserve(col);
	for (n = 0; n < col; n++) {
		rc = SQLDescribeCol(hstmt, n+1, (SQLTCHAR *)buf, _countof(buf), NULL,
			&datatype, NULL, NULL, NULL);
		lvCol.pszText	= buf;
		lvCol.iSubItem	= n;
		ListView_InsertColumn(g.hList, n, &lvCol);
		// 列情報
		ColInfo ci;
		ci.strName	= buf;
		ci.datatype	= datatype;
		g.vecci.push_back(ci);
		// Text 12 SQL_VARCHAR
		// Byte -6 SQL_TINYINT
	}
	// 行情報
	LV_ITEM lvItem;
	lvItem.mask	= LVIF_TEXT;
	lvItem.iItem	= 0;
	while (1) {
		rc = SQLFetch(hstmt);
		if (rc == SQL_NO_DATA) break;
		if (rc == SQL_ERROR) break;
		for (n = 0; n < col; n++) {
			SQLGetData(hstmt, n+1, SQL_C_TCHAR, buf, _countof(buf), &len);
			lvItem.pszText	= buf;
			lvItem.iSubItem	= n;
			if (n == 0) {
				ListView_InsertItem(g.hList, &lvItem);
			} else {
				ListView_SetItem(g.hList, &lvItem);
			}
		}
		lvItem.iItem++;
	}
	SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
}
 
//------------------------------------------------------------------------------
BOOL SaveTable(HWND hDlg)
{
	TCHAR szPath[MAX_PATH];
	TCHAR szBuf[256];
	int nColNum = g.vecci.size();
 
	// ファイルのオープン
	_stprintf_s(szPath, _T("%s\\%s"), DATABASE, TABLE2);
	FILE *pFile;
	errno_t er = _tfopen_s(&pFile, szPath, _T("wt"));
	if (er) {
		MessageBox(hDlg, _T("ファイルのオープンに失敗しました。"), NULL, MB_OK);
		return FALSE;
	}
 
	// ヘッダ行
	_stprintf_s(szPath, _T("%s\\schema.ini"), DATABASE);
	DWORD dw = GetPrivateProfileString(TABLE, _T("ColNameHeader"), NULL,
		szBuf, _countof(szBuf), szPath);
	if (_tcsicmp(szBuf, _T("true")) == 0) {
		for (int nCol = 0; ; ) {
			_ftprintf_s(pFile, _T("%s"), g.vecci[nCol].strName.c_str());
			if (nColNum <= ++nCol) {
				break;
			}
			_ftprintf_s(pFile, _T(","));
		}
		_ftprintf_s(pFile, _T("\n"));
	}
 
	// 書き込み
	int nRowNum = ListView_GetItemCount(g.hList);
	for (int nRow = 0; nRow < nRowNum; nRow++) {
		for (int nCol = 0; ; ) {
			ListView_GetItemText(g.hList, nRow, nCol, szBuf, _countof(szBuf));
			switch (g.vecci[nCol].datatype) {
			case SQL_VARCHAR:
				_ftprintf_s(pFile, _T("\"%s\""), szBuf);
				break;
			case SQL_TINYINT:
				_ftprintf_s(pFile, _T("%s"), szBuf);
				break;
			}
			if (nColNum <= ++nCol) {
				break;
			}
			_ftprintf_s(pFile, _T(","));
		}
		_ftprintf_s(pFile, _T("\n"));
	}
 
	fclose(pFile);
	return TRUE;
}
 

resource.h
#define IDD_MAIN	100
 
#define IDC_LIST	1000
#define IDC_SAVE	1001
 

CsvDirect.rc
// resource script
#include <windows.h>
#include "resource.h"
 
//------------------------------------------------------------------------------
IDD_MAIN DIALOGEX 100, 100, 320, 200
STYLE WS_POPUPWINDOW | WS_MINIMIZEBOX
EXSTYLE WS_EX_APPWINDOW
CAPTION "CsvDirect"
FONT 9, "MS Pゴシック"
BEGIN
	CONTROL		"",IDC_LIST,"SysListView32",
			WS_BORDER | WS_TABSTOP | LVS_REPORT,8,8,304,160
	PUSHBUTTON	"保存",IDC_SAVE,212,176,48,16
	PUSHBUTTON	"終了",IDCANCEL,264,176,48,16
END
 
最終更新:2012年10月27日 11:05