我想用OpenGL在单个窗口中查看图形并能够插入按钮。
例如:屏幕按钮的一半,另一半-图形。
创建子窗口,但在CreateOpenGLChildWindow()
函数中创建子窗口时出现错误1400。主程序窗口已正确创建,并且hWnd
(子窗口为hWndParent
)正确。但是CreateWindow()
函数中的CreateOpenGLChildWindow()
不会创建窗口。
怎么了?
对于如此糟糕的代码和问题的解释,我深表歉意。
我的代码:
#include <Windows.h>
#include <GL/GL.h>
#include <GL/GLU.h>
#include <strsafe.h>
#pragma comment(lib, "OpenGL32.lib")
void ErrorExit(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)& lpMsgBuf,
0, NULL);
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(dw);
}
HWND CreateOpenGLChildWindow(wchar_t* title, int x, int y, int width, int height,
BYTE type, DWORD flags, HWND hWndParent)
{
int pf;
HDC hDC;
HWND hWnd;
PIXELFORMATDESCRIPTOR pfd;
//error here
hWnd = CreateWindow(
L"OpenGL",
title,
CS_OWNDC | WS_CLIPSIBLINGS,
x,
y,
width,
height,
hWndParent,
NULL,
NULL,
NULL
);
if (!hWnd) {
MessageBox(NULL, L"CreateWindow() failed: Cannot create a window.",
L"Error", MB_OK);
ErrorExit((LPTSTR)L"CreateWindow");
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, L"ChoosePixelFormat() failed: "
"Cannot find a suitable pixel format.", L"Error", MB_OK);
return 0;
}
if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
MessageBox(NULL, L"SetPixelFormat() failed: "
"Cannot set format specified.", L"Error", MB_OK);
return 0;
}
DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
ReleaseDC(hWnd, hDC);
return hWnd;
}
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
wchar_t WinName[] = L"MainFrame";
int WINAPI WinMain(
HINSTANCE This,
HINSTANCE Prev,
LPSTR cmd,
int mode
)
{
HDC hDC; /* device context */
HGLRC hRC; /* opengl context */
HWND hWnd;
MSG msg;
WNDCLASS wc;
wc.hInstance = This;
wc.lpszClassName = WinName;
wc.lpfnWndProc = WndProc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszMenuName = NULL;
wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
if (!RegisterClass(&wc)) return NULL;
int windowWidth = 800;
int windowHeight = 800;
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
hWnd = CreateWindow(
WinName,
L"Title",
WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX,
(screenWidth - windowWidth) / 2,
(screenHeight - windowHeight) / 2,
windowWidth,
windowHeight,
HWND_DESKTOP,
NULL,
This,
NULL
);
if (!hWnd)
{
MessageBox(NULL, L"MAIN HWND ERROR!!!",
L"Error", MB_OK);
ErrorExit((LPTSTR)L"CreateWindow");
exit(1);
}
HWND childOpenGLWindowHWND = CreateOpenGLChildWindow(
WinName,
0,
0,
600,
800,
NULL,
NULL,
hWnd
);
if (!childOpenGLWindowHWND)
MessageBox(NULL, L"Child window init error", L"Error", MB_OK);
hDC = GetDC(hWnd);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
SendMessage(hWnd, WM_CHANGEUISTATE, MAKEWPARAM(UIS_SET, UISF_HIDEFOCUS), NULL);
ShowWindow(hWnd, mode);
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
wglMakeCurrent(NULL, NULL);
ReleaseDC(hWnd, hDC);
wglDeleteContext(hRC);
DestroyWindow(hWnd);
return msg.wParam;
//return NULL;
}
void display()
{
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
LRESULT CALLBACK WndProc(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
PAINTSTRUCT ps;
switch (message)
{
case WM_PAINT:
display();
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(NULL);
break;
default: return DefWindowProc(hWnd, message, wParam, lParam);
}
return NULL;
}
答案 0 :(得分:3)
在GetLastError()
中的CreateWindow()
之后立即呼叫CreateOpenGLChildWindow()
。您将收到错误1407(ERROR_CANNOT_FIND_WND_CLASS
)。
hWnd = CreateWindow(
L"OpenGL",
title,
CS_OWNDC | WS_CLIPSIBLINGS,
x,
y,
width,
height,
hWndParent,
NULL,
NULL,
NULL
);
if (!hWnd) {
DWORD dw = GetLastError();//error code: 1407
MessageBox(NULL, L"CreateWindow() failed: Cannot create a window.",
L"Error", MB_OK);
ErrorExit((LPTSTR)L"CreateWindow");
return NULL;
}
这表示类名L"OpenGL"
未注册。您需要像注册主窗口一样注册子窗口类。
CS_OWNDC
是类样式,而不是窗口样式。 To assign a style to a window class, assign the style to the style
member of the WNDCLASSEX
structure。
创建子窗口时,您需要添加WS_CHILD
样式。