上一篇文章就讲了一个将图像复制到剪切板的函数,这篇文章接着讲如何确定截图窗口。说道确定窗口就想到了一个常用的插件sp++,其查找界面如下:
通过单击图标,将光标移动到想要的窗口时就会在窗口外显示一个醒目的边框,并且得到该窗口的相应信息。
哈哈,这不就是我们想要的功能吗!!
关于此功能的实现,网上搜一下”SP++原理“有一大堆资料,我这里就稍微介绍一下(因为我们用到的功能就是显示提示边框和获得窗口的句柄信息)。
下面是具体实现:
1、外观界面的实现,实现效果是用户左键在图标上按下后,图标换成空白的,而同时光标变成,这样的效果是造成一种靶心被拖出去的感觉。
2、当用户左键弹起时,空白图标恢复成原样,同时光标也恢复原样。
3、显然实现此功能要响应WM_LBUTTONDOWN消息和WM_LBUTTONUP消息这两个消息,对话框上的是一个picture control控件,而picture control在正常状态下只响应鼠标单击消息BN_CLICK。所以,我们要通过子类化来响应上述两个消息。
4、导入所需的资源(两个图标文件和一个光标文件):
图标或光标 | ID |
IDI_ICON1 | |
IDI_ICON2 | |
IDC_CURSOR1 |
5、将picture control的ID设为IDC_PIC,设置图片控件(即picture control)的属性:类型为图标,图像IDI_ICON1。如图:
6、打开类向导,新建一个类CMyPic,基类为CStatic。如图:
7、在CMyPic类中,我们就可以响应鼠标左键按下和弹起的消息了。按Ctrl + W打开Class Wizard,选择Message Maps标签页,在Class name下拉列表中选择CMyPic。从Messages列表中分别增加WM_LBUTTONDOWN和WM_LBUTTONUP消息。
<span style="font-size:18px;">void CMyPic::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
SetCapture(); // 鼠标捕获
HCURSOR hc = LoadCursor(AfxGetApp()->m_hInstance, MAKEINTRESOURCE (IDC_CURSOR1));
//IDC_CURSOR1是靶形光标资源号
::SetCursor(hc);
HICON hicon2 = LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE (IDI_ICON2));
//IDI_ICON2为无靶图标资源号
this->SetIcon(hicon2);
CStatic::OnLButtonDown(nFlags, point);
}
void CMyPic::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
ReleaseCapture(); //释放鼠标捕获
HICON hicon1 = LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE (IDI_ICON1));
//IDI_ICON1是有靶图标资源号
this->SetIcon(hicon1);
CStatic::OnLButtonUp(nFlags, point);
}</span>
8、添加CMy123Dlg类的私有成员变量CMyPic m_pic,在对话框的初始化过程中将其与图片框关联。
<span style="font-size:18px;">BOOL CMy123Dlg::OnInitDialog()
{
……
// TODO: Add extra initialization here
m_pic.SubclassDlgItem(IDC_PIC,this); // 关联
return TRUE; // return TRUE unless you set the focus to a control
}</span>
9、至此,拖动动作完成,尝试运行,发现单击图标后没有任何反应,是因为图片控件(即picture control)的Notify属性(通知属性)未选中(所以不响应消息)。如图:
10、选中”通知“属性后,就能实现拖动操作了。