- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在学习 NeHe gamedev 教程(同时将它们更改为面向对象),但我遇到了 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, wParam, 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, 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, 0, 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"),
winStyle,
0, 0,
winRect.right - winRect.left,
winRect.bottom - winRect.top,
NULL,
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, WPARAM wParam, 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, msg, wParam, lParam);
}
最佳答案
您请求全屏显示是否会导致问题? w = new cog::Window(100, 100, 16, 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_,
0,
0,
INSTANCE,
nullptr,
::LoadCursorW(nullptr, MAKEINTRESOURCE(IDC_ARROW)),
nullptr,
nullptr,
CLASS_NAME,
nullptr
};
::RegisterClassExW(&wc); // ignore return value
auto const result = ::CreateWindowExW(
0,
CLASS_NAME,
L"window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
(HWND)nullptr ,
(HMENU)nullptr,
INSTANCE,
window
);
return result;
}
[编辑]我认为您对 CreateWindowExW 的调用的参数顺序错误——特别是实例参数。您是否使用 STRICT 进行编译?它应该检测到这种问题。
[编辑]没有直接关系,但是当编译为 64 位代码时您的实现将不起作用,并且它不会检查可能的错误——您应该使用类似的东西:
//--------------------------------------------------------------------------
//! 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)
);
}
}
}
[edit] 更多代码以防有帮助
//------------------------------------------------------------------------------
//! 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, UINT msg, WPARAM wParam, 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, msg, wParam, lParam);
} else {
// it's possible we will receive some messages beofre WM_NCCREATE;
// use the default handler
return ::DefWindowProcW(hwnd, msg, wParam, 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, UINT msg, WPARAM wParam, LPARAM lParam
) {
return ::DefWindowProcW(hwnd, msg, wParam, lParam);
}
//------------------------------------------------------------------------------
void impl::window_impl::create() {
handle_ = create_window_(this);
}
//------------------------------------------------------------------------------
void impl::window_impl::show(bool visible) {
::ShowWindow(handle_, SW_SHOWDEFAULT);
::InvalidateRect(handle_, nullptr, FALSE);
::UpdateWindow(handle_);
}
关于c++ - CreateWindowEx 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14026875/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!