D3DDrawLib 绘制外部动态菜单
一个基于D3DDrawLib库开发的外部动态菜单,其允许用户在任意窗体之上绘制自定义菜单界面,这一菜单具备高度的灵活性,能够通过热键实现上下左右的导航选择功能,用户可以轻松切换不同的功能项,并能够在多个应用程序之间无缝切换和操作。
实现动态菜单绘制功能,需要分别准备两个函数,其中Menu
函数可为菜单提供绘制功能,而MyFunctionCallBack
函数则可用于注册及管理热键,由于绘制及热键的监控是实时的此处还需要一个Draw
函数来将这两个函数串连起来,在main
主函数中仅需要注册热键并调用createWindow
来实现绘制即可。
引用头文件
首先读者应自行引入Microsoft DirectX SDK (June 2010)
开发工具包,引入D3DDrawLib.h
头文件,并通过pragma comment
导入D3DDrawLib.lib
静态库,在如下代码部分CurrentlySelected
指明了菜单默认选中项为第一个功能,IsItDisplayed
函数用于指定是否显示菜单,最后的MenuOnTheRight
用于控制菜单是居左显示还是居右显示,底部的功能A-G
则是不同功能项的开关按钮。
|
动态绘制菜单
如下 Menu
函数用于绘制一个动态的菜单界面,菜单的显示与否由 IsItDisplayed
变量控制。它根据窗口的宽度和高度,动态计算菜单的位置并绘制功能项。用户可以通过选择不同的功能项来开关功能,功能项的状态(开启或关闭)会在菜单中显示。
通过MenuOnTheRight
开关判断菜单是居左显示还是居右显示,接着DrawBorderRectangle
用于绘制选择条,紧随其后的DrawBorderRectangle
用于绘制整个功能菜单的外边框矩形,其内部的每一个子功能项都由一个DrawStringAndString
来绘制实现,而在字符串绘制时通过使用?:
条件运算符(也称为三元运算符)实现对选择字体的动态着色,当被开启时为绿色,而被关闭时则为蓝色。
void Menu() |
上述所示的代码虽然可以很好的实现菜单的功能绘制,但是若我们要新增一个菜单项则会很麻烦,我们需要手动计算外边框的高度及计算字体的排列位置,在优化时,我们将菜单项单独放入一个itemNames
数组内,并将每一个字符串与itemStates
数组中的元素相关联,通过使用For循环,循环itemCount
次,并调用DrawStringAndString
函数写菜单,来依次排列这些字符串到特定位置,最后通过DrawString
函数在矩形菜单之外写出一段提示信息,其改进后的代码如下所示;
void Menu() |
我们继续完善菜单功能,在上述代码不变的前提下,为菜单增加一个表头并在表头中显示一些文本文档以标注菜单名称及版本等信息,其他部分保持不变即可。
void Menu() |
增加热键检测
接着我们需要为菜单增加热键检测功能,此处通过上下按钮来选择菜单项,通过左右按钮来实现菜单项的打开与关闭,在主函数中通过调用RegisterHotKey
我们依次定义1-5
数字,并将其关联到VK_UP
、VK_DOWN
、VK_LEFT
、VK_RIGHT
、VK_HOME
热键上,在MyFunctionCallBack
控制器回调中,通过GetMessage
来获取键盘消息,并检测WM_HOTKEY
是否为热键,若是则通过判断msg.wParam
中的按键码来识别光标动作。
针对光标动作,若检测到上光标,由于CurrentlySelected
默认选中项是从1开始的,则等于0则说明是最顶部,此时需要将CurrentlySelected
设置为7,即跳转到最后一个菜单项上。
同理,若检测到下光标则判断CurrentlySelected
是否为8,若是则说明到最后一个了此时就需要将CurrentlySelected
指定为第一个菜单项上。
至于左光标与右光标,仅需要针对不同的CurrentlySelected
设置不同的状态即可,最后则是通过判断是否为HOME键,若是则直接执行真假切换即可。
// 控制器函数 |
绘制菜单演示
最后,在主调函数中通过Draw
函数将Menu
与MyFunctionCallBack
串联起来,并将Draw
绘制函数一并交给Start()->createWindow
窗体创建类处理,则可以完成整个窗体的绘制部分。
void Draw() |
读者可自行编译该程序代码,并运行窗体类名为DrawingBoard
的进程,当本程序被运行后则会默认在DrawingBoard
进程左侧出现一个可以控制的动态菜单,此时通过使用上下功能键可选择不同功能,通过使用右键开启功能,使用左键则是关闭功能,其绘制效果如下图所示;
警告:本篇文章中所涉及的内容仅用于技术交流与研究之用,仅允许被用于正规用途或学习目的,请读者自觉遵守相关法规,禁止滥用。