我正在开发一个显示图形的程序,该图形具有知识产权,有没有什么办法禁 用屏幕拷贝功能(Print Screen)以防止用户将图像拷贝到剪贴板上?
禁止 屏幕拷贝的办法倒是有一个,但是我得告诉你,要阻止其它应用程序从你的窗口 上复制像素内容是不可能的。许多第三方程序都能捕获屏幕内容,这种程序也不 难写。要想截获屏幕上的像素,你只要用 BitBlt 从屏幕设备上下文中拷贝它们 既可,例如:CWindowDC dc(NULL); // 用 NULL 获取整个屏幕
CDC memdc;
... // 创建, 初始化 memdc
memdc.BitBlt(..., &dc); // 拷贝屏幕内容
若要复制当前活动窗口的内容,只要获 取该窗口的 CWnd 指针,然后用它来构造一个 CWindowDC,即可从中提取内容。
总之,你无法阻止其它程序截获你窗口的像素。那么,如果你仅仅只是 要禁用“屏幕拷贝”,或是阻止该功能做些什么,那其实很容易。 Windows 通过注册热键来实现“屏幕 拷贝”功能。在我 2000 年 12 月的栏目中,我示范了如何用 RegisterHotKey 来注册应用程序热键(参见 C++ Q&A: Sending Messages in Windows, Adding Hot Keys to your Application),Windows 使用预定义的热键 IDHOT_SNAPDESKTOP 和 IDHOT_SNAPWINDOW 来处理“屏幕 拷贝”。这两个热键分别对应于 “Print Screen”和“Alt+Print Screen”,前者用来复 制整个屏幕,而后者则仅复制当前活动窗口。 为了禁用这些功能,你只要注册 这些热键,当用户按下这些热键时,让 Windows 向你的程序发送 WM_HOTKEY 消 息,此时你可以忽略这些消息, 旁路掉默认的屏幕复制行为既可。你的主框架 (mainframe)类是最适合做这件事的地方。
// 热键的处理方法
// MainFrame.h
#include "FolderFrame.h"
#include "resource.h"
////////////////
// Typical MFC Main frame window, override to disable PrintScreen.
//
class CMainFrame : public CFrameWnd {
protected:
...
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
// disable PrintScreen
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
afx_msg LRESULT OnHotKey(WPARAM wp, LPARAM lp);
afx_msg void OnDestroy();
DECLARE_MESSAGE_MAP()
};
MainFrame.cpp
#include "StdAfx.h"
#include "MainFrm.h"
#include "View.h"
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
...
// disable PrintScreen:
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_ACTIVATE()
ON_MESSAGE(WM_HOTKEY, OnHotKey)
END_MESSAGE_MAP()
...
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
...
RegisterHotKey(m_hWnd, IDHOT_SNAPDESKTOP, 0, VK_SNAPSHOT);
return 0;
}
void CMainFrame::OnDestroy()
{
UnregisterHotKey(m_hWnd, IDHOT_SNAPDESKTOP);
}
//////////////////
// Handle hotkey: should be PrintScreen or Alt-PrintScreen.
// Do nothing (bypass Windows screen capture)
//
LRESULT CMainFrame::OnHotKey(WPARAM wp, LPARAM)
{
UNREFERENCED_PARAMETER(wp);
return 0; // ignore
}
//////////////////
// When window is activated/deactivated, disable/enable Alt-PrintScreen.
// (IDHOT_SNAPWINDOW)
//
void CMainFrame::OnActivate(UINT nState, CWnd* pWndOther,
BOOL bMinimized)
{
CFrameWnd::OnActivate(nState, pWndOther, bMinimized);
if (nState)
RegisterHotKey (m_hWnd, IDHOT_SNAPWINDOW, MOD_ALT, VK_SNAPSHOT);
else
UnregisterHotKey(m_hWnd, IDHOT_SNAPWINDOW);
}