WEB开发网
开发学院软件开发VC 获得Win32窗口句柄的更好的方法 阅读

获得Win32窗口句柄的更好的方法

 2010-06-29 20:42:26 来源:WEB开发网   
核心提示:下面我们一步一步来分析实现过程,首先必须获取 IHTMLDocument2 接口:SPIHTMLDocument2 doc = GetHtmlDocument();SPIHTMLDocument2 与 CComQIPtr<IHTMLDocument2> 一样是一个指向 IHTMLDocument2 的ATL

下面我们一步一步来分析实现过程,首先必须获取 IHTMLDocument2 接口:

SPIHTMLDocument2 doc = GetHtmlDocument();

SPIHTMLDocument2 与 CComQIPtr<IHTMLDocument2> 一样是一个指向 IHTMLDocument2 的ATL智能指针,(当今 Windows 编程已进入 COM 时代,作为一名编写 Windows 应用程序的开发人员,如果你使用 COM 技术,但没有用过智能指针,那么这段代码会对你有所裨益),接着,必须创建一个SAFEARRAY,以便存放作为 BSTR 数组唯一元素的 HTML 串,SAFEARRAY是一个 COM 数据结构,其作用是在不同平台之间安全地传递数组数据,ATL提供了 CComBSTR 和 CComSafeArray 两个类,为开发人员在处理 BSTRs 和安全数组时减轻了许多痛苦:

// strHTML is LPCTSTR
CComSafeArray<VARIANT> sar;
sar.Create(1,0);
sar[0] = CComBSTR(strHTML);

如果不借助于 CComSafeArray 和 CComBSTR,而是用下列这些 API 函数来实现相同的处理,如 SafeArrayCreateVector,SafeArrayAccessData, 和 SafeArrayUnaccessData,那么至少还得写10-20行无聊的代码。一旦你上手了智能指针,你会觉得ATL的这些东西用起来真的很爽。

现在有了文档对象以及在安全数组中的内容,接下来便可以打开文档,进行写入操作,关闭文档等等。IHTMLDocument2::write需要 VARIANTS 和 BSTRs 类型的数据,这里ATL又一次显示了它的优势:

LPDISPATCH lpdRet;
doc->open(CComBSTR("text/html"), // MIME type
 CComVariant(CComBSTR("_self")), // open in same window
 CComVariant(CComBSTR("")),   // no features
 CComVariant((bool)1),      // replace history entry
 &lpdRet)); // IDispatch returned
doc->write(sar); // write it
doc->close(); // close
lpdRet->Release();

CHtmlCtrl::SetHTML 非常好用。使用它时有一个技巧:当第一次创建 CHtmlCtrl 时,它没有文档(GetHtmlDocument返回NULL)。所以在调用 CHtmlCtrl::SetHTML 之前,你必须创建一个文档,最简单的方法就是打开一个空文档,就象下面这样:

m_wndView.Navigate(_T("about:blank"));

此外,如果HTML很简单,你可以用 about: 代替 CHtmlCtrl::SetHTML 来得到HTML,如下面的代码:

m_wndView.Navigate(_T("about:<HTML><B>hello, world</B></HTML>"));

针对简单的HTML可以这么做,如果比较复杂的文档则要调用 SetHTML。本文附带的例子程序动态构造了一个包含图像、表格、链接等元素的HTML文档, 该文档列出所有顶层窗口的信息,然后将它们显示出来,如图一所示。

例子程序的参考代码如下:

//////////////////////////////////////
// HtmlApp.cpp
class CMyApp : public CWinApp {
public:
  virtual BOOL InitInstance();
protected:
  afx_msg void OnAppAbout();
  DECLARE_MESSAGE_MAP()
} theApp;
BEGIN_MESSAGE_MAP(CMyApp, CWinApp)
  ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
END_MESSAGE_MAP()
BOOL CMyApp::InitInstance()
{
  // Create main frame window (don''t use doc/view stuff)
  CMainFrame* pMainFrame = new CMainFrame;
  if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
   return FALSE;
  pMainFrame->ShowWindow(m_nCmdShow);
  pMainFrame->UpdateWindow();
  m_pMainWnd = pMainFrame;
  return TRUE;
}
//////////////////////////////////////////////////////
// “关于”对话框使用 HTML 控制显示内容.
//
class CAboutDialog : public CDialog {
protected:
  CHtmlCtrl m_page; // HTML control
  virtual BOOL OnInitDialog();
public:
  CAboutDialog() : CDialog(IDD_ABOUTBOX, NULL) { }
  DECLARE_DYNAMIC(CAboutDialog)
};
IMPLEMENT_DYNAMIC(CAboutDialog, CDialog)
///////////////////////
// 初始化“关于”对话框
//
BOOL CAboutDialog::OnInitDialog()
{
  // cmd map for CHtmlCtrl handles "app:ok"
  static HTMLCMDMAP AboutCmds[] = {
   { _T("ok"), IDOK },
   { NULL, 0 },
  };
  VERIFY(CDialog::OnInitDialog());
  VERIFY(m_page.CreateFromStatic(IDC_HTMLVIEW, this)); // create HTML
                            // ctrl
  m_page.SetHideContextMenu(TRUE); // hide context
                            // menu
  m_page.SetCmdMap(AboutCmds); // set command
                            // table
  m_page.LoadFromResource(_T("about.htm")); // load HTML from
                            // resource
  return TRUE;
}
/////////////////////
// 运行“关于”对话框
void CMyApp::OnAppAbout()
{
  static CAboutDialog dlg; // static to remember state of hyperlinks
  dlg.DoModal(); // run it
}
////////////////////////////////////////////////////////////////
// MainFrm.h
// 典型的主框架处理例程......
class CMainFrame : public CFrameWnd {
public:
  CMainFrame(){ }
  virtual ~CMainFrame() { }
protected:
  CHtmlCtrl  m_wndView; // CHtmlCtrl 作为主窗口视图
  CStatusBar m_wndStatusBar; // status line
  CToolBar  m_wndToolBar; // toolbar
  afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
  afx_msg void OnContextMenu(CWnd* pWnd, CPoint pos);
  // helper to format main window HTML
  CString FormatWindowListHTML();
  DECLARE_DYNCREATE(CMainFrame)
  DECLARE_MESSAGE_MAP()
};
////////////////////////////////////////////////////////////////
// MainFrm.cpp
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
  ON_WM_CREATE()
  ON_WM_CONTEXTMENU()
END_MESSAGE_MAP()
// Commmand map for app: commands in main window HTML.
HTMLCMDMAP MyHtmlCmds[] = {
  { _T("about"), ID_APP_ABOUT },
  { _T("exit"), ID_APP_EXIT },
  { NULL, 0 },
};
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  VERIFY(CFrameWnd::OnCreate(lpCreateStruct)==0);
  ...
  // create/init html control as view
  VERIFY(m_wndView.Create(CRect(), this, AFX_IDW_PANE_FIRST));
  m_wndView.SetHideContextMenu(TRUE); // 隐藏上下文菜单
  m_wndView.SetCmdMap(MyHtmlCmds); // 设置命令
  m_wndView.Navigate(_T("about:blank")); // 创建文档
  m_wndView.SetHTML(FormatWindowListHTML()); // 设置获取的HTML内容串
  SetActiveView(&m_wndView); // 设置MFC活动视图
  return 0;
}
///////////////////////////////////////////////////////////////////
// 处理上下文菜单的命令函数,当前该函数只是显示TRACE信息,以示被调用过。
//
void CMainFrame::OnContextMenu(CWnd* pWnd, CPoint pos)
{
  TRACE(_T("CMainFrame::OnContextMenu\n"));
}
//////////////////////////////////////////////////////////////////////
// 这个函数创建在主窗口视图中显示的 HTML。
// EnumWindows 回调该函数:如果窗口可见,则将窗口信息添加到 HTML table中。
//
static BOOL CALLBACK MyEnumWindowsProc(HWND hwnd, LPARAM lp)
{
  DWORD style = GetWindowLong(hwnd, GWL_STYLE);
  if (style & WS_VISIBLE) {
   CString& s = *(CString*)lp;
   char cname[256];
   GetClassName(hwnd, cname, sizeof(cname));
   TCHAR text[1024];
   GetWindowText(hwnd, text, sizeof(text)/sizeof(text[0]));
   CString temp;
   temp.Format(_T("<TR><TD>%p </TD><TD>%s</TD><TD>%s</TD></TR>\n"),
     hwnd, cname, text);
   s += temp;
  }
  return TRUE;
}
////////////////////////////////////////////////////////////////////////
// 该函数创建一个文本串,这个串就是要显示在主窗口的 HTML 文档。
CString CMainFrame::FormatWindowListHTML()
{
  // start w/top matter
  CString html = _T("<HTML><BODY STYLE=\"font-family:Verdana;\" \
  link=\"#02B7B7\" vlink=\"#02B7B7\">\n\
  <TABLE WIDTH=\"100%\">\n\
  <TR><TD VALIGN=top><A target=\"new\" HREF=\"http://www.vckbase.com\"><IMG \
  BORDER=0 ALT=\"VCKBASE Online Journal\" SRC=http://www.bianceng.cn/"res://AboutHtml3.exe/mlogo.gif\"></A></TD>\
  <TD COLSPAN=2><B>AboutHtml3 例子程序 -- 顶层可见窗口清单</B><BR>\n\
  <SMALL><A target=\"new\" \
  HREF=\"http://www.vckbase.com\"> VC知识库 </A></SMALL></TD></TR>\n\
  <TR><TD><B>窗口句柄(hwnd)</B></TD><TD><B>窗口类名</B></TD><TD WIDTH=75%><B>窗口标题</B>\
  </TD><TR>\n");

  // enumerate top-level windows to append their info
  EnumWindows(MyEnumWindowsProc, (LPARAM)&html);
  // append bottom matter. note commands app:about and app:exit
  html += _T("</TABLE>\n\
  <P><B>[<A HREF=\"app:about\">关于</A>] \
  [<A HREF=\"app:exit\">退出</A>]</B>\n\
  </BODY>\n\
  </HTML>");
  return html;
}

上一页  1 2 3 4 5  下一页

Tags:获得 Win 窗口

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接