// *****************************************************************
// -----------------------------------------------------------------
// AdaptMFC.h - Sorgt dafür, dass die MFC automatisch das
// Translation-System benutzt
// -----------------------------------------------------------------
// *****************************************************************

// *****************************************************************
// Mehrfach-Include-Schutz
// *****************************************************************

#ifndef INC_STRING_DEFINES_HEADER
#define INC_STRING_DEFINES_HEADER

// *****************************************************************
// Diese Funktion erledigt das CString.LoadString
// *****************************************************************

class __X_CString;
BOOL __X_TranslateLoadString(__X_CString& szText, UINT nID);

// *****************************************************************
// Überschreibe Klasse CString (nur wegen LoadString)
// *****************************************************************

class __X_CString : public CString
{
public:
	// Die Konstruktoren müssen überschrieben werden, wegen Castings
	__X_CString() : CString() {};
	__X_CString(const CString& stringSrc) : CString(stringSrc) {};
	__X_CString(TCHAR ch, int nRepeat = 1) : CString(ch, nRepeat) {};
	__X_CString(LPCSTR lpsz); // : CString(lpsz) {};
	__X_CString(LPCWSTR lpsz); // : CString(lpsz)  {};
	__X_CString(LPCTSTR lpch, int nLength) : CString(lpch, nLength) {};
	__X_CString(const unsigned char* psz) : CString(psz) {};

	// Die Funktion __X_LoadStringA (wegen #define unten)
	BOOL __X_LoadStringA(UINT nID)
	{
		return __X_TranslateLoadString(*this, nID);
	};

	// Die Funktion __X_LoadStringW (wegen #define unten)
	BOOL __X_LoadStringW(UINT nID)
	{
		return __X_TranslateLoadString(*this, nID); //*((CString*)this) = CString("Du dummer Idiot W!");
		//return TRUE;
	};

	// Damit man noch an die Stringtable kommt...	
	BOOL __X_GetTheString(UINT nID)
	{
		return CString::LoadString(nID);
	};

	// Ausgabe über Formatstring, Normale Version (gegen Compiler-Fehler)
	void AFX_CDECL Format(LPCTSTR lpszFormat, ...);

	// Ausgabe über Formatstring, Stringtable-Version
	void AFX_CDECL Format(UINT nFormatID, ...);
};

// *****************************************************************
// Braucht man, um OnCmdMsg überschreiben zu können
// *****************************************************************

struct EXTRA_POINTER
{
	LRESULT* pResult;
	NMHDR* pNMHDR;
};

// *****************************************************************
// Überschreibe Klasse CFrameWnd (für GetMessageString-Zugriff)
// *****************************************************************

class __X_CFrameWnd : public CFrameWnd
{
public:
	// Die Konstruktoren für Castings überschreiben
	__X_CFrameWnd() : CFrameWnd() {};

	// Weils die Basisklasse auch ist
	DECLARE_DYNCREATE(__X_CFrameWnd)

#undef CString
	// GetMessage für Message-Zugriff
	// Diese Funktion überschreibt virtuelle CFrameWnd -
	// Funktion, deshalb auch "original" CString
	virtual void GetMessageString(UINT nID, CString& rMessage) const;
#define CString __X_CString

	// Weil überschriebene virtuelle const's nicht in const-
	// Member-Funktionen aufgerufen werden können, und weil
	// CString so nicht passt, gibt's eine static Funktion
	// stattdessen (der User merkt nix davon, als wäres
	// ne const-Basisklassen-Member-Funktion)
	// Hier ist CString schon wieder __X_CString
	static void GetMessageString(UINT nID, CString& rMessage);
	
	// Damit das Anfangs-Menü gefangen wird
	virtual BOOL LoadFrame(UINT nIDResource,
		DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
		CWnd* pParentWnd = NULL,
		CCreateContext* pContext = NULL);

protected:
	// Für Zugriff auf die Tool-Tip-Texte
	afx_msg BOOL OnToolTipText(UINT nID, 
		NMHDR* pNMHDR, LRESULT* pResult);

	// Damit die ToolTip-Message empfangen werden kann
	virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,
		AFX_CMDHANDLERINFO* pHandlerInfo);

	// Damit der Message-Map funktioniert
	DECLARE_MESSAGE_MAP()
};

// *****************************************************************
// Überschreibe Klasse CMDIFrameWnd (für GetMessageStrin-Zugriff)
// *****************************************************************

class __X_CMDIFrameWnd : public CMDIFrameWnd
{
public:
	// Die Konstruktoren für Castings überschreiben
	__X_CMDIFrameWnd() : CMDIFrameWnd() {};

	// Weils die Basisklasse auch ist
	DECLARE_DYNCREATE(__X_CMDIFrameWnd)

#undef CString
	// GetMessage für Message-Zugriff
	// Diese Funktion überschreibt virtuelle CFrameWnd -
	// Funktion, deshalb auch "original" CString
	virtual void GetMessageString(UINT nID, CString& rMessage) const;
#define CString __X_CString

	// Weil überschriebene virtuelle const's nicht in const-
	// Member-Funktionen aufgerufen werden können, und weil
	// CString so nicht passt, gibt's eine static Funktion
	// stattdessen (der User merkt nix davon, als wäres
	// ne const-Basisklassen-Member-Funktion)
	// Hier ist CString schon wieder __X_CString
	static void GetMessageString(UINT nID, CString& rMessage);

	// Damit das Anfangs-Menü gefangen wird
	virtual BOOL LoadFrame(UINT nIDResource,
		DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
		CWnd* pParentWnd = NULL,
		CCreateContext* pContext = NULL);

protected:
	// Für Zugriff auf die Tool-Tip-Texte
	afx_msg BOOL OnToolTipText(UINT nID, 
		NMHDR* pNMHDR, LRESULT* pResult);

	// Damit die ToolTip-Message empfangen werden kann
	virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,
		AFX_CMDHANDLERINFO* pHandlerInfo);

	// Damit der Message-Map funktioniert
	DECLARE_MESSAGE_MAP()
};


// *****************************************************************
// Überschreibe Klasse CMDIFrameWnd (für GetMessageStrin-Zugriff)
// *****************************************************************

class __X_CMDIChildWnd : public CMDIChildWnd
{
	// Weils die Basisklasse auch ist
	DECLARE_DYNCREATE(__X_CMDIChildWnd)

public:
	// Die Konstruktoren für Castings überschreiben
	__X_CMDIChildWnd() : CMDIChildWnd() {};

	// Damit das Menu geändert werden kann
	virtual void OnUpdateFrameMenu(BOOL bActive, CWnd* pActivateWnd,
		HMENU hMenuAlt);

#undef CString
	// GetMessage für Message-Zugriff
	// Diese Funktion überschreibt virtuelle CFrameWnd -
	// Funktion, deshalb auch "original" CString
	virtual void GetMessageString(UINT nID, CString& rMessage) const;
#define CString __X_CString

	// Weil überschriebene virtuelle const's nicht in const-
	// Member-Funktionen aufgerufen werden können, und weil
	// CString so nicht passt, gibt's eine static Funktion
	// stattdessen (der User merkt nix davon, als wäres
	// ne const-Basisklassen-Member-Funktion)
	// Hier ist CString schon wieder __X_CString
	static void GetMessageString(UINT nID, CString& rMessage);

protected:
	// Für Zugriff auf die Tool-Tip-Texte
	afx_msg BOOL OnToolTipText(UINT nID, 
		NMHDR* pNMHDR, LRESULT* pResult);

public:
	// Damit die ToolTip-Message empfangen werden kann
	virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,
		AFX_CMDHANDLERINFO* pHandlerInfo);

protected:
	// Damit der Message-Map funktioniert
	DECLARE_MESSAGE_MAP()
};


// *****************************************************************
// Überschreibe Klasse COleIPFrameWnd (für GetMessageStrin-Zugriff)
// *****************************************************************

#ifdef __AFXOLE_H__

class __X_COleIPFrameWnd : public COleIPFrameWnd
{
	// Weils die Basisklasse auch ist
	DECLARE_DYNCREATE(__X_COleIPFrameWnd)

public:
	// Die Konstruktoren für Castings überschreiben
	__X_COleIPFrameWnd() : COleIPFrameWnd() {};

	// Damit das Menu geändert werden kann
	virtual BOOL OnCreateControlBars(CWnd* pWndFrame, CWnd* pWndDoc);

#undef CString
	// GetMessage für Message-Zugriff
	// Diese Funktion überschreibt virtuelle CFrameWnd -
	// Funktion, deshalb auch "original" CString
	virtual void GetMessageString(UINT nID, CString& rMessage) const;
#define CString __X_CString

	// Weil überschriebene virtuelle const's nicht in const-
	// Member-Funktionen aufgerufen werden können, und weil
	// CString so nicht passt, gibt's eine static Funktion
	// stattdessen (der User merkt nix davon, als wäres
	// ne const-Basisklassen-Member-Funktion)
	// Hier ist CString schon wieder __X_CString
	static void GetMessageString(UINT nID, CString& rMessage);

protected:
	// Für Zugriff auf die Tool-Tip-Texte
	afx_msg BOOL OnToolTipText(UINT nID, 
		NMHDR* pNMHDR, LRESULT* pResult);

public:
	// Damit die ToolTip-Message empfangen werden kann
	virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,
		AFX_CMDHANDLERINFO* pHandlerInfo);

protected:
	// Damit der Message-Map funktioniert
	DECLARE_MESSAGE_MAP()
};

#endif

// *****************************************************************
// Überschreibe Klasse CWinApp (für Initialisation-Zugriff)
// *****************************************************************

class __X_CWinApp : public CWinApp
{
public:
	// Die Konstruktoren für Castings überschreiben
	__X_CWinApp(LPCTSTR lpszAppName = NULL) 
		: CWinApp(lpszAppName) {};

	// Weils die Basisklasse auch ist
	DECLARE_DYNCREATE(__X_CWinApp)

	// Damit der Init-Kram gemacht werden kann
//	virtual BOOL InitApplication();

	// Damit der Exit-Kram gemacht werden kann
	virtual int ExitInstance(); // return app exit code
	
	// Für den Automatic-Handler
//	afx_msg void __X_OnSwitchAutomatic();

	// Damit der Message-Map funktioniert
//	DECLARE_MESSAGE_MAP()
};

// *****************************************************************
// Damit AfxGetApp() auch funktioniert
// *****************************************************************

__X_CWinApp* __X_AfxGetApp();

// *****************************************************************
// Hilfsklassen für AfxMessageBox
// *****************************************************************

class __X_ClassAfxMessageBox
{
public:
	int DoTheBox(UINT nIDPrompt, UINT nType = MB_OK,
				UINT nIDHelp = (UINT)-1)
	{
		return AfxMessageBox(nIDPrompt, nType, nIDHelp);
	};

	int DoTheBox(LPCTSTR lpszText, UINT nType = MB_OK,
				UINT nIDHelp = 0)
	{
		return AfxMessageBox(lpszText, nType, nIDHelp);
	};
};

// *****************************************************************
// Überschreibe Win32 - Funktion LoadString
// *****************************************************************

int __X_LoadStringA(HINSTANCE hInstance, UINT uID, 
	LPSTR lpBuffer, int nBufferMax);

int __X_LoadStringW(HINSTANCE hInstance, UINT uID, 
	LPWSTR lpBuffer, int nBufferMax);

// *****************************************************************
// Überschreibe AfxMessageBox - Funktion
// *****************************************************************

int __X_AfxMessageBox(UINT nIDPrompt, UINT nType = MB_OK,
				UINT nIDHelp = (UINT)-1);

int __X_AfxMessageBox(LPCTSTR lpszText, UINT nType = MB_OK,
				UINT nIDHelp = 0);

// *****************************************************************
// Nun #define die MFC-Klassen um
// *****************************************************************

#define CString __X_CString

#define CFrameWnd __X_CFrameWnd

#define CMDIFrameWnd __X_CMDIFrameWnd

#define CMDIChildWnd __X_CMDIChildWnd

#define COleIPFrameWnd __X_COleIPFrameWnd

#define CWinApp __X_CWinApp

// *****************************************************************
// Nun #define die Afx-Funktionen um, wenn nötig
// *****************************************************************

#define AfxMessageBox __X_AfxMessageBox

#define AfxGetApp __X_AfxGetApp

// *****************************************************************
// Nun #define das Token LoadString um
// *****************************************************************

#define LoadStringA __X_LoadStringA
#define LoadStringW __X_LoadStringW

// *****************************************************************
// Spezieller Hack:
// Damit direkt instantiierte CChildFrame - Objekte funktionieren
// (d.h. auch hier die __X_ - Version genommen wird)
// *****************************************************************

// Sicherheit
#ifdef RUNTIME_CLASS
	
	// Erstmal Makro wieder deaktivieren
	#undef RUNTIME_CLASS

	// Auch MDICHildWnd ausschalten
	#undef CMDIChildWnd

	// So sieht das neue Makro aus:
	#define RUNTIME_CLASS(class_name) \
	( \
		/* Ist das die (falsche) Runtime-Class der echten MFC-Klasse ? */ \
		((void*)(&class_name::class##class_name) == (void*)(&CMDIChildWnd::classCMDIChildWnd)) ? \
		\
		/* Ja: Dann nimm einfach die der überschriebenen __X_CMDIChildWnd */ \
		((CRuntimeClass*)&(__X_CMDIChildWnd::class__X_CMDIChildWnd)) : \
		\
		/* Nein: Dann wie das normale RUNTIME_CLASS - Makro */ \
		((CRuntimeClass*)(&class_name::class##class_name)) \
	) \

	// MDIChildWnd wieder einschalten
	#define CMDIChildWnd __X_CMDIChildWnd

// Ende Sicherheit
#endif

// *****************************************************************
// Mehrfach-Include-Schutz-Ende
// *****************************************************************

#endif


