DirectUI界面编程(六)实现右键弹出菜单
本节向大家介绍一下右键弹出菜单是如何实现的。效果如下,在窗口中点击鼠标右键弹出菜单,点击菜单项能够响应菜单点击事件。
使用Duilib库实现的弹出菜单,实际上也是一个Windows窗口,因此我们需要创建两个窗口(主窗口和菜单窗口),然后响应主窗口的鼠标右键点击事件,在主窗口右键点击事件的响应函数中获取鼠标位置,將菜单窗口的位置调整为当前鼠标位置,同时把窗口设置为显示即可。
菜单窗口的xml布局文件内容如下:
<?xml version="1.0" encoding="utf-8"?>
<Window bktrans="true" size="120,102">
<Font name="宋体" size="13" bold="false"/>
<Font name="宋体" size="12"/>
<VerticalLayout bkimage="file='menu_bk.png' corner='40,8,8,8'" hole="false">
<List header="hidden" inset="8,8,8,8" itemhotimage="file='menu_hot_bk.png' corner='2,2,2,2'" itemdisabledbkcolor="#20000000">
<ListContainerElement name="menu_Open" height="22" inset="40,0,0,0">
<Label text="打开" mouse="false"/>
</ListContainerElement>
<ListContainerElement name="menu_Mark" height="22" inset="40,0,0,0">
<Label text="标注" mouse="false"/>
</ListContainerElement>
<ListContainerElement name="menu_Delete" height="22" inset="40,0,0,0">
<Label text="删除" mouse="false"/>
</ListContainerElement>
<ListContainerElement name="menu_Test" height="22" inset="40,0,0,0">
<Label text="测试" mouse="false"/>
</ListContainerElement>
</List>
</VerticalLayout>
</Window>
我们需要编写一个菜单窗口类继承WindowImplBase来加载xml界面。和上节不同的是我们把这个类的声明和成员函数的定义放在一个单独的头文件中,这样代码容易维护一些。新建头文件MenuWnd.h:
#ifndef _MENUWND_H__
#define _MENUWND_H__
#include "win_impl_base.hpp"
#include <Windows.h>
class MenuWnd : public WindowImplBase
{
LPCTSTR GetWindowClassName() const
{
return L"MenuWnd";
}
UINT GetClassStyle() const{
return UI_CLASSSTYLE_FRAME|CS_DBLCLKS;
}
tString GetSkinFile(){
return L"tutorial6_menu.xml";
}
void Notify(TNotifyUI& msg)
{
if(msg.sType == L"itemclick")
{
//响应菜单事件
::MessageBox(NULL,L"hello",L"hello",MB_OK);
this->ShowWindow(false);
}
}
};
#endif
接下来是主窗口,主窗口的xml界面布局文件内容和上节相同,仅仅是主窗口类的定义有些变化,我们同样把主窗口类的声明和定义放在一个单独的头文件MyWnd.h中:
#ifndef _MYWND_H__
#define _MYWND_H__
#include "win_impl_base.hpp"
#include "MenuWnd.h"
#include <Windows.h>
class MyWnd : public WindowImplBase
{
public:
MyWnd()
{
pMenu = new MenuWnd();
pMenu->Create(m_hWnd,L"Menu",WS_POPUP,WS_EX_TOOLWINDOW);
pMenu->ShowWindow(false);
}
LPCTSTR GetWindowClassName() const
{
return L"MyWnd";
}
UINT GetClassStyle() const{
return UI_CLASSSTYLE_FRAME|CS_DBLCLKS;
}
tString GetSkinFile(){
return L"tutorial6.xml";
}
void Notify(TNotifyUI& msg)
{
if(msg.sType == L"click")
{
if(msg.pSender->GetName() == L"CloseBtn")
{
::PostQuitMessage(0);
}else if(msg.pSender->GetName() == L"MinBtn")
{
::SendMessage(m_hWnd,WM_SYSCOMMAND, SC_MINIMIZE, 0);
}
}
}
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_RBUTTONDOWN:
OnRButtonDown(wParam,lParam);
return 0;
default:
return WindowImplBase::HandleMessage(uMsg,wParam,lParam);
}
}
void OnRButtonDown(WPARAM wParam, LPARAM lParam)
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
POINT pt = {xPos,yPos};
ClientToScreen(m_hWnd,&pt);
pMenu->ShowWindow(true);
::SetWindowPos(pMenu->GetHWND(), NULL, pt.x, pt.y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
}
LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
//获取鼠标点击位置
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
//將位置转换为屏幕坐标
POINT pt = {xPos,yPos};
ClientToScreen(m_hWnd,&pt);
RECT menuWndRect = {0};
::GetWindowRect(pMenu->GetHWND(),&menuWndRect);
if(pt.x <= menuWndRect.left || pt.x >= menuWndRect.right
|| pt.y <= menuWndRect.top || pt.y >= menuWndRect.bottom)
{
pMenu->ShowWindow(false);
}
bHandled = FALSE;
return 0;
}
private:
MenuWnd* pMenu;
};
#endif
在主窗口类中定义一个MenuWnd指针类型的成员变量,在构造函数中创建菜单窗口设置显示风格为隐藏,重写父类的HandleMessage函数,响应主窗口鼠标右键点击事件,在右键点击事件的响应函数中重新设置菜单位置,并把窗口显示风格设置为显示。
最后在WinMain函数中创建并显示主窗口:
//tutorial6.cpp
#include <Windows.h>
#include "MyWnd.h"
INT WinMain(HINSTANCE hInst,HINSTANCE hPreInst,LPSTR lpCmdLine,INT Show)
{
CPaintManagerUI::SetInstance(hInst);
CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetResourcePath());
//创建主窗口
MyWnd* pFrame = new MyWnd();
pFrame->Create(NULL,L"Tutorial6",UI_WNDSTYLE_FRAME,WS_EX_WINDOWEDGE);
pFrame->CenterWindow();
pFrame->ShowWindow(true);
CPaintManagerUI::MessageLoop();
return 0;
}
博文源码:https://github.com/rongbo-j/duilib-tutorial
(参考tutorial6工程)
DirectUI界面编程(六)实现右键弹出菜单的更多相关文章
- vc++ 如何添加右键弹出菜单
一.创建新工程 二.编辑菜单资源 1.添加菜单 按"Ctrl+R",双击"Menu"图标 2.于菜单编辑器内编辑菜单 四.添加代码(红色部分) void CCM ...
- win32进阶之路:程序托盘图标+右键弹出菜单
开场白 本次介绍两个非常棒且实用的技巧:程序托盘图标和右键弹出菜单,效果如下图. 程序托盘图标用了迅雷的图标,右键点击时候会弹出三个选项的菜单. 程序托盘图标设置 我会用尽可能清晰明了的步骤介绍方式 ...
- Vue2的右键弹出菜单(vue-contextmenu)
给大家推荐一个基于Vue2的右键弹出菜单插件,支持单一SPA页面以及可以在循环绑定中使用. 项目地址为:https://github.com/chIIC/vue-...demo1: 父组件绑定右键事件 ...
- 关于MFC主菜单和右键弹出菜单
一.主菜单.弹出菜单和右键菜单的概念: 主菜单是窗口顶部的菜单,一个窗口或对话框只能有一个主菜单,但是主菜单可以被更改(SetMenu()更改): 创建方式:CMenu::CreateMenu(voi ...
- SWT中的Tree中 添加右键弹出菜单
先看一下效果: 如图:在树上单击鼠标右键会弹出 弹出式菜单.做法其实很简单,先做一个树: final TreeViewer treeViewer = new TreeViewer(group, SWT ...
- js+css实现带缓冲效果右键弹出菜单
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- QT 右键弹出菜单
QWidget及其子类都可有右键菜单 1.设置标志 在widget初始化的时候 setContextMenuPolicy(Qt::CustomContextMenu); 设置为自定义菜单模式 2.在需 ...
- Win32建立右键弹出菜单(PopMenu)
自定义右键菜单: #ifndef _CONTEXTMENU_H_ #define _CONTEXTMENU_H_ #include <windows.h> //动态菜单 #define I ...
- Qt编程之对QGraphicsItem点击右键弹出菜单
就是对这个contextMenuEvent 事件重新实现,在这个事件函数中创建菜单,大概就是这样. void MyItem::contextMenuEvent(QGraphicsSceneContex ...
随机推荐
- Computer Vision的尴尬
原文: Computer Vision是AI的一个非常活跃的领域,每年大会小会不断,发表的文章数以千计(单是CVPR每年就录取300多,各种二流会议每年的文章更可谓不计其数),新模型新算法新应用层出不 ...
- 编写可维护的javascript阅读笔记
格式 变量 变量命名, 采取小驼峰大小写 变量使用名词, 函数前缀为动词 局部变量应统一定义在函数的最上面, 而不是散落在函数的任意角落. 赋初始值的定义在未赋初始值的变量的上面. 我个人建议不使用单 ...
- JDK源码中的英文注释翻译(Class)
public final class Class<T> implements java.io.Serializable, GenericDeclaration, Type, Annotat ...
- SQL Server 2017 安装问题(转)
遇到问题 Polybase 要求安装 Oracle JRE7 更新 规则失败 安装完毕之后,登录提示:您试图连接的 SQL Server 实例未安装 安装完SQL Server 2017 后,无法启动 ...
- centos7.XXX配置python3环境
众做周知,centos 是自带python2.7的.可是随着社会的进步,科技的发展,技术一步步更新换代,python2.7已经不足以满足项目的需求.这时候python3横空出世. 下面跟着我来一起实现 ...
- Javascript继承(原始写法,非es6 class)
知识点: Object.create的内部原理: Object.create = function (o) { var F = function () {}; F.prototype ...
- IOS开发:使用lipo合并armv7,i386,armv7s库文件
假设多个版本的lib分别是 libxxx.armv7.a , libxxx.armv7s.a, libxxx.i386.a我们的目标是 把他们合并成超级通用版的libxxx.a 打开命令行 Term ...
- css中的流,元素,基本尺寸
流 元素 基本尺寸 流之所以影响整个css世界,是因为它影响了css世界的基石 --HTML HTML 常见的标签有虽然标签种类繁多,但通常我们就把它们分为两类: 块级元素(block-level e ...
- P3375 【模板】KMP字符串匹配 (KMP模板)
题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next. (如果你不知道这是什么意思也不要问,去百度 ...
- 树状数组||归并排序求逆序对+离散化 nlogn
我好咸鱼. 归并排序之前写过,树状数组就是维护从后往前插入,找比现在插入的数大的数的数量. 如果值域大,可以离散化 #include <cstdio> #include <cstri ...