基于Visual C++2010与windows7 sdk开发Windows7应用(3) 放大镜-方面视觉障碍用户

新的Windows 7放大镜是一个长期错过的工具,应已包括在以前的版本。随着大显示器变得越来越受欢迎,这样的工具成为必须拥有许多熟悉的用户。这也使得这样的介绍更加愉快的两个主持人和audients 。微软最后覆盖这块和杀害所有其他类似的第三方应用服务死刑。

很多朋友都有在深夜看电影或者玩游戏的习惯,为了家人的休息,此时往往会关闭书房的灯光,单纯依靠显示器的亮度,但是这样却给操作电脑带来一些不便。其实,可以利用Windows 7的放大镜组件助力“无灯环境”。

首先从开始菜单中依次选择“所有程序/附件/轻松访问/放大镜”,或者在按下Windows键的同时,按下数字键盘的“+”键,弹出放大镜窗口之后,单击齿轮状的“选项”图标(如图1),把缩放大小调整在100%,然后勾选“启用颜色反转”复选框,确认之后即可生效。以后,你就可以在夜晚关闭灯光的情况下,获得非常清晰的效果了(如图2)。是不是很像电子书阅读软件的夜晚模式呢?当然,如果显示器亮度不足的话,经常使用可能会对视力带来一些影响,因此请朋友们按照自己的实际情况进行选择。

 

可以简单地使用键盘快捷方式来启动和关闭,以放大镜你的整个桌面,即

Windows logo key Picture of Windows logo key + Plus to zoom in Windows logo key Picture of Windows logo key + Minus to zoom out, and Windows logo key Picture of Windows logo key + ESC to exit.

 

放大镜可放大屏幕的各个部分。这在查看难以看到的对象时特别有用,但也可以更加容易地查看整个屏幕。

放大镜有以下三种模式:

  • 全屏模式。在全屏模式下,您的整个屏幕会被放大。然后您可以使放大镜跟随鼠标指针。

  • 镜头模式。在镜头模式下,鼠标指针周围的区域会被放大。移动鼠标指针时,放大的屏幕区域随之移动。

  • 停靠模式。在停靠模式下,仅放大屏幕的一部分,桌面的其余部分处于正常状态。然后您可以控制放大哪个屏幕区域。

  • 您也可以使用长度选择只考核一个指针周围地区的工程,就像真正的放大镜移动在您的桌面上,或选择了被告席模式,显示了放大区上方的码头区。你可以切换回来和武力使用键盘快捷键,而您仍然在放大镜检视。

  • Ctrl + Alt + F – Full screen mode
  • Ctrl + Alt + L – Len mode
  • Ctrl + Alt + D – Dock mode

 

 

 

 

 

 

 

 

我们来亲自实践一下基于Visual C++2010与windows7 sdk开发Windows7应用(3) 放大镜-

 

 

详细请看代码分析  

 

#include <windows.h>
#include <wincodec.h>
#include <magnification.h>

// 为简单起见,使用一个 固定的放大系数
#define MAGFACTOR  2.0f
#define RESTOREDWINDOWSTYLES WS_SIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CAPTION | WS_MAXIMIZEBOX

//全局变量和字符串。
HINSTANCE           hInst;
const TCHAR         WindowClassName[]= TEXT("放大镜");
const TCHAR         WindowTitle[]= TEXT("屏幕放大镜例子");
const UINT          timerInterval = 16; //接近@ 60Hz的刷新率
HWND                hwndMag;
HWND                hwndHost;
RECT                magWindowRect;
RECT                hostWindowRect;

ATOM                RegisterHostWindowClass(HINSTANCE hInstance);
BOOL                SetupMagnifier(HINSTANCE hinst);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
void CALLBACK       UpdateMagWindow(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
void                GoFullScreen();
void                GoPartialScreen();
BOOL                isFullScreen = FALSE;

 

//初始化程序
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE /*hPrevInstance*/,
                     LPSTR     /*lpCmdLine*/,
                     int       nCmdShow)
{
    if (FALSE == MagInitialize())
    {
        return 0;
    }
    if (FALSE == SetupMagnifier(hInstance))
    {
        return 0;
    }

    ShowWindow(hwndHost, nCmdShow);
    UpdateWindow(hwndHost);

    // 创建时钟更新图像
    UINT_PTR timerId = SetTimer(hwndHost, 0, timerInterval, UpdateMagWindow);

    // 消息循环
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    // 关闭
    KillTimer(NULL, timerId);
    MagUninitialize();
    return (int) msg.wParam;
}


// 窗口程序的窗口承载放大镜

LRESULT CALLBACK HostWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message) 
    {
    case WM_KEYDOWN:
        if (wParam == VK_ESCAPE)
        {
            if (isFullScreen) 
            {
                GoPartialScreen();
            }
        }
        break;

    case WM_SYSCOMMAND:
        if (GET_SC_WPARAM(wParam) == SC_MAXIMIZE)
        {
            GoFullScreen();
        }
        else
        {
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    case WM_SIZE:
        if ( hwndMag != NULL )
        {
            GetClientRect(hWnd, &magWindowRect);
            // 重新设置窗口样式适应屏幕
            SetWindowPos(hwndMag, NULL, 
                magWindowRect.left, magWindowRect.top, magWindowRect.right, magWindowRect.bottom, 0);
        }
        break;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;  
}

//
//  注册放大镜窗口类
//
//  为窗口寄存器包含放大控制窗口类
//
ATOM RegisterHostWindowClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex = {};

    wcex.cbSize = sizeof(WNDCLASSEX); 
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = HostWndProc;
    wcex.hInstance      = hInstance;
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(1 + COLOR_BTNFACE);
    wcex.lpszClassName  = WindowClassName;

    return RegisterClassEx(&wcex);
}

//
// 创建和初始化的窗口放大。
//
BOOL SetupMagnifier(HINSTANCE hinst)
{
    //设定的窗口界限根据屏幕大小的主窗口。
    hostWindowRect.top = 0;
    hostWindowRect.bottom = GetSystemMetrics(SM_CYSCREEN) / 4;  //屏幕顶部
    hostWindowRect.left = 0;
    hostWindowRect.right = GetSystemMetrics(SM_CXSCREEN);

    // 创建主窗口
    RegisterHostWindowClass(hinst);
    hwndHost = CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED, 
        WindowClassName, WindowTitle, 
        RESTOREDWINDOWSTYLES,
        0, 0, hostWindowRect.right, hostWindowRect.bottom, NULL, NULL, hInst, NULL);
    if (!hwndHost)
    {
        return FALSE;
    }

    // 使窗口不透明。
    SetLayeredWindowAttributes(hwndHost, 0, 255, LWA_ALPHA);

    //创建一个放大镜控制填充图形区域
    GetClientRect(hwndHost, &magWindowRect);
    hwndMag = CreateWindow(WC_MAGNIFIER, TEXT("放大镜"), 
        WS_CHILD | MS_SHOWMAGNIFIEDCURSOR | WS_VISIBLE,
        magWindowRect.left, magWindowRect.top, magWindowRect.right, magWindowRect.bottom, hwndHost, NULL, hInst, NULL );
    if (!hwndMag)
    {
        return FALSE;
    }

    // 设置放大系数。
    MAGTRANSFORM matrix;
    memset(&matrix, 0, sizeof(matrix));
    matrix.v[0][0] = MAGFACTOR;
    matrix.v[1][1] = MAGFACTOR;
    matrix.v[2][2] = 1.0f;

    BOOL ret = MagSetWindowTransform(hwndMag, &matrix);

    if (ret)
    {
        MAGCOLOREFFECT magEffectInvert = 
        {{ 
            { -1.0f,  0.0f,  0.0f,  0.0f,  0.0f },
            {  0.0f, -1.0f,  0.0f,  0.0f,  0.0f },
            {  0.0f,  0.0f, -1.0f,  0.0f,  0.0f },
            {  0.0f,  0.0f,  0.0f,  1.0f,  0.0f },
            {  1.0f,  1.0f,  1.0f,  0.0f,  1.0f } 
        }};

        ret = MagSetColorEffect(hwndMag,&magEffectInvert);
    }

    return ret;  
}


//
//随着时钟频率更新窗口
//
void CALLBACK UpdateMagWindow(HWND /*hwnd*/, UINT /*uMsg*/, UINT_PTR /*idEvent*/, DWORD /*dwTime*/)
{
    POINT mousePoint;
    GetCursorPos(&mousePoint);

    int width = (int)((magWindowRect.right - magWindowRect.left) / MAGFACTOR);
    int height = (int)((magWindowRect.bottom - magWindowRect.top) / MAGFACTOR);
    RECT sourceRect;
    sourceRect.left = mousePoint.x - width / 2;
    sourceRect.top = mousePoint.y -  height / 2;

    //不突破屏幕区域
    if (sourceRect.left < 0)
    {
        sourceRect.left = 0;
    }
    if (sourceRect.left > GetSystemMetrics(SM_CXSCREEN) - width)
    {
        sourceRect.left = GetSystemMetrics(SM_CXSCREEN) - width;
    }
    sourceRect.right = sourceRect.left + width;

    if (sourceRect.top < 0)
    {
        sourceRect.top = 0;
    }
    if (sourceRect.top > GetSystemMetrics(SM_CYSCREEN) - height)
    {
        sourceRect.top = GetSystemMetrics(SM_CYSCREEN) - height;
    }
    sourceRect.bottom = sourceRect.top + height;

    // 设置为放大镜控件源矩形
    MagSetWindowSource(hwndMag, sourceRect);

     
    SetWindowPos(hwndHost, HWND_TOPMOST, 0, 0, 0, 0, 
        SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );

  
    InvalidateRect(hwndMag, NULL, TRUE);
}

 


//全屏
void GoFullScreen()
{
    isFullScreen = TRUE;
    //风格的必须为适当的渲染分层窗口。
    //它是自称为透明,以便它不捕获鼠标点击
    SetWindowLong(hwndHost, GWL_EXSTYLE, WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TRANSPARENT);
    // 给窗口的系统菜单,以便它可以在任务栏关闭
    SetWindowLong(hwndHost, GWL_STYLE,  WS_CAPTION | WS_SYSMENU);

    // 计算显示区域跨度。
    HDC hDC = GetDC(NULL);
    int xSpan = GetSystemMetrics(SM_CXSCREEN);
    int ySpan = GetSystemMetrics(SM_CYSCREEN);
    ReleaseDC(NULL, hDC);

    // 计算系统元素的大小。
    int xBorder = GetSystemMetrics(SM_CXFRAME);
    int yCaption = GetSystemMetrics(SM_CYCAPTION);
    int yBorder = GetSystemMetrics(SM_CYFRAME);

    // 计算窗口起源和跨度全屏幕模式
    int xOrigin = -xBorder;
    int yOrigin = -yBorder - yCaption;
    xSpan += 2 * xBorder;
    ySpan += 2 * yBorder + yCaption;

    SetWindowPos(hwndHost, HWND_TOPMOST, xOrigin, yOrigin, xSpan, ySpan, 
        SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOACTIVATE);
}

//停靠模式


void GoPartialScreen()
{
    isFullScreen = FALSE;

    SetWindowLong(hwndHost, GWL_EXSTYLE, WS_EX_TOPMOST | WS_EX_LAYERED);
    SetWindowLong(hwndHost, GWL_STYLE, RESTOREDWINDOWSTYLES);
    SetWindowPos(hwndHost, HWND_TOPMOST, 
        hostWindowRect.left, hostWindowRect.top, hostWindowRect.right, hostWindowRect.bottom, 
        SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOACTIVATE);
}

 

 


原文链接: http://blog.csdn.net/yincheng01/article/details/5500914

转载于:https://my.oschina.net/junwong/blog/47972

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值