// DlgInit.h --- dialog initialization by RT_DLGINIT            -*- C++ -*-
// This file is part of MZC4.  See file "ReadMe.txt" and "License.txt".
//////////////////////////////////////////////////////////////////////////////

#ifndef MZC4_DLGINIT_H_
#define MZC4_DLGINIT_H_     9   /* Version 9 */

// RT_DLGINIT
// BOOL ExecuteDlgInitDx(HWND hwnd, HMODULE module, const TCHAR *res_name);

//////////////////////////////////////////////////////////////////////////////

#include "MWindowBase.hpp"
#include "MString.hpp"

#ifndef RT_DLGINIT
	#define RT_DLGINIT  MAKEINTRESOURCE(240)
#endif

// Win16 messages
#define WIN16_LB_ADDSTRING  0x0401
#define WIN16_CB_ADDSTRING  0x0403
#define AFX_CB_ADDSTRING    0x1234

//////////////////////////////////////////////////////////////////////////////

inline const UNALIGNED WORD *
ExecuteDlgInitEntryDx(HWND hwnd, const UNALIGNED WORD *pw, SIZE_T& cbData)
{
	DWORD cb = 4 * sizeof(WORD);
	if (cbData <= cb)
		return NULL;
	cbData -= cb;

	// get data
	WORD ctrl = *pw++;
	WORD msg = *pw++;
	WORD w0 = *pw++;
	WORD w1 = *pw++;
	DWORD dwLen = MAKELONG(w0, w1);

	cb = dwLen;
	if (cbData <= cb)
		return NULL;
	cbData -= cb;

	// convert Win16 messages
	switch (msg)
	{
	case AFX_CB_ADDSTRING: msg = CBEM_INSERTITEM; break;
	case WIN16_LB_ADDSTRING: msg = LB_ADDSTRING; break;
	case WIN16_CB_ADDSTRING: msg = CB_ADDSTRING; break;
	}

	// NOTE: We don't support OCC.
	assert(msg == LB_ADDSTRING || msg == CB_ADDSTRING ||
		   msg == CBEM_INSERTITEM);

#ifndef NDEBUG
	const BYTE *pb = reinterpret_cast<const BYTE *>(pw);
	assert(pb[dwLen - 1] == 0);
#endif

	// send the message
	if (msg == CBEM_INSERTITEM)
	{
		MString text = MAnsiToText(CP_ACP, LPSTR(pw)).c_str();

		COMBOBOXEXITEM item;
		item.mask = CBEIF_TEXT;
		item.iItem = -1;
		item.pszText = &text[0];

		if (::SendDlgItemMessageA(hwnd, ctrl, msg, 0, LPARAM(&item)) == -1)
			return NULL;
	}
	else if (msg == LB_ADDSTRING || msg == CB_ADDSTRING)
	{
		if (::SendDlgItemMessageA(hwnd, ctrl, msg, 0, LPARAM(pw)) == -1)
			return NULL;
	}

	// go to next entry
	return reinterpret_cast<const UNALIGNED WORD *>(
		reinterpret_cast<const BYTE *>(pw) + dwLen);
}

inline BOOL
ExecuteDlgInitDataDx(HWND hwnd, const void *pData, SIZE_T& cbData)
{
#ifndef NDEBUG
	DWORD i = 0;
#endif
	const UNALIGNED WORD *pw;
	pw = reinterpret_cast<const UNALIGNED WORD *>(pData);
	while (pw && *pw)
	{
		pw = ExecuteDlgInitEntryDx(hwnd, pw, cbData);
#ifndef NDEBUG
		++i;
#endif
	}

	// NOTE: We don't send WM_INITIALUPDATE messages.
	return pw != NULL;
}

//////////////////////////////////////////////////////////////////////////////

inline BOOL
ExecuteDlgInitDx(HWND hwnd, HMODULE module, const TCHAR *res_name)
{
	BOOL bSuccess = FALSE;
	HGLOBAL hGlobal = NULL;
	void *pData = NULL;
	SIZE_T cbData = 0;

	// load from resource
	if (HRSRC hRsrc = FindResource(module, res_name, RT_DLGINIT))
	{
		hGlobal = LoadResource(module, hRsrc);
		cbData = SizeofResource(module, hRsrc);
		pData = LockResource(hGlobal);
	}

	// execute
	if (pData && cbData)
	{
		bSuccess = ExecuteDlgInitDataDx(hwnd, pData, cbData);
	}

	// clean up
	UnlockResource(hGlobal);
	FreeResource(hGlobal);

	return bSuccess;
}

//////////////////////////////////////////////////////////////////////////////

#endif  // ndef MZC4_DLGINIT_H_
