二、设置图片框
(一)图片框需要响应WM_LBUTTONDOWN消息和WM_LBUTTONUP消息。而图片框在正常状态下只响应鼠标单击消息BN_CLICK。所以,我们要通过子类化来响应上述两个消息。
属性设置里,把图片框的ID设为IDC_PIC,并选中其Notify属性(否则不响应消息)。依次点击菜单Insert->New Class,Class type选择MFC Class,类名取为CMyPic,基类为CStatic。添加CSpyXXDlg类的私有成员变量CMyPic m_pic,在对话框的初始化过程中将其与图片框关联。代码如下:
m_pic.SubclassDlgItem(IDC_PIC,this);//初始化过程中将其与拖动图标的图片框关联
在CMyPic类中,我们就可以响应鼠标左键按下和弹起的消息了。按Ctrl + W打开Class Wizard,选择Message Maps标签页,在Class name下拉列表中选择CMyPic。从Messages列表中分别增加WM_LBUTTONDOWN和WM_LBUTTONUP消息,并接受其缺省函数名OnLButtonDown和OnLButtonUp。图标交换和鼠标光标交换的代码如下:
void CMyPic::OnLButtonDown(UINT nFlags, CPoint point) { SetCapture(); HCURSOR hc = LoadCursor(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDC_CURSOR)); ::SetCursor(hc); HICON hicon2 = LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDC_CURSOR)); this->SetIcon(hicon2); SetTimer(1,55,NULL); CStatic::OnLButtonDown(nFlags, point); } void CMyPic::OnLButtonUp(UINT nFlags, CPoint point) { ReleaseCapture(); HICON hicon1 = LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDR_MAINFRAME)); this->SetIcon(hicon1); KillTimer(1); if (UnHwnd>0){ LRESULT result = 0; char cc[101]; ::GetWindowText(UnHwnd,cc,255); CString s;//&zx&kab&ak&qc&dtx&zwq& s.Format("%d",UnHwnd); pMatchScore->SetWindowText("OK"); } CStatic::OnLButtonUp(nFlags, point); }
(二)实现获取窗口句柄。根据鼠标位置来确定窗口需要用到API函数GetCursorPos和WindowFromPoint。此外,我们还想做到像抓图程序那样,鼠标移动到的地方,窗口四周会出现闪烁的矩形。这一点,我们用定时器来实现。
在OnLButtonDown里设置启动:SetTimer(1,55,NULL);在OnLButtonUp里将它停止:killtimer(1);
定时器代码如下:
void CMyPic::OnTimer(UINT nIDEvent) { POINT pnt; RECT rc; HWND DeskHwnd = ::GetDesktopWindow(); //取得桌面句柄 HDC DeskDC = ::GetWindowDC(DeskHwnd); //取得桌面设备场景 int oldRop2 = SetROP2(DeskDC, R2_NOTXORPEN); ::GetCursorPos(&pnt); //取得鼠标坐标 UnHwnd = ::WindowFromPoint(pnt) ; //取得鼠标指针处窗口句柄 g_hWnd=UnHwnd; hWnd=UnHwnd; ::GetWindowRect(g_hWnd, &rc); //获得窗口矩形 if( rc.left < 0 ) rc.left = 0; if (rc.top < 0 ) rc.top = 0; HPEN newPen = ::CreatePen(0, 3, 0); //建立新画笔,载入DeskDC HGDIOBJ oldPen = ::SelectObject(DeskDC, newPen); ::Rectangle(DeskDC, rc.left, rc.top, rc.right, rc.bottom); //在窗口周围显示闪烁矩形 Sleep(400); //设置闪烁时间间隔 ::Rectangle( DeskDC, rc.left, rc.top, rc.right, rc.bottom); ::SetROP2(DeskDC, oldRop2); ::SelectObject( DeskDC, oldPen); ::DeleteObject(newPen); ::ReleaseDC( DeskHwnd, DeskDC); DeskDC = NULL; CStatic::OnTimer(nIDEvent); }
现在运行一下,可以看到效果了。
测试通过:VC6 for Windows11
联系客服