もどる
#define STRICT
#include <windows.h>
#include <ddeml.h>
#include "resource.h"

HWND CreateConsole(HWND hwnd);
void ClearConsole(void);
void dprintf(char  *format,...);

HANDLE	Instance;
CHAR	szAppName[]	  = "DDE server";
CHAR	szClassName[] = "DDE server class";
CHAR	szServiceName[] = "DDE test";
CHAR	szTopicName[]	= "DDE topic";
CHAR	szItemName[]   = "advise item";
HSZ		hszServiceName,hszTopicName,hszItemName;

char	advdata[]="0";

DWORD		ddeinst;
HWND		hconsole;

HDDEDATA CALLBACK DdeCallback(UINT uType,UINT uFmt,HCONV hconv,HSZ hsz1,HSZ hsz2,
									HDDEDATA hdata,DWORD dwData1,DWORD dwData2)
{
	switch(uType){
		case XTYP_CONNECT:
			if(hsz1!=hszTopicName){
				dprintf("CONNECT failuer");
				return (HDDEDATA)FALSE;
			}
			dprintf("CONNECT\n");
			return (HDDEDATA)TRUE;

		case XTYP_DISCONNECT:
			dprintf("DISCONNECT\n");
			return (HDDEDATA)TRUE;

		case XTYP_ADVSTART:
			if(hsz1!=hszTopicName || hsz2!=hszItemName){
				dprintf("AVSTART failure\n");
				return (HDDEDATA)FALSE;
			}
			advdata[0]='0';
			dprintf("ADVSTART\n");
			return (HDDEDATA)TRUE;

		case XTYP_ADVSTOP:
			dprintf("ADVSTOP\n");
			return (HDDEDATA)TRUE;

		case XTYP_ADVREQ:
			if(hsz1!=hszTopicName || hsz2!=hszItemName){
				dprintf("ADVREQ failure\n");
				return (HDDEDATA)NULL;
			}
			dprintf("ADVREQ\n");
			return DdeCreateDataHandle(ddeinst,advdata,2,0,hszItemName,CF_TEXT,0);

		case XTYP_REQUEST:
			if(hsz1!=hszTopicName || hsz2!=hszItemName){
				dprintf("REQUEST failure\n");
				return (HDDEDATA)NULL;
			}
			dprintf("REQUEST\n");
			return DdeCreateDataHandle(ddeinst,advdata,2,0,hszItemName,CF_TEXT,0);

		case XTYP_POKE:
			if(hsz1!=hszTopicName || hsz2!=hszItemName){
				dprintf("POKE failure\n");
				DdeFreeDataHandle(hdata);
				return DDE_FNOTPROCESSED;
			}
			{
				char	*p;

				p=DdeAccessData(hdata,NULL);
				dprintf("POKE:%s\n",p);
				DdeUnaccessData(hdata);
				DdeFreeDataHandle(hdata);
			}
			return (HDDEDATA)DDE_FACK;

		case XTYP_EXECUTE:
			if(hsz1!=hszTopicName){
				dprintf("EXECUTE failure\n");
				DdeFreeDataHandle(hdata);
				return DDE_FNOTPROCESSED;
			}
			{
				char	*p;

				p=DdeAccessData(hdata,NULL);
				dprintf("EXECUTE:%s\n",p);
				DdeUnaccessData(hdata);
				DdeFreeDataHandle(hdata);
			}
			return (HDDEDATA)DDE_FACK;


		default:
			return (HDDEDATA) NULL;
	}
	return (HDDEDATA)NULL;
}

void UninitDdeServer(DWORD inst)
{
	if(inst){
		DdeFreeStringHandle(inst,hszServiceName);
		DdeFreeStringHandle(inst,hszTopicName);
		DdeFreeStringHandle(inst,hszItemName);
		DdeUninitialize(inst);
	}
}

DWORD  InitDdeServer(void)
{
	UINT	ret;
	HDDEDATA	ret2;
	DWORD	inst=0;

	ret=DdeInitialize(&inst,DdeCallback,
			CBF_SKIP_REGISTRATIONS,
			0);
	if(ret!= DMLERR_NO_ERROR) return 0;
	hszServiceName=DdeCreateStringHandle(inst,szServiceName,CP_WINANSI);
	hszTopicName=DdeCreateStringHandle(inst,szTopicName,CP_WINANSI);
	hszItemName=DdeCreateStringHandle(inst,szItemName,CP_WINANSI);
	ret2=DdeNameService(inst,hszServiceName,0,DNS_REGISTER);
	if(!ret2){
		UninitDdeServer(inst);
		return 0;
	}
	return inst;
}

void CenterWindow(HWND hwnd)
{
	HWND hwndOwner;
	RECT rc, rc2;
	int	x,y;

	/* Get the owner window and dialog box rectangles. */
	if((hwndOwner=GetParent(hwnd))==NULL) hwndOwner = GetDesktopWindow();
	GetWindowRect(hwndOwner, &rc);
	GetWindowRect(hwnd, &rc2);
	x = ((rc.right-rc.left) - (rc2.right-rc2.left)) / 2 +rc.left;
	y = ((rc.bottom-rc.top) - (rc2.bottom-rc2.top)) / 2 +rc.top;

	SetWindowPos(hwnd,
		HWND_TOP,
		x, y,
		0, 0,		   /* ignores size arguments */
		SWP_NOSIZE);
}

int CALLBACK WndProc(HWND hwnd, unsigned wMessage,
				  WPARAM wParam, LPARAM lParam)
{
	switch (wMessage)
	{
		case WM_CREATE:
			CenterWindow(hwnd);
			ddeinst=InitDdeServer();
			if(ddeinst==0){
				MessageBox(hwnd,"DDEを初期化できません","DDE error",
												MB_OK | MB_ICONEXCLAMATION);
				return -1;
			}
			hconsole=CreateConsole(hwnd);
			break;

		case WM_DESTROY:
			UninitDdeServer(ddeinst);
			PostQuitMessage(0);
			break;

		case WM_SIZE:
			advdata[0]='1';
			DdePostAdvise(ddeinst,hszTopicName,hszItemName);
			SetWindowPos(hconsole,0,0,0,LOWORD(lParam),HIWORD(lParam),SWP_NOMOVE | SWP_NOZORDER);
			break;

		default:
			return (DefWindowProc(hwnd, wMessage, wParam, lParam));
	}
	return 0;
}


int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
		  LPSTR lpszCmd, int nCmdShow)
{
	WNDCLASS	wndclass;
	MSG			msg;
	HWND		hwnd;
	RECT		rc;
	int xMaxAppWindow;
	int yMaxAppWindow;

	//二重起動の禁止
	if((FindWindow(szClassName,szAppName))!=NULL){
		return 0;
	}

	Instance = hInstance;

	wndclass.style			= CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc	= (WNDPROC) WndProc;
	wndclass.cbClsExtra	= 0;
	wndclass.cbWndExtra	= 0;
	wndclass.hInstance		= hInstance;
	wndclass.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
	wndclass.hCursor		= LoadCursor (NULL, IDC_ARROW);
	wndclass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE+1);
	wndclass.lpszMenuName	= szAppName;
	wndclass.lpszClassName = szClassName;

	if (!RegisterClass (&wndclass))		return FALSE;

	SystemParametersInfo(SPI_GETWORKAREA,0,&rc,0);
	xMaxAppWindow=(rc.right-rc.left)/2;
	yMaxAppWindow=(rc.bottom-rc.top)/2;

	/* Create the app. window */
	hwnd = CreateWindowEx( WS_EX_OVERLAPPEDWINDOW,
						  szClassName,
						  szAppName,
						  WS_OVERLAPPEDWINDOW,
						  CW_USEDEFAULT,
						  0,
						  xMaxAppWindow,
						  yMaxAppWindow,
						  NULL,
						  NULL,
						  hInstance,
						  NULL);

	ShowWindow (hwnd, nCmdShow);

	/* Enter message loop */
	while (GetMessage (&msg, NULL, 0, 0)) {
		TranslateMessage (&msg);
		DispatchMessage (&msg);
	}

	return msg.wParam;
}