MFC / Javascripts / CSS Integrations

Nowadays it feels like everywhere and everyone is using HTML. So why not use it for building a MFC based application by using lesser and lesser MFC dialogs.
Lets start by creating a MFC application using visual studio any version is fine.
Open up visual studio as below, and create a new MFC based application :
Image
Proceed to next and select a dynamic build if you plan to do so:
Important select Dialog based and use HTML dialog:
Image
Keep clicking next and then click finish. your project should open up:
when you build this project, you should be getting this:
Image
Now you can edit your html file as you wish and add CSS documents.
Open up the html file present in the project. Edit it according to whatever you want.
Now lets consider you want to use additional javascripts and css files for this project.
If you just try to write “css/main.css” and link it in your html file, you wont be able to dot it. since the HTML file is compiled into the MFC dialog. We need to do it as below:
First for the CSS, open up the .rc file in your project and define as below:
[sourcecode language=”html”]
<strong>
</strong>CSS_MAIN HTML "css/main.css"
CSS_NANO HTML "css/nanoscroller.css"
Now goto your html file and link this as below :
&lt;link rel="stylesheet" type="text/css" href="CSS_MAIN" /&gt;
For java script do the same:
&lt;script type="text/javascript" src="JS_EXTBASE"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="JS_EXTALL"&gt;&lt;/script&gt;
JS_EXTBASE HTML "js/ext-base.js"
JS_EXTALL HTML "js/ext-all.js"
[/sourcecode]
 
[sourcecode language=”cpp”]</strong>
For images the same should be done. In short all the link should be defined in the .rc file. Then only your CSS and javascripts will get detected.
Now comes the main part, where you need to pass data between javascript and C++. We need to use window.navigate and call that function in C++.
// this is inside javascript file
window.navigate(‘buttonPressedReport’)
<pre><code>
Now we need to map the clicks between javascripts and c++. We do this by opening up the testDlg.cpp in the searching for BEGIN_MESSAGE_MAP
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
Open up this and type the following :
BEGIN_EVENTSINK_MAP(CMFC_GUIDlg, CDHtmlDialog)
ON_EVENT(CMFC_GUIDlg, AFX_IDC_BROWSER, 250 /* BeforeNavigate2 */, _HandleJavascriptCalls /* this is the name of the function you should be defining to handle your calls from javascript*/ , VTS_DISPATCH VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PBOOL)
END_EVENTSINK_MAP()
CTestDialog::_HandleJavascriptCalls(LPDISPATCH pDisp, VARIANT FAR* URL, VARIANT FAR* Flags, VARIANT FAR* TargetFrameName, VARIANT FAR* PostData, VARIANT FAR* Headers, BOOL FAR* Cancel)
{
if(url == "") // handle specific calls
}
<strong> </strong>
This should do the work for you. In the next post, I will explain how to call Javascripts from C++.
The source code is as below :
// *************************************************************************************************************
// test3Dlg.cpp : implementation file
//
#include "stdafx.h"
#include <iostream>
#include "test3.h"
#include "test3Dlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
using namespace std;
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// Ctest3Dlg dialog
BEGIN_DHTML_EVENT_MAP(Ctest3Dlg)
DHTML_EVENT_ONCLICK(_T("ButtonOK"), OnButtonOK)
DHTML_EVENT_ONCLICK(_T("ButtonCancel"), OnButtonCancel)
END_DHTML_EVENT_MAP()
BEGIN_EVENTSINK_MAP(Ctest3Dlg, CDHtmlDialog)
ON_EVENT(Ctest3Dlg, AFX_IDC_BROWSER, 250 /* BeforeNavigate2 */, _jsCalledCpp,
VTS_DISPATCH VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PBOOL)
END_EVENTSINK_MAP()
Ctest3Dlg::Ctest3Dlg(CWnd* pParent /*=NULL*/)
: CDHtmlDialog(Ctest3Dlg::IDD, Ctest3Dlg::IDH, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void Ctest3Dlg::DoDataExchange(CDataExchange* pDX)
{
CDHtmlDialog::DoDataExchange(pDX);
}
void Ctest3Dlg::_jsCalledCpp(LPDISPATCH pDisp, VARIANT FAR* URL, VARIANT FAR* Flags,
VARIANT FAR* TargetFrameName, VARIANT FAR* PostData, VARIANT FAR* Headers, BOOL FAR* Cancel)
{
//std::cout<<"test in jscalledcpp "<<std::endl;
CString str(V_BSTR(URL));
std::wstring url = (LPCTSTR)str;
if(url.find(L"testthis") != -1)
{
MessageBox(L"In CPP ", L"in cpp", MB_OK);
}else
MessageBox(L"No testthis called ", L"in cpp", MB_OK);
}
BEGIN_MESSAGE_MAP(Ctest3Dlg, CDHtmlDialog)
ON_WM_SYSCOMMAND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// Ctest3Dlg message handlers
BOOL Ctest3Dlg::OnInitDialog()
{
CDHtmlDialog::OnInitDialog();
// Add "About…" menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application’s main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void Ctest3Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDHtmlDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void Ctest3Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() – cxIcon + 1) / 2;
int y = (rect.Height() – cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDHtmlDialog::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR Ctest3Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
HRESULT Ctest3Dlg::OnButtonOK(IHTMLElement* /*pElement*/)
{
OnOK();
return S_OK;
}
HRESULT Ctest3Dlg::OnButtonCancel(IHTMLElement* /*pElement*/)
{
OnCancel();
return S_OK;
}
***********************************************************************************************************
// test3Dlg.h : header file
//
#pragma once
// Ctest3Dlg dialog
class Ctest3Dlg : public CDHtmlDialog
{
// Construction
public:
Ctest3Dlg(CWnd* pParent = NULL); // standard constructor
void _jsCalledCpp(LPDISPATCH pDisp, VARIANT FAR* URL, VARIANT FAR* Flags, VARIANT FAR* TargetFrameName, VARIANT FAR* PostData, VARIANT FAR* Headers, BOOL FAR* Cancel);
// Dialog Data
enum { IDD = IDD_TEST3_DIALOG, IDH = IDR_HTML_TEST3_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
HRESULT OnButtonOK(IHTMLElement *pElement);
HRESULT OnButtonCancel(IHTMLElement *pElement);
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
DECLARE_DHTML_EVENT_MAP()
DECLARE_EVENTSINK_MAP()
};
<strong>[/sourcecode]
**********************************************************************************************************
[sourcecode language=”html”]
&lt;HTML&gt;
&lt;HEAD&gt;
&lt;/HEAD&gt;
&lt;script type="text/javascript"&gt;
function btnPressed()
{
window.navigate("testthis");
}
&lt;/script&gt;
&lt;BODY ID=Ctest3Dlg BGCOLOR=LIGHTGREY&gt;
&lt;TABLE WIDTH=100%&gt;
&lt;TR&gt;
&lt;TD ALIGN=RIGHT&gt;
&lt;BUTTON STYLE="WIDTH:100" ID="ButtonOK"&gt;OK&lt;/BUTTON&gt;&lt;BR&gt;
&lt;BUTTON STYLE="WIDTH:100" ID="ButtonCancel"&gt;Cancel&lt;/BUTTON&gt;
&lt;BUTTON onclick=btnPressed()&gt;click here&lt;/BUTTON&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR WIDTH=100% HEIGHT=75&gt;
&lt;TD ALIGN=CENTER VALIGN=BOTTOM&gt;
TODO: Place controls here.
&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TABLE&gt;
&lt;/BODY&gt;
&lt;/HTML&gt;
***************************************************************************
[/sourcecode]
good luck.,

In

Leave a Reply

Your email address will not be published. Required fields are marked *