• <Win32_9>有意思的程序——抓取屏幕


    Win32学了一段时间了,跟着杨老师的脚步,准备学习MFC,因此最近几天在复习C++,于是发现有将近一周没写博文了……

    今天来写一个较为简单、但是比较有意思的东西

    不知大家在理发店理发的时候注意到一个奇观没:

    理发店一般都有两面对立的镜子,你仔细一看会发现,两面镜子里面的成像逐渐缩小,并且居中排列,很有意思

    盗梦空间中也有一个类似的场景,我截了一个图:

    yes,今天就来做一个这样的效果,只不过是抓的屏幕

    好吧,先来看看程序运行效果,来对比一下:

    下面进入主题,剖析实现细节,主要分两大步:

    (1)要对屏幕"工作",在Win32中必须获取屏幕的hdc。有两种主要的方式:

    1)GetDC(HWND), 传递参数NULL——GetDC(NULL)

    2)CreateDC(TEXT("DISPLAY"),  NULL, NULL, NULL);

    (2)贴图

    获取环境hdc后,在hdc中会保存屏幕的状态——相当于屏幕的截图,只是用bmp保存的

    今天贴图用一个更好的函数StretchBlt,它有一个很好的功能——可以按比例缩放bmp位图,然后显示:

    BOOL StretchBlt(
      HDC hdcDest,      // handle to destination DC
      int nXOriginDest, // x-coord of destination upper-left corner
      int nYOriginDest, // y-coord of destination upper-left corner
      int nWidthDest,   // width of destination rectangle
      int nHeightDest,  // height of destination rectangle
      HDC hdcSrc,       // handle to source DC
      int nXOriginSrc,  // x-coord of source upper-left corner
      int nYOriginSrc,  // y-coord of source upper-left corner
      int nWidthSrc,    // width of source rectangle
      int nHeightSrc,   // height of source rectangle
      DWORD dwRop       // raster operation code
    );

    使用方法和BitBlt很类似,应该不用赘述了……

    具体核心实现代码如下:

    int	cxScreen, cyScreen;//全局变量——屏幕的长宽,用于窗口居中和缩放显示bmp
    hdcCli = BeginPaint(hwnd, &ps);
    
    hdcScr = GetDC(NULL);
    
     
    
    //循环3次
    
    i = 0;
    while(i<3)
    {
     //按比例显示桌面截图
     StretchBlt(hdcCli, 0, 0, cxClient, cyClient, hdcScr, 0, 0, cxScreen, cyScreen, SRCCOPY);
     i++;
    }
    
    
    DeleteDC(hdcScr);
    EndPaint(hwnd, &ps);
    
    


    这种方式很简单,当然我肯定不会简单用一下这个函数就了事了,这个没什么大不了的,下面我在介绍一种使用GDI映射模式+BitBlt来贴bmp位图,实现效果和上面说的完全一样

    BitBlt函数没有缩放功能,我就用映射模式来实现缩放功能,缩放的具体实现代码如下:

    hdcCli = BeginPaint(hwnd, &ps);
    
    hdcScr = GetDC(NULL);
    
    SetMapMode(hdcCli, MM_ANISOTROPIC);//设定x、y方向异性模式,就是说x、y方向可以不同
    SetWindowExtEx(hdcCli, cxScreen, cyScreen, NULL);//设定窗口范围
    SetViewportExtEx(hdcCli, cxClient, cyClient, NULL);//设定视口范围
    //这样就能将cxScreen * cyScreen的大小缩放为cxClient * cyClient的大小,就是将屏幕大小缩小为客户区大小
    //循环3次
    i = 0;
    while(i<3)
    {
    	//由于已经在内存中缩放了屏幕bmp位图,这里就可直接贴图
    	BitBlt(hdcCli, 0, 0, cxScreen, cyScreen, hdcScr, 0, 0, SRCCOPY);//直接显示
    	i++;
    }
    
    
    DeleteDC(hdcScr);
    EndPaint(hwnd, &ps);

    这两种方式实现的效果完全一样,多一种方式,多一种思路,这样才能提高能力……

    源代码待会儿上传……

  • 相关阅读:
    第01组 每周小结(2/3)(组长)
    第01组 每周小结 (1/3)(组长)
    第01组 Beta冲刺 总结(组长)
    第01组Beta冲刺(5/5)(组长)
    第01组Beta冲刺(4/5)(组长)
    第01组Beta冲刺(3/5)(组长)
    第01组Beta冲刺(2/5)(组长)
    第01组Beta冲刺(1/5)(组长)
    软工实践个人总结
    每周小结(3/3)
  • 原文地址:https://www.cnblogs.com/riskyer/p/3238851.html
Copyright © 2020-2023  润新知