我是靠谱客的博主 傻傻棒球,最近开发中收集的这篇文章主要介绍Windows锁屏实现,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1、屏蔽键盘鼠标,利用HOOK封锁键盘和鼠标。

//键盘HOOK回调
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {

	if (nCode == HC_ACTION && wParam == WM_KEYDOWN)
	{
		LPKBDLLHOOKSTRUCT pKbs = (LPKBDLLHOOKSTRUCT)lParam;
		if (pKbs->vkCode == VK_RETURN)
		{
			g_widgetApp->quitApp();
		}
	}

	if (nCode >= 0)
		return 1;
	else
		return CallNextHookEx(g_KeyboardHook, nCode, wParam, lParam);
}

//鼠标HOOK回调
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
	if (nCode == 0) 
		return 1;

	return CallNextHookEx(g_MouseHook, nCode, wParam, lParam);
}

//设置HOOK
void QtWidgetsApplication1::installHook()
{
	//安装键盘钩子
	g_KeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0);
	qDebug() << "SetHook keyboard" << (g_KeyboardHook != NULL);

	//安装鼠标钩子
	g_MouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, NULL, 0);
	qDebug() << "SetHook mouse" << (g_MouseHook != NULL);
}

//取消设置HOOK
void QtWidgetsApplication1::uninstallHook()
{
	if (g_KeyboardHook)
		qDebug() << "Unhook keyboard:" << (bool)UnhookWindowsHookEx(g_KeyboardHook);
	
	if(g_MouseHook)
		qDebug() << "Unhook mouse:" << (bool)UnhookWindowsHookEx(g_MouseHook);
}

2、上面的HOOK却屏蔽不了Ctrl+Alt+Del,可以挂起winlogon.exe进程,强制它不处理Ctrl+Alt+Del事件

//挂起winlogon.exe进程 即可使Ctrl+Alt+Del失效
void Freeze()
{
	//枚举进程信息
	PROCESSENTRY32 pe32;
	pe32.dwSize = sizeof(pe32);
	HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

	int processPid;
	//CString strTmp;
	BOOL b = ::Process32First(hProcessSnap, &pe32);
	while (b)
	{
		processPid = pe32.th32ProcessID;
		//char *exeFile = ConvertLPWSTRToLPSTR(pe32.szExeFile);
		char *exeFile = pe32.szExeFile;
		if (strcmp(exeFile, "winlogon.exe") == 0)
		{
			break;
		}

		//delete[] exeFile;

		b = ::Process32Next(hProcessSnap, &pe32);
	}
	::CloseHandle(hProcessSnap);

	THREADENTRY32 th32;
	th32.dwSize = sizeof(th32);
	HANDLE hThreadSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
	g_processId = processPid;
	unsigned long Pid;
	Pid = processPid;
	b = ::Thread32First(hThreadSnap, &th32);
	while (b)
	{
		if (th32.th32OwnerProcessID == Pid)
		{
			HANDLE oth = OpenThread(THREAD_ALL_ACCESS, FALSE, th32.th32ThreadID);
			if (!(::SuspendThread(oth)))
			{
				qDebug() << "freeze successed";
			}
			else
			{
				qDebug() << "freeze failed";
				QMessageBox::information(nullptr, "提示", "freeze failed");
			}
			CloseHandle(oth);
			break;
		}
		::Thread32Next(hThreadSnap, &th32);
	}
	::CloseHandle(hThreadSnap);
}

//恢复winlogon.exe进程
void unFreeze()
{
	unsigned long Pid;
	Pid = g_processId;

	THREADENTRY32 th32;
	th32.dwSize = sizeof(th32);

	HANDLE hThreadSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
	BOOL b = ::Thread32First(hThreadSnap, &th32);
	while (b)
	{
		if (th32.th32OwnerProcessID == Pid)
		{
			HANDLE oth = OpenThread(THREAD_ALL_ACCESS, FALSE, th32.th32ThreadID);
			if (::ResumeThread(oth))
			{
				qDebug() << "unfreeze successed";
			}
			else
			{
				QMessageBox::information(nullptr, "提示", "unfreeze failed");
				qDebug() << "unfreeze failed";
			}
			CloseHandle(oth);
			break;
		}
		::Thread32Next(hThreadSnap, &th32);
	}
	::CloseHandle(hThreadSnap);
}

3、第2步需要提升调试权限和管理员权限

//提升Debug权限
void EnableDebugPriv() 
{
	HANDLE hToken;
	LUID luid;
	TOKEN_PRIVILEGES tkp;
	OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
	LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);
	tkp.PrivilegeCount = 1;
	tkp.Privileges[0].Luid = luid;
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	AdjustTokenPrivileges(hToken, false, &tkp, sizeof(tkp), NULL, NULL);
	CloseHandle(hToken);
}

//判断当前是否是以管理员权限运行的
bool IsProcessRunAsAdmin()
{
	SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
	PSID AdministratorsGroup;
	BOOL b = AllocateAndInitializeSid(
		&NtAuthority,
		2,
		SECURITY_BUILTIN_DOMAIN_RID,
		DOMAIN_ALIAS_RID_ADMINS,
		0, 0, 0, 0, 0, 0,
		&AdministratorsGroup);
	if (b)
	{
		CheckTokenMembership(NULL, AdministratorsGroup, &b);
		FreeSid(AdministratorsGroup);
	}
	return b == TRUE;
}

//以Admin权限运行程序
short GetAdmin()
{
	if (IsProcessRunAsAdmin())
		return 0;
	CHAR Path[MAX_PATH];
	ZeroMemory(Path, MAX_PATH);
	::GetModuleFileNameA(NULL, Path, MAX_PATH);           //获取程序路径
	HINSTANCE res;
	res = ShellExecuteA(NULL, "runas", Path, NULL, NULL, SW_SHOW);
	if ((int)res > 32)
		return 1;
	else
		return 0;
}

int main(int argc, char *argv[])
{
	//以管理员身份启动的进程继续运行,当前进程退出
	if (GetAdmin() == 1)
		return 0;

    QApplication a(argc, argv);
    QtWidgetsApplication1 w;
    w.show();
    return a.exec();
}

4、窗口设置全屏

//全屏置顶显示
setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
this->showFullScreen();

5、启动的时候如果任务管理器在,关掉任务管理器,防止上面的设置失效

//关闭任务管理器
void closeTaskMngr()
{
	DWORD dwProcessID = FindProcessId("Taskmgr.exe");
	if (dwProcessID != 0)
	{
		HANDLE hProcess = ::OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessID);
		::TerminateProcess(hProcess, 0);
		CloseHandle(hProcess);
	}
}

6、第一步的时候保留了一个回车键用来退出锁屏,进程退出的时候注意要取消安装的钩子和恢复winlogon.exe进程。

以上,一个简单的锁屏程序就完成了,后面我们就可以再加些为所欲为的功能了,比如开机锁屏,计时锁屏、密码解锁等等。【狗头】

完整代码传送门:

Windows下利用HOOK和进程挂起实现的桌面锁屏-C++文档类资源-CSDN文库icon-default.png?t=MBR7https://download.csdn.net/download/hanzhaoqiao1436/87392878

最后

以上就是傻傻棒球为你收集整理的Windows锁屏实现的全部内容,希望文章能够帮你解决Windows锁屏实现所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部