(200分求解)在Form中加入一个TCppWebBrowser,如果获得它的消息或事件啊

gloom 2002-10-24 03:11:34
在Form中使用TCppWebBrowser,除了DoucmentCompelete等之外,如果获得文档的Mouse事件(消息)或KeyBoard事件。
此题200分求解,为避免无解而浪费可用分,先放50,一旦得解,决不食言
...全文
172 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
gk0205 2002-12-19
  • 打赏
  • 举报
回复
收藏呀,精彩就是看不懂
gloom 2002-11-09
  • 打赏
  • 举报
回复
这个问题不能算是完全解决了,但我也收获不少,非常感谢BCB_Fans兄的帮助
bcb_fans 2002-11-07
  • 打赏
  • 举报
回复
最好检测一下

handle=FindWindowEx(handle,NULL,"Internet Explorer_Server",NULL);

的返回值,看看是否为NULL。

============

如果网页中含有Frame,这种方法无法判断网页是否真正下载完成!
gloom 2002-11-07
  • 打赏
  • 举报
回复
不好意思,我的代友贴错了,应该是
//---------------------------------------------------------------------------

void __fastcall TForm1::WebDocumentComplete(TObject *Sender,
LPDISPATCH pDisp, Variant *URL)
{
handle=Web->Handle;
handle=FindWindowEx(handle,NULL,"Shell DocObject View",NULL);
handle=FindWindowEx(handle,NULL,"Internet Explorer_Server",NULL);
pCanvas->Handle =GetWindowDC(handle);
::SetFocus(handle);
//DrawBtn->Enabled =true;
//this->Cursor =crAppStart;
FOldAppProc = (FARPROC)GetWindowLong(handle, GWL_WNDPROC);
FNewAppObjectInstance = MakeObjectInstance(NewAppProc);
SetWindowLong(handle, GWL_WNDPROC, long(FNewAppObjectInstance));
}
bcb_fans 2002-11-07
  • 打赏
  • 举报
回复
我看只能自己实现IDispatch接口了,不然怎么接受事件!?

但是不是调用元素的put_onEvent(...)来设置事件句柄,而是调用IHTMLDocument2的put_mousedown(...)来设置。

你自己先试一下,我也没有编写过这方面的程序。BHO倒是编过,只是在BHO里边接受的事件是诸如OnBeforeNavigate2这种事件,跟你的要求不一样。

如果实在不行,我再试试。
gloom 2002-11-07
  • 打赏
  • 举报
回复
谢谢BCB_FANS兄的热心帮助,我已将分值加到200分,再请问一下,我想知道某个消息(事件)具体是由哪个元素发出的,在IHTMLEventObj有个get_srcElement的方法可以获得,但现在这种处理消息过程无法获得IHTMLEventObj接口,我是否可以用IHTMLElement接口的put_onmousedown(VARIANT v)或类似的函数,这个好像可以更改事件的处理函数,不知道如何使用,在MSDN上说的不是很明白
pBody->put_onEvent( &_variant_t(pDisp) );
// pDisp a pointer to an IDispatch interface
// pBody a pointer to an element of interest
是不是要自己实现IDispatch接口,在Invoke中写事件处理代码,再用此函数将事件与自己的接口关联起来?
gloom 2002-11-06
  • 打赏
  • 举报
回复
另:BCB_Fans兄,你在截获WM_Paint画图时无法显示是正常的,因为你没有截获WM_NCPAINT,这个也会重绘,我对这两个消息都处理就正常。但我不知道为什么不能获得鼠标消息,
//WebBrowser的DoucmentComplete事件
void __fastcall TForm1::WebDocumentComplete(TObject *Sender,
LPDISPATCH pDisp, Variant *URL)
{
AnsiString str="";
switch (Message.Msg)
{
case WM_LBUTTONDOWN:
str="LButtonDown";
break;
case WM_LBUTTONUP:
str="LButtonUp";
break;
case WM_MOUSEMOVE:
str="MouseMove";
break;
case WM_NCPAINT:
CallWindowProc(FOldAppProc,handle,Message.Msg,Message.WParam,Message.LParam);
pCanvas->MoveTo(20,40);
pCanvas->LineTo(100,200);
return;
case WM_PAINT:
CallWindowProc(FOldAppProc,handle,Message.Msg,Message.WParam,Message.LParam);
pCanvas->MoveTo(20,40);
pCanvas->LineTo(100,200);
return;
default:
return;
}
str+=":"+IntToStr(Message.WParam)+":"+IntToStr(Message.LParam);
Memo1->Lines->Add(str);
return ;
}
//自定义的窗口过程
void __fastcall TForm1::NewAppProc(TMessage& Message)
{
AnsiString str="";
switch (Message.Msg)
{
case WM_LBUTTONDOWN:
str="LButtonDown";
break;
case WM_LBUTTONUP:
str="LButtonUp";
break;
case WM_MOUSEMOVE:
str="MouseMove";
break;
case WM_NCPAINT:
CallWindowProc(FOldAppProc,handle,Message.Msg,Message.WParam,Message.LParam);
pCanvas->MoveTo(20,40);
pCanvas->LineTo(100,200);
return;
case WM_PAINT:
CallWindowProc(FOldAppProc,handle,Message.Msg,Message.WParam,Message.LParam);
pCanvas->MoveTo(20,40);
pCanvas->LineTo(100,200);
return;
default:
return;
}
str+=":"+IntToStr(Message.WParam)+":"+IntToStr(Message.LParam);
Memo1->Lines->Add(str);
return ;
}
上面的代码能在HTML上画出我的图形,但不能获得鼠标和键盘事件啊
gloom 2002-11-06
  • 打赏
  • 举报
回复
让老兄见笑了,我知道WebBrowser的三层结构,我上面省略了几行代码:

HWND handle=Web->Handle;
handle=FindWindowEx(handle,NULL,"Shell DocObject View",NULL);
handle=FindWindowEx(handle,NULL,"Internet Explorer_Server",NULL);
PreWndProc=SetWindowLong(handle,GWL_WNDPROC,MyWndProc);

我还真没有也不会替换过窗口过程,我以前是这样试过,获得Internet Exporer_Server的HDC,再在上面绘图,但窗口内容中的图形无法显示,只有在滚动条的部分能画上去。我觉得DHTML在解析HTML标记时会为其中的元素另外分配HDC资源,如果这样的话要获得这些元素的HDC就更难办了。
bcb_fans 2002-11-06
  • 打赏
  • 举报
回复
1、

不可能啊,我使用我贴的代码测试了,的确可以捕获到鼠标消息。
---------------------------------------------------------------------------
void __fastcall TForm1::NewAppProc(TMessage& Message)
{
Message.Result=::CallWindowProc((FARPROC)FOldAppProc,hIE,
Message.Msg,Message.WParam,Message.LParam);

if(Message.Msg == WM_LBUTTONDOWN)
{
//经过测试,单击鼠标时,这个对话框显示了,证明可以捕获鼠标消息
MessageBox(NULL,"Mouse Down",NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);
}
else if(Message.Msg == WM_PAINT)
{
........


我上面已经说了,必须在主窗口完全显示之后,才能替换IE的窗口过程,否则找不到“Internet Explorer_Server”窗口,你可以进行测试,看看找到没有。

2、你上面贴出的代码让人感到不可思议:

(1)

void __fastcall TForm1::WebDocumentComplete(TObject *Sender,
LPDISPATCH pDisp, Variant *URL)
{
AnsiString str="";
switch (Message.Msg)
{
case WM_LBUTTONDOWN:
str="LButtonDown";
break;

DocumentComplete事件是文件下载完成后触发的事件,你怎么在里边检测鼠标消息?而且,那个Message在哪里定义?

(2)
void __fastcall TForm1::NewAppProc(TMessage& Message)
{
AnsiString str="";
switch (Message.Msg)
{
case WM_LBUTTONDOWN:
str="LButtonDown";
break

为什么不把鼠标消息继续往下传?不继续传,IE怎么知道有鼠标消息发生?
bcb_fans 2002-11-05
  • 打赏
  • 举报
回复
//"Shell Embedding" (针对内嵌的TCppWebBrowser,独立的IE为“IEFrame”)
// + "Shell DocObject View"
// + "Internet Explorer_Server"

可以使用SPY++查看。
bcb_fans 2002-11-05
  • 打赏
  • 举报
回复
不会吧?老兄,难道以前你都没有替换过窗口过程?

1、MyWndProc必须是全局函数。

2、如果想让MyWndProc作为成员函数存在,必须这样做:

FARPROC FOldAppProc;
void* FNewAppObjectInstance;

FOldAppProc = (FARPROC)GetWindowLong(Application->Handle, GWL_WNDPROC);
// NewAppProc作为成员函数存在
FNewAppObjectInstance = MakeObjectInstance(NewAppProc);
SetWindowLong(Application->Handle, GWL_WNDPROC, long(FNewAppObjectInstance));

程序结束的时候调用:

SetWindowLong(Application->Handle, GWL_WNDPROC, long(FOldAppProc));
FreeObjectInstance(FNewAppObjectInstance);

3、你上面贴出的代码:

PreWndProc=SetWindowLong(handle,GWL_WNDPROC,MyWndProc);

我不知道你是随手写的,还是在你的程序就真存在这么一行代码,如果是真存在,你截获的是主窗口的窗口过程,跟IE根本就不沾边。当在IE中打开一个页面之后,它的窗口层次如下:

//"Shell Embedding" (针对内嵌的TCppWebBrowser,独立的IE为“IEFrame”)
// + "Shell DocObject View"
// + "Internet Explorer_Server"

真正应该截获的是窗口"Internet Explorer_Server",比如下面的代码:


HWND hIE;

void __fastcall TForm1::FormDestroy(TObject *Sender)
{
if(hIE != NULL)
{
SetWindowLong(hIE, GWL_WNDPROC, long(FOldAppProc));
FreeObjectInstance(FNewAppObjectInstance);
}
}
//---------------------------------------------------------------------------
//必须在主窗口完全显示后,才能进行截获。否则找不到窗口“Internet Explorer_Server”。

void __fastcall TForm1::Button2Click(TObject *Sender)
{
TWinControl *WinCtrl;

WinCtrl = (dynamic_cast<TWinControl*>(CppWebBrowser1));
if(WinCtrl != NULL)
{
hIE = WinCtrl->Handle;
hIE = FindWindowEx(hIE,0,"Shell DocObject View",NULL);
hIE = FindWindowEx(hIE,0,"Internet Explorer_Server",NULL);

if(hIE != NULL)
{
FOldAppProc = (FARPROC)GetWindowLong(hIE, GWL_WNDPROC);
FNewAppObjectInstance = MakeObjectInstance(NewAppProc);
SetWindowLong(hIE, GWL_WNDPROC, long(FNewAppObjectInstance));
}
else
{
Memo1->Lines->Add("Null IE Handle.Err = " + SysErrorMessage(GetLastError()));
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::NewAppProc(TMessage& Message)
{
Message.Result=::CallWindowProc((FARPROC)FOldAppProc,hIE,
Message.Msg,Message.WParam,Message.LParam);

if(Message.Msg == WM_LBUTTONDOWN)
{
HDC hIEDC;

hIEDC = GetDC(hIE);
if(hIEDC != NULL)
{
TCanvas *TempCanvas;

TempCanvas = new TCanvas();
TempCanvas->Handle = hIEDC;
TempCanvas->Brush->Color = clRed;
TempCanvas->FillRect(TRect(2,2,10,10));

delete TempCanvas;
ReleaseDC(hIE,hIEDC);
}
else
{
MessageBox(NULL,AnsiString("Null DC.Err = " + SysErrorMessage(GetLastError())).c_str(),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);
}

MessageBox(NULL,"Mouse Down",NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);
}
else if(Message.Msg == WM_PAINT)
{
//经过我的测试,发现在这里无法显示自己的图形!奇怪!

HDC hIEDC;

hIEDC = GetDC(hIE);
if(hIEDC != NULL)
{
TCanvas *TempCanvas;

TempCanvas = new TCanvas();
TempCanvas->Handle = hIEDC;
TempCanvas->Brush->Color = clRed;
TempCanvas->FillRect(TRect(2,2,10,10));

ReleaseDC(hIE,hIEDC);
delete TempCanvas;
}
}
}
//---------------------------------------------------------------------------

想实际应用,还有很多的事要做!!!
gloom 2002-11-05
  • 打赏
  • 举报
回复
我这样写怎么编译不通过啊?

//声明WndPron
LRESULT CALLBACK TForm1::MyWndProc( HWND hwnd, UINT msg,UINT wParam, LONG lParam );
//设置WndProc函数
PreWndProc=SetWindowLong(handle,GWL_WNDPROC,MyWndProc);
//错误
[C++ Error] main.cpp(604): E2034 Cannot convert 'long (__stdcall * (_closure )(void *,unsigned int,unsigned int,long))(void *,unsigned int,unsigned int,long)' to 'long'
[C++ Error] main.cpp(604): E2342 Type mismatch in parameter 'dwNewLong' (wanted 'long', got 'void')
bcb_fans 2002-11-05
  • 打赏
  • 举报
回复
不清楚!瞎说一下:

1、根据MSDN的说明,IHTMLEventObj对象只有在事件脚本里边才有实际意义,象你通过OnMessage
那样来编程应该没有效果。说白了,就是使用IHTMLDocument2->put_onmousedown(...)来设置
事件的处理句柄,比如自己实现IDispatch接口,然后调用这个方法来设置,这样发生事件的时
候,你的IDispatch接口就可以得到通知了。

2、想在页面上划线,理论上只要调用GetDC得到IE窗口的句柄就可以画了。问题在于:

(1)当页面中含有Frame时,IE5.0建立子窗口来放那个Frame,比如上下两个Frame充满了IE窗口,
这时候想在页面上画线,也就是说画一条线在那两个窗口上面,难度比较大!?

(2)就算IE中没有Frame,想画线也同样很难!因为只要IE刷新,你画的线就没有了!目前比较的
方法就是截获IE窗口的窗口过程,然后检测消息WM_PAINT :

LRESULT CALLBACK MyWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
if(uMsg == WM_PAINT)
{
//先进行正常的绘画
CallWindowProc(.......)

//然后再画自己的东西
.....

return;
}
else
{
CallWindowProc(...);
}
}

瞎说了这么多,也不知道有没有用:)
gloom 2002-11-04
  • 打赏
  • 举报
回复
获得IE页面中的事件应该是一个值得探讨的课题,事件和消息还是不一样的,特别是IE页面中,很多方法都可以获得消息,就如BCB_FANS所言,但IE页面中的事件有特别之处,事件的相关参数全是存放在IHTMLEventObj中,消息中并没有很多相关的参数,所以处理IE页面中的事件都需要IHTMLEventObj接口,但你光是获得消息的话意思不大,很多相关的数据消息中没有,要使用IHTMLEventObj来查询获得,至于用途就更广泛了,我自己是想做一个控件:能够随意在HTML页面上绘线、作标记,如同IMarkup的绘线功能,但这有两个难关,一是如题所述的需要自己处理HTML中的事件,另一个难题是如何获得一个覆盖在整个页面上的一个HDC能够用来绘线,我见过一个例子,利用IE5.5的IHTMLElementBehavior和IHTHLPaint属性基本可实现但它只能附在一个页面元素上,不能对整个文档操作,如果对容器操作也有很大问题,看看兄弟们有没有好的方法,由于我对DHTML对象模型不熟悉,在此劳各位了。
xiaomu2188 2002-11-01
  • 打赏
  • 举报
回复
我也研究过TCppWebBrowser,还真没发现有这样的事件,嗯难!
bcb_fans 2002-11-01
  • 打赏
  • 举报
回复
还是不明白你的意思,如果仅仅是为了得到鼠标消息,可以使用进程中WH_GETMESSAGE Hook!!!只是你想用鼠标消息来做什么?说出这个原因,看看有没有别的办法可以办到。
gloom 2002-11-01
  • 打赏
  • 举报
回复
我就是想处理WebBrowser中的鼠标事件和键盘,其它应该是Doucment的吧。
bcb_fans 2002-10-28
  • 打赏
  • 举报
回复
先说一说你的目的吧!详细一点!
gloom 2002-10-28
  • 打赏
  • 举报
回复
我看过一个VC的示例,不全,要用实现一个Dispatch类,再在这个类的Invoke函数中接收消息,不知道在BCB中应该怎么做,
我尝试了一种非正常的方法,在窗口中加一个TApplicationEvents,在它的OnMessage中处理WebBrowser发出来的消息,但无法获得IHTMLEventObj接口。下面是示例,请各位高手看看是否可行:
//我已经在WebBrowser的DocumentComplete中获得了IHTMLDocument2接口。
void __fastcall TForm1::ApplicationEvents1Message(tagMSG &Msg,
bool &Handled)
{
//如果消息是由WebBrowser发出
if (Msg.hwnd !=Web->Handle) return;
if (Msg.message ==WM_LBUTTONDOWN)
{
//ShowMessage(IntToHex((__int64)Msg.hwnd,8));
//如果尚未加载HTML文件则返回
if (!pDoc2) return;
//下面正常
pDoc2->get_parentWindow(&pWin);
if (!pWin)
{
ShowMessage("无法获得IHTMLWindow2接口");
return;
}
//下面出现错误,无法获得pEvent(IHTMLEventObj)
pWin->get_event(&pEvent);
if (!pEvent)
{
ShowMessage("无法获得IHTMLEventObject");
return;
}
pEvent->get_srcElement(&pElem);
BSTR html;
pElem->get_outerHTML(&html);
ShowMessage(html);
SysFreeString(html);
pEvent->Release();
pElem->Release();
pWin->Release();
}
}
warton 2002-10-26
  • 打赏
  • 举报
回复
这个问题我也考虑过,但是,好像没有这方面的资料!!
加载更多回复(1)
内容概要:本文介绍了一种用于电磁暂态(EMT)研究的第四类全变流器型风力发电系统的通用Simulink仿真模型,旨在构建一个能够准确反映实际风电系统动态特性的简化通用模型。该模型涵盖了风力机、传动链、发电机、全功率变流器及其控制策略等关键组成部,重点突出系统在电网故障、风速波动等复杂工况下的动态响应能力,适用于风电并网电磁暂态析、新型电力系统稳定性评估及高比例可再生能源接入场景的研究。模型设计兼顾准确性与仿真效率,便于研究人员快速搭建和调试,推动风电系统建模与控制技术的发展; 适合人群:具备一定电力系统理论基础和MATLAB/Simulink仿真能力,从事新能源发电、电力电子变换、风电并网控制及相关方向的研究生、科研人员及工程技术人员; 使用场景及目标:①开展风电系统在电网扰动下的电磁暂态仿真析;②研究全功率变流器风电机组的动态行为与控制特性;③支撑新型电力系统高渗透率风电接入的稳定性与电能质量评估,服务于学术研究、课程教学与工程项目前期仿真验证; 阅读建议:建议读者结合文提供的模型结构与参数设置,在Simulink环境动手复现并调试仿真模型,通过设置不同运行工况(如三相短路、低电压穿越、风速突变等)观察系统响应,深入理解全变流器风电机组的建模方法、控制逻辑与动态特性,进而拓展应用于更复杂的多机并网或综合能源系统仿真场景。
源码下载地址: https://pan.quark.cn/s/d18200fd2664 在基于Ubuntu的系统,针对TCP与UDP网络进行排错对于开发人员及系统维护者而言是日常工作的关键环节。为了能够迅速地识别并解决网络层面的故障,挑选出合适的辅助工具显得尤为必要。提及的"适用于ubuntu的TCP/UDP排错资源"很可能是指向`mNetAssist`这款应用,从压缩文件清单包含一个名为`mNetAssist-released.deb`的条目来看,这通常表明该文件是为Debian或Ubuntu平台设计的软件安装包。`mNetAssist`作为一个功能全面的网络监控与排错软件,能够协助用户对TCP/IP网络连接进行检测、剖析以及调试。接下来,我们将对这款软件的各项特性以及其在Ubuntu系统上的安装与运用方法进行详尽的阐述。 为了部署`mNetAssist`,首先需要确认Ubuntu系统已经更新至最新状态,并且已经配置了`apt`软件包管理机制。在终端界面输入下列指令来执行软件包的安装流程: ```bash sudo apt update sudo apt install dpkg ``` 接着,将`mNetAssist-released.deb`软件包文件传输到Ubuntu系统的某个文件夹内,例如`~/Downloads`目录,随后利用`dpkg`指令进行安装操作: ```bash cd ~/Downloads sudo dpkg -i mNetAssist-released.deb ``` 在安装阶段若遭遇依赖性难题,可能需要借助`apt-get`来处理: ```bash sudo apt-get install -f ``` 完成安装后,用户可以通...
内容概要:本文探讨了Hash算法在芯片行业,特别是网络处理器(NPU)的性能优化实践,聚焦于如何通过硬件流水线设计实现纳秒级高速哈希查找。文章析了传统软件哈希方案在高带宽场景下的局限性,提出基于硬件描述语言或高层次综合(HLS)的设计方法,采用CRC32等硬件友好型哈希函数、并行多路哈希、流水线化解耦以及双端口存储结构等核心技术,实现低延迟、无阻塞的数据包处理。通过C++风格的HLS代码示例,展示了从算法选择到资源优化的完整硬件加速逻辑,并深入剖析了循环展开、位宽控制、内存映射和流水线调度等关键实现细节。最后展望了可编程交换机、P4语言支持及TCAM与哈希混合架构等未来发展方向。; 适合人群:具备数字电路基础、熟悉Verilog/SystemVerilog或HLS的芯片设计工程师,以及从事网络芯片、FPGA加速、高性能路由设备研发的技术人员(工作年限1-5年为宜);也适合对硬件加速算法感兴趣的研究人员。; 使用场景及目标:①掌握如何将哈希算法高效映射到硬件逻辑以满足线速转发需求;②理解流水线设计、资源约束优化、读写冲突规避等在实际芯片项目的应用;③为开发高性能网络处理器的流表/路由表查找单元提供技术参考与实现范例。; 阅读建议:学习时应结合HLS工具(如Xilinx Vitis HLS)进行代码仿真与综合,重点关注#pragma指令对硬件结构的影响,并对比不同哈希算法在资源占用与时序表现上的差异,深入理解“空间换时间”的硬件优化本质。
内容概要:本文系统研究了基于粒子群优化(PSO)、灰狼优化(GWO)、鲸鱼优化(WOA)、哈里斯鹰优化(HHO)、蜣螂优化(DBO)和麻雀搜索算法(SSA)六种智能优化算法在无人机三维路径规划的应用,并在Matlab平台上实现了相应的仿真代码。研究构建了复杂的三维地形与障碍物环境模型,设计了包含路径长度、飞行时间、能耗及安全性等多维度的成本函数,通过定义合理的适应度函数与飞行约束条件,对各类算法的路径搜索能力、收敛速度与规划质量进行了全面对比析。通过仿真实验验证了各算法在静态复杂环境下的性能表现,旨在为实际无人机任务优化算法的选择提供科学依据和技术支持。; 适合人群:具备一定Matlab编程基础,从事智能优化算法、无人机路径规划、自动化控制及相关领域研究的研究生、科研人员或工程技术人员。; 使用场景及目标:① 掌握主流群智能优化算法在无人机三维路径规划的建模与实现方法;② 对比析不同算法在相同复杂环境下的性能差异,为算法选型提供量化依据;③ 为后续研究动态环境路径规划、多无人机协同任务配等问题奠定理论与技术基础; 阅读建议:建议读者结合提供的Matlab代码逐模块析算法实现流程,重点关注适应度函数的设计、障碍物规避策略的实现以及多目标成本函数的权衡机制,同时可通过调整参数设置或引入新型优化算法进行扩展实验,以深化对算法性能的理解与实际应用能力。

13,873

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧