吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2733|回复: 9
收起左侧

[C&C++ 原创] 简单模仿Spy++(MFC实例源码)

[复制链接]
嵌入式.h 发表于 2023-6-27 16:10
本帖最后由 嵌入式.h 于 2023-6-30 15:39 编辑

先上图吧。摸鱼临时写的没有验证、有些逻辑存在一些问题、MFC的客户区对控件消息可能会有一定影响、隐藏起来或将客户区大小设置为0可能比较好。
sshot-1.png

流程和思路都是借鉴的、自己用MFC实现的、只是实现获取窗口句柄、类名、和标题、发上来仅供有兴趣的新手朋友学习交流、下面贴源码:
[C++] 纯文本查看 复制代码
// SpyPPDlg.h : 头文件
//

#pragma once


// CSpyPPDlg 对话框
class CSpyPPDlg : public CDialogEx
{
// 构造
public:
        CSpyPPDlg(CWnd* pParent = NULL);        // 标准构造函数

// 对话框数据
        enum { IDD = IDD_SPYPP_DIALOG };

        protected:
        virtual void DoDataExchange(CDataExchange* pDX);        // DDX/DDV 支持


// 实现
protected:
        HICON m_hIcon;
        BOOL m_bMouseOver; //跟踪鼠标移动的标志。
        // 生成的消息映射函数
        virtual BOOL OnInitDialog();
        afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
        afx_msg void OnPaint();
        afx_msg HCURSOR OnQueryDragIcon();
        DECLARE_MESSAGE_MAP()
public:
        afx_msg void OnBnClickedOk();
        afx_msg void OnTimer(UINT_PTR nIDEvent);
        afx_msg void OnMouseMove(UINT nFlags, CPoint point);
        afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
        afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
};


[C++] 纯文本查看 复制代码
// SpyPPDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "SpyPP.h"
#include "SpyPPDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

HWND topHwnd;                                        //鼠标指针出窗口句柄全局变量
HCURSOR mHCURSOR,hCursor;                //新旧鼠标光标
void HuaBk();                                        //画边框函数声明
HWND GetMouseWindowHandle();        
CString GetWindowTitleFromHandle(HWND hwnd);
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
        CAboutDlg();

// 对话框数据
        enum { IDD = IDD_ABOUTBOX };

        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
        DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
        CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CSpyPPDlg 对话框




CSpyPPDlg::CSpyPPDlg(CWnd* pParent /*=NULL*/)
        : CDialogEx(CSpyPPDlg::IDD, pParent)
{
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
        m_bMouseOver=FALSE;
}

void CSpyPPDlg::DoDataExchange(CDataExchange* pDX)
{
        CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CSpyPPDlg, CDialogEx)
        ON_WM_SYSCOMMAND()
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_BN_CLICKED(IDOK, &CSpyPPDlg::OnBnClickedOk)        
        ON_WM_TIMER()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
END_MESSAGE_MAP()


// CSpyPPDlg 消息处理程序

BOOL CSpyPPDlg::OnInitDialog()
{
        CDialogEx::OnInitDialog();

        // 将“关于...”菜单项添加到系统菜单中。

        // IDM_ABOUTBOX 必须在系统命令范围内。
        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
        ASSERT(IDM_ABOUTBOX < 0xF000);

        CMenu* pSysMenu = GetSystemMenu(FALSE);
        if (pSysMenu != NULL)
        {
                BOOL bNameValid;
                CString strAboutMenu;
                bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
                ASSERT(bNameValid);
                if (!strAboutMenu.IsEmpty())
                {
                        pSysMenu->AppendMenu(MF_SEPARATOR);
                        pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
                }
        }

        // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
        //  执行此操作
        SetIcon(m_hIcon, TRUE);                        // 设置大图标
        SetIcon(m_hIcon, FALSE);                // 设置小图标

        // TODO: 在此添加额外的初始化代码

        mHCURSOR=::LoadCursorFromFileA("res\\eye.cur"); //加载鼠标替换光标
        hCursor = ::LoadCursor(NULL, IDC_ARROW); // 加载系统的箭头光标

        return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CSpyPPDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
        if ((nID & 0xFFF0) == IDM_ABOUTBOX)
        {
                CAboutDlg dlgAbout;
                dlgAbout.DoModal();
        }
        else
        {
                CDialogEx::OnSysCommand(nID, lParam);
        }
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CSpyPPDlg::OnPaint()
{
        if (IsIconic())
        {
                CPaintDC dc(this); // 用于绘制的设备上下文

                SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

                // 使图标在工作区矩形中居中
                int cxIcon = GetSystemMetrics(SM_CXICON);
                int cyIcon = GetSystemMetrics(SM_CYICON);
                CRect rect;
                GetClientRect(&rect);
                int x = (rect.Width() - cxIcon + 1) / 2;
                int y = (rect.Height() - cyIcon + 1) / 2;

                // 绘制图标
                dc.DrawIcon(x, y, m_hIcon);
        }
        else
        {
                CDialogEx::OnPaint();
        }
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CSpyPPDlg::OnQueryDragIcon()
{
        return static_cast<HCURSOR>(m_hIcon);
}



void CSpyPPDlg::OnBnClickedOk()
{
        // TODO: 在此添加控件通知处理程序代码
        CDialogEx::OnOK();
}
//画边框
void HuaBk()
{

        HWND DesktopWindowHwnd=GetDesktopWindow();//取桌面窗口hwnd 
        HDC DesktopWindowDC= GetWindowDC(DesktopWindowHwnd);//取窗口设备场景 
        int DrawMode= SetROP2(DesktopWindowDC,10);//设置指定设备场景的绘图模式,并返回窗口前一个绘图模式 
        CRect rect;
        GetWindowRect(topHwnd,rect);//获得整个窗口的范围矩形,窗口的边框、标题栏、滚动条及菜单等都在这个矩形内 
        HPEN PenHwnd =::CreatePen(0,4,0x00ff00);//用指定的样式、宽度和颜色创建一个画笔,并返回一个画笔hwnd 
        HGDIOBJ OldPenHwnd =SelectObject(DesktopWindowDC,PenHwnd);//选入设备场景,并返回以前选入设备场景的相同hObject类型的一个对象的hwnd 
        Rectangle(DesktopWindowDC,rect.left-1,rect.top-1,rect.right+1,rect.bottom+1);
        SelectObject(DesktopWindowDC,OldPenHwnd);//选入设备场景 
        SetROP2(DesktopWindowDC,DrawMode);//设置指定设备场景的绘图模式 
        DeleteObject(PenHwnd);//删除对象 
        ReleaseDC(DesktopWindowHwnd,DesktopWindowDC);//释放由调用GetDC或GetWindowDC函数获取的指定设备场景 

}



//定时器消息映射
void CSpyPPDlg::OnTimer(UINT_PTR nIDEvent)
{
        // TODO: 在此添加消息处理程序代码和/或调用默认值
        topHwnd=GetMouseWindowHandle();//获得鼠标处窗口句柄
        SetDlgItemInt(IDC_EDIT_HWND,(int)topHwnd);//显示句柄
        TCHAR classname[256];
        GetClassName(topHwnd,classname,256);//取类名
        SetDlgItemText(IDC_EDIT_CLASS,CString(classname));//显示类名
        SetDlgItemTextW(IDC_EDIT_TITLE,GetWindowTitleFromHandle(topHwnd));//显示标题
        HuaBk();
        CDialogEx::OnTimer(nIDEvent);
}
//鼠标移动映射消息
void CSpyPPDlg::OnMouseMove(UINT nFlags, CPoint point)
{
        // TODO: 在此添加消息处理程序代码和/或调用默认值
        //获取控件的句柄
        CWnd* pWnd=FromHandle(GetDlgItem(IDC_STATIC)->GetSafeHwnd());
        //检查鼠标是否在控件上
        CRect rect;
        pWnd->GetClientRect(&rect);
        if (rect.PtInRect(point))
        {
                if (!m_bMouseOver)
                {
                        // 鼠标进入控件
                        m_bMouseOver = TRUE;
                        // 执行鼠标移动时的操作
                        // ...
                        /*AfxMessageBox(L"鼠标进入控件");*/
                        SetClassLongA(m_hWnd,-12,(LONG)mHCURSOR);//设置鼠标光标为新的光标
                }
        }
        else
        {
                if (m_bMouseOver)
                {
                        // 鼠标离开控件
                        m_bMouseOver = FALSE;
                        // 执行鼠标离开时的操作
                        // ...
                        //AfxMessageBox(L"鼠标离开控件");
                        SetClassLongA(m_hWnd,-12,(LONG)hCursor);//设置鼠标光标为默认光标
                }
        }
        CDialogEx::OnMouseMove(nFlags, point);
}

//鼠标左键按下映射消息
void CSpyPPDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
        // TODO: 在此添加消息处理程序代码和/或调用默认值
        SetTimer(0x11,300,nullptr);//注册定时器开始画捕获窗口的边框
        SetCapture();   //捕获鼠标、防止鼠标跑出窗口、无法捕获鼠标消息

        CDialogEx::OnLButtonDown(nFlags, point);
}

//鼠标左键释放映射消息
void CSpyPPDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
        // TODO: 在此添加消息处理程序代码和/或调用默认值
        KillTimer(0x11);//定时器销毁、停止捕获窗口
        ReleaseCapture();  //释放鼠标捕获
        CDialogEx::OnLButtonUp(nFlags, point);
}
//取鼠标指针处窗口句柄
HWND GetMouseWindowHandle()
{
        // 获取当前鼠标光标位置
        CPoint ptCursor;
        GetCursorPos(&ptCursor);

        // 从屏幕坐标来获取窗口句柄
        HWND hWnd = ::WindowFromPoint(ptCursor);

        return hWnd;
}
//取标题
CString GetWindowTitleFromHandle(HWND hwnd)
{
        TCHAR windowTitle[256];
        int titleLength = GetWindowTextLength(hwnd);
        GetWindowText(hwnd, windowTitle, sizeof(windowTitle));
        return CString(windowTitle, titleLength);
}


SpyPP.7z

67.99 KB, 下载次数: 76, 下载积分: 吾爱币 -1 CB

MFC编译的程序

免费评分

参与人数 4吾爱币 +10 热心值 +4 收起 理由
Never + 1 + 1 用心讨论,共获提升!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
junjia215 + 1 + 1 用心讨论,共获提升!
Fan2115 + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

benny856694 发表于 2023-6-27 16:47
不错的,mfc已经很久没用过了。学c#了
adamfh 发表于 2023-6-27 20:28
 楼主| 嵌入式.h 发表于 2023-6-27 23:49
下载附件的朋友,需要注意一下附件里是没有鼠标光标文件的,拖动时鼠标光标不会改变、我没把光标文件加到资源里,可参考代码自行添加,或自己动手写一个
Limit-fly 发表于 2023-6-29 14:52
不错不错   我用QT模仿写一个!
wqq4309593 发表于 2023-11-2 19:42
到处找,终于找到了。
SKY666DASHUAIGE 发表于 2023-11-24 19:10
感谢,对我有帮助
彩色旗子321 发表于 2023-12-25 10:17
刚好需要,太棒了
gulei 发表于 2024-2-24 16:25
刚好需要,太棒了
wuhao121 发表于 2024-3-5 11:28
MFC和C#哪个好用?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 20:01

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表