调整大小时表单属性未被调用

3

我有一个.NET表单,其中有一个布尔属性叫做_isResized。当SizeChanged事件被调用时,它被设置为true,当调用bool isResized()函数时,它被设置为false

ref class net_window : public System::Windows::Forms::Form
{
private:
    bool _isResized;
public:
    net_window(void)
        : _isResized(false){
        InitializeComponent();
    }

    void InitializeComponent(void){
        this->SizeChanged += gcnew EventHandler(this, &net_window::eventResized);
    }

    bool isResized(void){
        bool temp = _isResized;
        _isResized = false;
        return temp;
    }

    Void eventResized(Object^ sender, EventArgs^ e){
        _isResized = true;
    }
};

我还有一个称为window的本地C++类,它作为.NET表单周围的一层。该类在主循环的每帧更新,并使用表单的bool isResized()函数来查看大小是否已更改。

class Window
{
private:
    void* _net_window_handle;
    Window(){
        _net_window_handle = new gcroot<net_window^>;
        (*(gcroot<net_window^>*)_net_window_handle) = gcnew net_window;
    }
    ~Window(){
        delete _net_window_handle;
    }

    void update(void)//Called every frame.
    {
        if( (*(gcroot<net_window^>*)_element)->isResized() )
            //Do stuff.
    }
};

每当窗体被调整大小时,添加到SizeChanged的委托就会被调用,因此一旦窗体大小发生变化,_isResized就会被设置为true,但由于某种原因,当窗口类使用bool isResized()函数时,主循环线程会冻结,直到用户释放窗体边缘并完成调整大小。
在窗体调整大小时,似乎无法访问.NET窗体值。是否有替代方法?
谢谢。
编辑:
我使用一个主循环,每帧调用System::Windows::Forms::Application::DoEvents()。当循环线程进入此函数并且主窗口正在调整大小时,它会冻结。是否有办法避免这个问题?

如果您添加了一些代码,那么我们就能更好地理解您的问题。 - Matt Smith
4
DoEvents再次出现。当用户开始拖动窗口边缘时,Windows会抛出一个模态消息循环。这意味着你的DoEvents循环不再运行。使用计时器替代,使用15或31毫秒间隔的SetTimer较为合适。当然,最好直接响应Resize事件来处理代码。 - Hans Passant
@HansPassant 谢谢。如果您将其转换为答案,我会将其标记为正确答案。 - JMRC
我会放弃了,之前在 DoEvent 相关问题上遭受了太多的挫败。你可以发布自己的答案并标记它。 - Hans Passant
1个回答

1
DoEvents再次出现问题。当用户开始拖动窗口边缘时,Windows会推送一个模态消息循环。这意味着您的DoEvents循环不再运行。使用定时器替代,设置15或31毫秒的间隔是比较合适的。当然,直接响应调整大小事件的代码是首选。感谢Hans Passant。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接