여기에 기괴한 문제가 있습니다. 계층화 된 창을 사용하여 반투명 스플래시 화면 (.png 파일)을 표시합니다. 일부 컴퓨터에서는 작동하지만 다른 컴퓨터에서는 작동하지 않습니다. 작동하지 않는 컴퓨터에서 GetLastError는 317을 반환합니다 (별로 도움이되지 않습니다). 이전에 경험 한 사람이 있습니까? 다음은 관련 기능입니다. CreateAsPNG에 대한 들어오는 매개 변수는 WS_VISIBLE | WS_POPUP (dwStyle), 0 (dwExStyle) 및 부모에 대한 숨겨진 도구 창의 핸들이므로 작업 표시 줄 항목이 만들어지지 않습니다. 임베디드 PNG 리소스를 CImage에로드 할 수 있고 이미지의 크기가 올바른지 확인했습니다.Win32 : UpdateLayeredWindow가 때때로 실패합니다 (오류 317)
미리 도움을 청하십시오!
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_nWndWidth, m_nWndHeight);
HBITMAP hBmpOld = (HBITMAP) ::SelectObject(hDC, hBmp);
img.Draw(hDC, 0, 0, m_nWndWidth, m_nWndHeight, 0, 0, m_nWndWidth, 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, 0, &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
UPDATE : 심지어 동일한 시스템에, 때로는 UpdateLayeredWindow이 성공 것을 내가 찾은 다른 시간이 실패 (그러나 항상 코드 (317)와 함께이 실패하는 경우). 또 다른 정보는이 스플래시가 별도의 UI 스레드에서 실행되고 있다는 것입니다. 그것은 항상 내 컴퓨터에서 작동하지만 ...
그래, 나는 그것을 알아낼 수 없었다. UpdateLayeredWindow 호출로 실패를 감지하면 PNG 대신 비트 맵을 표시합니다. 그래도 고마워, 크리스. – Steve