2409wtl,网浏包装

原文

介绍

本教程帮助你用IE引擎构建一个基于WTL,并使用我编写的处理IWebBrowser2接口包装类的迷你浏览器.

因为知道代码可能很难读,因此本教程帮助你逐步开发一个迷你浏览器.

背景

大部分都与互联网浏览有关.我常用超文本视图使用SDI.

有时,我要用真正的浏览器函数,因此我为IWebBrowser2编写了一个包装器.

包装类可处理在IE中嵌入的窗口.它还可非常简单处理事件沉(如:OnDocumentComplete).

创建新项

首先创建一个新的WTL项.我假设你已安装了WTL文件.在向导的第一页上,选择一个SDI应用,并勾选生成.CPP文件.

在第二页上,按超文本视图更改默认视图.

第一步是编辑stdafx.h.请包括atlmisc.h(会不时使用CString)和atlctrlx.h(CMultiPaneStatusBarCtrl).

还需要注释掉_ATL_DLL定义(不想可执行文件依赖atl.dll)并按5版本更改IE版本.

//更改这些值以使用不同版本
#define WINVER      0x0400
//`#define_WIN32_WINNT0x0400`
#define _WIN32_IE   0x0500
#define _RICHEDIT_VER   0x0100//这是在`ATL7`中`管理`浏览器所必需的
//#define _ATL_DLL#include <atlbase.h>
#include <atlapp.h>
extern CAppModule _Module;
#include <atlcom.h>
#include <atlhost.h>
#include <atlwin.h>
#include <atlctl.h>
#include <atlmisc.h>//..
#include <atlframe.h>
#include <atlctrls.h>
#include <atldlgs.h>
#include <atlctrlw.h>
#include <atlctrlx.h>//..
//`{{AFX_INSERT_LOCATION}}MicrosoftVisualC++`插入在上一行前立即其他声明.

更新视图

视图类中,需要包含browser.h,并从它继承视图类.还需要链接它到消息映射,这样该类可处理多条消息(WM_CREATE,WM_DESTROY).

#include "browser.h"
class CWTLBrowserView : public CWindowImpl<CWTLBrowserView, CAxWindow>,public CWebBrowser2<CWTLBrowserView>//..
{
public:DECLARE_WND_SUPERCLASS(NULL, CAxWindow::GetWndClassName())BOOL PreTranslateMessage(MSG* pMsg);BEGIN_MSG_MAP(CWTLBrowserView)CHAIN_MSG_MAP(CWebBrowser2<CWTLBrowserView>)//..END_MSG_MAP()//处理器原型(如果需要,请取消注释参数):`LRESULTMessageHandler(UINT/*uMsg*/,WPARAM/*wParam*/,LPARAM/*lParam*/,BOOL&/*bHandled*/)LRESULTCommandHandler(WORD/*wNotifyCode*/,WORD/*wID*/,HWND/*hWndCtl*/,BOOL&/*bHandled*/)LRESULTNotifyHandler(int/*idCtrl*/,LPNMHDR/*pnmh*/,BOOL&/*bHandled*/)`
};

创建菜单

要在菜单中添加一些新项.典型的浏览器处理back,forward,home,stop(后退,前进,主页,停止)刷新.在菜单和工具栏添加这些命令.

因为有时禁止使用某些项,因此需要处理它们的UI(不能总是使用后退和前进).首先,要在UI更新映射中(在mainfrm.h中)添加它们.

UPDATE_ELEMENT(ID_VIEW_GOTO_BACK, UPDUI_MENUPOPUP|UPDUI_TOOLBAR)
UPDATE_ELEMENT(ID_VIEW_GOTO_FORWARD, UPDUI_MENUPOPUP|UPDUI_TOOLBAR)

通过OnIdle函数更新它们.

UIEnable(ID_VIEW_GOTO_BACK,m_view.CanBack());
UIEnable(ID_VIEW_GOTO_FORWARD,m_view.CanForward());

CWebBrowser2公开了2个函数(CanBackCanForward),可确定后退和前进动作的状态.

因为默认向导microsoft.com启动,因此需要将按about:blank更改代码,并从正常主页开始.需要更改CMainFrame::OnCreate中的代码.

m_hWndClient = m_view.Create(m_hWnd, rcDefault,_T("about:blank"),WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |WS_HSCROLL | WS_VSCROLL, WS_EX_CLIENTEDGE);
.
.
.
m_view.GoHome();
return 0;

创建地址栏

现在有个工作帧,但仍无法在那里输入URL!为此,创建一个用户可输入URL浏览的地址栏.给主框架添加新的叫m_URL(CEdit)成员变量.

CMainFrame::OnCreate创建并初化它.因为还想地址栏自动补全,因此在编辑控件上使用了SHAutoComplete函数.

CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
AddSimpleReBarBand(hWndCmdBar);
AddSimpleReBarBand(hWndToolBar, NULL, TRUE);
CString szAddress;//<<
szAddress.LoadString(IDS_ADDRESS);
m_URL.Create(m_hWnd,CRect(0,0,0,18),NULL,WS_CHILD|WS_VISIBLE,WS_EX_STATICEDGE);
AddSimpleReBarBand(m_URL,szAddress.GetBuffer(0),TRUE);
m_URL.SetFont(AtlGetDefaultGuiFont());
SHAutoComplete(m_URL,SHACF_URLALL);//>>CreateSimpleStatusBar();

如果试编译项,则在链接文件时会出现错误.出现此错误的原因是SHAutoComplete是从shlwapi.dll导出的.要解决它,需要链接(shlwapi.lib)库.

编译项后,看到新的编辑栏等待输入.但是,嘿!如果试按回车键,浏览器只会一直休息!来修复它!

浏览

因为超文本框架把所有键击转发超文本文档,因此不能只等待WM_CHAR消息.需要在预翻译消息函数中添加一些代码.

需要从地址栏中取WM_CHAR消息并处理VK_RETURN符.

BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{if(CFrameWindowImpl<CMainFrame>::PreTranslateMessage(pMsg))return TRUE;if (pMsg->message==WM_CHAR && m_URL==pMsg->hwnd){switch (pMsg->wParam){case VK_RETURN:{CString szURL;int nLength=m_URL.GetWindowTextLength();m_URL.GetWindowText(szURL.GetBuffer(nLength),nLength+1);szURL.ReleaseBuffer();m_view.Navigate(szURL);return TRUE;}}return FALSE;}return m_view.PreTranslateMessage(pMsg);
}

命令

现在,可输入URL并浏览它,来观察浏览器.但仍缺少.不可使用back,forward其他新命令?在主框架类中需要添加它们的函数.

调整UI

测试一下浏览器.试转到http://www.codeproject.com/并点击WTL部分.为什么在地址栏中看不到新位置,要修复它,需要在每次更改位置更新地址栏.

一个好地方是处理视图类中的OnNavigateComplete2.因为需要更新,在主框架类中保存的m_URL,因此在视图类中创建它的新引用,并给构造器传递变量.
现在,可处理消息更新地址栏.

void CWTLBrowserView::OnNavigateComplete2(IDispatch* pDisp, const String& szURL)
{m_URL.SetWindowText(GetLocationURL());
}

另一个有用调整包括进度通知,安全图标状态栏文本.它们都在状态栏上.该推出CMultiPaneStatusBarCtrl!

主框架类中创建一个新变量,并在视图类中创建一个引用.状态栏应包含3个部分:默认文本,安全图标和进度通知.

因为默认文本有唯一的ID(ID_DEFAULT_PANE),因此只需要创建另外两个标识.在"View->ResourceSymbols"菜单中,需要创建新符号:IDR_LOCKIDR_PROGRESS.

创建它们后,可从CMainFrame::OnCreate函数初化新状态栏.

CreateSimpleStatusBar();
m_StatusBar.SubclassWindow(m_hWndStatusBar);
int nPanes[]={ID_DEFAULT_PANE,IDR_LOCK,IDR_PROGRESS};
m_StatusBar.SetPanes(nPanes,sizeof(nPanes)/sizeof(int),false);
m_StatusBar.SetPaneWidth(IDR_LOCK,30);
m_StatusBar.SetPaneWidth(IDR_PROGRESS,50);

还需要给项添加新(IDI_LOCK)图标,并在(m_hSecured)变量中加载它.为了正确更新UI,在UI更新映射中添加一行新行:

UPDATE_ELEMENT(0, UPDUI_STATUSBAR)

视图类中,添加一个新的(m_bSecured)变量和一些代码来处理更新状态栏:

void CWTLBrowserView::OnStatusTextChange(const String& szText)
{m_StatusBar.SetPaneText(ID_DEFAULT_PANE,szText);
}
void CWTLBrowserView::OnProgressChange(long nProgress, long nProgressMax)
{CString szText;if (nProgressMax>0)szText.Format(_T("%d%%"),nProgress*100/nProgressMax);m_StatusBar.SetPaneText(IDR_PROGRESS,szText);
}
void CWTLBrowserView::OnSetSecureLockIcon(long nSecureLockIcon)
{m_bSecured=nSecureLockIcon>0;
}

最后,需要给CMainFrame::OnIdle添加一些代码:

m_StatusBar.SetPaneIcon(IDR_LOCK,m_view.IsSecured()? m_hSecured : NULL);
UIUpdateToolBar();
UIUpdateStatusBar();
return FALSE;

文件命令

要允许浏览器保存和打印文件,需要处理文件消息.要给浏览器发送命令,要用ExecWB函数.要(对UI映射)查询命令状态,可用QueryStatusWB函数.

为了保存/打印,需要添加适当的函数,更新UI更新映射,并在OnIdle函数处理它们的UI.

编辑命令

编辑命令是一个特例.因为可与浏览器地址栏一起使用,因此需要在每次使用这些命令时检查焦点窗口.
首先,在UI更新映射中添加它们,然后通过OnIdle函数处理更新:

if (GetFocus()==m_URL)
{DWORD dwSelection=m_URL.GetSel();BOOL bEnable=HIWORD(dwSelection)!=LOWORD(dwSelection);UIEnable(ID_EDIT_CUT,bEnable);UIEnable(ID_EDIT_COPY,bEnable);if (m_URL.OpenClipboard()){UIEnable(ID_EDIT_PASTE,IsClipboardFormatAvailable(CF_TEXT));CloseClipboard();}elseUIEnable(ID_EDIT_PASTE,FALSE);UIEnable(ID_EDIT_UNDO,m_URL.CanUndo());
}
else
{UIEnable(ID_EDIT_CUT,m_view.QueryStatusWB(OLECMDID_CUT) & OLECMDF_ENABLED);UIEnable(ID_EDIT_COPY,m_view.QueryStatusWB(OLECMDID_COPY) & OLECMDF_ENABLED);UIEnable(ID_EDIT_PASTE,m_view.QueryStatusWB(OLECMDID_PASTE) & OLECMDF_ENABLED);UIEnable(ID_EDIT_UNDO,m_view.QueryStatusWB(OLECMDID_UNDO) & OLECMDF_ENABLED);
}

还需要在执行实际命令区分它们:

LRESULT CMainFrame::OnEditCut(WORD /*`wNotifyCode`*/, WORD /*`wID`*/, HWND /*`hWndCtl`*/, BOOL& /*b已处理*/)
{if (GetFocus()==m_URL)m_URL.Cut();elsem_view.ExecWB(OLECMDID_CUT,OLECMDEXECOPT_DONTPROMPTUSER,NULL,NULL);return 0;
}
LRESULT CMainFrame::OnEditCopy(WORD /*`wNotifyCode`*/, WORD /*`wID`*/, HWND /*`hWndCtl`*/, BOOL& /*b已处理*/)
{if (GetFocus()==m_URL)m_URL.Copy();elsem_view.ExecWB(OLECMDID_COPY,OLECMDEXECOPT_DONTPROMPTUSER,NULL,NULL);return 0;
}
LRESULT CMainFrame::OnEditPaste(WORD /*`wNotifyCode`*/, WORD /*`wID`*/, HWND /*`hWndCtl`*/, BOOL& /*b已处理*/)
{if (GetFocus()==m_URL)m_URL.Paste();elsem_view.ExecWB(OLECMDID_PASTE,OLECMDEXECOPT_DONTPROMPTUSER,NULL,NULL);return 0;
}
LRESULT CMainFrame::OnEditUndo(WORD /*`wNotifyCode`*/, WORD /*`wID`*/, HWND /*`hWndCtl`*/, BOOL& /* b已处理*/)
{if (GetFocus()==m_URL)m_URL.Undo();elsem_view.ExecWB(OLECMDID_UNDO,OLECMDEXECOPT_DONTPROMPTUSER,NULL,NULL);return 0;
}

见,wtlbrowser_demo.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/419541.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

搭建Docker私有仓库管理本地的Docker镜像,通过harbor实现Web UI访问和管理私有仓库

要在本地搭建一个Docker私有仓库&#xff0c;你可以按照以下步骤进行设置&#xff1a; 安装Docker 确保你已经安装了Docker。如果还没有安装&#xff0c;可以按照官方指南进行安装&#xff1a; 对于Ubuntu系统&#xff0c;你可以运行以下命令来安装Docker&#xff1a; sudo ap…

十一、C语言:字符串函数

目录 一、strlen 二、strcpy 三、strcat 四、strcmp 五、strstr 六、strtok 七、strerror 一、strlen 注意&#xff1a;strlen()函数的返回值是size_t&#xff0c;两个size_t相减仍为无符号数 int main() {char arr[10] "abc";char brr[10] "abc123&quo…

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆&#xff0c;该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使…

【数据结构与算法 | 灵神题单 | 删除链表篇】力扣3217, 82, 237

总结&#xff0c;删除链表节点问题使用到列表&#xff0c;哈希表&#xff0c;递归比较容易超时&#xff0c;我觉得使用计数排序比较稳&#xff0c;处理起来也不是很难。 1. 力扣3217&#xff1a;从链表中移除在数组中的节点 1.1 题目&#xff1a; 给你一个整数数组 nums 和一…

【Linux】应用层http协议

一、HTTP协议 1.1 简要介绍一下HTTP 我们在网络的应用层中可以自己定义协议&#xff0c;但是&#xff0c;已经有大佬定义了一些现成的&#xff0c;非常好用的应用层协议&#xff0c;供我们直接使用&#xff0c;HTTP&#xff08;超文本传输协议&#xff09;就是其中之一。 在互…

yolo算法小结

文章目录 yolov1工作原理限制 yolov2网络结构改进点 yolov3改进点 yolov4网络结构图改进点 yolov5改进点 参考资料 YOLO的核心思想是将物体检测视为一个回归问题&#xff0c;它不采用传统的区域提议方法&#xff0c;而是通过单一的神经网络对整个图像进行预测。这意味着YOLO只需…

C/C++两点坐标求距离以及C++保留两位小数输出,秒了

目录 1. 前言 2. 正文 2.1 问题 2.2 解决办法 2.2.1 思路 2.2.2 代码实现 3. 备注 1. 前言 依旧是带来一个练手的题目&#xff0c;目的就一个&#xff0c;方法千千万&#xff0c;通向终点的方式有很多种&#xff0c;没有谁与谁&#xff0c;我们都是为了成为更好的自己。…

使用亚马逊Bedrock的Stable Diffusion XL模型实现文本到图像生成:探索AI的无限创意

引言 什么是Amazon Bedrock&#xff1f; Amazon Bedrock是亚马逊云服务&#xff08;AWS&#xff09;推出的一项旗舰服务&#xff0c;旨在推动生成式人工智能&#xff08;AI&#xff09;在各行业的广泛应用。它的核心功能是提供由顶尖AI公司&#xff08;如AI21 Labs、Anthropic…

python中的循环结构

注意&#xff1a;range&#xff08;&#xff09;函数 累加和&#xff1a; 注意&#xff1a;if 下面如果有好几行&#xff0c;只执行一行 print必须和 for 开头相同格数 例题&#xff1a;水仙花数 注意在print语句中&#xff0c;一句好“ 。。。。。 ”后面必须有逗号然后再写变…

C++(一)----C++基础

1.C的发展史 C语言诞生后&#xff0c;很快普及使用&#xff0c;但是随着编程规模增大且越来越复杂&#xff0c;并且需要高度的抽象和建模时&#xff0c;C语言的诸多短板便表现了出来&#xff0c;为了解决软件危机&#xff0c;上世纪八十年代&#xff0c;计算机界提出了oop&…

linux top命令介绍以及使用

文章目录 介绍 top 命令1. top 的基本功能2. 如何启动 top3. top 的输出解释系统概况任务和 CPU 使用情况内存和交换空间进程信息 4. 常用操作 总结查看逻辑CPU的个数查看系统运行时间 介绍 top 命令 top 是一个在类 Unix 系统中广泛使用的命令行工具&#xff0c;用于实时显示…

WebGL系列教程二(环境搭建及初始化Shader)

目录 1 前言2 新建html页面3 着色器介绍3.1 顶点着色器、片元着色器与光栅化的概念3.2 声明顶点着色器3.3 声明片元着色器 4 坐标系(右手系)介绍5 着色器初始化5.1 给一个画布canvas5.2 获取WebGL对象5.3 创建着色器对象5.4 获取着色器对象的源5.5 绑定着色器的源5.6 编译着色器…

ChatGPT 3.5/4.0使用手册:解锁人工智能的无限潜能

1. 引言 在人工智能的浪潮中&#xff0c;ChatGPT以其卓越的语言理解和生成能力&#xff0c;成为了一个革命性的工具。它不仅仅是一个聊天机器人&#xff0c;更是一个能够协助我们日常工作、学习和创造的智能伙伴。随着ChatGPT 3.5和4.0版本的推出&#xff0c;其功能和应用范围…

windows电脑自动倒计时关机

今天聊一聊其他的。我时不时的有一个需求&#xff0c;是关于在windows电脑上定时关机。 不知道怎么地&#xff0c;我好几次都忘了这个自动定时关机的终端命令&#xff0c;于是每一次都要去网上查。 1.鼠标右击【开始菜单】选择【运行】或在键盘上按【 WinR】快捷键打开运行窗口…

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大&#xff0c;需要补充太多的知识点&#xff0c;教授讲得内容跨越较大&#xff0c;一般一节课的内容是书本上的一章节内容&#xff0c;所以看视频比较吃力&#xff0c;需要先预习课本内容后才能够很好的理解教授讲…

网络学习-eNSP配置VRRP

虚拟路由冗余协议(Virtual Router Redundancy Protocol&#xff0c;简称VRRP) VRRP广泛应用在边缘网络中&#xff0c;是一种路由冗余协议&#xff0c;它的设计目标是支持特定情况下IP数据流量失败转移不会引起混乱&#xff0c;允许主机使用单路由器&#xff0c;以及即使在实际…

模版的价值工程

我们在做什么 工作吗 最终不过是在做模版工程模版&#xff0c;最终会进化 沦为后世的参考文档。仅此而已&#xff01; 或者已经沦为了文档类别 其他&#x1f4c4; 最终我们会选择EXIT 指令 尽快它是 window桌面 我们只是图像 人字&#x1f31f;的&#x1f9a3; &#x1f631;…

leveldb源码剖析(二)——LSM Tree

LSM Tree LSM Tree&#xff1a;Log-Structured Merge Tree&#xff0c;日志结构合并树。是一种频繁写性能很高的数据结构。 LSM Tree将写入操作与合并操作分离&#xff0c;数据首先写入磁盘中的日志文件&#xff08;WAL&#xff09;&#xff0c;随后写入内存缓存&#xff0c;…

Adobe After Effects的插件--------CC Particle World

CC Particle World是一个粒子效果器,用于在三维空间中生成和模拟各种粒子系统,包括火焰、雨、雪、爆炸、烟雾等等。它会自动随时间变化发射粒子。 本文部分参照 https://www.163.com/dy/article/IEJVDN760536FE6V.html 使用条件 使用该插件的图层需是2D图层。 我们新建一个…

Matlab simulink建模与仿真 第十一章(端口及子系统库)【上】

参考视频&#xff1a;simulink1.1simulink简介_哔哩哔哩_bilibili 一、端口及子系统库中的模块概览 注&#xff1a;In模块、Out模块和Subsystem模块在第二章中均有介绍&#xff0c;本章不再赘述&#xff1b;Subsystem Examples子系统实例模块也不进行介绍。 二、使能及其子模…