// MfcHostingAnAvalonControl.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "MfcHostingAnAvalonControl.h"
#include "MainFrm.h"

// DONE
using namespace System;
using namespace System::Windows;
using namespace System::Windows::Controls;
using namespace System::Windows::Interop;
using namespace System::Windows::Media;

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CMfcHostingAnAvalonControlApp

BEGIN_MESSAGE_MAP(CMfcHostingAnAvalonControlApp, CWinApp)
	ON_COMMAND(ID_APP_ABOUT, &CMfcHostingAnAvalonControlApp::OnAppAbout)
END_MESSAGE_MAP()


// CMfcHostingAnAvalonControlApp construction

CMfcHostingAnAvalonControlApp::CMfcHostingAnAvalonControlApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}


// The one and only CMfcHostingAnAvalonControlApp object

CMfcHostingAnAvalonControlApp theApp;


// CMfcHostingAnAvalonControlApp initialization

BOOL CMfcHostingAnAvalonControlApp::InitInstance()
{
	// InitCommonControlsEx() is required on Windows XP if an application
	// manifest specifies use of ComCtl32.dll version 6 or later to enable
	// visual styles.  Otherwise, any window creation will fail.
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	// Set this to include all the common control classes you want to use
	// in your application.
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);

	CWinApp::InitInstance();

	// Initialize OLE libraries
	if (!AfxOleInit())
	{
		AfxMessageBox(IDP_OLE_INIT_FAILED);
		return FALSE;
	}
	AfxEnableControlContainer();
	// Standard initialization
	// If you are not using these features and wish to reduce the size
	// of your final executable, you should remove from the following
	// the specific initialization routines you do not need
	// Change the registry key under which our settings are stored
	// TODO: You should modify this string to be something appropriate
	// such as the name of your company or organization
	SetRegistryKey(_T("Local AppWizard-Generated Applications"));
	// To create the main window, this code creates a new frame window
	// object and then sets it as the application's main window object
	CMainFrame* pFrame = new CMainFrame;
	if (!pFrame)
		return FALSE;
	m_pMainWnd = pFrame;
	// create and load the frame with its resources
	pFrame->LoadFrame(IDR_MAINFRAME,
		WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
		NULL);

	// The one and only window has been initialized, so show and update it
	pFrame->ShowWindow(SW_SHOW);
	pFrame->UpdateWindow();
	// call DragAcceptFiles only if there's a suffix
	//  In an SDI app, this should occur after ProcessShellCommand
	return TRUE;
}


// CMfcHostingAnAvalonControlApp message handlers




// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog {
public:
  CAboutDlg();

  // Dialog Data
  enum { IDD = IDD_ABOUTBOX };

public: // VS05b1 requires the delegate map to be public
  BEGIN_DELEGATE_MAP(CAboutDlg)
    EVENT_DELEGATE_ENTRY(okButton_Clicked, Object^, RoutedEventArgs^)
  END_DELEGATE_MAP()

protected:
  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  BOOL OnInitDialog();
  void okButton_Clicked(Object^ sender, RoutedEventArgs^ e);


  // Implementation
protected:
  DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

HwndSource^ CreateWpfOkButton(HWND hwndParent, int x, int y, int width, int height) {
  // Create a fancy WPF OK button
  Button^ wpfButton = gcnew Button();
  wpfButton->Content = "OK";
  //wpfButton->RenderTransform = gcnew RotateTransform(180.0, width / 2.0, height / 2.0);
  wpfButton->Background = gcnew LinearGradientBrush(Colors::White, Colors::Red, Point(0, 0), Point(1, 1));

  // Host the button in the border to fill in the background
  // using a dynamic resource so if the user changes the
  // window background color, our border changes with it
  Border^ wpfBorder = gcnew Border();
  //wpfBorder->Background = System::Windows::SystemColors::ControlBrush;
  wpfBorder->SetResourceReference(Border::BackgroundProperty, System::Windows::SystemColors::ControlBrushKey);
  wpfBorder->Child = wpfButton;

  // Host the border in an HwndSource and return the host
  HwndSourceParameters params;
  params.ParentWindow = IntPtr(hwndParent);
  params.WindowStyle = WS_CHILD | WS_VISIBLE;
  params.PositionX = x;
  params.PositionY = y;
  params.Width = width;
  params.Height = height;
  HwndSource^ src = gcnew HwndSource(params);
  src->RootVisual = wpfBorder;

  return src;
}

BOOL CAboutDlg::OnInitDialog() {
  // Get position of the native OK button relative to the about box
  HWND hwndParent = this->GetSafeHwnd();
  HWND hwndOkButton = ::GetDlgItem(hwndParent, IDOK);
  RECT rect = { 0 };
  ::GetWindowRect(hwndOkButton, &rect);
  ::MapWindowPoints(0, hwndParent, (POINT*)&rect, 2); // the violence inherent in the system...

  // Hide the native OK button
  ::ShowWindow(hwndOkButton, SW_HIDE);

  // Create and show the WPF button
  HwndSource^ srcWpfButton = CreateWpfOkButton(
    hwndParent,
    rect.left,
    rect.top,
    rect.right - rect.left,
    rect.bottom - rect.top);

  // Handle the Click event
  Button^ wpfButton = (Button^)((Border^)srcWpfButton->RootVisual)->Child;
  wpfButton->Click += MAKE_DELEGATE(RoutedEventHandler, okButton_Clicked);

  ::ShowWindow((HWND)srcWpfButton->Handle.ToPointer(), SW_SHOW);
  return TRUE;
}

void CAboutDlg::okButton_Clicked(Object^ sender, RoutedEventArgs^ e) {
  this->OnOK();
}


void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()

// App command to run the dialog
void CMfcHostingAnAvalonControlApp::OnAppAbout()
{
	CAboutDlg aboutDlg;
	aboutDlg.DoModal();
}


// CMfcHostingAnAvalonControlApp message handlers

