我这里有一个奇怪的问题.我正在使用分层窗口显示半透明的启动画面(.png文件).它适用于某些机器但不适用于其他机器.在它不起作用的机器上,GetLastError返回317(这不是很有用).有谁之前经历过这个吗?这是我的相关功能. CreateAsPNG的传入参数是WS_VISIBLE | WS_POPUP(dwStyle),0(dwExStyle),以及父级隐藏工具窗口的句柄,因此不会创建任务栏条目.我已经验证我可以将嵌入的PNG资源加载到C
Image中,并且图像的大小是正确的.
在此先感谢您的帮助!
BOOL MySplashWnd::CreateAsPNG( DWORD dwStyle,DWORD dwExStyle,const CString& sTitle,HWND hWndParent ) { ATL::CImage img; CreateStreamOnResource( m_nBitmapID,img ); m_nWndWidth = img.GetWidth(); m_nWndHeight = img.GetHeight(); int nTop = 0; int nLeft = 0; GetTopLeft( nTop,nLeft ); dwExStyle |= WS_EX_LAYERED; // Create the Splash Window BOOL bRetVal = CWnd::CreateEx( dwExStyle,AfxRegisterWndClass( CS_CLASSDC ),sTitle,dwStyle,nLeft,nTop,m_nWndWidth,m_nWndHeight,hWndParent,NULL ); //Couldn't create the window for some unknown reason... X_ASSERT( bRetVal != FALSE ); if ( bRetVal ) { HDC hScreenDC = ::GetDC( m_hWnd ); HDC hDC = ::CreateCompatibleDC( hScreenDC ); HBITMAP hBmp = ::CreateCompatibleBitmap( hScreenDC,m_nWndHeight ); HBITMAP hBmpOld = ( HBITMAP ) ::SelectObject( hDC,hBmp ); img.Draw( hDC,m_nWndHeight ); BLENDFUNCTION blend = { 0 }; blend.BlendOp = AC_SRC_OVER; blend.BlendFlags = 0; blend.SourceConstantAlpha = 255; blend.AlphaFormat = AC_SRC_ALPHA; POINT ptPos = { nLeft,nTop }; SIZE sizeWnd = { m_nWndWidth,m_nWndHeight }; POINT ptSource = { 0,0 }; if ( ::UpdateLayeredWindow( m_hWnd,hScreenDC,&ptPos,&sizeWnd,hDC,&ptSource,&blend,ULW_ALPHA ) ) { } else { // The last error value is 317 on some Win7 machines. TRACE( _T( "*** Last error: %d\n" ),::GetLastError() ); } ::SelectObject( hDC,hBmpOld ); ::DeleteObject( hBmp ); ::DeleteDC( hDC ); ::ReleaseDC( NULL,hScreenDC ); } return bRetVal; } void MySplashWnd::CreateStreamOnResource( UINT nIDRes,ATL::CImage& img ) { HINSTANCE hInstance = ::GetMUIResourceInstance(); if ( hInstance == NULL ) { return; } HRSRC hResource = ::FindResource( hInstance,MAKEINTRESOURCE( nIDRes ),"PNG" ); if ( hResource == NULL ) { return; } DWORD dwResourceSize = ::SizeofResource( hInstance,hResource ); if ( dwResourceSize == 0 ) { return; } HGLOBAL hImage = ::LoadResource( hInstance,hResource ); if ( hImage == NULL ) { return; } LPVOID pvImageResourceData = ::LockResource( hImage ); if ( pvImageResourceData == nullptr ) { return; } HGLOBAL hImageData = ::GlobalAlloc( GMEM_MOVEABLE,dwResourceSize ); if ( hImageData == NULL ) { return; } LPVOID pvImageBuffer = ::GlobalLock( hImageData ); if ( pvImageBuffer != nullptr ) { ::CopyMemory( pvImageBuffer,pvImageResourceData,dwResourceSize ); ::GlobalUnlock( hImageData ); IStream* pStream = nullptr; if ( SUCCEEDED( ::CreateStreamOnHGlobal( hImageData,TRUE,&pStream ) ) ) { img.Load( pStream ); pStream->Release(); } ::GlobalUnlock( hImageData ); } ::GlobalFree( hImageData ); } // CTTSplashWnd::CreateStreamOnResource
更新:我发现即使在同一台机器上,有时UpdateLayeredWindow会成功,有时会失败(但如果失败则始终使用代码317).另一条信息是这个启动是在一个单独的UI线程上运行的.它总是适用于我的机器…
解决方法
我遇到了同样的问题,我也找不到任何信息.使用SetWindowAttributes方法可以工作,但我想使用SetLayeredWindow方式.我将要通过整个Windows API进行调试,以了解发生了什么,因为msdn提供了有关此错误消息的插孔信息.唯一的区别是我看到的使用此方法的OpenGL分层窗口演示示例使用CreateDIBSection而不是CreateCompatibleBitmap,它似乎可以在我的PC上运行.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。