admin管理员组

文章数量:1621658


SDL2.0在windows下渲染电脑锁屏后解锁出现画面卡住的现象

***解决方法,利用windows下的锁屏检测,当检测到锁屏过后判断用户解锁,将SDL的SDL_Renderer和SDL_Texture使用SDL_DestroyRenderer和SDL_DestroyTexture销毁重新创建,即可解决。

C++ 锁屏检测代码链接如下:
https://blog.csdn/flushhip/article/details/83141062

这个博客下提到的锁屏检测win7和win10返回状态不一致,我测试过确实如此,优化方法是对windows的版本进行判断,我由于处理逻辑只区分win7和其它版本,win8,win11版本没有单独区分,修改后的代码如下:

先定义个成员或全局变量:
bool m_bWin7 =false;

unsigned long dwMajorVer	= 0;
unsigned long dwMinorVer	= 0;
unsigned long dwBuildNumber	= 0;
int nRet = GetNtVersionNumbers(dwMajorVer, dwMinorVer, dwBuildNumber);
if (TRUE != nRet)
{
	printf("get Windows Version Fail!");
}

	/*	
	5.0 Windows 2000";
	5.1 Windows XP";
	5.2 Windows 2003";
	6.0 Windows Vista";
	6.1 Windows 7";
	6.2 Windows 8";
	6.3 Windows 8.1";
	10.0 Windows 10";
	其他版本
	*/
	if (6 == dwMajorVer && 1 == dwMinorVer)
	{
		m_bWin7 = true;
	}
int GetNtVersionNumbers(unsigned long& dwMajorVer, unsigned long& dwMinorVer, unsigned long& dwBuildNumber)
{
	int bRet						= FALSE;
	HMODULE hModNtdll				= NULL;
	if (hModNtdll					= ::LoadLibraryW(L"ntdll.dll"))
	{
		typedef void (WINAPI *pfRTLGETNTVERSIONNUMBERS)(unsigned long*, unsigned long*, unsigned long*);
		pfRTLGETNTVERSIONNUMBERS pfRtlGetNtVersionNumbers;
		pfRtlGetNtVersionNumbers	= (pfRTLGETNTVERSIONNUMBERS)::GetProcAddress(hModNtdll, "RtlGetNtVersionNumbers");
		if (pfRtlGetNtVersionNumbers)
		{
			pfRtlGetNtVersionNumbers(&dwMajorVer, &dwMinorVer, &dwBuildNumber);
			dwBuildNumber			&= 0x0ffff;
			bRet					= TRUE;
		}

		::FreeLibrary(hModNtdll);
		hModNtdll					= NULL;
	}

	return bRet;
}
bool IsSessionLocked()
{
    typedef BOOL(PASCAL * WTSQuerySessionInformation)(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPTSTR* ppBuffer, DWORD* pBytesReturned);
    typedef void (PASCAL * WTSFreeMemory)(PVOID pMemory);

    WTSINFOEXW * pInfo = NULL;
    WTS_INFO_CLASS wtsic = WTSSessionInfoEx;
    bool bRet = false;
    if (m_bWin7)
	{
		bRet = true;
	}
    LPTSTR ppBuffer = NULL;
    DWORD dwBytesReturned = 0;
    LONG dwFlags = 0;
    WTSQuerySessionInformation pWTSQuerySessionInformation = NULL;
    WTSFreeMemory pWTSFreeMemory = NULL;

    HMODULE hLib = LoadLibrary(L"wtsapi32.dll");
    if (!hLib)
    {
        return false;
    }
    pWTSQuerySessionInformation = (WTSQuerySessionInformation)GetProcAddress(hLib, "WTSQuerySessionInformationW");
    if (pWTSQuerySessionInformation)
    {
        pWTSFreeMemory = (WTSFreeMemory)GetProcAddress(hLib, "WTSFreeMemory");
        if (pWTSFreeMemory != NULL)
        {
            DWORD dwSessionID = WTSGetActiveConsoleSessionId();
            if (pWTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionID, wtsic, &ppBuffer, &dwBytesReturned))
            {
                if (dwBytesReturned > 0)
                {
                    pInfo = (WTSINFOEXW*)ppBuffer;
                    if (pInfo->Level == 1)
                    {
                        dwFlags = pInfo->Data.WTSInfoExLevel1.SessionFlags;
                    }
                    if (dwFlags == WTS_SESSIONSTATE_LOCK)
                    {
                        bRet = true;
                        if (m_bWin7)
						{
							bRet = false;
						}
                    }
                }
                pWTSFreeMemory(ppBuffer);
                ppBuffer = NULL;
            }
        }
    }
    if (hLib != NULL)
    {
        FreeLibrary(hLib);
    }
    return bRet;
}

当面临多分屏播放多对象时可开线程检测线程函数如下:

void LockScreenWork()
{
	while (m_bLockScreen)
	{
		Sleep(5000);
		bool bLockScreen = IsSessionLocked();
		while (bLockScreen)
		{
			Sleep(2000);
			bLockScreen = IsSessionLocked();
			if (!bLockScreen)
			{
				printf( "解屏\n");
				map<int , TaskObject *>::iterator itemTask = m_mapTask.begin();
				for (; itemTask != m_mapTask.end(); itemTask++)
				{
					itemTask->second->LockScreen(true);//这个标志传入渲染对象内部作为重置渲染资源判断
				}
			}
		}
		
	}
	printf("锁屏检测函数结束\n");
}

本文标签: Windows下锁屏