简体   繁体   English

win32程序在GCC中编译,但未在G ++ HDC错误中编译

[英]win32 program compiles in GCC but not G++ HDC error

I have a simple win32 program for basic opengl drawing. 我有一个简单的win32程序用于基本的opengl绘图。 It will compile with gcc but if I use g++ it gives me the error: 它将使用gcc进行编译,但是如果我使用g ++,则会出现以下错误:

minimal.c: In function 'HWND__* CreateOpenGLWindow(char*, int, int, int, int, BYTE, DWORD)':
minimal.c:130:24: error: cannot convert 'HDC {aka HDC__*}' to 'HWND {aka HWND__*}' for argument '1' to 'int ReleaseDC(HWND, HDC)'
     ReleaseDC(hDC, hWnd);
                        ^
minimal.c: In function 'int WinMain(HINSTANCE, HINSTANCE, LPSTR, int)':
minimal.c:160:24: error: cannot convert 'HDC {aka HDC__*}' to 'HWND {aka HWND__*}' for argument '1' to 'int ReleaseDC(HWND, HDC)'
     ReleaseDC(hDC, hWnd);

I don't know why it would compile with gcc but fail when I use g++? 我不知道为什么它会用gcc编译但在使用g ++时失败?

here is the code: 这是代码:

#include <windows.h>            /* must include this before GL/gl.h */
#include <GL/gl.h>          /* OpenGL header file */
#include <GL/glu.h>         /* OpenGL utilities header file */
#include <stdio.h>


void
display()
{
    /* rotate a triangle around */
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_TRIANGLES);
    glColor3f(1.0f, 0.0f, 0.0f);
    glVertex2i(0,  1);
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex2i(-1, -1);
    glColor3f(0.0f, 0.0f, 1.0f);
    glVertex2i(1, -1);
    glEnd();
    glFlush();
}

LONG WINAPI
WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ 
    static PAINTSTRUCT ps;

    switch(uMsg) {
    case WM_PAINT:
    display();
    BeginPaint(hWnd, &ps);
    EndPaint(hWnd, &ps);
    return 0;

    case WM_SIZE:
    glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
    PostMessage(hWnd, WM_PAINT, 0, 0);
    return 0;

    case WM_CHAR:
    switch (wParam) {
    case 27:            /* ESC key */
        PostQuitMessage(0);
        break;
    }
    return 0;

    case WM_CLOSE:
    PostQuitMessage(0);
    return 0;
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam); 
} 



HWND
CreateOpenGLWindow(char* title, int x, int y, int width, int height, 
           BYTE type, DWORD flags)
{
    int         pf;
    HDC         hDC;
    HWND        hWnd;
    WNDCLASS    wc;
    PIXELFORMATDESCRIPTOR pfd;
    static HINSTANCE hInstance = 0;

    /* only register the window class once - use hInstance as a flag. */
    if (!hInstance) {
    hInstance = GetModuleHandle(NULL);
    wc.style         = CS_OWNDC;
    wc.lpfnWndProc   = (WNDPROC)WindowProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = NULL;
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = "OpenGL";

    if (!RegisterClass(&wc)) {
        MessageBox(NULL, "RegisterClass() failed:  "
               "Cannot register window class.", "Error", MB_OK);
        return NULL;
    }
    }

    hWnd = CreateWindow("OpenGL", title, WS_OVERLAPPEDWINDOW |
            WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
            x, y, width, height, NULL, NULL, hInstance, NULL);

    if (hWnd == NULL) {
    MessageBox(NULL, "CreateWindow() failed:  Cannot create a window.",
           "Error", MB_OK);
    return NULL;
    }

    hDC = GetDC(hWnd);

    /* there is no guarantee that the contents of the stack that become
       the pfd are zeroed, therefore _make sure_ to clear these bits. */
    memset(&pfd, 0, sizeof(pfd));
    pfd.nSize        = sizeof(pfd);
    pfd.nVersion     = 1;
    pfd.dwFlags      = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | flags;
    pfd.iPixelType   = type;
    pfd.cColorBits   = 32;

    pf = ChoosePixelFormat(hDC, &pfd);
    if (pf == 0) {
    MessageBox(NULL, "ChoosePixelFormat() failed:  "
           "Cannot find a suitable pixel format.", "Error", MB_OK); 
    return 0;
    } 

    if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
    MessageBox(NULL, "SetPixelFormat() failed:  "
           "Cannot set format specified.", "Error", MB_OK);
    return 0;
    } 

    DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);

    ReleaseDC(hDC, hWnd);

    return hWnd;
}    



int APIENTRY
WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,
    LPSTR lpszCmdLine, int nCmdShow)
{
    HDC hDC;                /* device context */
    HGLRC hRC;              /* opengl context */
    HWND  hWnd;             /* window */
    MSG   msg;              /* message */

    hWnd = CreateOpenGLWindow("minimal", 0, 0, 256, 256, PFD_TYPE_RGBA, 0);
    if (hWnd == NULL)
    exit(1);

    hDC = GetDC(hWnd);
    hRC = wglCreateContext(hDC);
    wglMakeCurrent(hDC, hRC);

    ShowWindow(hWnd, nCmdShow);

    while(GetMessage(&msg, hWnd, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }

    wglMakeCurrent(NULL, NULL);
    ReleaseDC(hDC, hWnd);
    wglDeleteContext(hRC);
    DestroyWindow(hWnd);

    return msg.wParam;
}

Can someone post an explanation why the compiler for g++ would produce the HWND HDC error yet the gcc compiler accepts the code? 有人可以发表解释为什么g ++编译器会产生HWND HDC错误而gcc编译器接受该代码吗?

ReleaseDC(hDC, hWnd);

应该

ReleaseDC(hWnd, hDC);

HANDLE s of different types ( HWND , HDC , etc.) are declared using the DECLARE_HANDLE() macro. 使用DECLARE_HANDLE()宏声明不同类型的HANDLEHWNDHDC等)。 When STRICT is defined, it has this definition: 定义STRICT ,其定义如下:

#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name

It would seem that g++ defines this implicitly, since the version of DECLARE_HANDLE() that allows interchanging different handle types requires STRICT to not be defined, in which case DECLARE_HANDLE() has this definition instead: g ++似乎隐式定义了此定义,因为允许互换不同句柄类型的DECLARE_HANDLE()版本不需要定义STRICT ,在这种情况下, DECLARE_HANDLE()具有以下定义:

#define DECLARE_HANDLE(name) typedef HANDLE name

You are calling ReleaseDC() with the parameters in the wrong order . 您正在以错误的顺序调用带有参数的ReleaseDC() The first parameter is an HWND ; 一个参数是HWND ; the second parameter is an HDC . 第二个参数是HDC Read the documentation for it carefully. 请仔细阅读文档 STRICT is designed to prevent such coding mistakes. STRICT旨在防止此类编码错误。

This also means that your hDC is permanently allocated, by the way. 顺便说一句,这也意味着您的hDC已永久分配。

If you ever needed to convert between handle types in C++ code (unlikely to ever need a legitimate reason for this), you will need something like: 如果您曾经需要在C ++代码中的句柄类型之间进行转换(不太可能为此需要合理的理由),则将需要以下内容:

HWND hWnd = reinterpret_cast<HWND>(hDC);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM