c – CreateWindowEx失败
发布时间:2020-12-16 07:34:19 所属栏目:百科 来源:网络整理
导读:我正在关注NeHe gamedev教程(同时将它们改为OO)并且我遇到了CreateWindowEx演示的问题(http://nehe.gamedev.net/tutorial/creating_an_opengl_window_(win32)/13001/). 我正在尝试通过lpParam向WndProc传递指向我的Window对象的指针(详见此处:http://web.ar
我正在关注NeHe gamedev教程(同时将它们改为OO)并且我遇到了CreateWindowEx演示的问题(http://nehe.gamedev.net/tutorial/creating_an_opengl_window_(win32)/13001/).
我正在尝试通过lpParam向WndProc传递指向我的Window对象的指针(详见此处:http://web.archive.org/web/20051125022758/www.rpi.edu/~pudeyo/articles/wndproc/),但如果我尝试这样做,则CreateWindowEx会因GetLastError返回1400而失败 – ERROR_INVALID_WINDOW_HANDLE. 我是Windows API的初学者,已经用尽了我解决这个问题的所有方法,请你在这里指出我的错误吗? LRESULT CALLBACK cog::WindowProc(HWND window,UINT msg,WPARAM wParam,LPARAM lParam) { // Member method as windowproc: http://web.archive.org/web/20051125022758/www.rpi.edu/~pudeyo/articles/wndproc/ if(msg == WM_NCCREATE) { LPCREATESTRUCT cs = (LPCREATESTRUCT)lParam; SetWindowLong(window,GWL_USERDATA,(long)cs->lpCreateParams); } cog::Window* w = (cog::Window*)GetWindowLong(window,GWL_USERDATA); if(w) { return w->windowProc(msg,wParam,lParam); } else { return DefWindowProc(window,msg,lParam); } } cog::Window::Window(int width,int height,int bits,bool fullscreen) : fullscreen(fullscreen),appInstance(GetModuleHandle(NULL)),active(FALSE) { // Generate a rectangle corresponding to the window size RECT winRect = {0,width,height}; WNDCLASS winClass; winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size,And Own DC For Window. winClass.lpfnWndProc = (WNDPROC) cog::WindowProc; // WndProc Handles Messages winClass.cbClsExtra = 0; // No Extra Window Data winClass.cbWndExtra = sizeof(this); // Window Data - pointer to Window object winClass.hInstance = this->appInstance; // Set The Instance winClass.hIcon = LoadIcon(NULL,IDI_WINLOGO); // Load The Default Icon winClass.hCursor = LoadCursor(NULL,IDC_ARROW); // Load The Arrow Pointer winClass.hbrBackground = NULL; // No Background Required For GL winClass.lpszMenuName = NULL; // We Don't Want A Menu winClass.lpszClassName = TEXT("OpenGL"); if(!RegisterClass(&winClass)) { throw cog::WindowException(std::string("Failed to register class")); } if(this->fullscreen) { DEVMODE screenSettings; memset(&screenSettings,sizeof(DEVMODE)); screenSettings.dmSize = sizeof(DEVMODE); screenSettings.dmPelsWidth = width; screenSettings.dmPelsHeight = height; screenSettings.dmBitsPerPel = bits; screenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; if(DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettings(&screenSettings,CDS_FULLSCREEN)) { if(MessageBox(NULL,"Cannot start in full screen mode - start in windowed mode instead?","OpenGL",MB_YESNO | MB_ICONEXCLAMATION)) { this->fullscreen = FALSE; } else { throw cog::WindowException(std::string("Refused to launch program in windowed mode")); } } } DWORD winExStyle; DWORD winStyle; if(fullscreen) { winExStyle = WS_EX_APPWINDOW; winStyle = WS_POPUP; ShowCursor(FALSE); } else { winExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; winStyle = WS_OVERLAPPEDWINDOW; } AdjustWindowRectEx(&winRect,winStyle,FALSE,winExStyle); /* * !! BLOWS UP AT THIS CALL - WindowException triggered */ if(!(this->window = CreateWindowEx( winExStyle,TEXT("OpenGL"),TEXT("OpenGL Testing"),winRect.right - winRect.left,winRect.bottom - winRect.top,NULL,this->appInstance,this))) { throw cog::WindowException(std::string("Failed to create window")); } // ... cut here ... } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE lPrevInstance,LPSTR lpCmdLine,int nCmdShow) { MSG msg; cog::Window* w = NULL; try { w = new cog::Window(100,100,16,TRUE); // ... cut here ... } catch(cog::Exception e) { MessageBox(NULL,e.what(),"Exception Raised",MB_OK | MB_ICONEXCLAMATION); } if(w) { delete w; } } 会员windowProc: LRESULT CALLBACK cog::Window::windowProc(UINT msg,LPARAM lParam) { switch(msg) { case WM_ACTIVATE: if(HIWORD(wParam)) { this->active = FALSE; } else { this->active = TRUE; } return 0;; case WM_SYSCOMMAND: switch(wParam) { case SC_SCREENSAVE: case SC_MONITORPOWER: return 0; } break; case WM_CLOSE: PostQuitMessage(0); return 0; case WM_KEYDOWN: this->keys[wParam] = TRUE; break; case WM_KEYUP: this->keys[wParam] = FALSE; break; case WM_SIZE: this->resize(LOWORD(lParam),HIWORD(lParam)); return 0; default: break; } return DefWindowProc(this->window,lParam); } 解决方法
您是否要求全屏导致问题? w = new cog :: Window(100,TRUE);
如果它有帮助,这适用于我的代码库: HWND impl::window_impl::create_window_( window_impl* window // associated window object ) { auto const INSTANCE = ::GetModuleHandleW(L""); WNDCLASSEXW const wc = { sizeof(WNDCLASSEXW),CS_OWNDC | CS_HREDRAW | CS_VREDRAW,window_impl::top_level_wnd_proc_,INSTANCE,nullptr,::LoadCursorW(nullptr,MAKEINTRESOURCE(IDC_ARROW)),CLASS_NAME,nullptr }; ::RegisterClassExW(&wc); // ignore return value auto const result = ::CreateWindowExW( 0,L"window",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,(HWND)nullptr,(HMENU)nullptr,window ); return result; } [编辑] [编辑] //-------------------------------------------------------------------------- //! Get the userdata for the window given by @c hwnd (our window object). //! @throw bklib::platform::windows_exception //-------------------------------------------------------------------------- impl::window_impl* get_window_ptr(HWND hwnd) { ::SetLastError(0); auto const result = ::GetWindowLongPtrW(hwnd,GWLP_USERDATA); if (result == 0) { auto const e = ::GetLastError(); if (e) { BOOST_THROW_EXCEPTION(bklib::platform::windows_exception() << bklib::platform::windows_error_code(e) ); } } return reinterpret_cast<impl::window_impl*>(result); } //-------------------------------------------------------------------------- //! Set the userdata for the window given by @c hwnd to be our //! window object. //! @throw bklib::platform::windows_exception //-------------------------------------------------------------------------- void set_window_ptr(HWND hwnd,impl::window_impl* ptr) { ::SetLastError(0); auto const result = ::SetWindowLongPtrW(hwnd,GWLP_USERDATA,reinterpret_cast<LONG_PTR>(ptr)); if (result == 0) { auto const e = ::GetLastError(); if (e) { BOOST_THROW_EXCEPTION(bklib::platform::windows_exception() << bklib::platform::windows_error_code(e) ); } } } [编辑]更多代码,以防它有所帮助 //------------------------------------------------------------------------------ //! Top level window procedure which forwards messages to the appropriate //! impl::window_impl instance. //! @throw noexcept //! Swallows all exceptions at the API boundary. //------------------------------------------------------------------------------ LRESULT CALLBACK impl::window_impl::top_level_wnd_proc_( HWND hwnd,LPARAM lParam ) try { // set the instance pointer for the window given by hwnd if it was just created if (msg == WM_NCCREATE) { auto const cs = reinterpret_cast<CREATESTRUCTW const*>(lParam); auto const window_ptr = reinterpret_cast<window_impl*>(cs->lpCreateParams); set_window_ptr(hwnd,window_ptr); } // the window object to forward the message to auto const window = get_window_ptr(hwnd); if (window) { return window->window_proc_(hwnd,lParam); } else { // it's possible we will receive some messages beofre WM_NCCREATE; // use the default handler return ::DefWindowProcW(hwnd,lParam); } } catch (std::exception&) { ::PostQuitMessage(-1); return 0; } catch (...) { ::PostQuitMessage(-1); return 0; } //------------------------------------------------------------------------------ //! Called by the top level window proc. Dispatches messages to their //! appropriate handler function. //------------------------------------------------------------------------------ LRESULT impl::window_impl::window_proc_( HWND hwnd,LPARAM lParam ) { return ::DefWindowProcW(hwnd,lParam); } //------------------------------------------------------------------------------ void impl::window_impl::create() { handle_ = create_window_(this); } //------------------------------------------------------------------------------ void impl::window_impl::show(bool visible) { ::ShowWindow(handle_,SW_SHOWDEFAULT); ::InvalidateRect(handle_,FALSE); ::UpdateWindow(handle_); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |