我遇到了Winapi窗口的问题。我有一个应用程序,可能(但不一定)以全屏模式启动,如果有,我切换到全屏之前不能显示空窗口。所以,我正在做的是:
呼叫
ShowWindow(HWnd, SW_HIDE);
UpdateWindow(HWnd);
从文件中读取设置
重置D3D渲染器,调整窗口,可以切换到全屏,然后调用
SetWindowPos(HWnd, HWND_NOTOPMOST, posx, posy,sizex, sizey, SWP_SHOWWINDOW);
ShowWindow(HWnd, SW_SHOW);
在全屏模式下一切都很好,但是当应用程序以窗口模式启动时,根本就没有窗口 - CreateWindowEx
返回正确的窗口句柄,应用程序在后台运行以及所有内容,但是没有找到的窗口。我忘记了什么?
修改
好的,有些进展。事实证明,在D3D渲染器重置例程中没有调用SetWindowPos。我修复了这个问题,现在出现了新的问题 - 窗口是它应该的位置,但是它完全透明,除了光标外,客户区没有显示任何内容。
全屏一切正常。如果应用程序以全屏模式启动并且用户切换到窗口,一切都很好。
EDIT2
好的,我设法找到了窗口中没有任何渲染的原因 - IDirect3DDevice9::BeginScene
方法返回D3DERR_INVALIDCALL
,所以显然重置D3D渲染器有问题。
void VD3D9Renderer::Reset(bool windowed, ulong width, ulong height)
{
for (size_t i=0; i<Fonts.size(); i++)
Fonts[i]->Font->OnLostDevice();
if (FontMgr)
FontMgr->OnLostDevice();
for (VMap<VString, VD3D9Texture*>::iterator it = TextureMap.begin(); it != TextureMap.end(); it++)
{
VD3D9Texture* tex = it->second;
if (tex && tex->IsRenderTarget())
tex->TexturePtr->Release();
}
D3DD->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &BackBufferColor);
D3DD->GetDepthStencilSurface(&BackBufferDepthStencil);
if (BackBufferColor) BackBufferColor->Release();
if (BackBufferDepthStencil) BackBufferDepthStencil->Release();
bool change_fs = (windowed==true && D3DPP.Windowed == FALSE) || (windowed==false && D3DPP.Windowed == TRUE) ? true : false;
D3DPP.Windowed = windowed;
if (width) D3DPP.BackBufferWidth = width;
if (height) D3DPP.BackBufferHeight = height;
D3DD->Reset(&D3DPP);
RECT rc;
rc.left = 0;
rc.top = 0;
rc.right = D3DPP.BackBufferWidth;
rc.bottom = D3DPP.BackBufferHeight;
if (change_fs)
{
if(D3DPP.Windowed)
{
DWORD style = GetWindowLong(HWnd, GWL_STYLE);
DWORD exstyle = GetWindowLong(HWnd, GWL_EXSTYLE);
style = WS_CAPTION | WS_SYSMENU;
exstyle = 0;
int posx = (GetSystemMetrics(SM_CXSCREEN) - (rc.right-rc.left)) >> 1;
int posy = 0;
AdjustWindowRectEx(&rc, style, false, exstyle);
SetWindowLong(HWnd, GWL_STYLE, style);
SetWindowLong(HWnd, GWL_EXSTYLE, exstyle);
if(!SetWindowPos(HWnd, HWND_NOTOPMOST, posx, posy, rc.right, rc.bottom, SWP_SHOWWINDOW))
{
DWORD error = GetLastError();
VLog("Error in SetWindowPos: %u\n", error);
}
ShowWindow(HWnd, SW_SHOW);
}
else
{
DWORD style = GetWindowLong(HWnd, GWL_STYLE);
DWORD exstyle = GetWindowLong(HWnd, GWL_EXSTYLE);
style = WS_POPUP;
exstyle = 0;
int posx = (GetSystemMetrics(SM_CXSCREEN) - (width)) >> 1;
int posy = 0;
SetWindowLong(HWnd, GWL_STYLE, style);
SetWindowLong(HWnd, GWL_EXSTYLE, exstyle);
if(!SetWindowPos(HWnd, HWND_NOTOPMOST, posx, posy, rc.right, rc.bottom, SWP_SHOWWINDOW))
{
DWORD error = GetLastError();
VLog("Error in SetWindowPos: %u\n", error);
}
ShowWindow(HWnd, SW_SHOW);
}
}
else
{
if (rc.right > 0 && rc.bottom > 0)
{
DWORD style = GetWindowLong(HWnd, GWL_STYLE);
AdjustWindowRect(&rc, style, false);
int posx = (GetSystemMetrics(SM_CXSCREEN) - (rc.right-rc.left)) >> 1;
int posy = 0;
if(!SetWindowPos(HWnd, HWND_NOTOPMOST, posx, posy, rc.right, rc.bottom, SWP_SHOWWINDOW))
{
DWORD error = GetLastError();
VLog("Error in SetWindowPos: %u\n", error);
}
//SetWindowPos(HWnd, HWND_NOTOPMOST, posx, posy, rc.right, rc.bottom, SWP_SHOWWINDOW);
ShowWindow(HWnd, SW_SHOW);
}
}
for (VMap<VString, VD3D9Texture*>::iterator it = TextureMap.begin(); it != TextureMap.end(); it++)
{
VD3D9Texture* tex = it->second;
if (tex && tex->IsRenderTarget())
D3DD->CreateTexture(tex->Width, tex->Height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT, &tex->TexturePtr, NULL);
}
for (size_t i=0; i<Fonts.size(); i++)
Fonts[i]->Font->OnResetDevice();
if (FontMgr)
FontMgr->OnResetDevice();
ResetDeviceState();
}