0

我对 Winapi 窗口有疑问。我有一个应用程序,它可能(但不一定)以全屏模式启动,如果是这样,在切换到全屏之前我不能显示一个空窗口。所以,我正在做的是:

  1. 创建窗口
  2. 称呼

    ShowWindow(HWnd, SW_HIDE);
    UpdateWindow(HWnd);
    
  3. 从文件中读取设置

  4. 重置 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();
}
4

0 回答 0