DDEを使いExcelファイル(Excel 2010β)よりセルを読み込みセルに書き出すプログラムです。

起動後、メニュよりDDEデモ(D) データの読み込み・書き込み(S)を選択すると上記ダイアログボックスが表示されExcelファイル名・シート名、読み込みセルの範囲、書き込みセルおよび内容を入力してOKを押すとExcelが起動し、本プログラムのウィンドウにExcelのシートの内容が表示されます。またExcelには書き込みセルで指定した場所に書き込み内容が反映されます。

 

 

dde.cpp

#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <stdio.h>
#include <tchar.h>
#include "resource.h"



HDDEDATA CALLBACK DdemlCallback(UINT, UINT, HCONV, HSZ, HSZ,HDDEDATA, ULONG_PTR, ULONG_PTR);
LRESULT CALLBACK inDlgProc(HWND, UINT, WPARAM, LPARAM);

BOOL InitApp(HINSTANCE);	//	ウィンドウクラス登録
BOOL InitInstance(HINSTANCE, int);	//	メインウィンドウ作成
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int DDE_INIT(HWND);			//	DDE初期化	
int DDE_CONNECT(HWND);		//	ファイル・シートに接続
int DDE_DISCONNECT(HWND);	//	ファイル・シートと切断
int DDE_SetData(HWND);	//	セル書き込み
int DDE_GetData(HWND);		//	セル読み込み
bool cells(TCHAR* a1,int* r,int* c);	// EXCELで使用するA1形式のセル番地をRC系列に変換する
void colmn_set(int x,TCHAR* s);	//	列番号よりA1形式の列名を得る。 
bool Excel_Set_Cell(DWORD ddeInst,HCONV hConv2,int r,int c,TCHAR* write_data);	//	Excelのセルに書き込む
bool Excel_Get_Cell(DWORD ddeInst,HCONV hConv2,int r,int c,TCHAR* szData,int sz);	//	Excelのセルを読み込む

HINSTANCE hInst;	//	アプリケーションインスタンス
TCHAR szClassName[] = TEXT("dde_test");        //ウィンドウクラス
DWORD ddeInst=0;			//	インタンス
HSZ hszService;				//	
HSZ hszTopic1;				//	ファイル名文字列ハンドル
HSZ hszTopic2;				//	シート名文字列ハンドル
HCONV hConv1;				//	ファイル名へのハンドル
HCONV hConv2;				//	シート名へのハンドル
TCHAR fname[MAX_PATH];		//	Excel ファイル名
TCHAR sname[32];			//	Excel シート名
TCHAR read_cell_top[32];	//	読み込みセル左上
TCHAR read_cell_bottom[32];	//	読み込みセル右下
TCHAR write_cell[32];		//	書き込みセル
TCHAR write_data[64];		//	書き込み内容
HWND hList;					//	リストビューハンドル


int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,LPSTR lpsCmdLine, int nCmdShow){
    MSG msg;
    
    if (!InitApp(hCurInst))
        return FALSE;
    if (!InitInstance(hCurInst, nCmdShow)) 
        return FALSE;
	BOOL b;
    while ((b=GetMessage(&msg, NULL, 0, 0))!=0) {
		if(b==-1)	//	エラー時に無限ループにならないようにする
			break;
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}


BOOL InitApp(HINSTANCE hInst){
    WNDCLASSEX wc;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInst;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = TEXT("DDEMENU");
    wc.lpszClassName = (TCHAR*)szClassName;
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    return (RegisterClassEx(&wc));
}


BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){
    HWND hWnd;
    hInst = hInstance;

    hWnd = CreateWindow(szClassName,
            TEXT("DDE Excel Demo"),
            WS_OVERLAPPEDWINDOW, 
            CW_USEDEFAULT, 
            CW_USEDEFAULT, 
			CW_USEDEFAULT,
            CW_USEDEFAULT,
            NULL,
            NULL, 
            hInstance,   
            NULL);
    if (!hWnd)
        return FALSE;
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    return TRUE;
}


LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
	int h;
	int col_max;
	int x;
	TCHAR buf[64];
    switch (msg) {
		case WM_CREATE:
			hList = CreateWindowEx(0,
              WC_LISTVIEW, TEXT(""),
               WS_CHILD | WS_VISIBLE | LVS_REPORT,
               0, 0, 0, 0,
               hWnd,
               (HMENU)ID_LISTVIEW,
               hInst,
               NULL);
			read_cell_top[0]=read_cell_bottom[0]=fname[0]=sname[0]=_T('\0');
			break;
        case WM_COMMAND:
            switch (LOWORD(wParam)) {
                case IDM_END:
                    SendMessage(hWnd, WM_CLOSE, 0, 0);
                    break;
                case IDM_START:
					if(DialogBox(hInst, TEXT("INDLG"), hWnd, (DLGPROC)inDlgProc)==IDOK){
						if((h=(int)ShellExecute(hWnd,TEXT("open"),fname,TEXT(""),TEXT(""),SW_SHOW))<=32){
							_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),TEXT("ShellExecute APIでエラーが発生しました。(0x%x)"),h);

							MessageBox(hWnd, buf, TEXT("エラー"), MB_OK | MB_ICONERROR);
							break;
						}
						SendMessage(hList,LVM_DELETEALLITEMS,0,0);
						col_max=(int)SendMessage(ListView_GetHeader(hList),HDM_GETITEMCOUNT,0,0);
						for(x=0;x<col_max;x++){
							ListView_DeleteColumn(hList, 0);
						}
						if(ddeInst==0)
							DDE_INIT(hWnd);
						DDE_CONNECT(hWnd);
						DDE_GetData(hWnd);
						DDE_SetData(hWnd);
						DDE_DISCONNECT(hWnd);
					}
 		  			break;
            }
	        break;
	    case WM_SIZE:
			MoveWindow(hList, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
			break;
        case WM_CLOSE:
            DestroyWindow(hWnd);
            break;
        case WM_DESTROY:
			if(ddeInst)
				if(DdeUninitialize(ddeInst) == 0)
					MessageBox(hWnd, TEXT("DdeUninitialize"),TEXT( "エラー"), MB_OK | MB_ICONERROR);            PostQuitMessage(0);

            break;
        default:
            return (DefWindowProc(hWnd, msg, wParam, lParam));
    }
    return 0;
}

int DDE_INIT(HWND hWnd){
	TCHAR buf[64];
	UINT ret;
    if((ret=DdeInitialize(&ddeInst, DdemlCallback, APPCMD_CLIENTONLY, 0)) != DMLERR_NO_ERROR){
		_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),TEXT("DdeInitialize APIでエラーが発生しました。(0x%x)"),ret);
        MessageBox(hWnd, buf, TEXT("エラー"), MB_OK | MB_ICONERROR);
        return -1;
    }
    return 0;
}

int DDE_CONNECT(HWND hWnd){
	UINT ret;
	TCHAR buf[64];
#ifdef UNICODE
    hszService = DdeCreateStringHandle(ddeInst, TEXT("Excel"), CP_WINUNICODE);
    hszTopic1 = DdeCreateStringHandle(ddeInst, fname, CP_WINUNICODE);
    hszTopic2 = DdeCreateStringHandle(ddeInst, sname, CP_WINUNICODE);
#else
	hszService = DdeCreateStringHandle(ddeInst, TEXT("Excel"), CP_WINANSI);
    hszTopic1 = DdeCreateStringHandle(ddeInst, fname, CP_WINANSI);
    hszTopic2 = DdeCreateStringHandle(ddeInst, sname, CP_WINANSI);
#endif
	hConv1 = DdeConnect(ddeInst, hszService, hszTopic1, NULL);
    if ((ret=DdeGetLastError(ddeInst)) != DMLERR_NO_ERROR) {
		_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),TEXT("DdeConnect(ブック) APIでエラーが発生しました。(0x%x)"),ret);
        MessageBox(0, buf, TEXT("エラー"), MB_OK | MB_ICONERROR);
        return -1;
    }
	hConv2 = DdeConnect(ddeInst, hszService, hszTopic2, NULL);
    if ((ret=DdeGetLastError(ddeInst)) != DMLERR_NO_ERROR) {
		_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),TEXT("DdeConnect(シート) APIでエラーが発生しました。(0x%x)"),ret);
        MessageBox(0, buf, TEXT("エラー"), MB_OK | MB_ICONERROR);
        return -2;
    }
	return 0;
}

int DDE_DISCONNECT(HWND hWnd){
	UINT ret;
	TCHAR buf[64];
    if (hConv1){
        if(DdeFreeStringHandle(ddeInst, hszService) == 0)
            MessageBox(hWnd, TEXT("DdeFreeStringHandle(Excel)"), TEXT("エラー"), MB_OK);
        if(DdeFreeStringHandle(ddeInst, hszTopic1) == 0)
            MessageBox(hWnd, TEXT("DdeFreeStringHandle(ブック)"), TEXT("エラー"), MB_OK);
        if(DdeFreeStringHandle(ddeInst, hszTopic2) == 0)
            MessageBox(hWnd, TEXT("DdeFreeStringHandle(シート)"), TEXT("エラー"), MB_OK);
		if(DdeDisconnect(hConv1) == 0){
			ret=DdeGetLastError(ddeInst);
			_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),TEXT("DdeDisconnect(ブック) APIでエラーが発生しました。(0x%x)"),ret);
			MessageBox(hWnd, buf, TEXT("エラー"), MB_OK | MB_ICONERROR);
		}
		if(DdeDisconnect(hConv2) == 0){
			ret=DdeGetLastError(ddeInst);
			_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),TEXT("DdeDisconnect(シート) APIでエラーが発生しました。(0x%x)"),ret);
			MessageBox(hWnd, buf, TEXT("エラー"), MB_OK | MB_ICONERROR);
		}
        hConv1 = 0;
		hConv2 = 0;
    }
    return 0;
}

bool Excel_Set_Cell(DWORD ddeInst,HCONV hConv2,int r,int c,TCHAR* write_data){
	TCHAR write_cell[16];
    HSZ hszMyTopic;
	HDDEDATA hRet;
	UINT err;
	TCHAR buf[64];

	_stprintf_s(write_cell,sizeof(write_cell)/sizeof(TCHAR),TEXT("R%iC%i"),r,c);
#if	UNICODE
	hszMyTopic = DdeCreateStringHandle(ddeInst, write_cell, CP_WINUNICODE);
    hRet = DdeClientTransaction(
        (LPBYTE)write_data,
        int(_tcslen(write_data)+1)*sizeof(TCHAR) ,
        hConv2,
        hszMyTopic,
        CF_UNICODETEXT, 
        XTYP_POKE,
        10000,
        NULL);
#else
	hszMyTopic = DdeCreateStringHandle(ddeInst, write_cell, CP_WINANSI);
    hRet = DdeClientTransaction(
        (LPBYTE)write_data,
        int(_tcslen(write_data)+1),
        hConv2,
        hszMyTopic,
        CF_TEXT,
        XTYP_POKE,
        10000,
        NULL);
#endif
    
    if(!hRet && (err=DdeGetLastError(ddeInst)) != DMLERR_NO_ERROR){
		_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),TEXT("DdeClientTransaction(XTYP_POKE) %s %s %x"),write_cell,write_data,err);
        MessageBox(0, buf, TEXT("エラー"), MB_OK);
        return false;
    }else if (hRet) {
        DdeFreeStringHandle(ddeInst, hszMyTopic);
        DdeFreeDataHandle(hRet);
    }
	return true;
}

int DDE_SetData(HWND hWnd){
	int r,c;
    if (!hConv1){
        MessageBox(hWnd, TEXT("DdeInitializeが呼び出されていないかエラーが発生しております"), TEXT("エラー"), MB_OK | MB_ICONERROR);
        return -1;
    }
	cells(write_cell,&r,&c);
	Excel_Set_Cell(ddeInst,hConv2,r,c,write_data);

	return 0;
}

bool Excel_Get_Cell(DWORD ddeInst,HCONV hConv2,int r,int c,TCHAR* szData,int sz){
    HDDEDATA hRet;
    HSZ hszMyTopic;
	TCHAR szBuf[16];
	UINT err;
	TCHAR buf[64];
	_stprintf_s(szBuf,sizeof(szBuf)/sizeof(TCHAR),TEXT("R%iC%i"),r,c);
#ifdef UNICODE
	hszMyTopic = DdeCreateStringHandle(ddeInst, szBuf, CP_WINUNICODE);
	hRet = DdeClientTransaction(NULL, 0, hConv2, hszMyTopic,	CF_UNICODETEXT,	XTYP_REQUEST,1000,	NULL);
#else
	hszMyTopic = DdeCreateStringHandle(ddeInst, szBuf, CP_WINANSI);
	hRet = DdeClientTransaction(NULL, 0, hConv2, hszMyTopic,	CF_TEXT,XTYP_REQUEST,1000,	NULL);
#endif
	if(!hRet && (err=DdeGetLastError(ddeInst)) != DMLERR_NO_ERROR){
		_stprintf_s(buf,sz,TEXT("DdeClientTransaction(XTYP_REQUEST) %s 0x%x"),szBuf,err);
		MessageBox(0 , buf,TEXT( "エラー"), MB_OK);
		return false;
	}else if (hRet){
		DdeGetData(hRet, (LPBYTE)szData, sz, 0);
		DdeFreeStringHandle(ddeInst, hszMyTopic);
		DdeFreeDataHandle(hRet);
	}
	return true;
}


int DDE_GetData(HWND hWnd){
	LV_ITEM item;
	int x,y;
	int col_max=0;
	TCHAR szBuf[64];
	TCHAR szData[64];
    if(!hConv1){
        MessageBox(hWnd, TEXT("DdeInitializeが呼び出されていないかエラーが発生しております"), TEXT("エラー"), MB_OK | MB_ICONERROR);
        return -1;
    }
	int top_x,top_y;
	int bottom_x,bottom_y;
	cells(read_cell_top  , &top_y, &top_x);
	cells(read_cell_bottom, &bottom_y, &bottom_x);
	LV_COLUMN lvcol;
	lvcol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
    lvcol.fmt = LVCFMT_LEFT;
    lvcol.cx = 64;
    lvcol.pszText = TEXT("行・列");
    lvcol.iSubItem = 0;
    ListView_InsertColumn(hList,0 , &lvcol);

	for(x=top_x;x<=bottom_x;x++){
		colmn_set(x,szBuf);
        lvcol.pszText = szBuf;
        lvcol.iSubItem = x - top_x+1;
        ListView_InsertColumn(hList,x - top_x+1 , &lvcol);
	}
	for(y=top_y;y<=bottom_y;y++){
		_stprintf_s(szBuf,sizeof(szBuf)/sizeof(TCHAR),TEXT("%i"),y);
		item.mask = LVIF_TEXT  | LVIF_PARAM;
		item.pszText = szBuf;
		item.iItem = y-top_y;
		item.iSubItem = 0;
		item.lParam = y-top_y;
		ListView_InsertItem(hList, &item);
		for(x=top_x;x<=bottom_x;x++){
			Excel_Get_Cell(ddeInst,hConv2,y,x,szData,sizeof(szData)/sizeof(TCHAR));
			item.mask = LVIF_TEXT;
			item.pszText = szData;
			item.iItem = y - top_y;
			item.iSubItem = x - top_x+1;
			ListView_SetItem(hList, &item);
		}
	}
    return 0;
}

LRESULT CALLBACK inDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
	OPENFILENAME o;
    switch (msg) {
		case WM_INITDIALOG:
			SetWindowText(GetDlgItem(hDlg, IDC_EDIT1),read_cell_top);
			SetWindowText(GetDlgItem(hDlg, IDC_EDIT2),read_cell_bottom);
			SetWindowText(GetDlgItem(hDlg, IDC_EDIT3),fname);
			SetWindowText(GetDlgItem(hDlg, IDC_EDIT4),sname);
			SetWindowText(GetDlgItem(hDlg, IDC_EDIT5),write_cell);
			SetWindowText(GetDlgItem(hDlg, IDC_EDIT6),write_data);
			
			break;
        case WM_COMMAND:
            switch (LOWORD(wParam)){
                case IDOK:
                    Edit_GetText(GetDlgItem(hDlg, IDC_EDIT1), read_cell_top, sizeof(read_cell_top)/sizeof(TCHAR));
                    Edit_GetText(GetDlgItem(hDlg, IDC_EDIT2), read_cell_bottom, sizeof(read_cell_bottom)/sizeof(TCHAR));
                    Edit_GetText(GetDlgItem(hDlg, IDC_EDIT3), fname, sizeof(fname)/sizeof(TCHAR));
                    Edit_GetText(GetDlgItem(hDlg, IDC_EDIT4), sname, sizeof(sname)/sizeof(TCHAR));
                    Edit_GetText(GetDlgItem(hDlg, IDC_EDIT5), write_cell, sizeof(write_cell)/sizeof(TCHAR));
                    Edit_GetText(GetDlgItem(hDlg, IDC_EDIT6), write_data, sizeof(write_data)/sizeof(TCHAR));
                    EndDialog(hDlg, IDOK);
                    return TRUE;
				case IDC_REF:
					ZeroMemory(&o,sizeof(o));
					o.lStructSize=sizeof(o);
					o.Flags=0;
					o.Flags |= OFN_HIDEREADONLY;
					o.lpstrFile=fname;
					o.nMaxFile=sizeof(fname)/sizeof(TCHAR);
					o.lpstrFilter=TEXT("xls\0\0");
					o.nFilterIndex=1;
					if(GetOpenFileName(&o)){
						SetWindowText(GetDlgItem(hDlg, IDC_EDIT3),fname);
					}
					break;

                case IDCANCEL:
                    EndDialog(hDlg, IDCANCEL);
                    return TRUE;
            }
            break;
    }
    return FALSE;
}


HDDEDATA CALLBACK DdemlCallback(UINT uType, UINT uFmt, HCONV hconv, HSZ hsz1, HSZ hsz2, HDDEDATA hdata, ULONG_PTR dwData1, ULONG_PTR dwData2){

    return (HDDEDATA)NULL;
}


// EXCELで使用するA1形式のセル番地をRC系列に変換する	


bool cells(TCHAR* a1,int* r,int* c){
	TCHAR* p=a1;
	*c=0;
	*r=0;
	TCHAR ch;
	int t;
	while(*p){
		ch=*p;
		if(_istupper(*p)){
			t = ch - _T('A')+1;
			*c = *c * 26 + t;
		}else if(_istdigit(*p)){

			t = ch - _T('0');
			*r = *r * 10 + t;
		}else{
			return false;
		}
		++p;
	}
	if(256<*c)
		return false;

	return true;

}

//	列番号よりA1形式の列名を得る。 

void colmn_set(int x,TCHAR* s){
	int t1=x/26;
	int t2=x % 26;
	TCHAR* p=s;
	if(t1>=1){
		*p=_T('A')+t1-1;
		++p;
	}
	*p=_T('A')+t2-1;
	++p;
	*p=_T('\0');
}

resource.h

#define IDM_END	100
#define IDM_START	110

#define IDC_STATIC	200
#define IDC_STATIC2	220
#define IDC_STATIC3	230
#define IDC_STATIC4	240
#define IDC_STATIC5	250
#define IDC_STATIC6	260
#define IDC_EDIT1	310
#define IDC_EDIT2	320
#define IDC_EDIT3	330
#define IDC_EDIT4	340
#define IDC_EDIT5	350
#define IDC_EDIT6	360
#define IDC_FILENAME	370
#define IDC_REF	380


#define ID_LISTVIEW 400

 

dde.rc

#include <windows.h>
#include "resource.h"

DDEMENU MENU 
BEGIN
    POPUP "DDEデモ(&D)"
    BEGIN
        MENUITEM "データの読み込み・書き込み(&S)",                  IDM_START
        MENUITEM "プログラムの終了(&X)",                IDM_END
    END
END



INDLG DIALOGEX 0, 0, 375, 179
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Excel データ読み込み・書き込み"
FONT 9, "MS Pゴシック", 0, 0, 0x0
BEGIN
    LTEXT           "ファイル名",IDC_STATIC3,9,9,31,8
    EDITTEXT        IDC_EDIT3,15,19,293,12,ES_AUTOHSCROLL
    DEFPUSHBUTTON   "参照",IDC_REF,328,19,35,14
    LTEXT           "シート名",IDC_STATIC4,9,35,26,8
    EDITTEXT        IDC_EDIT4,15,45,293,12,ES_AUTOHSCROLL
    LTEXT           "読み取り範囲",IDC_STATIC,9,69,28,8
    EDITTEXT        IDC_EDIT1,15,79,32,12,ES_AUTOHSCROLL
    LTEXT           "~",IDC_STATIC2,55,79,8,8
    EDITTEXT        IDC_EDIT2,75,79,32,12,ES_AUTOHSCROLL

    LTEXT           "書き込みセル",IDC_STATIC5,9,95,48,8
    EDITTEXT        IDC_EDIT5,15,105,22,12,ES_AUTOHSCROLL
    LTEXT           "書き込み内容",IDC_STATIC6,9,124,48,8
    EDITTEXT        IDC_EDIT6,15,134,32,12,ES_AUTOHSCROLL

	
	
	DEFPUSHBUTTON   "OK",IDOK,250,154,50,14
    PUSHBUTTON      "キャンセル",IDCANCEL,311,154,50,14
	
END