Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.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
C++ 如何知道延迟WindowPos()是否导致了重新分配?_C++_Winapi_Mfc - Fatal编程技术网

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
,则重新分配