- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
好吧,我可以理解该函数是否会返回错误或抛出异常,但出于某种原因,我对 DestroyWindow 的调用会在此时退出程序。就像实际的 exit() 函数改变了我的程序流程一样。文档没有提到这样的事情,而且我没有办法弄清楚发生了什么,因为我没有收到错误代码。有没有人遇到过这样的事情?
与使用 winapi 相比,我对这个对象所做的工作要多得多,所以请忽略其余部分。这里还有什么问题?
SYNC_WinSystem.h
#ifndef SYNC_WINSYSTEM_H
#define SYNC_WINSYSTEM_H
#include "SYNC_ISystem.h"
#include <Windows.h>
#include <array>
#include "SYNC_Winput.h"
#include "SYNC_IRenderer.h"
#include "SYNC_D3D11Renderer.h"
#define FULL_SCREEN true
// SYNC_WinSystem
class SYNC_WinSystem : public SYNC_ISystem
{
public:
class WindowsContext;
SYNC_WinSystem();
virtual long Initialize(InitializeContext *);
virtual void Init_Loop();
virtual void Shutdown();
virtual long MakeDirectory(std::string);
virtual bool CreateSkin(std::string, std::string, SYNC::ISkin *&);
virtual ISound * CreateSound();
LRESULT CALLBACK MessageHandler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
private:
virtual long InitializeWindows();
virtual bool Frame();
virtual void ShutdownWindows();
private:
SYNC_Winput m_Input;
private:
std::shared_ptr<SYNC_IRenderer> m_Graphics;
HINSTANCE m_hinstance;
HWND m_hwnd;
int m_screenWidth;
int m_screenHeight;
std::string m_WindowName;
};
// SYNC_WinSystem::WindowsContext
class SYNC_WinSystem::WindowsContext : public SYNC_ISystem::InitializeContext
{
public:
WindowsContext();
std::string Type();
HINSTANCE m_hinstance;
std::string m_WindowName;
private:
const static std::string m_Identifier;
};
#endif
SYNC_WinSystem.cpp
#include "SYNC_WinSystem.h"
// SYNC_WinSystem definitions
SYNC_WinSystem * g_windows;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
SYNC_WinSystem::SYNC_WinSystem()
: m_Graphics(new SYNC_D3D11Renderer)
{
m_hinstance = nullptr;
m_hwnd = nullptr;
m_screenWidth = 0;
m_screenHeight = 0;
}
long SYNC_WinSystem::Initialize(InitializeContext * context)
{
long result = 0;
char errors[256];
WindowsContext * cContext;
if(context->Type() == "WindowsContext")
cContext = static_cast<WindowsContext *>(context);
else
return false;
m_hinstance = cContext->m_hinstance;
m_WindowName = cContext->m_WindowName;
g_windows = this;
result = InitializeWindows();
if(result)
{
sprintf_s(errors, "The Window could not initialize. Windows error code: %i", result);
MessageBox(NULL, errors, "Error!", MB_OK);
return result;
}
std::array<std::string, 3> folderNames=
{{
"Compiled_Models",
"Temp_Models",
"Materials"
}};
for(int i = 0; i < (int) folderNames.size(); i++)
{
result = MakeDirectory(folderNames[i]);
if( result && (result != ERROR_ALREADY_EXISTS))
{
sprintf_s(errors, "Error creating directory \" %s \" for system. Windows error code: %i", folderNames[i].c_str(), result);
MessageBox(NULL, errors, "Error!", MB_OK);
return result;
}
result = 0;
}
SYNC_D3D11Renderer::D3D11Context graphicsContext;
graphicsContext.fullscreen = true;
graphicsContext.hwnd = m_hwnd;
graphicsContext.screenDepth = 1000.0f;
graphicsContext.screenNear = 0.1f;
graphicsContext.screenWidth = m_screenWidth;
graphicsContext.screenHeight = m_screenHeight;
if(!m_Graphics->Initialize(&graphicsContext))
return false;
return result;
}
void SYNC_WinSystem::Init_Loop()
{
MSG msg;
bool done, result;
ZeroMemory(&msg, sizeof(MSG));
done = false;
while(!done)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(m_Input.IsKeyPressed(VK_ESCAPE))
{
done = true;
}
else
{
result = Frame();
if(!result)
{
done = true;
}
}
}
}
void SYNC_WinSystem::Shutdown()
{
ShutdownWindows();
}
long SYNC_WinSystem::MakeDirectory(std::string dirName)
{
DWORD result = 0;
long returnValue = 0;
dirName.insert(0, ".\\");
result = CreateDirectory(dirName.c_str(), NULL);
if(result == 0)
{
returnValue = GetLastError();
}
return returnValue;
}
bool SYNC_WinSystem::Frame()
{
if(!m_Graphics->Frame())
return false;
return true;
}
long SYNC_WinSystem::InitializeWindows()
{
DWORD result = 0;
WNDCLASSEX wc;
DEVMODE dmScreenSettings;
int posX, posY;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = &WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = m_hinstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hIconSm = wc.hIcon;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = m_WindowName.c_str();
wc.cbSize = sizeof(WNDCLASSEX);
if(RegisterClassEx(&wc) == 0)
{
result = GetLastError();
return result;
}
m_screenWidth = GetSystemMetrics(SM_CXSCREEN);
m_screenHeight = GetSystemMetrics(SM_CYSCREEN);
if(FULL_SCREEN)
{
memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = (unsigned long) m_screenWidth;
dmScreenSettings.dmPelsHeight = (unsigned long) m_screenHeight;
dmScreenSettings.dmBitsPerPel = 32;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
posX = posY = 0;
m_hwnd = CreateWindowEx(WS_EX_APPWINDOW,
m_WindowName.c_str(),
m_WindowName.c_str(),
WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP,
posX, posY, m_screenWidth, m_screenHeight,
NULL, NULL, m_hinstance, NULL);
}
else
{
m_screenWidth = 800;
m_screenHeight = 600;
posX = ((GetSystemMetrics(SM_CXSCREEN)/2) - (m_screenWidth/2));
posY = ((GetSystemMetrics(SM_CYSCREEN)/2) - (m_screenHeight/2));
m_hwnd = CreateWindowEx(WS_EX_APPWINDOW,
m_WindowName.c_str(),
m_WindowName.c_str(),
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP,
posX, posY, m_screenWidth, m_screenHeight,
NULL, NULL, m_hinstance, NULL);
}
if(!m_hwnd)
{
result = GetLastError();
return result;
}
ShowWindow(m_hwnd, SW_SHOW);
SetForegroundWindow(m_hwnd);
SetFocus(m_hwnd);
return result;
}
void SYNC_WinSystem::ShutdownWindows()
{
ShowCursor(true);
if(FULL_SCREEN)
{
ChangeDisplaySettings(NULL, 0);
}
if(DestroyWindow(m_hwnd) == 0)
{
char meh[256];
sprintf(meh, "error: %i" , GetLastError());
MessageBox(NULL, meh, "error!", MB_OK);
}
m_hwnd = NULL;
UnregisterClass(m_WindowName.c_str(), m_hinstance);
m_hinstance = NULL;
g_windows = NULL;
return;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch(msg)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
case WM_CLOSE:
{
PostQuitMessage(0);
return 0;
}
default:
{
return g_windows->MessageHandler(hwnd, msg, wparam, lparam);
}
}
}
LRESULT CALLBACK SYNC_WinSystem::MessageHandler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch(msg)
{
case WM_KEYDOWN:
{
m_Input.KeyDown((unsigned int) wparam);
return 0;
}
case WM_KEYUP:
{
m_Input.KeyDown((unsigned int) wparam);
return 0;
}
default:
{
return DefWindowProc(hwnd, msg, wparam, lparam);
}
}
}
ISound * SYNC_WinSystem::CreateSound()
{
return nullptr;
}
bool SYNC_WinSystem::CreateSkin(std::string filename, std::string shaderName, SYNC::ISkin *& skin)
{
if(!m_Graphics->CreateSkin(filename, shaderName, skin))
return false;
return true;
}
// SYNC_WinSystem::WindowsContext definitions
const std::string SYNC_WinSystem::WindowsContext::m_Identifier = "WindowsContext";
SYNC_WinSystem::WindowsContext::WindowsContext()
{
}
std::string SYNC_WinSystem::WindowsContext::Type()
{
return m_Identifier;
}
快速解释我是如何做到这一点的。窗口句柄和实例在对象中具有私有(private)成员,并且在 Initialize() 和 InitializeWindows() 函数期间,创建了窗口类和窗口本身。 Windows 过程在下面被定义为一个全局函数,因为您不能将成员函数用作Windows 过程。我通过在顶部创建一个全局指针 (gasp) 并将其分配给系统的 this 指针来避免这种情况,这允许过程调用成员函数过程。仍然只允许系统的一个实例,但这就是我所需要的:。任何人在关机期间调用 ShutdownWindows(),然后调用 DestroyWindow。正是在这个调用期间,我的程序简单地结束了,没有错误,没有异常。 MSVC++ express 告诉我它返回错误代码 3,但就 Windows 错误代码而言,这只是一个 ERROR_PATH_NOT_FIND,在这种情况下没有任何意义。有人知道吗?
主要.cpp
#include <memory>
#include <Windows.h>
#include "Syncopate.h"
#include "SYNC_WinSystem.h"
using namespace std;
#include "SYNC_Winput.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR lpCmdLine, INT nCmdShow)
{
//create a new instance of the engine
std::shared_ptr<SYNC_WinSystem> system( new SYNC_WinSystem);
// create an init context for this specific derivative of SYNC_ISystem
SYNC_WinSystem::WindowsContext context;
context.m_hinstance = hInstance;
context.m_WindowName = "Syncopate";
// Initialize the system object. if something goes wrong, return ERROR
if(system->Initialize(&context))
return 1;
SYNC::ISkin * model;
if(!system->CreateSkin("data.txt", "ColorShader", model))
return 1;
system->Init_Loop();
system->Shutdown();
return 0;
}
最佳答案
您的消息循环中没有任何内容会注意到 WM_QUIT
并中止。消息循环的“标准”做法是调用 GetMessage()
直到失败,这表明 WM_QUIT
,但您正在调用 PeekMessage()
根本没有处理 WM_QUIT
。您的消息循环仅在 done 为真时退出,这只会在按下转义键或您的 Frame()
调用失败时发生。
正如您发现的那样,解决方案是重新设计循环以正确处理 WM_QUIT
消息,并且在循环结束后不调用 DestroyWindow。
关于c++ - winapi destroyWindow() 立即退出我的程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12649056/
DestroyWindow()文档说明如下: The function also destroys the window's menu, flushes the thread message queu
进行一些dll注入(inject)并需要销毁某个窗口。但是,DestroyWindow 仅当创建窗口的同一线程调用它时才起作用。否则,它将失败并显示错误 5:访问被拒绝。 我想也许我可以通过获取它的线
WndProc是主窗口的窗口过程。 ChildProc是子窗口的窗口过程。 ChildProc 未收到 WM_DESTROY。我做错了什么? 编辑:如果我从 hChild = CreateWindow
我在创建主窗口后创建了一个窗口,但在其句柄上调用 DestroyWindow 会关闭整个应用程序,我怎样才能简单地摆脱它? 它看起来像这样: BOOL InitInstance(HINSTANCE h
好吧,我可以理解该函数是否会返回错误或抛出异常,但出于某种原因,我对 DestroyWindow 的调用会在此时退出程序。就像实际的 exit() 函数改变了我的程序流程一样。文档没有提到这样的事情,
我打开了一个窗口,就像 OpenCV 教程所示,但我希望能够关闭该窗口并在程序中执行其他操作。图像显示正确,但是当调用 destroyWindow 时,它似乎什么也没做,只是移到下一行代码。我也尝试过
我有这门课: WNDCLASSEX ActionButton::m_wndClass = CreateWndClass(); ActionButton::ActionButton() : m_
嗨,我正在创建 Windows 上下文菜单的模拟。 显示对话框执行以下操作: 使用 CreateDialogIndirectParam 创建一个对话框 运行消息循环: while ( Continue
我目前正在 MFC 应用程序中处理对话框,诚然,我对 MFC 还很陌生。 假设我有一个类 A(派生自 CDialog),它使用类 B(也派生自 CDialog) >)。因此,A::OnInitDial
您好,我正在使用 MFC 制作一个基于对话框的应用程序: BOOL CClockMasterDlg::OnInitDialog() { CDialogEx::OnInitDialog(); m_Mod
在我的演示应用中 case WM_CLOSE: DestroyWindow(hndl); return 0; 和 case WM_CLOSE: PostQuitMessage(
我刚开始用 Python 学习 OpenCV for Raspberry Pi 3。我为 namedWindow() 写了一个简单的代码。问题是 destroyWindow() 没有像我预期的那样工作
我在 Mac OS X (Lion) 上的 Python 2.7 下使用 openCV...每当我运行代码以简单地显示相机源(来自 iSight)时,Python 就会卡住。看起来相机实际上并没有得到
我正在用 C++ 编写实时视频处理程序,并希望能够在彩色、灰度和单色模式下切换具有相同 mjpeg 流的三个窗口。我的所有图像源都在运行,但是,由于我的屏幕很小,我希望能够单独打开和关闭它们。为此,我
在下面的代码中,DestroyWindow 或DestroyAllWindows 无法关闭ShowImage 打开的窗口。当我试图通过单击关闭按钮关闭它时,窗口暂停。杀死窗口后,整个 IDLE 关闭。
我的程序使用以下代码生成一系列窗口: def display(img, name, fun): global clicked cv.NamedWindow(name, 1) c
我是一名优秀的程序员,十分优秀!