简体   繁体   English

窗口大小调整时,C ++ MFC按钮消失

[英]C++ MFC button disappears at window resize

I have a Dialog in MFC C++ that has a CButton attached. 我在MFC C ++中有一个附加了CButton的Dialog。 I want to modify OnSize() so that the button will anchor to bottom-left. 我想修改OnSize(),以便按钮将锚定到左下角。

if (btn.m_hWnd) {
        CRect winRect;
        GetWindowRect(&winRect);

        int width = winRect.right - winRect.left;
        int height = winRect.bottom - winRect.top;

        int x = width - wndWidth;
        int y = height - wndHeight;


        CRect rect;
        btn.GetWindowRect(&rect);
        rect.left += x;
        rect.top += y;
        btn.MoveWindow(&rect);
        ScreenToClient(&rect);
        btn.ShowWindow(SW_SHOW);
    }

x and y are the difference of how much the window has changed and will be added to the button's start coordinates. x和y是窗口已更改的差异,并将添加到按钮的起始坐标。

I am not sure about the last 2 commands (I might as well delete them) but then I run the program the button disappears. 我不确定最后2个命令(我不妨删除它们)但是然后我运行程序按钮消失了。

I need to know a way to move the button by x and y. 我需要知道一种通过x和y移动按钮的方法。

The original code was using the wrong coordinate system for both the parent dialog, and the button. 原始代码对父对话框和按钮使用了错误的坐标系。

A correct way to dock to the bottom left would be like this: 停靠在左下方的正确方法是这样的:

if (btn.m_hWnd) { 
    CRect winRect; 
    GetClientRect(&winRect); 

    CRect rect; 
    btn.GetWindowRect(&rect); 
    ScreenToClient(&rect); 

    int btnWidth = rect.Width();
    int btnHeight = rect.Width();
    rect.left = winRect.right-btnWidth; 
    rect.top  = winRect.bottom-btnHeight;
    rect.right = winRect.right;
    rect.bottom = winRect.bottom; 
    btn.MoveWindow(&rect); 
}

OR 要么

if (btn.m_hWnd) { 
    CRect winRect; 
    GetClientRect(&winRect); 

    CRect rect; 
    btn.GetWindowRect(&rect); 
    ScreenToClient(&rect); 

    int btnWidth = rect.Width();
    int btnHeight = rect.Width();
    btn.SetWindowPos(NULL,winRect.right-btnWidth,winRect.bottom-btnHeight,0,0,SWP_NOSIZE|SWP_NOZORDER);
}

Basically, the answer should be to do ScreenToClient before MoveWindow! 基本上,答案应该是在MoveWindow之前做ScreenToClient!

Some more detail: You need to familiarize yourself with what function returns or uses client coordinates (and relative to what these client coordinates are) and which screen coordinates; 更多细节:您需要熟悉哪些函数返回或使用客户端坐标(以及相对于这些客户端坐标是什么)以及哪些屏幕坐标; this is one of the parts of MFC which can be really confusing. 这是MFC的一个部分,可能真的令人困惑。 As to your question: 至于你的问题:

CWnd::GetWindowRect returns screen coordinates; CWnd :: GetWindowRect返回屏幕坐标; CWnd::MoveWindow expects coordinates relative to the parent CWnd (or to the screen if it's a top level window). CWnd :: MoveWindow期望相对于父CWnd的坐标(或者如果它是顶级窗口则指向屏幕)。 So before calling MoveWindow, you have to convert the rect returned by GetWindowRect to client coordinates of your parent window; 因此,在调用MoveWindow之前,必须将GetWindowRect返回的rect转换为父窗口的客户端坐标; suppose pParent is the CWnd * to the parent window of btn , then your moving code should look like this: 假设pParent是btn的父窗口的CWnd * ,那么你的移动代码应如下所示:

CRect rect;
btn.GetWindowRect(&rect);
pParent->ScreenToClient(&rect);  // this line and it's position is important
rect.left += x;
rect.top += y;
btn.MoveWindow(&rect);

If you're in a method of the parent window (as I think you are, since you mention OnSize of the dialog), then just leave out the pParent-> . 如果你在父窗口的方法中(我认为你是,因为你提到了对话框的OnSize),那么就pParent-> The way you do ScreenToClient at the moment, it has no effect on MoveWindow, since it's executed after it! 你现在使用ScreenToClient的方式,它对MoveWindow没有任何影响,因为它在它之后执行!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM