MFC全屏显示和多窗口动态显示的一些技巧和方法

时间:2020-12-08 23:21:55

一、全屏

  1、全屏窗口从dialogex继承,因为要处理一些东西

  2、全屏代码,这样设置后尺寸不会出bug,只设置为最大值的话容易出bug

    //get current system resolution
    int g_iCurScreenWidth = GetSystemMetrics(SM_CXSCREEN);
    int g_iCurScreenHeight = GetSystemMetrics(SM_CYSCREEN);

    //for full screen while backplay
    GetWindowPlacement(&_struOldWndpl);

    CRect rectWholeDlg;//entire client(including title bar)
    CRect rectClient;//client area(not including title bar)
    CRect rectFullScreen;
    GetWindowRect(&rectWholeDlg);
    RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery, &rectClient);
    ClientToScreen(&rectClient);

    rectFullScreen.left = rectWholeDlg.left - rectClient.left;
    rectFullScreen.top = rectWholeDlg.top - rectClient.top;
    rectFullScreen.right = rectWholeDlg.right + g_iCurScreenWidth - rectClient.right;
    rectFullScreen.bottom = rectWholeDlg.bottom + g_iCurScreenHeight - rectClient.bottom;
    //enter into full screen;
    WINDOWPLACEMENT struWndpl;
    struWndpl.length = sizeof(WINDOWPLACEMENT);
    struWndpl.flags = 0;
    struWndpl.showCmd = SW_SHOWNORMAL;
    struWndpl.rcNormalPosition = rectFullScreen;
    SetWindowPlacement(&struWndpl);
    return true;

  3、全屏机制,创建全局的全屏类,也可以动态创建,竞争可以比较指针代替状态设置

  4、ShowWindow(SW_SHOW);ShowWindow(SW_HIDE);进行显示关闭

  5、全屏对按键消息的处理,包括win按键的处理

    BOOL cloudfullscreen::PreTranslateMessage(MSG* pMsg)
    {
    if (pMsg->message == WM_KEYUP)
    {
      switch (pMsg->wParam)
      {
        case VK_ESCAPE:
        resetOwner();
        break;
        case VK_LWIN:
        resetOwner();
        break;
        case VK_RWIN:
        resetOwner();
        break;
        defalut:
        break;

      }
    }
    return CDialogEx::PreTranslateMessage(pMsg);
    }

  6、dialog对话框的bug,重写

    virtual void OnCancel();
    virtual void OnOK();并注释掉原来的处理内容

    不然esc和return按键会出bug

  7、设置焦距:->SetFocus();

  8、设置全屏实例化的对话框也需要创建才会执行initdialog函数

    cloud_fullscreen_dialog_global.Create(IDD_CLOUD_FULLSCREEN);

    可以用静态标志位判断是否第一次创建。

二、动态显示子窗口及子窗口中的多个控件

  1、子窗口最好继承dialogex,这样才能处理消息和重载虚函数

  2、控件可以静态画上去,或动态创建

  3、思想:同一子窗口中的不同控件分层思想设置显示位置,(一般按相对比率来计算绝对位置,再画上去。若控件数目不定则用其它方法)

  4、获取客户区大小

    CRect clientRect;
    ::GetClientRect(this->m_hWnd, &clientRect); //取客户区大小

  5、移动控件,改变大小

    ::MoveWindow(c._wnd, r.left, r.top, r.Width(), r.Height(), TRUE);

  6、显示::ShowWindow(i.second->_wnd, SW_SHOW);

  7、控件是否被点击判断

    POINT CurPt;
    CurPt.x = point.x;
    CurPt.y = point.y;
    CRect PntDspRect;
    ::GetWindowRect(_wnd, &PntDspRect);
    CWnd::FromHandle(_wnd)->GetParent()->ScreenToClient(&PntDspRect);

    if ((CurPt.x < PntDspRect.left) || (CurPt.x > PntDspRect.right)
    || (CurPt.y < PntDspRect.top) || (CurPt.y > PntDspRect.bottom))
    {
      return false;
    }
    CurPt.x = CurPt.x - PntDspRect.left;
    CurPt.y = CurPt.y - PntDspRect.top;
    if (CurPt.x < 0 || CurPt.y > PntDspRect.right || CurPt.y<0 || CurPt.y > PntDspRect.bottom)
      return false;

    return true;

  注意:鼠标滚轮旋转(注意只是旋转,滚轮点击鼠标输入坐标和左右键输入坐标一样)输入坐标是屏幕坐标,应直接判断,不需要用父窗口判断

  8、dialog对话框的bug,重写

    virtual void OnCancel();
    virtual void OnOK();并注释掉原来的处理内容

    不然esc和return按键会出bug

  9、设置焦距:->SetFocus();