Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winapi SetWindowText慢速,Win32 C++;_Winapi_User Interface - Fatal编程技术网

Winapi SetWindowText慢速,Win32 C++;

Winapi SetWindowText慢速,Win32 C++;,winapi,user-interface,Winapi,User Interface,我有一个简单的应用程序,读取一些内部变量并将它们发布到菜单上的EditControl 下面是一段代码片段 case 0: SetWindowText(GetDlgItem( gHWnd, IDC_PACKETID ), (LPSTR)std::to_string(long long(NC->mPacketNum)).c_str()); break; 所以那里发生了很多事情。我只是想把一个数字转换成可以在编辑对话框

我有一个简单的应用程序,读取一些内部变量并将它们发布到菜单上的EditControl

下面是一段代码片段

case 0:
        SetWindowText(GetDlgItem( gHWnd, IDC_PACKETID ), 
                     (LPSTR)std::to_string(long long(NC->mPacketNum)).c_str());
        break;
所以那里发生了很多事情。我只是想把一个数字转换成可以在编辑对话框中显示的数字。这太慢了,只要进入这一部分,我就可以从50Hz降到30Hz左右


有什么办法可以显著加快速度吗?

对于高帧速率,您需要使用Direct2D或OpenGL渲染,而不是内置的编辑窗口类


如果您不需要高帧速率,只需要高吞吐量,您可以执行
invalidate
,并且只在收到绘画消息时更改文本。Windows将限制它发送给您的速率
WM\u PAINT
。或者使用计时器。通过这种方式,您只需将新值存储在一个内部变量中,当您得到绘制或计时器回调时,将其从间隔变量移动到编辑控件。

我通过维护上一次窗口更新的时间戳来解决这类问题。然后,除非经过一定的时间,否则我将阻止另一次更新。十分之一秒对我来说似乎很有效。性能显著提高,更新看起来仍然很顺利。

这段代码中有很多内容

SetWindowText本身似乎不太可能是缓慢的部分。让我们一件一件地把它拆开,看看时间会到哪里去。(唯一能确定的方法是做个人简介,但我不能帮你做,所以我在寻找可能性。这取决于你来衡量。)

  • GetDlgItem调用可能正在发送消息以遍历gHWnd的子窗口。如果有很多孩子,如果IDC_PACKETID不是第一个孩子,这可能需要一些时间。考虑一下计算一次并缓存结果。除非销毁控件并创建新控件,否则HWND不会更改

  • 您正在使用ASCII字符串调用SetWindowText。(为什么要强制转换结果?尤其是,为什么要放弃常量?)如果您使用的是现代版本的Windows,那么您的ASCII字符串将被动态转换为宽字符串,这可能涉及额外的动态内存管理。您可以调用SetWindowTextW(注意W后缀)并直接使用std::towstring计算宽字符串。根据std::towstring的实现细节,这可能会更快

  • 窗口真的是一个编辑控件吗?如果在30-50赫兹的频率下进行更改,似乎不太可能需要一个完整的编辑控件。您可以使用静态文本控件吗?它可能有一个更简单、更快的实现

  • NC->mPacketNum是否将长期正确对齐?如果不对齐,可能会对性能产生不利影响。看看你是否能保证对齐


  • 使用
    setdlgitemit
    可以大大简化这行代码。谢谢。我试试看。我还尝试了LPCTSTR(NC->mPacketNum),它工作得很好,除非该变量被更改为浮点型?或者它将是一个SetDlgItemText的东西,带有浮点到文本的转换。是的,我不认为有一个MS提供的浮点数字包装器
    SetDlgItemText
    仍然保存单独的
    GetDlgItem
    。我编写了一个快速测试来评测SetWindowText,耗时78微秒。使用合适的分析器来发现问题。同意,但我正在编辑旧代码,只是为了更新一点。希望能以便宜的价格取胜。@Grommit:好吧,那些渲染在Win32窗口客户端区域内,但如果您只想让一个窗口快速重新绘制,则不必更换整个GUI。@Grommit:添加了另一个想法。谢谢。已经在做类似的事情了。。。。每次更新需要更新时,我都会得到帧速率命中率。这似乎是一个很慢的电话。谢谢,我会尝试所有这些。现在正在玩分析器。McAfee主机入侵防护不喜欢它,但我正在想办法让它发挥作用。谢谢你的帮助。当我的时间缩短时,我会发回邮件,以便其他人知道答案。谢谢。。。。的确如此,但每一次通话都非常昂贵,而不是累积。尝试上面的建议,很可能是我正在做的一件让人悲伤的事。
    SetWindowText(GetDlgItem( gHWnd, IDC_PACKETID ), 
                  (LPSTR)std::to_string(long long(NC->mPacketNum)).c_str());