飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 2520|回复: 1

[C/C++] [原创]星号密码查看器(MFC)

[复制链接]

该用户从未签到

发表于 2009-8-15 16:11:00 | 显示全部楼层 |阅读模式
星号密码查看器,MFC程序,源码如下
PS:论坛没有代码着色插件,发源码真不爽。。。

///////////////////////////////////////////////////////////////////////
// DropButton.h : 声明文件
//

#pragma once


// CDropButton

class CDropButton : public CButton
{
        DECLARE_DYNAMIC(CDropButton)

public:
        CDropButton();
        virtual ~CDropButton();

protected:
        DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
};


///////////////////////////////////////////////////////////////////////
// DropButton.cppParam : 实现文件
//

#include "stdafx.h"
#include "ShowPass.h"
#include "DropButton.h"


// CDropButton

IMPLEMENT_DYNAMIC(CDropButton, CButton)

CDropButton::CDropButton()
{
}

CDropButton::~CDropButton()
{
}

BEGIN_MESSAGE_MAP(CDropButton, CButton)
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
END_MESSAGE_MAP()

//------------这里以上都是MFC框架代码------------

//全局结构体和函数

//EnumChildWindowProc只能传一个4字节参数,所以传该结构体的指针
struct Param
{
    int x;
    int y;
    HWND hFind;
    DWORD dwWidth;
};

BOOL CALLBACK EnumChildWindowProc(HWND hwnd,LPARAM lParam)
{
    struct Param* pParam = (struct Param*)lParam;
    RECT rcWindow;

    //不处理不可见的窗口
    if (!IsWindowVisible(hwnd))
        return TRUE;

    //获取窗口所在的矩形范围
    GetWindowRect(hwnd, &rcWindow);

    //检查(pParam.x,pParam.y)是否位于该矩形范围内
    if (pParam->x >= rcWindow.left &&
        pParam->y >= rcWindow.top &&
        pParam->x <= rcWindow.right &&        
        pParam->y <= rcWindow.bottom)
    {
        //找位于该矩形范围内,宽度最小的窗口
        DWORD dwWidth = (DWORD)(rcWindow.right - rcWindow.left);

        if( dwWidth < pParam->dwWidth)
        {
            pParam->hFind = hwnd;
            pParam->dwWidth = dwWidth;
        }
    }

    return TRUE;
}


HWND SearchWindow(HWND hWnd, POINT ptScreen)
{
    struct Param param;
   
    param.x = ptScreen.x;
    param.y = ptScreen.y;
    param.hFind = 0;
    param.dwWidth = -1;

    //枚举子窗口
    EnumChildWindows(hWnd, EnumChildWindowProc, (LPARAM)&param);

    //当没有找到窗口,或者找到的窗口就是窗口本身时,结束递归
    if (param.hFind == NULL || param.hFind == hWnd)
        return hWnd;

    //递归调用
    return SearchWindow(param.hFind, ptScreen);
}

HWND GetWindowFromPointEx(POINT ptScreen)
{
    HWND hWnd = NULL;       //鼠标指向的窗口句柄
    DWORD dwStyle = 0;      //鼠标指向的窗口样式
    POINT ptRelative = {0}; //相对于窗口的位置
    POINT ptWindow = {0};   //窗口在屏幕中的位置
    HWND hChild = NULL;     //子窗口句柄
    LPARAM lParam = NULL;   //WM_NCHITTEST消息的参数
    DWORD dwResult = 0;     //接收SendMessageTimeout的传出参数
    DWORD dwRet = 0;        //接收SendMessageTimeout的返回值

    //获取指定位置下的窗口(如果是子窗口,取得的将是其父窗口的句柄)
    hWnd = WindowFromPoint(ptScreen);
    if (hWnd==NULL)
    {
        return NULL;
    }

    //将坐标从指定窗口的(0,0)位置转化为全屏幕的坐标
    //也就是取得窗口在屏幕中的位置
    ClientToScreen(hWnd,&ptWindow);

    //计算指定位置在这个窗口中的相对坐标
    ptRelative.x = ptScreen.x - ptWindow.x;
    ptRelative.y = ptScreen.y - ptWindow.y;

    //先尝试使用API获得子窗口
    hChild = ChildWindowFromPoint(hWnd, ptRelative);
    if (hChild != NULL)
        hWnd = hChild;

    //把屏幕坐标位置放入lParam中
    lParam = MAKELPARAM(ptScreen.x, ptScreen.y);

    //获取窗口样式,如果是子窗口就直接返回这个窗口的句柄
    dwStyle = GetWindowLong(hWnd, GWL_STYLE);
    if (!(dwStyle & WS_CHILDWINDOW))
    {
        return hWnd;
    }

    //向目标窗口发送WM_NCHITTEST消息
    dwRet = SendMessageTimeout(
        hWnd,               //hWnd
        WM_NCHITTEST,       //Msg
        0,                  //wParam
        lParam,             //lParam
        SMTO_ABORTIFHUNG,   //fuFlags
        1000,               //uTimeout
        &dwResult           //lpdwResult
        );

    //检查窗口是否处理了WM_NCHITTEST消息
    if(dwRet != NULL && dwResult == HTTRANSPARENT)
    {
        //如果目标窗口没有处理,说明还有子窗口
        //调用自己的函数搜索子窗口
        hWnd = SearchWindow(GetParent(hWnd), ptScreen);
    }

    return hWnd;
}

// CDropButton 消息处理程序

//鼠标左键按下
void CDropButton::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    SetCapture();       //设置捕获,当鼠标移出当前窗口范围时,依然可以收到鼠标左键弹起等消息
    CButton::OnLButtonDown(nFlags, point);  //调用父类处理函数
}

//鼠标左键弹起
void CDropButton::OnLButtonUp(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    HWND hCurrentWnd = NULL;    //当前鼠标指向的窗口句柄
    CPoint PointScreen;         //鼠标箭头在屏幕中的位置

    ReleaseCapture();           //释放捕获,和SetCapture成对出现
    GetCursorPos(&PointScreen); //获取当前鼠标箭头的位置
    hCurrentWnd = GetWindowFromPointEx(PointScreen);    //获取鼠标指向的窗口
    if (hCurrentWnd != NULL)
    {
        //如果找到了这个窗口,就向其发送消息“EM_SETPASSWORDCHAR”,设置密码回显字符为空
        ::PostMessage(hCurrentWnd, EM_SETPASSWORDCHAR, 0, 0);
    }
   
    //此时应该重绘目标窗口,但我没有做,有兴趣的自己做重绘吧
    //不做重绘的话,用其他窗口遮挡一下再移开,就看到星号密码了

    CButton::OnLButtonUp(nFlags, point);    //调用父类处理函数
}
PYG19周年生日快乐!

该用户从未签到

发表于 2009-8-25 10:08:40 | 显示全部楼层

哇~~~~~~

哇~~~~~~
PYG19周年生日快乐!
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

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