Minimalist CreateWindowEx fails - c++

this is just a minimalist console application that should show a windows created on the fly :
#include <windows.h>
void main()
{
WNDCLASSEX _c4w = {0};
_c4w.cbSize = sizeof(WNDCLASSEX);
//_c4w.hCursor = ::LoadCursor(0, IDC_APPLICATION);
//_c4w.hIcon = ::LoadIcon(0, IDI_APPLICATION);
_c4w.hInstance = 0;
_c4w.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
_c4w.lpszClassName = "c4w";
HWND _h;
if(!::RegisterClassEx(&_c4w))
{ _h = ::CreateWindowEx( 0, "c4w",
"Minimal Windows Application",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0, 0, 640, 480,
HWND_DESKTOP,
0,
::GetModuleHandle(0), NULL
);
::ShowWindow(_h, SW_SHOW);
}
....
}
unfortunatlity the RegisterClassEx function actually always fails...
I am using C++ Builder 5 and compiling a console Application optioned as MultiThreaded but no VCL...

As #WhozCraig said Your window class doesn't have a wndproc. If you want to use winapi well, please study according to the official documentation. Your program needs a wndproc.
Here is how to create a blank window in MSDN.
Notice that the program does not explicitly call the WindowProc
function, even though we said this is where most of the application
logic is defined. Windows communicates with your program by passing it
a series of messages.
In the code, wc.lpfnWndProc = WindowProc specifies the process callback function.

I understood that a normal Win32 application using HWND and WNDPROC is not what I have done, but here is my solution :
HWND GetSTD()
{ static
HWND _result(0);
static
bool _lock(false);
static
bool _setup(false);
while(_lock) ::Sleep(0);
if(_setup == false)
{ _lock = true;
OSVERSIONINFO _os;
_os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
::GetVersionEx(&_os);
if(_os.dwPlatformId != VER_PLATFORM_WIN32s)
{ char _title[1024];
::GetConsoleTitle(_title, sizeof(_title));
_result = ::FindWindow(0, _title);
if(_os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{ _result = ::GetWindow(_result, GW_CHILD);
if(_result != 0)
{ char _class[128];
::GetClassName(_result, _class, sizeof(_class));
while(::strcmp(_class, "ttyGrab") != 0)
{ _result = ::GetNextWindow(_result, GW_HWNDNEXT);
if(_result != 0)
::GetClassName(_result, _class, sizeof(_class));
}
}
}
}
_setup = true;
_lock = false;
}
return _result;
}
Using the resulting HWND, we could draw over the console with the ::GetDC() and ::ReleaseDC() mechanism...
NB : static variables are used to ensure to return only 1 STD handle per call...

Related

Opengl: Rendering to a Win32 API context

I'm trying to create an opengl context (ogl 4.5 at least) and render to it; it works fine with SDL2 but I can't figure out why it doesn't with Win32: I'm trying the screen color to RGBA(1, 0, 0, 1) with glClearColor()/glClear, but nothing seems to happen. Here is my code:
--EDIT I updated the code as you suggested but still, nothing seems rendered; also the problem is not because of gl 3.x/4.x features because I initialized GLEW after having created a wiggle context
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
HGLRC ourOpenGLRenderingContext;
bool running = true;
int WinMain(__in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd)
{
MSG msg = { 0 };
WNDCLASS wc = { 0 };
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wc.lpszClassName = L"oglversionchecksample";
wc.style = CS_OWNDC;
if (!RegisterClass(&wc))
return 1;
CreateWindowW(wc.lpszClassName, L"openglversioncheck",
WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 640, 480, 0, 0, hInstance, 0);
while (GetMessage(&msg, NULL, 0, 0) > 0)
DispatchMessage(&msg);
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
glViewport(0, 0, 100, 100); //render to a viewport of width (100; 100)
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
break;
case WM_CREATE:
{
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags
PFD_TYPE_RGBA, //The kind of framebuffer. RGBA or palette.
32, //Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, //Number of bits for the depthbuffer
8, //Number of bits for the stencilbuffer
0, //Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
HDC ourWindowHandleToDeviceContext = GetDC(hWnd);
int letWindowsChooseThisPixelFormat;
letWindowsChooseThisPixelFormat = ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd);
SetPixelFormat(ourWindowHandleToDeviceContext, letWindowsChooseThisPixelFormat, &pfd);
ourOpenGLRenderingContext = wglCreateContext(ourWindowHandleToDeviceContext);
wglMakeCurrent(ourWindowHandleToDeviceContext, ourOpenGLRenderingContext);
MessageBoxA(0, (char*)glGetString(GL_VERSION), "OPENGL VERSION", 0);
if(glewInit() != GLEW_OK) {
MessageBoxA(0, (char*)glGetString(GL_VERSION), "Error: Could not init OGL API (GLEW)", 0);
}
}
break;
case WM_CLOSE:
//quit code
wglDeleteContext(ourOpenGLRenderingContext);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Creating a modern OpenGL rendering context in Windows takes a bit more effort. Essentially you first have to create a proxy context to load the necessary extensions, then you create the proper context using those. I wrote a small library that does the internal proxy context housekeeping behind the curtains and lets you get right to the core business without further ado: http://github.com/datenwolf/wglarb
For the sake of StackOverflow best practice of include code in answeres instead of linking here's the main implementation file (it's a mere 238 lines):
/*
Copyright (c) 2014 Wolfgang 'datenwolf' Draxinger
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <GL/gl.h>
#include "wglarb.h"
#define wglarb_BuildAssert(cond) ((void)sizeof(char[1 - 2*!(cond)]))
static HANDLE wglarb_intermediary_mutex = NULL;
static DWORD wglarb_intermediary_lock(void)
{
wglarb_BuildAssert( sizeof(PVOID) == sizeof(HANDLE) );
if( !wglarb_intermediary_mutex ) {
/* Between testing for the validity of the mutex handle,
* creating a new mutex handle and using the interlocked
* exchange there is a race... */
/* //// START \\\\ */
HANDLE const new_mutex =
CreateMutex(NULL, TRUE, NULL);
HANDLE const dst_mutex =
InterlockedCompareExchangePointer(
&wglarb_intermediary_mutex,
new_mutex,
NULL );
/* //// FINISH \\\\ */
if( !dst_mutex ) {
/* mutex created in one time initialization and held
* by calling thread. Return signaled status. */
return WAIT_OBJECT_0;
}
/* In this case we lost the race and another thread
* beat this thread in creating a mutex object.
* Clean up and wait for the proper mutex. */
ReleaseMutex(new_mutex);
CloseHandle(new_mutex);
}
return WaitForSingleObject(wglarb_intermediary_mutex, INFINITE);
}
static BOOL wglarb_intermediary_unlock(void)
{
return ReleaseMutex(wglarb_intermediary_mutex);
}
#define WGLARB_INTERMEDIARY_CLASS "wglarb intermediary"
#define WGLARB_INTERMEDIARY_STYLE (WS_CLIPSIBLINGS|WS_CLIPCHILDREN)
#define WGLARB_INTERMEDIARY_EXSTYLE 0
static HWND wglarb_intermediary_hWnd = 0;
static BOOL wglarb_intermediary_create_Wnd(void)
{
HINSTANCE const hInstance = GetModuleHandle(NULL);
WNDCLASS wc;
memset(&wc,0,sizeof(wc));
wc.hInstance = hInstance;
wc.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
wc.lpfnWndProc = DefWindowProc;
wc.lpszClassName = WGLARB_INTERMEDIARY_CLASS;
RegisterClass(&wc);
wglarb_intermediary_hWnd =
CreateWindowEx(
WGLARB_INTERMEDIARY_EXSTYLE,
WGLARB_INTERMEDIARY_CLASS,
NULL,
WGLARB_INTERMEDIARY_STYLE,
0,0,0,0,
NULL,NULL,
hInstance,
NULL );
if( !wglarb_intermediary_hWnd ) {
return FALSE;
}
return TRUE;
}
static HDC wglarb_intermediary_hDC = 0;
static BOOL wglarb_intermediary_create_DC(void)
{
if( !wglarb_intermediary_hWnd
&& !wglarb_intermediary_create_Wnd() ) {
return FALSE;
}
wglarb_intermediary_hDC = GetDC(wglarb_intermediary_hWnd);
if( !wglarb_intermediary_hDC ) {
return FALSE;
}
return TRUE;
}
static HGLRC wglarb_intermediary_hRC = 0;
static BOOL wglarb_intermediary_create_RC(void)
{
if( !wglarb_intermediary_hDC
&& !wglarb_intermediary_create_DC() ) {
return FALSE;
}
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd,0,sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_SUPPORT_OPENGL|PFD_GENERIC_ACCELERATED|PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.iLayerType = PFD_MAIN_PLANE;
int iPF;
if( !(iPF = ChoosePixelFormat(wglarb_intermediary_hDC, &pfd))
|| !(SetPixelFormat(wglarb_intermediary_hDC, iPF, &pfd))
|| !(wglarb_intermediary_hRC = wglCreateContext(wglarb_intermediary_hDC))
) {
return FALSE;
}
return TRUE;
}
static BOOL wglarb_intermediary_makecurrent(HDC *hOrigDC, HGLRC *hOrigRC)
{
*hOrigDC = wglGetCurrentDC();
*hOrigRC = wglGetCurrentContext();
if( !wglarb_intermediary_hRC
&& !wglarb_intermediary_create_RC() ) {
return FALSE;
}
return wglMakeCurrent(wglarb_intermediary_hDC, wglarb_intermediary_hRC);
}
HGLRC WINAPI wglarb_CreateContextAttribsARB(
HDC hDC,
HGLRC hShareContext,
const int *attribList)
{
if( WAIT_OBJECT_0 != wglarb_intermediary_lock() ) {
return NULL;
}
HDC hOrigDC;
HGLRC hOrigRC;
if( !wglarb_intermediary_makecurrent(&hOrigDC, &hOrigRC) ) {
wglarb_intermediary_unlock();
return NULL;
}
PFNWGLCREATECONTEXTATTRIBSARBPROC impl =
(PFNWGLCREATECONTEXTATTRIBSARBPROC)
wglGetProcAddress("wglCreateContextAttribsARB");
HGLRC ret = NULL;
if( impl ) {
ret = impl(hDC, hShareContext, attribList);
}
wglMakeCurrent(hOrigDC, hOrigRC);
wglarb_intermediary_unlock();
return ret;
}
BOOL WINAPI wglarb_ChoosePixelFormatARB(
HDC hdc,
const int *piAttribIList,
const FLOAT *pfAttribFList,
UINT nMaxFormats,
int *piFormats,
UINT *nNumFormats)
{
if( WAIT_OBJECT_0 != wglarb_intermediary_lock() ) {
return FALSE;
}
HDC hOrigDC;
HGLRC hOrigRC;
if( !wglarb_intermediary_makecurrent(&hOrigDC, &hOrigRC) ) {
wglarb_intermediary_unlock();
return FALSE;
}
PFNWGLCHOOSEPIXELFORMATARBPROC impl = NULL;
impl = (PFNWGLCHOOSEPIXELFORMATARBPROC)
wglGetProcAddress("wglChoosePixelFormatARB");
if( !impl ) {
/* WGL_EXT_pixel_format uses the same function prototypes
* as the WGL_ARB_pixel_format extension */
impl = (PFNWGLCHOOSEPIXELFORMATARBPROC)
wglGetProcAddress("wglChoosePixelFormatEXT");
}
BOOL ret = FALSE;
if( impl ) {
ret = impl(
hdc,
piAttribIList,
pfAttribFList,
nMaxFormats,
piFormats,
nNumFormats );
}
wglMakeCurrent(hOrigDC, hOrigRC);
wglarb_intermediary_unlock();
return ret;
}
Look at the code for SDL to see what it does - I think there's some faffing about to get a context with modern (>=3 or >=4) OpenGL.
https://www.opengl.org/wiki/Creating_an_OpenGL_Context_%28WGL%29

WinApi - How to obtain SHELLDLL_DefView

I am trying to obtain handle to SHELLDLL_DefView.
So, I have this code.
HWND hProgman = FindWindow(L"Progman", NULL);
HWND hWnd = FindWindowEx(hProgman, 0, L"SHELLDLL_DefView", NULL);
Eveyrtihing works OK, until I change in Windows desktop brackground to slideshow. Then when I search with spy++ hierarchy of the windows, than SHELLDLL_DefView has another parent. Now it is #32769 (Desktop) -> WorkerW -> SHELLDLL_DefView. So I can't find it. Problem is that when I try
HWND desktop = GetDesktopWindow();
HWND hWnd = FindWindowEx(desktop , 0, L"WorkerW", NULL);
HWND hWnd = FindWindowEx(hWnd, 0, L"SHELLDLL_DefView", NULL);
Than SHELLDLL_DefView is not found. WorkerW yes.
Can anybody help?
Your code only works on some Windows versions as "SHELLDLL_DefView" can be found under "WorkerW" or "Progman" and as you discovered there can be many windows under the "WorkerW" class (normal in Win7).
Microsoft Docs report EnumWindows() is more reliable than calling GetWindow()/FindWindowEx() functions in loops, so more universal code (tested on Windows 98/Windows 7) would look like this (say you want to refresh the desktop):
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
HWND hNextWin;
hNextWin = FindWindowExA(hwnd, 0, "SHELLDLL_DefView", 0);
if ( hNextWin ) {
// The correct desktop shell window under Progman/WorkerW will have only 1 child window!
if ( GetNextWindow(hNextWin, GW_HWNDNEXT) || GetNextWindow(hNextWin, GW_HWNDPREV) )
return true;
// We found correct handle
PostMessageA(hNextWin, WM_KEYDOWN, VK_F5, 0);
return false;
}
return true;
}
void main() {
EnumWindows(&EnumWindowsProc, 0);
}
I found the answer. Need to iterate through all WorkerW.
HWND destop = GetDesktopWindow();
HWND hWorkerW = NULL;
HWND hShellViewWin = NULL;
do
{
hWorkerW = FindWindowEx(destop, hWorkerW, L"WorkerW", NULL);
hShellViewWin = FindWindowEx(hWorkerW, 0, L"SHELLDLL_DefView", 0);
} while (hShellViewWin == NULL && hWorkerW != NULL);

Chinese characters in Title bar

I am creating a Win32 application, ASCII only. However, when I create the window, the title bar shows chinese characters, instead of the intended text:
//registering the window class:
WNDCLASSEXA wc = { };
wc.hInstance = hThisInstance;
wc.lpszClassName = g_classname;
wc.lpfnWndProc = WndPrc;
wc.style = 0;
wc.cbSize = sizeof (WNDCLASSEXA);
wc.hIcon = (HICON) LoadImage(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDI_APPICO), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
wc.hIconSm = (HICON) LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_APPICO),
IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wc.cbClsExtra = 0; /* no extra bytes after the window class */
wc.cbWndExtra = 0; /* structure or the window instance */
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE); /*(HBRUSH) GetStockObject(WHITE_PEN);*/
if (!RegisterClassEx(&wc))
return FAIL;
return OK;
g_hwndMain = CreateWindow(g_classname, "Hello World", WS_OVERLAPPEDWINDOW,
g_progsettings.winX,
g_progsettings.winY,
g_progsettings.winWidth,
g_progsettings.winHeight,
0, 0, NULL, 0);
if (!g_hwndMain) {
MessageBox(NULL, "Couldn't make window", "CreateWindowEx",
MB_OK | MB_ICONERROR);
exit(EXIT_FAILURE);
}
if (g_progsettings.winX == -1 && g_progsettings.winY == -1)
centerwin(g_hwndMain);
/* Make the window visible on the screen */
ShowWindow(g_hwndMain, nCmdShow);
UpdateWindow(g_hwndMain);
Here is the titlebar:
When I run the program repeatedly, I still get the same titlebar. UNICODE is not #defined.
Unlike other similar questions, I am not casting a const char * into a LPCWSTR or vice versa, so that shouldn't be the cause of the problem.
Here is my WinMain (a lot of irrelevant details)
INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInstance,LPSTR lpszArgument, int nCmdShow)
{
MSG msg;
HACCEL hAccel;
BOOL msgRet;
INITCOMMONCONTROLSEX icex;
if (signal(SIGSEGV, onSegfault) == SIG_ERR) {
errmsg("Failed to register handler for SIGSEGV", "");
return EXIT_FAILURE;
}
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_STANDARD_CLASSES;
if (InitCommonControlsEx(&icex) == FALSE) {
fmtmsgbox(MB_ICONERROR, "extended common controls err: %s", fmtmsg());
return EXIT_FAILURE;
}
if (winregister(hInst) == FAIL)
errmsg("window class error", "window class");
memset(&g_progsettings, 0, sizeof (settings));
if (g_progsettings.readSettings() == FAIL)
g_progsettings.setDefaults();
mainwindow(hInst, nCmdShow);
hAccel = LoadAccelerators(hInst, MAKEINTRESOURCEA(IDR_ACCEL));
onCreat();
while ((msgRet = GetMessageW(&msg, NULL, 0, 0)) != 0) {
if (msgRet == -1) {
errmsg("GetMessage -1", fmtmsg());
exit(EXIT_FAILURE);
}
if (!g_fd.isdlgmsg(&msg)) {
if (!TranslateAcceleratorW(g_hwndMain, hAccel, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return 0;
}
You are creating an Ansi-based window via RegisterClassExA() and CreateWindowA(), but you are running a Unicode-based message loop by calling GetMessageW() (and TranslateAcceleratorW()) instead of GetMessageA() (and TranslateAcceleratorA()), and then you are using DispatchMessageA() to dispatch those messages. Presumably your WndProc is also calling DefWindowProcA() instead of DefWindowProcW(). So, even though you are creating an Ansi window with an Ansi title, the default window painting is not going to draw the title data correctly when processing Unicode messages as Ansi (or vise versa). You should not mix Ansi and Unicode APIs together when handling your windows. If you create an Ansi window, use an Ansi message loop. If you create a Unicode window (which you should be), use a Unicode message loop.

CreateWindow - window is not shown in IE

I have this BHO in C++ that I'm writing,
Basically what I'm trying to do is open a window, but it is not shown, I think it might have something to do with the HINSTANCE I passed to it. This is the code I use, anyone recognizing what's not right in this snippet?
Thanks :)
IServiceProvider* pServiceProvider = NULL;
if (SUCCEEDED(m_pWebBrowser->QueryInterface(
IID_IServiceProvider,
(void**)&pServiceProvider)))
{
IOleWindow* pWindow = NULL;
if (SUCCEEDED(pServiceProvider->QueryService(
SID_SShellBrowser,
IID_IOleWindow,
(void**)&pWindow)))
{
HWND hwndBrowser = NULL;
if (SUCCEEDED(pWindow->GetWindow(&hwndBrowser)))
{
HWND g_hwndMain;
g_hwndMain = CreateWindow(TEXT ("AnxJTest Class"),TEXT("My Window"),WS_POPUP | WS_VISIBLE,0, 0, 200, 300,NULL, NULL, (HINSTANCE)hwndBrowser, NULL);
ShowWindow(g_hwndMain, SW_SHOW);
}
pWindow->Release();
}
pServiceProvider->Release();
}

Windows function ChoosePixelFormat returns ERR_OLD_WIN_VERSION on windows 7

I'm trying to teach myself the win32 API by making a window and attaching an OpenGL context to it. In order to fetch the appropriate pixel format a call to ChoosePixelFormat must be made which should return a pixel format that the system supports and best meets my needs. When I check for errors everything goes smoothly until this function is called which stops execution and logs error 1150-ERR_OLD_WIN_VERSION which is supposed to mean that my version of windows does not support this function. This is obviously not the case and msdn confirms that this function runs on all versions of windows since windows 2000. Right now I'm running windows 7 x64 on my desktop and I made sure my video driver and os were fully updated. Lots of people seem to have had trouble with the pixel format functions but I have not found any with my problem so I decided to post here for help. Here is my full code; I have not tested it on any machines other than my own.
WinMain.cpp (the only non-default msvc lib this is linked with is 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 (problem occurs in the class constructor)
#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);}
After I have tried all mentioned solutions I still had the same problem with ERR_OLD_WIN_VERSION after ChoosePixelFormat. In my case the problem was about the graphics card driver:
The system I'm working on uses an EVGA card with a GTX 770 GPU and yesterday I installed driver version 331.65. After that I got the same problems as the questioner. Installing the current Version 337.88 fixed the issue in my case. However ERR_OLD_WIN_VERSION seams to lead us in the wrong direction.
In your Display constructor, it looks like you don't initialize the hWindow member before you use it. That would be the value returned by CreateWindowEx.
Instead of testing the address of the GetLastError function, you should be calling it and testing its return value against ERROR_SUCCESS. I think this may be an oversight when you pasted the code, as you seem to be getting meaningful results from GetLastError (...).
UPDATE:
You might want to try something like:
#ifndef WINVER
# define WINVER 0x0500
#endif
Before #include <Windows.h>
That tells it to include all of the fields in the data structures that are new in Windows NT 5.0 (Windows 2000). Many of these structures determine the version of Windows they are targeting by the sizeof your structure, which will vary depending on how you have WINVER defined.
I was not able to boot up my older machine, but I did discover something when looking through the source code of SDL. It seems that they defined their own version of ChoosePixelFormat that loops through all available pixel formats using DescribePixelFormat and then compares them to the desired pixel format before choosing the best one. Since this is the exact same definition of windows's ChoosePixelFormat I suspect they had a good reason to make their own. Perhaps they knew it gave trouble in certain situations. Unfortunately since Microsoft Developer support is a myth, and barely anyone seems to care, this is as good an answer as I'll get for now. And since I've stopped caring too, this is probably the closest this question will ever get to an answer. Thnaks to those of you who tried to help.