在mfc编程中创建web风格的图形用户界面(二)

来源:互联网 发布:怎么开通淘宝卖家账号 编辑:程序博客网 时间:2024/05/07 19:32

html窗口事件处理

   CHtmlView类中缺少了什么?

   典型的程序处理脚本都是假定能够从程序界面的各个元素(比如按钮)中接收到事件或者数据输入。所以在我们的程序中,还需要解决html界面与MFC后台程序的信息交互问题。我们不必头疼,其实这个问题也并不复杂,我们可以利用CHtmlView类中的OnBeforeNavigate2函数把html界面中的事件传递给MFC后台代码进行处理。

   在html上同样存在事件这个概念。在dhtml中的可能出现的事件模型数量很多。

   html事件的发生可以转化为对window.navigate(%line%)的调用。MFC后台代码可以截获到OnBeforeNavigate2函数以参数%line%调用的消息。用参数%line%我们可以传递任何html上的参数给MFC后台代码,以便于程序处理相关的用户操作。比如说,当用户点击ok按钮的时候该事件会被传递给后台,同时,相应文本框中的内容也会传递给后台。以下是一个实例:

--网页中的代码--

...<SCRIPT LANGUAGE="JScript">function onBtnOk(){        var Txt = txtBox.value;   // the line from TextBox    window.navigate("app:1005@" + Txt);    // "app:1005@" – this is the MFC code command prefix.    // Txt – data can be transmitted along with the event.}</SCRIPT>;<BODY>...<input type=text style="width:50" id=txtBox ><input type=BUTTON value="Ok" onClick="onBtnOk()" style="width:45%">     // the button has an event handler – the onBtnOk() script function...</BODY></HTML>
--MFC后台的相应处理代码--
void CHtmlCtrl::OnBeforeNavigate2( LPCTSTR lpszURL,    DWORD nFlags,    LPCTSTR lpszTargetFrameName,    CByteArray& baPostedData,    LPCTSTR lpszHeaders,    BOOL* pbCancel ){    const char APP_PROTOCOL[] = "app:";    int len = _tcslen(APP_PROTOCOL);    if (_tcsnicmp(lpszURL, APP_PROTOCOL, len)==0) {        // there is a specific Application’s reaction there.        OnAppCmd(lpszURL + len);        // Event cancellation, otherwise an error will occur.        *pbCancel = TRUE;    }    CHtmlView::OnBeforeNavigate2(lpszURL, nFlags,               lpszTargetFrameName, baPostedData,               lpszHeaders, pbCancel);}
 

    因为除了html界面以外,MFC本身也有可能成为事件来源,所以必须有相应的MFC代码能够将数据传递给html界面。为了实现这个要求,我们可以采用一种办法,调用html中的脚本函数,将要传递的数据以参数的方式传递给这些函数。这个好主意是由 Eugene Khodakovsky 提出的。 

 

   下面是例子:

void CHtmlCtrl::OnDocumentComplete(LPCTSTR lpszURL) {...    HRESULT hr;        hr = GetHtmlDocument()->QueryInterface(IID_IHTMLDocument,                                         (void**) &m_pDocument);    if (!SUCCEEDED(hr))    {        m_pDocument= NULL;                return;    }     IDispatch *disp;    m_pDocument->get_Script( &disp);    // get script object...}

--用来调用html脚本函数并传递参数的MFC代码--

...    CStringArray strArray;        strArray.Add("Parameter 1");    strArray.Add("Parameter 2");    strArray.Add("Parameter 3");    // the call of "SetParameters" function    // from the script, (passing array of strings)    m_HtmlCtrl.CallJScript2("SetParameters", strArray);// inside the CallJScript2 function://    GetIDsOfNames() – get the ID number of the script function//    Invoke() – call the script-function by the number ...

   html脚本是一个强大而简单易用的工具,整个程序的界面和相应的用户操作响应都可以用它来完成。用这种web风格的界面方式使得编程变得更简单。这种方式将MFC对于用户界面事件的响应和处理转到对html脚本进行处理。html的编写和程序后台的编写分开进行有一个好处:即使改变了html代码,也可以避免对MFC程序代码进行重新编译。(这里需要说明一下,不用重新编译代码,但是link资源这个步骤还是需要重新进行一下的)

用CHtmlDialog类创建dialog窗口显示html

   除了主窗口之外,大部分应用程序还需要创建其它会话窗口。这些会话窗口也可能会需要设计十分复杂的界面,不仅仅是在外观上来说,还包括对于用户操作的响应也是一样繁杂。所以说,十分有必要在这些地方也使用dhtml来设计用户界面。关于如何使用CView的派生类显示会话窗口的内容,在msdn中 Paul DiLascia 已经为我们提供了解决方案。在前面对ChtmlView进行改进之后,我们现在又要用CView的派生类Chtmldialog来显示dialog窗口的内容。ChtmlClass将为我们解决两个问题:设置dialog窗口的名称和尺寸。具体参数将由html页面指出。 

   CHtmlDialog类的使用步骤:

   ♦ 将dialog插入资源文件中,并显示dialog界面中的静态元素(这些元素之后将被html的元素所取代),然后,创建一个mfc基类(派生于CDialog)。

   ♦ 在头文件中由CHtmlDialog中派生一个类(例如Dlg4.h)。

// inheriting the class from CHtmlDialog
class CDlg4 : public CHtmlDialog
{
// Construction
public:

   ♦ 在派生类CDlg4的构造函数运行时确保基类ChtmlDialog的构造函数先运行(例如Dlg4.cpp)。

CDlg4::CDlg4(CWnd* pParent /*=NULL*/)
    :CHtmlDialog(CDlg4::IDD,pParent,  IDR_HTML4,
         IDC_STATIC1) // the HTML page resource transmission
{
    //{{AFX_DATA_INIT(CDlg4)
        // NOTE: the ClassWizard will add member initialization here
    //}}AFX_DATA_INIT
}

    ChtmlDialog类还可以允许改变会话框的大小。请看下面的两副屏幕截图。

   看了之前的几篇笔记,似乎所有问题都解决了?不不,还有两个问题给我们留下一些小小的麻烦。

   1、在用窗口中显示出来的html格式界面的同时,通过函数SetWindowLong设置窗口的外部属性无法生效。

   2、当用户改变了IE的设置也就是说改变了html格式的显示设置之后,程序的界面就会发生变化。

   如果说第一个问题大部分人还能够容忍的话,第二个问题则是让我们无法接受。这将导致我们的程序在不同的用户IE设置下呈现出不同的外观。

    对于这第二个问题,当前,也已经有了更高级的解决方案,叫做Advanced Hosting Interfaces (AHI) 。Ethan Akhgari 为我们提供了很好的实例介绍这种更好的解决方案。

http://www.codeproject.com/dialog/web_gui.asp

译者“且听风吟”注:

本人翻译这篇高手之作为了将学习界面编程的好文章与大家分享,然而事与愿违的是本人的英文水平真的太有限,也许我的译文连自己都看不明白。所以这里附上原文地址:

原创粉丝点击