论坛上有不少同学问过关于选项卡 右键菜单实现的问题
因为选项卡设计的原因,选项卡的消息是不能进入消息路由,很多同学没有找到实现的方式,最后放弃了!今天给大家讲的就是如何实现这个功能
我们先看效果图,所谓有图有真相
下面给大家提供一个方法以及源码
我们可以采用取巧的方式来实现,利用消息过程中的 123 消息,来**到右键在窗口上点击的消息
查看msdn 对123消息的描述是 当用户某个窗口中点击了一下右键就发送此消息给这个窗口
于是我们在消息过程中,监 听123这个消息,并判断鼠标当前位置的窗口句柄,做匹配,最后弹出我们的菜单
下面直接看源码,同时我们上传附件
- var 右键控件句柄数组 = array()
- var 表格句柄
- //消息过程功能
- 功能 选项卡与表格右键菜单开源_消息过程(消息,w参数,l参数)
- if(消息 == 123)
-
- var now_hwnbd = windowgetpointhwnd()
- traceprint(now_hwnbd)
- var key = arrayfindvalue(右键控件句柄数组,now_hwnbd)
- if(strlen(key))
- var menuinfo ,index
- if(key == "表格") //表格有个缺点 只有得到焦点才能获取内容,但是右键菜单会在得到焦点之前弹出,所以要先单击一次,然后右键
- var row,col,str
- 表格获取焦点选项("表格0",row,col)
- str = 表格获取内容("表格0",row,col)
- index = PopuMenu("|"&str&"|抖动窗口|√任务栏隐藏|_|最小化|离开",menuinfo)
- else
- index = PopuMenu("|"&key&"|抖动窗口|√任务栏隐藏|_|最小化|离开",menuinfo)
- end
- RunFun(index,menuinfo)
- end
-
- end
- 结束
- 功能 选项卡与表格右键菜单开源_初始化()
- //这里添加你要执行的代码
- 右键控件句柄数组["表格"] = controlgethandle("表格0")
- var len =tabgetcount("选项卡0")
- for(var i = 0; i < len; i++)
- 右键控件句柄数组["选项卡分页"&i] = tabgetpagehandle("选项卡0",i)
- end
-
- for(var i = 0; i < 5; i++)
- for(var j = 1; j < 5; j++)
- gridsetcontent("表格0",j,i,"第"&j&"行,第"&i&"列")
- end
- end
- 结束
复制代码 右键菜单部分
- var m_hwnd
- var WS_EX_LAYERED =#80000//让窗口有透明属性
- var WS_BORDER =#00800000//无边框属性
- var WS_CAPTION =#00C00000
- var WS_CLIPSIBLINGS =#04000000
- var WS_CLIPCHILDREN =#02000000
- var TRANSPARENT =1
- //让无边框的窗口可以,鼠标点击拖动
- function NoBorderWindowMove()
- dllcall("user32.dll","Long","ReleaseCapture")
- dllcall("user32.dll","Long","SendMessageA","Long",m_hwnd,"Long",161,"Long",2,"Long",1)
- end
- //更新窗口扩展风格
- function UdateWindowStyleEx(hwnd,Style)
- var GWL_STYLE=-20
- var style=dllcall("user32.dll","int","GetWindowLongA","int",m_hwnd,"int",GWL_STYLE)
- dllcall("user32.dll","int","SetWindowLongA","int",m_hwnd,"int",GWL_STYLE,"int",style+Style)
- end
- //更新窗口风格
- function UdateWindowStyle(hwnd,Style)
- var GWL_STYLE=-16
- var style=dllcall("user32.dll","int","GetWindowLongA","int",m_hwnd,"int",GWL_STYLE)
- dllcall("user32.dll","int","SetWindowLongA","int",m_hwnd,"int",GWL_STYLE,"int",style+Style)
- end
- //透明度
- //hwnd:窗口句柄
- //color:要透明的颜色
- //Alpha:透明度 0-255
- //dwFlags:1,color有效;2,Alpha;3color、Alpha都有效
- function Transparency(hwnd,color,Alpha,dwFlags)
- return dllcall("user32.dll","int","SetLayeredWindowAttributes","int",hwnd,"int",color,"int",Alpha,"int",dwFlags)
- end
- //对窗口的裁剪
- function 异型窗体(hwnd)
- //获取窗口要裁剪的范围
- var hr=dllcall("gdi32.dll","int","CreateRectRgn","int",10,"int",10,"int",110,"int",110)
- //对窗口进行裁剪,对裁剪过的区域不显示
- var dl=dllcall("user32.dll","int","SetWindowRgn","int",hwnd,"int",hr,"bool",true)
-
- end
- var isCheck=array() //用来记录单选框状态的
- function PopuMenu(title,&array_PopuMenuInfo)
-
- var TPM_LEFTBUTTON =#0000
- var TPM_RIGHTBUTTON =#0002
- var TPM_RETURNCMD =#0100
-
- var TPM_LEFTALIGN =#0000
- var TPM_CENTERALIGN =#0004
- var TPM_RIGHTALIGN =#0008
-
- var TPM_TOPALIGN =#0000
- var TPM_VCENTERALIGN =#0010
- var TPM_BOTTOMALIGN =#0020
-
- var MF_SEPARATOR =#00000800//分割线
- var MF_CHECKED =#00000008//选中
- var MF_POPUP =#00000010
- var MF_STRING =#00000000
- var MF_BITMAP =#00000004
- var MF_OWNERDRAW =#00000100
-
- var IMAGE_BITMAP =#0
- var LR_LOADFROMFILE =#00000010
-
- var MF_BYCOMMAND =#00000000
- var MF_BYPOSITION =#00000400
-
- var title_array
- var array1
- var count = strsplit(title,"|",title_array)
-
- var h_Menu=dllcall("user32.dll","int","CreatePopupMenu")
- if(h_Menu==0)
- return 0 //菜单创建失败就直接返回0
- end
-
- for(var i=1;i<count;i++)
- //下面是增加菜单的item(理解成选项吧)
- select(title_array[i])
- case "-" //表示使用分割线
- dllcall("user32.dll","int","AppendMenuA","int",h_Menu,"int",MF_SEPARATOR,"int",0,"char *","fff")
- isCheck[i]=false
- case "_"//表示使用分割线
- dllcall("user32.dll","int","AppendMenuA","int",h_Menu,"int",MF_SEPARATOR,"int",0,"char *","fff")
- isCheck[i]=false
- default
- var t = title_array[i]
- //表示要使用复选框
- if(strsub(title_array[i],0,1)=="√")
- //截取√符号不显示
- title_array[i]=strsub(title_array[i],1,strlen(title_array[i]))
- if(isCheck[i])
- //选中状态
- dllcall("user32.dll","int","AppendMenuA","int",h_Menu,"int",MF_CHECKED,"int",i,"char *",title_array[i])
- isCheck[i]=true
- else
- //未选中状态
- dllcall("user32.dll","int","AppendMenuA","int",h_Menu,"int",0,"int",i,"char *",title_array[i])
- isCheck[i]=false
- end
- else
- //正常的
- dllcall("user32.dll","int","AppendMenuA","int",h_Menu,"int",0,"int",i,"char *",title_array[i])
- isCheck[i]=false
- end
-
- end
-
- end
-
- var x,y
- mousegetpoint(x,y)
- //弹出生成好的菜单,并返回你点击的选项,返回选项id.从上往下从1开始递增
- var ret=dllcall("user32.dll","int","TrackPopupMenu","int",h_Menu,"int",TPM_RIGHTALIGN+TPM_TOPALIGN+TPM_LEFTBUTTON+TPM_RIGHTBUTTON + TPM_RETURNCMD,"int",x,"int",y,"int",0,"int",windowgetmyhwnd(),"int",0)
- //销毁菜单(菜单点击完成后都是要关闭的)
- dllcall("user32.dll","int","DestroyMenu","int",h_Menu)
-
- //设置选择中项的状态
- if(isCheck[ret])
- isCheck[ret]=false
- else
- isCheck[ret]=true
- end
-
- //这里没有对 非复选框做过滤,不影响正常显示
- array_PopuMenuInfo = stringtoarray("array(1,2,3)")
- arraysetcache(array_PopuMenuInfo,count)
- for(var i=0;i<count;i++)
- var tmp = array(i,isCheck[i],title_array[i])
- array_PopuMenuInfo[i] = tmp
- end
- return ret
- end
- //根据菜单返回的ID执行指定的函数
- function RunFun(index,menuinfo)
-
- var SC_MINIMIZE=#F020
- var SC_MAXIMIZE=#F030
- var WM_SYSCOMMAND=#112
- select(index)
- case 0
- JitterWindow(m_hwnd,2,3)
-
- case 1
- if(menuinfo[2][1])//ID=2是复选框,所以要判断一下菜单信息里面的一些属性//下面是一个隐藏任务栏图标的dll
- dllcall(getrcpath("rc:dlltest.dll"),"int","ShowInTaskbar","int",m_hwnd,"int",0)
- else
- dllcall(getrcpath("rc:dlltest.dll"),"int","ShowInTaskbar","int",m_hwnd,"int",1)
- end
-
- case 2
- windowsendmessage(m_hwnd,WM_SYSCOMMAND,SC_MINIMIZE,0)//向TC窗口自身发送最小化的消息
-
- case 3
- exit()
-
- end
-
- end
- //窗口抖动
- //hwnd:要抖动的窗口句柄
- //count:抖动的次数
- //nWidth: 抖动的范围
- function JitterWindow(hwnd,count,nWidth)
- //这个函数就不详细注释了 代码很简单,就是改变窗口位置
- var x,y
- windowgetpos(hwnd,x,y)
- for(var i=0;i<count;i++)
- windowsetpos(hwnd,x+nWidth,y)
- sleep(10)
- windowsetpos(hwnd,x+nWidth,y-nWidth)
- sleep(10)
- windowsetpos(hwnd,x,y-nWidth)
- sleep(10)
- windowsetpos(hwnd,x-nWidth,y-nWidth)
-
- sleep(10)
- windowsetpos(hwnd,x-nWidth,y)
- sleep(10)
- windowsetpos(hwnd,x-nWidth,y+nWidth)
- sleep(10)
- windowsetpos(hwnd,x,y+nWidth)
- sleep(10)
- windowsetpos(hwnd,x+nWidth,y+nWidth)
- sleep(10)
-
- end
- windowsetpos(hwnd,x,y)
-
- end
复制代码
最后源码在附件中下载
|