C++ 如何知道延迟WindowPos()是否导致了重新分配?
假设我有以下用于调整窗口内选项卡控件大小的代码:C++ 如何知道延迟WindowPos()是否导致了重新分配?,c++,winapi,mfc,C++,Winapi,Mfc,假设我有以下用于调整窗口内选项卡控件大小的代码: HDWP hDWP = BeginDeferWindowPos(5); HDWP hDWPUpdated = DeferWindowPos(hDWP, hWinParent, hTabControl, nullptr,
HDWP hDWP = BeginDeferWindowPos(5);
HDWP hDWPUpdated = DeferWindowPos(hDWP,
hWinParent,
hTabControl,
nullptr,
0,
0,
newTabSize.cx,
newTabSize.cy,
SWP_NOZORDER
);
延迟WindowPos
可能导致基础结构大小增加,例如,如果页面比最初指示的多。在这种情况下,hdwpdated
将是更新位置结构的句柄。是否有方法检测此结构尺寸更新?我正在考虑比较hDWP
和hDWP更新的
:
if(hDWPUpdated != hDWP)
{
// Reallocation took place...
}
但唯一的声明是:
[…]此函数返回的句柄可能与传递的句柄不同
对函数进行修改
这让我想到,即使结构大小没有改变,句柄也可能不一样。我可以假设如果手柄不一样,那么大小就不同吗?如果没有,我该怎么做呢?设计了一个句柄来隐藏所有的实现细节。您无法比较句柄后面的结构内容,也无法在句柄更改时推断任何内容 您可以做的一件事是跟踪自己对
的调用次数。我怀疑这是否值得,因为无论您是否预测要移动的窗口数量,DeferWindowPos
都是为工作而设计的。任何效率方面似乎都可能在噪音中消失。但如果您坚持,我的建议是创建一个类,为您跟踪所有内容并提供一点RAII
class CDefer
{
int m_nRemaining;
HDWP m_hDWP;
public:
CDefer(int nMaxDefers) : m_nRemaining(nMaxDefers)
{
m_hDWP = BeginDeferWindowPos(nMaxDefers);
}
~CDefer()
{
EndDeferWindowPos(m_hDWP);
}
void DeferWindowPos(HWND hWnd, HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT uFlags)
{
m_hDWP = ::DeferWindowPos(m_hDWP, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
ASSERT(m_nRemaining > 0);
--m_nRemaining;
}
};
句柄用于隐藏所有实现细节。您无法比较句柄后面的结构内容,也无法在句柄更改时推断任何内容
您可以做的一件事是跟踪自己对的调用次数。我怀疑这是否值得,因为无论您是否预测要移动的窗口数量,DeferWindowPos
都是为工作而设计的。任何效率方面似乎都可能在噪音中消失。但如果您坚持,我的建议是创建一个类,为您跟踪所有内容并提供一点RAII
class CDefer
{
int m_nRemaining;
HDWP m_hDWP;
public:
CDefer(int nMaxDefers) : m_nRemaining(nMaxDefers)
{
m_hDWP = BeginDeferWindowPos(nMaxDefers);
}
~CDefer()
{
EndDeferWindowPos(m_hDWP);
}
void DeferWindowPos(HWND hWnd, HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT uFlags)
{
m_hDWP = ::DeferWindowPos(m_hDWP, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
ASSERT(m_nRemaining > 0);
--m_nRemaining;
}
};
是否有方法检测此结构大小更新?--出于什么原因,这些信息对您的申请有用?--我可以假设如果手柄不一样,那么大小就不同吗?--如果您要求BeginDeferWindowPos()
为5个窗口分配一个结构,然后为1-5个窗口调用DeferWindowPos()
,我认为不必重新分配结构是理所当然的,而且DeferWindowPos())
很可能只返回给定的相同结构句柄(但不能保证)。当你为6个以上的窗口调用它时,它会重新分配。那么,为什么不记录下你要移动多少扇窗户呢?或者更好的方法是,为什么不以准确的窗口计数开始调用BeginderWindowPos()
?@RemyLebeau它可以用来断言是否使用足够的窗口计数调用了BeginderWindowPos()
。DeferWindowPos
将成功,即使使用不适当的计数调用了BeginderWindowPos
,那么你为什么要断言?如果你不能提前准确预测将移动多少个窗口,不要担心。另外,句柄的全部意义在于,你不允许知道它所代表的结构。我看不到需要修复的错误。与重新定位窗口、使其失效和重新绘制相比,调整底层结构的大小是便宜的。加上对内核的调用。这些都是昂贵的电话。如果您需要优化,请先去那里。是否有方法检测此结构大小更新?--出于什么原因,这些信息对您的申请有用?--我可以假设如果手柄不一样,那么大小就不同吗?--如果您要求BeginDeferWindowPos()
为5个窗口分配一个结构,然后为1-5个窗口调用DeferWindowPos()
,我认为不必重新分配结构是理所当然的,而且DeferWindowPos())
很可能只返回给定的相同结构句柄(但不能保证)。当你为6个以上的窗口调用它时,它会重新分配。那么,为什么不记录下你要移动多少扇窗户呢?或者更好的方法是,为什么不以准确的窗口计数开始调用BeginderWindowPos()
?@RemyLebeau它可以用来断言是否使用足够的窗口计数调用了BeginderWindowPos()
。DeferWindowPos
将成功,即使使用不适当的计数调用了BeginderWindowPos
,那么你为什么要断言?如果你不能提前准确预测将移动多少个窗口,不要担心。另外,句柄的全部意义在于,你不允许知道它所代表的结构。我看不到需要修复的错误。与重新定位窗口、使其失效和重新绘制相比,调整底层结构的大小是便宜的。加上对内核的调用。这些都是昂贵的电话。如果你需要优化,首先去那里。我喜欢这个想法,为这个提供一些RAII,但是我不知道这个实现如何帮助我的案例。如果我将此实例与nMaxDefer=5
关联,但我最终拥有6个窗口,这对我有什么帮助?将有一个重新分配
调用延迟窗口POS
(或者如果缺少资源,它将失败),并且m\u n保留
将下降到5
。我遗漏了什么吗?@BobMorane您遗漏了ASSERT
。如果您调用DeferWindowPos
太多次,它将触发。但是当ASSERT
弹出时,将发生重新分配(在DeferWindowPos
内)。如果开发人员没有多次调用延迟窗口POS
,则重新分配