Duilib嵌入CEF禁止浏览器响应拖拽事件

在开发中有一个需求,拖拽外部文件到客户端,然后客户端响应WM_DROPFILES消息,在拖拽消息里处理一下业务,最后把处理结果显示到客户区html中,但实际中发现当拖拽文件到客户区,浏览器首先处理了拖拽事件,外层的Win32窗口无法捕捉到拖拽消息,因此要想实现此操作,刚开始我想了一个本办法,在客户区最外层罩了一个透明的Win32原生窗口,这样拖拽文件时,在最外层透明窗口的WM_DROPFILES消息中处理具体业务,最后用C++调用js函数,在页面显示处理结果。

方法一:

透明窗口

LayeredWindow.h

 1 #ifndef _LAYEREDWINDOW_H_
 2 #define _LAYEREDWINDOW_H_
 3
 4 class CLayeredWindow :public WindowImplBase
 5 {
 6 public:
 7     CLayeredWindow();
 8     ~CLayeredWindow();
 9
10 public:
11     LPCTSTR GetWindowClassName() const;
12
13     virtual void OnFinalMessage(HWND hWnd);
14
15     virtual LRESULT ResponseDefaultKeyEvent(WPARAM wParam);
16
17     virtual UILIB_RESOURCETYPE GetResourceType() const;
18
19     virtual CDuiString GetSkinFile();
20
21     virtual CDuiString GetSkinFolder();
22
23     virtual CControlUI* CreateControl(LPCTSTR pstrClass);
24
25     virtual void InitWindow();
26
27     virtual void Notify(TNotifyUI& msg);
28
29     virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
30
31     virtual void OnClick(TNotifyUI& msg);
32
33     void OnPrepare();
34 };
35 #endif//_LAYEREDWINDOW_H_

LayeredWindow.cpp

  1 #include "stdafx.h"
  2 #include "LayeredWindow.h"
  3
  4 CLayeredWindow::CLayeredWindow()
  5 {
  6
  7 }
  8
  9 CLayeredWindow::~CLayeredWindow()
 10 {
 11
 12 }
 13
 14 LPCTSTR CLayeredWindow::GetWindowClassName() const
 15 {
 16     return _T("LayeredWindow");
 17 }
 18
 19 void CLayeredWindow::OnFinalMessage(HWND hWnd)
 20 {
 21     CWindowWnd::OnFinalMessage(hWnd);
 22 }
 23
 24 LRESULT CLayeredWindow::ResponseDefaultKeyEvent(WPARAM wParam)
 25 {
 26     if (wParam == VK_RETURN)
 27     {
 28         return FALSE;
 29     }
 30     else if (wParam == VK_ESCAPE)
 31     {
 32         return TRUE;
 33     }
 34     return FALSE;
 35 }
 36
 37 DuiLib::UILIB_RESOURCETYPE CLayeredWindow::GetResourceType() const
 38 {
 39     return UILIB_FILE;
 40 }
 41
 42 DuiLib::CDuiString CLayeredWindow::GetSkinFile()
 43 {
 44     return _T("LayeredDlg.xml");
 45 }
 46
 47 DuiLib::CDuiString CLayeredWindow::GetSkinFolder()
 48 {
 49     return _T("");
 50 }
 51
 52 CControlUI* CLayeredWindow::CreateControl(LPCTSTR pstrClass)
 53 {
 54     return NULL;
 55 }
 56
 57 void CLayeredWindow::InitWindow()
 58 {
 59
 60     //加入WS_EX_LAYERED扩展属性
 61     SetWindowLong(this->GetHWND(),GWL_EXSTYLE,
 62         GetWindowLong(this->GetHWND(),GWL_EXSTYLE)^0x80000);
 63     HINSTANCE hInst = LoadLibrary(L"User32.DLL");
 64     if(hInst)
 65     {
 66         typedef BOOL (WINAPI *MYFUNC)(HWND,COLORREF,BYTE,DWORD);
 67         MYFUNC fun = NULL;
 68         //取得SetLayeredWindowAttributes函数指针
 69         fun=(MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes");
 70         if(fun)fun(this->GetHWND(),0,1,2);
 71         FreeLibrary(hInst);
 72     }
 73 }
 74
 75
 76 void CLayeredWindow::OnPrepare()
 77 {
 78
 79 }
 80
 81 void CLayeredWindow::Notify(TNotifyUI& msg)
 82 {
 83     if( msg.sType == _T("windowinit") ) OnPrepare();
 84
 85     if(msg.sType == _T("click"))
 86     {
 87     }
 88
 89     WindowImplBase::Notify(msg);
 90 }
 91
 92 void CLayeredWindow::OnClick(TNotifyUI& msg)
 93 {
 94     __super::OnClick(msg);
 95 }
 96
 97 //禁用双击标题栏窗口最大化
 98 LRESULT CLayeredWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
 99 {
100     LRESULT lRes = 0;
101     BOOL bHandled = TRUE;
102     switch( uMsg)
103     {
104     case WM_NCLBUTTONDBLCLK:
105         {
106             return 0;
107         }
108         break;
109     default:
110         bHandled = FALSE;
111     }
112     return WindowImplBase::HandleMessage(uMsg,wParam,lParam);
113 }

1.在主窗口InitWindow函数里面创建透明窗口

2.在主窗口的WM_SIZE 和 WM_MOVE消息中移动这个透明窗口,让其跟随主窗口移动

方法二:

最好的办法是取消CEF浏览器对拖拽事件的处理,这样让外层Win32窗口处理拖拽事件

研究了一下CEF源码,发现有一个类CefDragHandler,是浏览器拖拽事件,可以让你自己的CLientHandler继承这个类,然后重写它里面的虚函数

virtual bool OnDragEnter(CefRefPtr<CefBrowser>browser,CefRefPtr<CefDragData> dragData,CefDragHandler::DragOperationsMask mask){

CEF_REQUIRE_UI_THREAD();

// Forbid dragging of link URLs.
    if (mask & DRAG_OPERATION_LINK)
    return true;

return false;

}

让其返回true,取消拖拽响应,刚开始只重写了这个虚函数,但在拖拽时还是无法禁止,最后发现少写一个获取拖拽事件处理器

// CefClient 事件处理器,如果没有对应处理器则默认使用内部处理器

virtual CefRefPtr<CefDragHandler> GetDragHandler()  {
        return this;
    }

加上这个函数后,才能真正禁止拖拽事件

时间: 2024-08-08 10:17:19

Duilib嵌入CEF禁止浏览器响应拖拽事件的相关文章

禁止浏览器上下拖拽方法

在触屏写的一些弹层总会引发不同浏览器里面的bug. 比如下图左侧窗口出现的时候,用户在拖拽右侧的body区域就会在某些浏览器里引发一些bug. 索性干掉这个方法,在弹层显示时不让用户拖拽页面. 引用的方法 //body一屏显示禁止上下拖拽 setPreventDefault.start(); //取消事件 setPreventDefault.end(); 1 /*禁止浏览器滚动*/ 2 var setPreventDefault = { 3 oldScrollTop : 0,/*记录滚动条位置*

window响应拖拽文件操作

1.首先调用DragAcceptFiles,让控件或者窗体支持文件拖动操作函数功能:用来为拖放文件作初始化.函数原型:void DragAcceptFiles(    HWND hWnd, //指明目标窗体的句柄    BOOL fAccept //为True时 则hWnd所指向的窗体可以接受拖放的文件. ); 2.消息事件中响应拖拽操作(WM_DROPFILES), 调用函数DragQueryFile和DragFinish[1].DragQueryFile函数功能:用来查下拖放文件的文件名.函

HTML5 02. 多媒体控件、拖拽事件、历史记录、web存储、应用程序缓存、地理定位、网络状态

多媒体 video:是行内块(text-align: center; 对行内块适用) <figure></figure>: 多媒体标签 : <figcaption></figcaption>: 多媒体标题 方法: load() 加载.play()播放.pause()暂停 属性: currentTime 视频播放的当前进度. duration:视频的总时间. paused:视频播放的状态 事件:   oncanplay:事件在用户可以开始播放视频/音频(aud

拖拽事件

<h1>拖拽事件</h1><ul>    <li>onmousedown:鼠标按下</li>    <li>onmousemove:鼠标移动</li>    <li>onmouseup:鼠标放开</li></ul>    <p>拖拽的时候如果有文字选中,会出现问题!: 当鼠标按下的时候,如果页面中有文字被选中,那么会触发浏览器的默认拖拽文字的效果</p>    &

JS Event 鼠标拖拽事件

<!DOCTYPE html><html> <head>        <meta charset="UTF-8">        <title>JS Event鼠标拖拽事件</title>                <style>            #box{width:200px;height:200px;background:#000;position:absolute;}       

Android Launcher拖拽事件详解【android4.0--Launcher系列二】

AndroidICS4.0版本的launcher拖 拽的流程,基本和2.3的相似.就是比2.3写的封装的接口多了一些,比如删除类的写法就多了个类.等等.4.0的改变有一些,但是不是特别大.这个月一 直在改动Launcher的缩略图的效果,4.0的缩略图的功能没有实现,还得从2.3的Launcher中摘出来.通过做这个缩略图对Launcher 的模块有一点点了解,拿来分享一下Launcher拖拽的工作流程.有图有真相!   (1) 先来看看类之间的继承关系      图(1)  (2)再来看看La

原生js实现 拖拽事件

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> .box { width: 200px; height: 200px; background-color: #000000; position: absolute; left: 0; top: 0;

h5学习--七个h5拖拽事件

<script> // 七个h5拖拽事件 const box = document.getElementById('box') const left = document.getElementById('left') const right = document.getElementById('right') let num = 0 //ondragstart 拖拽开始的时候,进行移动 right.ondragstart= function(){ console.log("lll&q

H5拖拽事件-- 自定义创建a标签热区

有两个BUG未更正, 1.拖拽后,动态创建的div始终在鼠标的下方,导致拖拽定位不准确 2.当窗口为自适应时,定位left为百分比,窗口改变大小时会存在定位偏差 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="./jquery-1