- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我是新手Win32 ,并且我一直在解决一个问题(如果它可以称为问题的话),当用户捕获窗口标题栏并将其在屏幕上移动时,Windows 会在事件期间阻塞您的程序流。
我没有正当理由来解决这个问题,只是它困扰着我。一些可能性包括完全移除框架,但这似乎是一个不方便的黑客。有些游戏(单人游戏)根本不觉得这是个问题。然而,我读到多人游戏在程序卡住时可能会遇到问题,因为它期望信息连续流动,并且在这种延迟后可能会不堪重负。
我已经尝试将它添加到我的 WindowProc
switch (uMsg)
{
case WM_SYSCOMMAND:
if (wParam == SC_CLOSE)
PostQuitMessage(0);
return 0;
...
...
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
uMsg
的和
wParam
的处理。
WS_SYSMENU | WS_MINIMIZEBOX
创建窗口.
最佳答案
为什么我的应用程序卡住? - 消息循环和线程简介
这种现象并非孤立于任何特定消息。这是 Windows 消息循环的一个基本属性:当正在处理一条消息时,不能同时处理其他消息。它并没有完全以这种方式实现,但您可以将其视为一个队列,您的应用程序将消息从队列中拉出,以与它们插入的相反顺序进行处理。
因此,处理任何消息的时间过长会暂停其他消息的处理,从而有效地卡住您的应用程序(因为它无法处理任何输入)。解决这个问题的唯一方法是显而易见的:不要花太长时间处理任何一条消息。
通常这意味着将处理委托(delegate)给后台线程。您仍然需要处理主线程上的所有消息,后台工作线程需要在完成后向主方法报告。与 GUI 的所有交互都需要在单个线程上进行,而这几乎总是应用程序中的主线程(这就是它通常被称为 UI 线程的原因)。
(并且回答您的问题中提出的反对意见,是的,您可以在单处理器机器上运行多个线程。您不一定会看到任何性能改进,但它会使 UI 响应更快。这里的逻辑是一个线程可以一次只做一件事,但处理器可以极快地在线程之间切换,有效地模拟一次做不止一件事。)
这篇 MSDN 文章中提供了更多有用的信息:Preventing Hangs in Windows Applications
特殊情况:模态事件处理循环
Windows 上的某些窗口操作是模态操作。模态是计算中的一个常用词,它基本上是指将用户锁定在一个特定的模式中,在这种模式下他们不能做任何其他事情,直到他们改变(即退出)模式。每当模式操作开始时,就会启动一个单独的新消息处理循环,并且在该模式的持续时间内进行消息处理(而不是您的主消息循环)。这些模态操作的常见示例是拖放、窗口大小调整和消息框。
考虑这里的窗口大小调整示例,您的窗口会收到 WM_NCLBUTTONDOWN
消息,您传递给 DefWindowProc
用于默认处理。 DefWindowProc
确定用户打算开始移动或调整大小操作,并进入位于 Windows 自己代码内部深处某处的移动/调整大小消息循环。因此,您的应用程序的消息循环不再运行,因为您已进入新的移动/调整大小模式。
只要用户交互地移动/调整窗口大小,Windows 就会运行这个移动/调整大小循环。它这样做是为了可以拦截鼠标消息并相应地处理它们。当移动/调整大小操作完成时(例如,当用户释放鼠标按钮或按下 Esc 键时),控制将返回到您的应用程序代码。
值得指出的是,您会通过 WM_ENTERSIZEMOVE
message 收到此模式更改已发生的通知。 ;对应的 WM_EXITSIZEMOVE
message表示模态事件处理循环已经退出。这允许您创建一个将继续生成 WM_TIMER
的计时器。您的应用程序可以处理的消息。如何实现的实际细节相对不重要,但快速解释是DefWindowProc
继续派送WM_TIMER
在它自己的模态事件处理循环内向您的应用程序发送消息。使用 SetTimer
function创建一个计时器以响应 WM_ENTERSIZEMOVE
消息,以及 KillTimer
function销毁它以回应 WM_EXITSIZEMOVE
信息。
不过,我只是为了完整性才指出这一点。在我编写的大多数 Windows 应用程序中,我从来不需要这样做。
那么,我的代码有什么问题?
除此之外,您在问题中描述的行为是不寻常的。如果您使用 Visual Studio 模板创建一个新的空白 Win32 应用程序,我怀疑您是否能够复制这种行为。如果没有看到窗口过程的其余部分,我无法判断您是否阻止了任何消息(如上所述),但我在问题中看到的部分是错误的。您必须始终调用 DefWindowProc
对于您自己没有明确处理的消息。
在这种情况下,您可能会误以为自己正在这样做,但是 WM_SYSCOMMAND
它的 wParam
可以有很多不同的值.您只处理其中之一,SC_CLOSE
.其余的都被忽略了,因为你 return 0
.这包括所有窗口移动和调整大小的功能(例如 SC_MOVE
、 SC_SIZE
、 SC_MINIMIZE
、 SC_RESTORE
、 SC_MAXIMIZE
等)。
而且真的没有很好的理由来处理 WM_SYSCOMMAND
你自己;就让 DefWindowProc
为你照顾它。您唯一需要处理的时间 WM_SYSCOMMAND
是当您将自定义项目添加到窗口菜单时,即使如此,您也应该将所有您不认识的命令传递给 DefWindowProc
.
一个基本的窗口过程应该是这样的:
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CLOSE:
DestroyWindow(hWnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
您的消息循环也可能是错误的。惯用的 Win32 消息循环(位于
WinMain
函数底部附近)如下所示:
BOOL ret;
MSG msg;
while ((ret = GetMessage(&msg, nullptr, 0, 0)) != 0)
{
if (ret != -1)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// An error occurred! Handle it and bail out.
MessageBox(nullptr, L"Unexpected Error", nullptr, MB_OK | MB_ICONERROR);
return 1;
}
}
您不需要任何类型的 Hook 。有关这些的 MSDN 文档非常好,但您是对的:它们很复杂。在您更好地理解 Win32 编程模型之前,请远离。确实是一种罕见的情况,您需要钩子(Hook)提供的功能。
关于c++ - 在拖动窗口或按住菜单按钮期间,如何阻止 Windows 阻止程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18041622/
我正在使用 gridstack 来显示我的小部件。拖动和调整大小适用于 gridstack 卡,但当我将卡拖到底部时,卡的容器不会滚动。我想在拖动卡片时滚动那个容器。该容器只是一个 div 元素,所有
我目前正在构建一个多个处理的 slider 小部件,并且目前正在实现手势检测器。我有一个问题,如果您用第二根手指触摸/拖动屏幕,检测器会识别它并调用 onDragUpdate 函数,这是我试图禁用的功
我是 AngularJS 的新手,我对当前的项目有点压力,这就是我在这里问的原因。 我看到 AngularJS 有 ng-dragstart 事件( http://docs.ng.dart.ant.c
关于缩放大图像和平移有什么建议吗?最好内联在页面上。 我一直在使用PanoJS(又名GSV2),但是现在越来越多的人使用iPhone/iPad/Android类型的设备,这个库要么太慢,要么旧版本不支
我在尝试拖动 JPanel 时遇到问题。如果我纯粹在 MouseDragged 中将其实现为: public void mouseDragged(MouseEvent me) { me.getS
我有一个需要与屏幕底部对齐的 ImageButton,当我单击并拖动它时,它会随着我的手指移动一定距离,超过该距离它不会远离原点,而是继续跟随我的手指从原点开始的方向。 当我松手时,按钮必须滑回原点。
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 9 年前。 Improve this qu
我需要一个解决方案来实现拖动和缩放,在不使用矩阵的情况下围绕屏幕 onTouch 事件路由 ImageView。我搜索了很多但所有答案都是用矩阵完成的,因为我在屏幕矩阵中有多个对象不适合我,我想拖动和
我需要一些帮助来拖动 UIView 以显示主视图下方的菜单 View 。 我有两个 UIView。menuView - 包括菜单按钮和标签 和 mainView - 位于 menuView 之上。 我
谷歌地图即使设为 true 也不可拖动/拖动。 重现步骤:在新选项卡中加载带有 map 的页面,检查并在不执行任何操作的情况下转到移动 View 。现在在移动 View 中左右上下拖动 map ,它将
我在绘制和缩放 ImageView 时遇到问题。请帮帮我.. 当我画一些东西然后拖动或缩放图像时 - 绘图保留在原处,如您在屏幕截图中所见。而且我只需要简单地在图片上绘图,并且可以缩放和拖动这张图片。
所以我试图模拟鼠标左键单击和鼠标左键释放来执行一些自动拖放操作。 它目前在 C# Winforms(是的,winforms :|)中并且有点笨拙。 基本上,一旦发送了点击,我希望它根据 Kinect
我有一个巨大的 HTML5 Canvas,我希望它像谷歌地图一样工作:用户可以拖动它并始终只看到它的一小部分(屏幕大小)。它只呈现您在屏幕上可以看到的部分。我该怎么做?你有想法吗? 最佳答案 2 个简
我有以下拖放应用程序代码,它在桌面上按预期工作,但是当我想在移动设备上使用该应用程序时,拖动事件无法按预期工作。我知道触摸事件是必需的,但我不确定如何设置它们和实现这些功能。 .object
我正在使用 react-leaflet map ,我用状态改变了很多 map 属性,但是当使用状态来改变拖动属性时它不起作用。 { this.map = map}}
我知道我可以轻松地允许用户在OpenLayers中选择多个功能/几何图形,但是随后我希望使用户能够轻松地同时拖动/移动所有选定的功能。 使用ModifyFeature控件一次只能移动一个要素...是否
我有一个 Windows Phone 运行时应用程序,我使用 xaml 在 map 上显示图钉。 当我拖动 map 时,控件试图保持在相同位置时会出现一些滞后。 任何帮助,将不胜感
我通常不会提出此类问题/答案,但我想我会这样做,因为我已经看到这个问题被问了 20 多次,但没有一个答案真正有效。简而言之,问题是,如果您在可拖动 jQuery 项目内的任何位置有可滚动内容(over
我确信一定有一种简单的方法可以做到这一点,但到目前为止,我已经花了很长时间在各种兔子洞中没有成功。 我有一个支持拖放的 Collection View 。被拖动的单元格有 UIImageView在 c
如何在两个virtualtreeview之间复制以复制所有列,而不仅仅是第一列? 复制前: 复制后: 最佳答案 树控件不保存任何数据。它不包含要显示的列数据,因此无法复制它。而是,当树控件想要显示任何
我是一名优秀的程序员,十分优秀!