2

我试图通过制作一个窗口并将OpenGL上下文附加到它来自学win32 API。为了获取适当的像素格式,必须调用 ChoosePixelFormat,它应该返回系统支持并最能满足我需求的像素格式。当我检查错误时,一切都很顺利,直到调用该函数停止执行并记录错误 1150-ERR_OLD_WIN_VERSION 这应该意味着我的 Windows 版本不支持此函数。显然情况并非如此,msdn 确认此功能可在自 windows 2000 以来的所有 windows 版本上运行。现在我在桌面上运行 windows 7 x64,并确保我的视频驱动程序和操作系统已完全更新。很多人似乎在使用像素格式功能时遇到了问题,但我没有发现任何问题,所以我决定在这里发帖寻求帮助。这是我的完整代码;除了我自己的机器,我还没有在任何机器上测试过它。

WinMain.cpp(与之链接的唯一非默认 msvc 库是 opengl32.lib)

#include"Display.h"
#include<iostream>
#include<fstream>

MSG message;
DWORD error;
int status;

LRESULT CALLBACK WndProc(HWND hWindow, UINT message, WPARAM wParam, LPARAM lParam)
{   switch(message)
    {case WM_CREATE:
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    case WM_KEYDOWN:
        switch(wParam)
        {case VK_ESCAPE:
            PostQuitMessage(0);
            return 0;}}
    return DefWindowProc(hWindow, message, wParam, lParam);}

int MainLoop(Display d)
{
    while((status = PeekMessage(&message, d.hWindow, 0, 0, PM_REMOVE)) != 0)
    {
        if (status == -1)
        {
            return -1;
        }
        DispatchMessage(&message);
    }
    return 0;
}

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    std::ofstream file("log.txt", std::ios::trunc);


    Display window("TEST", hInstance, WndProc, 50, 50, 50, 50, NULL, NULL);
    if(window.status == -1)
    {   error = GetLastError();
        file << error;
        return 1;}

    ShowWindow(window.hWindow, SW_SHOWNORMAL);
    EnableWindow(window.hWindow, true);
    MainLoop(window);

    return 0;
}

Display.h(类构造函数出现问题)

#include <Windows.h>

class Display   
{public:
    Display(const char*, HINSTANCE, WNDPROC, int, int, int, int, DWORD, DWORD);
    ~Display();
    HWND hWindow;
    int status;
private:
    WNDCLASSEX data;
    HDC hDeviceContext;
    HGLRC hGLContext;
    PIXELFORMATDESCRIPTOR PFD;
    int x, y, width, height;};
Display::Display(const char* title, HINSTANCE InstanceHandle, WNDPROC WindowProcedure, int ScreenPositionX, int ScreenPositionY, int WindowWidth, int WindowHeight, DWORD StyleFlags, DWORD ExtendedStyleFlags)
{   data.cbSize = sizeof(WNDCLASSEX);
    data.style = CS_OWNDC;
    data.lpfnWndProc = WindowProcedure;
    data.cbClsExtra = 0;
    data.cbWndExtra = 0;
    data.hInstance = InstanceHandle;
    data.hIcon = NULL;
    data.hCursor = NULL;
    data.hbrBackground = NULL;
    data.lpszMenuName = NULL;
    data.lpszClassName = "WIN1"; 
    data.hIconSm = NULL;
    RegisterClassEx(&data);
    hWindow = CreateWindowEx(ExtendedStyleFlags, data.lpszClassName, title, StyleFlags | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, x = ScreenPositionX, y = ScreenPositionY, width = WindowWidth, height = WindowHeight, NULL, NULL, InstanceHandle, NULL);
    PFD.nSize = sizeof(PIXELFORMATDESCRIPTOR);
    PFD.nVersion = 1;
    PFD.iPixelType = PFD_TYPE_RGBA;
    PFD.iLayerType = PFD_MAIN_PLANE;
    PFD.dwVisibleMask = 0;
    PFD.dwLayerMask = 0;
    PFD.dwDamageMask = 0;
    PFD.dwFlags = PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL;
    PFD.cAuxBuffers = 0;
    PFD.bReserved = 0;
    PFD.cColorBits = 24;
    PFD.cAccumBits = 0;
    PFD.cDepthBits = 32;
    PFD.cStencilBits = 0;
    PFD.cAlphaBits = 0;
    PFD.cAccumAlphaBits = 0;
    PFD.cAlphaShift = 0;
    PFD.cBlueBits = 0;
    PFD.cAccumBlueBits = 0;
    PFD.cBlueShift = 0;
    PFD.cGreenBits = 0;
    PFD.cAccumGreenBits = 0;
    PFD.cGreenShift = 0;
    PFD.cRedBits = 0;
    PFD.cAccumRedBits = 0;
    PFD.cRedShift = 0;
    hDeviceContext = GetDC(hWindow);
    int pf = ChoosePixelFormat(hDeviceContext, &PFD); //throws error 1150, next three throw error 2000 because of this failing
    SetPixelFormat(hDeviceContext, pf, &PFD);
    hGLContext = wglCreateContext(hDeviceContext);
    wglMakeCurrent(hDeviceContext, hGLContext);
    if(GetLastError() != ERROR_SUCCESS)
        {status = -1;}
    else
        {status = 0;}
    return;}
Display::~Display()
{   wglMakeCurrent(NULL, NULL);
    wglDeleteContext(hGLContext);
    DestroyWindow(hWindow);
    UnregisterClass(data.lpszClassName, data.hInstance);}
4

4 回答 4

1

在我尝试了所有提到的解决方案之后,在选择像素格式之后,我仍然遇到与 ERR_OLD_WIN_VERSION 相同的问题。就我而言,问题在于显卡驱动程序:

我正在使用的系统使用带有 GTX 770 GPU 的 EVGA 卡,昨天我安装了驱动程序版本 331.65。之后,我遇到了与提问者相同的问题。安装当前版本 337.88解决了我的问题。然而,ERR_OLD_WIN_VERSION 接缝将我们引向错误的方向。

于 2014-06-22T11:31:55.780 回答
0

与其测试GetLastError函数的地址,不如调用它并针对ERROR_SUCCESS. 我认为这可能是您粘贴代码时的疏忽,因为您似乎从GetLastError (...).

更新:

您可能想尝试以下方法:

#ifndef WINVER
# define WINVER 0x0500
#endif

#include <Windows.h>

这告诉它在数据结构中包含 Windows NT 5.0 (Windows 2000) 中新增的所有字段。其中许多结构根据sizeof您的结构确定它们所针对的 Windows 版本,这取决于您定义 WINVER 的方式。

于 2013-09-04T23:52:07.077 回答
0

在您的Display构造函数中,看起来您hWindow在使用之前没有初始化该成员。那将是返回的值CreateWindowEx

于 2013-09-04T00:06:20.307 回答
0

我无法启动我的旧机器,但在查看SDL的源代码时确实发现了一些东西。似乎他们定义了自己的 ChoosePixelFormat 版本,该版本使用 DescribePixelFormat 遍历所有可用的像素格式,然后在选择最佳像素格式之前将它们与所需的像素格式进行比较。由于这与 windows 的 ChoosePixelFormat 的定义完全相同,我怀疑他们有充分的理由制作自己的。也许他们知道这在某些情况下会带来麻烦。不幸的是,由于 Microsoft 开发人员支持是一个神话,而且似乎几乎没有人关心,所以这是我现在得到的最好的答案。而且由于我也不再关心,这可能是这个问题最接近答案的地方。感谢那些试图提供帮助的人。

于 2013-09-09T17:43:18.457 回答