设为首页收藏本站

中国膜结构网

 找回密码
 立即注册
膜结构车棚
膜结构车棚膜结构资质国产膜材 膜结构网中国膜结构协会
查看: 70|回复: 4

MFC 随笔(临时收集)

[复制链接]
  • TA的每日心情
    开心
    2021-3-7 10:01
  • 签到天数: 1440 天

    连续签到: 19 天

    [LV.10]以坛为家III

    发表于 2021-2-8 17:03 | 显示全部楼层 |阅读模式
    http://www.mjgw.org/ 专业从事膜结构设计、制作加工、施工安装的膜结构咨询服务,能够为客户提供专业的膜结构整体解决方案。做中国最好的膜结构综合服务平台。欢迎大家联系QQ:463017170.
    void MyExam07Dlg::OnButtonAngle()
    {
            BeginEditorCommand();

            ads_point pt;
            acdbDisToF(m_strXPt, -1, &pt[X]);
            acdbDisToF(m_strYPt, -1, &pt[Y]);
            acdbDisToF(m_strZPt, -1, &pt[Z]);
            double angle;
           
            if (acedGetAngle(pt, "\nPick an angle: ", &angle) == RTNORM) {
           
                    CompleteEditorCommand();
                   
                    m_strAngle.Format("%g", angle*(180.0/PI));
                    DisplayAngle();
            }
            else
            {
                    CancelEditorCommand();
            }
    }


    有时我们需要点击对话框上的一个按钮的时候,对话框隐藏起来,然后执行完某个操作后,对话框又弹出来,

    这时我们可以使用BeginEditorCommand()和CompleteEditorCommand()函数来完成,前者是告诉程序,要

    进行用户交互操作了,此时对话框将被隐藏起来,然后知道程序运行到CompleteEditorCommand()函数,这时

    交互操作完成,对话框弹出。如果要中途取消交互操作可以使用CancelEditorCommand()函数来提前退出交互,

    弹出对话框。

    注:这两个函数都是在CAcUiDialog类中,所有要使用这两个函数,必须让对话框类继承这个类,同时要注意,如

    果对话框类继承了这个类,那么我们将不能使用点击鼠标右键来添加变量绑定控件了,只能使用手动的方式来绑定。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2021-3-7 10:01
  • 签到天数: 1440 天

    连续签到: 19 天

    [LV.10]以坛为家III

     楼主| 发表于 2021-2-8 17:22 | 显示全部楼层
    功能:通过点击“添加按钮”来打开选择文件对话框,如图2,选择我们要用的图纸,这里我们默认只能选择.dwg文件,然后点击“打开”,就会将该图纸的路劲保存在图1中的listbox控件中,这里就需要我们判断选择加入的图纸是否已经加入到listbox空间中了。下面就是我的实现代码:

    void CMyCombineDlg::OnBnClickedButton1()
    {
    // TODO: 在此添加控件通知处理程序代码
    CFileDialog dlg(true, _T(".dwg"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
    _T("All Files(*.dwg)|*.dwg||"), AfxGetMainWnd());
    //默认打开的时候显示D盘
    dlg.m_ofn.lpstrInitialDir = _T("D:\\");
    if (dlg.DoModal() == IDOK)
    {
    //获取文件路径
    CString pathName = dlg.GetPathName();
    //获取文件名
    //CString fileName = dlg.GetFileName();

    //使用FindString()函数来在listbox空间中查找字符串pathName,

    //其中第一个参数为查找的起始位置,第二个参数为要查找的字符串,返回值为该字符串在listbox控件中的行数
    int str = m_list.FindString(0, pathName);

    //返回值在listbox的行数范围内,则说明已经添加了该图纸
    if (str >=0 && str <=m_list.GetCount())
    {
    MessageBox(_T("该图纸已经选择了!"));
    return;
    }
    else
    {
    //将选择的文件路径保存到list空间中
    m_list.AddString(pathName);
    }
    }
    }



    ///////////////////////////////////////////////////////////////////////////////////////

    2.删除listbox中选中的行。

    鼠标选择listbox中要删除的那一行,然后点击“移除图纸”,则可以从listbox控件从移除该行,实现代码:

    void CMyCombineDlg::OnBnClickedButton2()
    {
    // TODO: 在此添加控件通知处理程序代码
    //获取选择项信息,通过GetSelCount()函数获得用户所选择的行数

    int nItemcount = m_list.GetSelCount();

    //使用memset来申请一段内存,用来保存条目索引
    int *indexBuf = new int[nItemcount];
    memset(indexBuf, 0, nItemcount * sizeof(int));
    //存储选中的条目索引
    m_list.GetSelItems(nItemcount, indexBuf);

    for (int loop = nItemcount; loop >= 0; loop--)
    {
    m_list.DeleteString(indexBuf[loop]);
    }
    delete[] indexBuf;
    }

    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2021-3-7 10:01
  • 签到天数: 1440 天

    连续签到: 19 天

    [LV.10]以坛为家III

     楼主| 发表于 2021-2-18 16:40 | 显示全部楼层
    VC++6.0控件工具箱:
    2 图形控件(picture):常用于显示位图(Bitmap)和图标(Icon)

    3 静态文本(Static Text):用来在指定的位置显示特定的字符串,一般用来标识附近另一个控件的内容。显示在静态文本控件中的字符串一般不再改变,但是在需要的时候,也可以通过调用相应的函数来进行设置。MFC提供了CStatic类支持静态控件。

    4 编辑框(Edit Box):用来接收用户输入的字符串。通过选择编辑框的选项,编辑框可以接收字符串、数字、密码等;编辑框还可以设置成接收多行字符串的模式;可以自动进行大小写转换。编辑框可能向其父窗口发送多种控件通知,如果用户需要,可以对这些控件通知进行处理。MFC提供了CEdit类支持编辑框控件。

    5 组成框(Group Box):用来包围具有逻辑关系的一组控件,在这些控件的周围加上边界和标题。需注意的是,组成框仅仅是在视觉效果上对控件进行“成组”,真正的“成组”工作还需要另外一些工作。

    6 按钮(Button):用来接收用户的命令,应用程序在接收到用户命令后,通常需要进行一些后台工作。按钮可以响应单击或双击动作,在按钮接收到鼠标动作后,向其父窗口发送相应的控件通知,用户可以对这些控件通知进行消息映射,从而进行相应的处理。在一个对话框中,可以定义一个默认按钮,这只要选中按钮属性中的“Default”选项。如果在对话框活动的时候按下了Enter键,则等同于单击了默认按钮。MFC提供了CButton类支持按钮控件。

    7 复选框(Check Box):用来显示某种可能的选择,该项选择是独立的,用户可以选中或取消该选项。在选项被选中的时候核选标记出现,选项被取消时核选标记消失。MFC中由CButton类对核选框进行支持,用户可以通过SetCheck()函数和GetCheck()函数设置或获取核选框当前的状态。

    8 单选按钮(Radio Button):用来选择某种可能的选择,与核选框不同,该选项不是独立的。一般是几个单选按钮组成一组,同组中的单选按钮可以有也只能有一个按钮被选中。MFC同样使用CButton类对单选按钮控件进行支持,SetCheck()函数和GetCheck()函数对单选按钮也是适用的。

    9 组合框(Combo Box):列表框和编辑框的组合,用户除了可以在列表中对已经存在的选项进行选择外,还可以输入新的选择。MFC提供了CComboBox类对组合框控件进行支持。

    10 列表框(List Box):用来选择一系列的可能选择,用户通过滚动条可以在这些选择中浏览。在列表框中,可以进行单项选择,也可以进行多项选择,这取决于用户在控件属性对话框中的设置。MFC提供了CListBox类对列表框控件进行支持。

    11、12 滚动条(Scroll Bar):这包括水平滚动条和垂直滚动条,除了在视觉效果上的方向不同外,水平滚动条在被滚动时发生WM_HSCROLL消息,而垂直滚动条在被滚动时发送WM_VSCROLL消息。MFC提供了CScrollBar进行支持。

    13 微调按钮(Spin Button):包括一对紧靠在一起的上下箭头,使用微调按钮可以增大或者缩小某个特定的数值。微调按钮往往都需要一个“伙伴”控件,这通常都是一个编辑框。当微调按钮的向上箭头被单击时,编辑框中的数字就增大;反之则减小。MFC提供了CPinButtonCtrl类进行支持。

    14 进度条(Progress):在进行一项需要占有较长时间的操作时来反应当前的进度。当操作的进度不断前进时,进度条就用特色颜色填充进度条框。用户可以设定进度条的范围和当前位置。MFC提供了CProgressCtrl类进行支持。

    15 滑块控件(Slider):通常用来在程序中接受一系列离散的数值。用户可以设置滑块控件的取值范围,并可以为控件加上刻度标记以显示特定位置的含义。MFC提供了CSliderCtrl类进行支持。

    16 热键控制(Hot Key):热键控件看起来就像一个编辑框,但是在热键控件中能够立刻反应用户刚刚按下的键组合,这在设置程序的热键时特别有用。热键控件只是在“视觉”上显示了按键组合,设置热键的工作还需要用户添加代码完成。MFC提供了CHotKey类进行支持。

    17 列表控制(List Control):按一定的排列顺序显示一系列带图标的字符串,列表控件提供了四种显示模式:大图标、小图标、列表和详细信息。用户可以向列表控件中添加新的项,也可以控制列表控件的显示模式。MFC提供了CListCtrl类进行支持。

    18 树形控件(Tree Control):用来显示一系列项目的层次关系,最典型的例子是显示磁盘上的文件与文件夹。如果有子项目的话,单击树形控件中的项目可以展开或者收缩其子项目。MFC提供了CTreeCtrl类进行支持。

    19 属性表控件(Tab Control):用来包含大量的控件,可以满足用户显示或者获取大量数据的要求。每个属性表又分为好几个属性页,这些属性页由各自的标签进行区分,这些属性页中都可以包容其他控件。在显示属性表的时候,一次只能够显示一个属性页的全部内容,同时显示其他属性页的标签,用户通过单击标签打开相应的属性页。MFC提供了CTabCtrl类进行支持。

    20 动画控件(Animation):用来播放一段AVI格式的视频剪辑。用户可以控制视频剪辑的播放、停止和定位,但也仅限于这些功能。动画控件设置不能播放音频剪辑,如果用户需要更高层次的视频或者音频的支持,请选用MCIWnd控件。MFC提供了CAnimateCtrl类对动画控件进行支持。

    21 高级编辑框(Rich Edit):编辑控件功能的扩展。在高级编辑框中,除了简单的输入和编辑字符串外,用户还可以为字符或段落指定特定的格式,用户甚至还可以向高级编辑框中插入OLE项。高级编辑框基本上实现了一个带格式的文本编辑器功能,而只需要用户添加少量的接口。MFC提供了CRichEditCtrl类进行支持。

    22 日历控件(Month Calender):看似与真正的日历类似,操作也类似,直观的为用户提供了观察和显示当前日期的途径。MFC提供了CMonthCalCtrl类进行支持。

    23 日期/时间选择器(Date Time Picker):向用户提供了一种直观的选择日期和时间的方法、日期/时间选择器在外观上类似于一个组合框,但是当用户单击下拉箭头时就会展开一个日历控件供用户选择,而一旦用户做出了选择,日期/时间选择器会自动显示新的日期/时间。MFC提供了CDateTimeCtrl类进行支持。

    24 IP地址控件(IP Adress):IP地址控件用来输入和编辑IP地址。该控件外观类似于一个编辑框,但是可以自动对输入的字符按3个一组进行区分和加间隔圆点。IP地址控件为开发支持Internet技术的程序提供了方便。MFC提供了CIPAddressCtrl类进行支持。

    26 扩展组合框(Extended Combo Box):在普通组合框的基础上还支持图像列表。即,可以在组合框中显示特定的图标表示相应的选择,而不仅仅是显示文本。MFC提供了CComboBoxEx类进行支持。



    所有控件的公共属性:

    ID:控件的资源标识。

    Visiable:控件是否可见。

    Disabled:控件是否被禁止、被禁止的控件无法接受键盘和鼠标输入。

    Group:是否从这个空间开始一个新组。

    Tab stop:在程序中是否可以用【Tab】键切换到这个控件。

    Help ID:是否给控件分配一个帮助标识,帮助标识基于控件本身的资源标识。

    Client edge:给控件增加一个凹陷的边界,使整个控件看起来像是凹下去的一样。

    Static edge:给控件增加一个边界。

    Modal frame:给控件增加一个3维的框架,与Client edge相反,它是凸出来的。

    Transparent:拥有此属性的窗口是透明的,它下面的窗口不会被它遮掩住。

    Accept files:拥有此属性的窗口可以接收拖放文件,如果一个文件被拖动到这个控件上面,控件会收到WM_DROPFILES消息。

    No parent notify:表示控件不向其父窗口发送WM_PARENTNOTIFY消息。

    Right aligned text:表示文本右对齐。

    以上属性可通过控件的属性对话框进行设置,在属性对话框中按【F1】键可以查看属性的帮助信息。



    每一种控件都由一个MFC控件类来管理,当通过资源编辑器在对话框上添加一个控件时,visualC++会自动为控件类生成一个实例,即对象,并调用构造函数,当对话框关闭时,其各个子控件对象被自动销毁。

    也可以不使用资源编辑器,自己在程序中写代码创建、显示控件并设置控件的属性。

    所有的控件类都继承自CWnd,控件的某些操作和属性设置需要用到CWnd本身的成员函数,CWnd某些函数经常用来操纵控件和设置控件属性。

    SetWindowText:设置控件上要显示的标题文本,即用来设置控件的caption属性

    GetWindowText:得到控件的标题文本

    EnableWindow:设置控件的Disabled属性,即社会自控件是否可以接收键盘和鼠标的输入

    SetWindowPos:改变窗口的大小、位置和Z轴次序。

    MoveWindow:改变窗口的大小和位置

    GetWindowRec:得到窗口的大小、位置(信息存放在一个矩形结构中)。

    GetClientRect:得到窗口客户区的大小(信息存放在一个矩形结构中 )

    ShowWindow:设置窗口的可见性(即窗口是否可见)

    SetWindowText/GetWindowText还可以用来设置/得到对话框的标题文本。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2021-3-7 10:01
  • 签到天数: 1440 天

    连续签到: 19 天

    [LV.10]以坛为家III

     楼主| 发表于 2021-2-18 16:42 | 显示全部楼层
    MFC中实现自绘菜单
    为了实现菜单的自绘,花了我几个小时,其实真正解决后又发现很简单。实现菜单的自绘只需要三个步骤:

    第一步:将所有菜单项设置为MF_OWNERDRAW,即自绘模式

    第二步:在WM_MEASUREITEM消息中设置菜单项的大小

    第三步:在WM_DRAWITEM消息中进行菜单项的绘制

    问题首先出现在了第一步,我要绘制的是一个上下文菜单,即右键菜单,要将菜单项设置为MF_OWNERDRAW,需要用到ModifyMenu函数,起始由于ModifyMenu函数的参数设置错误,导致程序怎么也响应不了WM_MEASUREITEM和WM_DRAWITEM消息,所以建议在使用ModifyMenu时对返回值进行检查。


    void CMainWindow::OnRButtonDown(UINT nFlags, CPoint point)
    {
        ClientToScreen(&point);
        CMenu Menu;
        Menu.LoadMenuW(IDR_MENU2);
        CMenu *pMenu = Menu.GetSubMenu(0);
        CString strText;
        for (int i = 0; i < pMenu->GetMenuItemCount(); i++)
        {
            BOOL bModi = pMenu->ModifyMenuW(ID_123_456 + i, MF_BYCOMMAND|MF_OWNERDRAW, ID_123_456 + i);
            if (!bModi)
           {
                  TRACK("ModifyMenu fail!");
           }
            pMenu->GetMenuStringW(i, strText, MF_BYPOSITION);
        }
        pMenu->TrackPopupMenu(TPM_LEFTBUTTON|TPM_LEFTALIGN,
            point.x,
            point.y,
            this);
    }

    第一步的问题解决后,接在在第二步的WM_MEASUREITEM消息中设置菜单项的大小:


    void CMainWindow::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpmis)
    {
        //lpmis->itemWidth = ::GetSystemMetrics(SM_CYMENU) * 4;
        lpmis->itemWidth = 150;
        lpmis->itemHeight = ::GetSystemMetrics(SM_CYMENU);
    }
    在WM_MEASUREITEM消息中设置的菜单项大小会传入WM_DRAWITEM消息中,然后再在WM_DRAWITEM消息中根据菜单项的大小来进行重绘。

    到第三步也遇到了几个问题,由于最初对WM_DRAWITEM消息中的LPDRAWITEMSTRUCT结构体不了解,以致写出的程序不管在什么时候都会作同一个绘制操作,先来看看WM_DRAWITEM消息的声明:

    afx_msg void CMainWindow::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpdis);

    在这个消息中有两个参数,在自绘菜单时,两个参数都要用到。其中nIDCtl,书上说是所属控件的ID,不太明白是什么意思,在MSDN看到,对于菜单发出的WM_DRAWITEM消息,nIDCtl为0。再说LPDRAWITEMSTRUCT结构体,该结构体中包含了菜单复选状态、选中状态以及菜单项的大小等信息。

    下面是OnDrawItem消息的实现代码:

    void CMainWindow::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpdis)
    {
        CBrush *brush = new CBrush;
        CPen *pen = new CPen;
        CString strText;
        CDC *pDC = CDC::FromHandle(lpdis->hDC); //获取菜单项的设备句柄
        //菜单项是否为选中状态
        if ((lpdis->itemState & ODS_SELECTED))
        {
            //在菜单项上自绘矩形框的背景颜色
            brush->CreateSolidBrush(RGB(182, 189,210));
            //在菜单项自绘矩形的边框颜色
            pen->CreatePen(PS_SOLID, 1, RGB(10,36,106));
            //设置菜单项的文字背景颜色
            pDC->SetBkColor(RGB(182,189,210));
        }
        else
        {
            brush->CreateSolidBrush(GetSysColor(COLOR_MENU));
            pen->CreatePen(PS_SOLID, 0, GetSysColor(COLOR_MENU));
            pDC->SetBkColor(GetSysColor(COLOR_MENU));
        }
        pDC->SelectObject(pen);
        pDC->SelectObject(brush);
        //在当前菜单项上画一个矩形框
        pDC->Rectangle(lpdis->rcItem.left,
            lpdis->rcItem.top,
            lpdis->rcItem.right,
            lpdis->rcItem.bottom);
        /*--------------------------------------*/
        //获取当前消息所在菜单项的文本
        CMenu menu;
        menu.Attach((HMENU)lpdis->hwndItem);
        menu.GetMenuStringW(lpdis->itemID, strText,MF_BYCOMMAND);
        /*--------------------------------------*/
        //如果为菜单发出的DrawItem消息
        if (nIDCtl == 0)
        {
            //在菜单项上输出菜单文本
            pDC->TextOutW(lpdis->rcItem.left + 20, lpdis->rcItem.top + 4, strText.GetBuffer(0), strText.GetLength());
        }
        menu.Detach();
        delete brush;
        delete pen;
    }
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2021-3-7 10:01
  • 签到天数: 1440 天

    连续签到: 19 天

    [LV.10]以坛为家III

     楼主| 发表于 2021-2-18 16:48 | 显示全部楼层
    在mfc工程中控件或者窗口位置的调整是经常遇到的,特别是基于对话框的工程。位置的调整包括坐标、长度和宽度的变化,一般在窗口类的OnSize函数中实现。控件位置的调整涉及的函数有:GetWindowRect()、ScreenToClient()、GetClientRect()、MoveWindow()或SetWindowPos(),功能意义如下:

    例子:

    窗口大小用setwindowpos();为1024*768

    控件为 500*500(GetDlgItem(IDC_STATIC)->SetWindowPos(0, 0, 0, 500, 500, NULL);)

    GetWindowRect():获得窗口在屏幕上的矩形坐标,调整控件位置时必须首先获得该屏幕坐标; 带四周边框  GetWindowRect(Rect rect);

    得到的窗口为: {top=0 bottom=768 left=0 right=1024}

    控件为: {top=30 bottom=530 left=8 right=508}

    ScreenToClient():转换屏幕坐标到客户区坐标,如果为子窗口,转换后坐标为相对于父窗口的坐标,若为独立窗口,转换后客户区左上坐标为(0,0);调整子窗口时这一步也是必须的;



    GetClientRect():获得窗口客户区坐标,左上坐标永远为(0,0); 不带边框  GetClientRect(Rect rect);

    得到的窗口为:  {top=0 bottom=730 left=0 right=1008}  

    控件为: {top=0 bottom=500 left=0 right=500}

    MoveWindow():调整控件到指定位置;

    MoveWindow( int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE ); (有文件链接)

    SetWindowPos():调整控件的位置,该函数使用更灵活,多用于只修改控件位置而大小不变或只修改大小而位置不变的情况: 以客户区的起始坐标为原点

    SetWindowPos(HWND hWndlnsertAfter, int X,int Y,int cX,int cY,UNIT Flags);(有文件链接)


    控件位置调整涉及的参变量有:主窗口的cx、cy坐标、参考点坐标。相对于调整位置时调用的函数,变量稍许复杂些。cx、cy坐标为主窗口的宽和高,有OnSize的参数给出,为窗口控件调整提供了变化的范围,所有的控件为了能够正常显示都不能超出这个范围。其实在开发过程中较难和重要的是参考控件的选择,其位置相对于主窗口来说必须好确定。常用的策略:

    1.  选择主窗口上位置不随窗口大小变化的控件为参考;

    2.  选择主窗口上控件的宽或者高固定的控件;

    3.  选择与主窗口满足固定坐标关系的控件 ;

    4.  选择主窗口上控件位置或者高宽容易确定的控件。

    以上四种策略可在实际开发中作为参考!不管遇到什么的情况,一定要清楚:选择一个

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    MFC如何获取控件在对话框上的位置坐标
    2010-09-13 20:20
    本来希望的效果是在对话框上设置两个picture控件,分别显示两幅图像,然后将两幅图像中的相似部分利用一条直线连接起来。要实现这样的效果需要知道相似位置在这两幅图中的坐标以及这两个控件在对话框上的坐标,然后通过加减运算就可以得到图像上的相似区域在对话框的坐标,直接将这两个坐标用直线连接就可以了。                                                                                

    为此,如何获得控件在对话框上的坐标是关键问题。编写了如下的测试小程序,目的是将两个picture控件中的点用直线连接起来,比较直观的是picture控件的四个角,所以程序中是将控件的拐角连接起来。首先在对话框上并排放置两个同样大小的picture控件,将他们的标识分别设成IDC_LEFT和IDC_RIGHT,然后添加两个编辑框用于显示picture控件的大小,给这两个编辑框添加相应的数据成员m_row和m_colume。添加一个按钮用于连接picture控件中的点,为这个按钮添加成员函数OnMatch() 。

    void CControlDlg::OnMatch()  { // TODO: Add your control notification handler code here CRect rectL,rectR; GetDlgItem(IDC_LEFT)->GetWindowRect(&rectL);//获取控件相对于屏幕的位置 ScreenToClient(rectL);//转化为对话框上的相对位置 GetDlgItem(IDC_RIGHT)->GetWindowRect(&rectR);//获取控件相对于屏幕的位置 ScreenToClient(rectR);//转化为对话框上的相对位置 m_row=rectL.bottom-rectL.top; m_colume=rectL.right-rectL.left; UpdateData(FALSE);

    CClientDC dc(this); dc.MoveTo(rectL.left,rectL.top); dc.LineTo(rectR.right,rectR.bottom); dc.MoveTo(rectL.right,rectL.top); dc.LineTo(rectR.left,rectR.bottom);

    dc.MoveTo(rectL.left+m_colume/2,rectL.top+m_row/2);//连接两个控件中心点 dc.LineTo(rectR.left+m_colume/2,rectR.top+m_row/2);
    }



    MFC中,如何获得对话框控件相对于父窗口(对话框窗口)的位置
    创建者: nottoobad最后修改: 2010-11-29 21:07:54状态: 公开
    标签: mfc
    在MFC中,如何获得对话框控件相对于父窗口(对话框窗口)的位置:
    CRect r;
    pWnd->GetWindowRect(&r);
    这样获得的r是控件相对于屏幕的坐标,然后用ScreenToClient(&r)就可以获得控件相对于父窗口的坐标。如果用GetClientRect(&r)的话,r.left和r.top始终是0,得到的并不是实际坐标。
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    以用GetSystemMetrics函数可以获取系统分辨率,但这只是其功能之一,GetSystemMetrics函数只有一个参数,称之为「索引」,这个索引有75个标识符,通过设置不同的标识符就可以获取系统分辨率、窗体显示区域的宽度和高度、滚动条的宽度和高度。

    为了使使GetSystemMetrics的功能,我们以获取系统分辨率为例,并将其中的两个值用TextOut输出到窗体中。

    第一步:用GetSystemMetrics获取屏幕的宽度和高度

    int x, y;
    x = GetSystemMetrics(SM_CXSCREEN); //屏幕宽度
    y = GetSystemMetrics(SM_CYSCREEN); //屏幕高度
    获取窗体显示区域大小

    已我现在的了解,获取窗体显示区域大小有三种方法。

    第一种方法:使用GetSystemMetrics函数

    GetSystemMetrics(SM_CXFULLSCREEN); //获取最大化窗体的显示区域宽度
    GetSystemMetrics(SM_CYFULLSCREEN); //获取最大化窗体的显示区域高度
    下面是GetSystemMetrics函数参数nIndex的定义:



    SM_ARRANGE 返回是否预备最小化. SM_CLEANBOOT 返回系统启动方式:     0 正常启动     1 安全模式启动     2 网络安全模式启动 SM_CMOUSEBUTTONS 返回值为系统支持的鼠标键数,返回0,则系统中没有安装鼠标。 SM_CXBORDER, SM_CYBORDER 返回以相素值为单位的Windows窗口边框的宽度和高度,如果Windows的为3D形态,则 等同于SM_CXEDGE参数 SM_CXCURSOR, SM_CYCURSOR 返回以相素值为单位的标准光标的宽度和高度 SM_CXDLGFRAME, SM_CYDLGFRAME 等同与SM_CXFIXEDFRAME and SM_CYFIXEDFRAME SM_CXDOUBLECLK, SM_CYDOUBLECLK 以相素值为单位的双击有效的矩形区域 SM_CXEDGE,SM_CYEDGE 以相素值为单位的3D边框的宽度和高度 SM_CXFIXEDFRAME, SM_CYFIXEDFRAME 围绕具有标题但无法改变尺寸的窗口(通常是一些对话框)的边框的厚度 SM_CXFRAME,SM_CYFRAME 等同于SM_CXSIZEFRAME and SM_CYSIZEFRAME SM_CXFULLSCREEN, SM_CYFULLSCREEN 全屏幕窗口的窗口区域的宽度和高度 SM_CXHSCROLL, SM_CYHSCROLL 水平滚动条的高度和水平滚动条上箭头的宽度 SM_CXHTHUMB 以相素为单位的水平滚动条上的滑动块宽度 SM_CXICON,SM_CYICON 系统缺省的图标的高度和宽度(一般为32*32) SM_CXICONSPACING, SM_CYICONSPACING 以大图标方式查看Item时图标之间的间距,这个距离总是大于等于 SM_CXICON and SM_CYICON. SM_CXMAXIMIZED, SM_CYMAXIMIZED 处于顶层的最大化窗口的缺省尺寸 SM_CXMAXTRACK, SM_CYMAXTRACK 具有可改变尺寸边框和标题栏的窗口的缺省最大尺寸,如果窗口大于这个 尺寸,窗口是不可移动的。 SM_CXMENUCHECK, SM_CYMENUCHECK 以相素为单位计算的菜单选中标记位图的尺寸 SM_CXMENUSIZE, SM_CYMENUSIZE 以相素计算的菜单栏按钮的尺寸 SM_CXMIN,SM_CYMIN 窗口所能达到的最小尺寸 SM_CXMINIMIZED, SM_CYMINIMIZED 正常的最小化窗口的尺寸 SM_CXMINTRACK, SM_CYMINTRACK 最小跟踪距离,当使用者拖动窗口移动距离小于这个值,窗口不会移动。 SM_CXSCREEN, SM_CYSCREEN 以相素为单位计算的屏幕尺寸。 SM_CXSIZE,SM_CYSIZE 以相素计算的标题栏按钮的尺寸 SM_CXSIZEFRAME, SM_CYSIZEFRAME 围绕可改变大小的窗口的边框的厚度 SM_CXSMICON, SM_CYSMICON 以相素计算的小图标的尺寸,小图标一般出现在窗口标题栏上。 M_CXVSCROLL, SM_CYVSCROLL 以相素计算的垂直滚动条的宽度和垂直滚动条上箭头的高度 SM_CYCAPTION 以相素计算的普通窗口标题的高度 SM_CYMENU 以相素计算的单个菜单条的高度 SM_CYSMCAPTION 以相素计算的窗口小标题栏的高度 SM_CYVTHUMB 以相素计算的垂直滚动条中滚动块的高度 SM_DBCSENABLED 如果为TRUE或不为0的值表明系统安装了双字节版本的USER.EXE,为FALSE或0则不是。 SM_DEBUG 如果为TRUE或不为0的值表明系统安装了debug版本的USER.EXE,为FALSE或0则不是。 SM_MENUDROPALIGNMENT 如果为TRUE或不为0的值下拉菜单是右对齐的否则是左对齐的。 SM_MOUSEPRESENT 如果为TRUE或不为0的值则安装了鼠标,否则没有安装。 SM_MOUSEWHEELPRESENT 如果为TRUE或不为0的值则安装了滚轮鼠标,否则没有安装。(Windows NT only) SM_SWAPBUTTON 如果为TRUE或不为0的值则鼠标左右键交换,否则没有。


    回到顶部
    Invalidate(TRUE)的闪屏问题  (2010-05-03 02:58:24)转载▼
    标签:   杂谈        分类: MFC小游戏
        在使用Invalidate(TRUE)进行窗口重绘时,总是会遇到闪屏的问题。

        一开始以为是绘图速度过慢照成的,但在对绘图时间做了一个测试之后发现,即使整个绘图过程只持续了几个毫秒,还是会看见很明显的闪烁,所以时间并不是造成闪烁的决定性因素。

        那到底是什么原因呢?现在来看看Invalidate(TRUE)都干了些什么。其实,它只是间接向消息队列添加了WM_ERASEBKGND和WM_PAINT两个消息。但是,如果使用Invalidate(FALSE)的话,则只有WM_PAINT消息产生,这时是不会有任何闪烁的。

        现在看来,闪烁似乎是由WM_ERASEBKGND消息产生的,事实上,的确与它有关。那WM_ERASEBKGND有干了什么呢?WM_ERASEBKGND消息由OnEraseBkgnd()消息处理函数响应,它的作用就是重绘客户区背景。我们可以通过向工程里添加WM_ERASEBKGND这个消息,然后在重写的消息处理函数中将返回语句修改为return TRUE来屏蔽这一功能,这样做的好处是这时不会重绘背景了,坏处是这时背景也不会被擦出来。

        好像还没有说到真实原因,其实真正的原因就隐含在其中。现在来做一个实验,分别尝试一下快速的眨眼和慢速的眨眼,你会发现快速眨眼时我们会感觉眼前的黑色一闪而过,而慢速眨眼时,则会觉得整个过程是连续的,没有什么异样。其实闪烁也就是这么回事,即多张不连续图像的快速切换。这里有三个条件,多张和快速和不连续,而且需要同时具备才会发生闪烁。如果只是两张,只会感觉到突变,还谈不上闪烁;如果频率慢的话,也相当于两张图像的情况了;最后如果是连续图像的话,那就像是看电影,平稳的过渡也不会让人觉得不适。

        知道了这些,接下来就可以做决策了。

        解决方案:

        使用Invalidate(FALSE),添加WM_ERASEBKGND消息处理函数或者局部刷新三者选其一,都是可以解决问题的。它们的都是通过除去图像不连续这一因素来达到目的的。



        另外,要说的是GDI的BitBlt()函数是及其高效的,一次操作所需要的时间只有几到十几个微秒,所以我们可以放心的使用它,而不用担心任何效率问题。不过相对于BitBlt()来说StretchBlt()就要慢的多,大概是几十倍的差别。

        还有就是一般的绘图工作都是先绘制在一个缓冲区上,然后再一次拷贝到屏幕上。

        有时,当我们需要利用闪烁的效果的话,也是可以通过多张图像的快速切换来做到,在这里我们也将两张图像的重复切换理解为多张图像。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    推荐膜材品牌上一条 /5 下一条

    进口膜材 国产膜材 pvdf膜材ptfe膜材ETFE膜材
    最好的膜结构公司 一级膜结构资质 膜结构一级资质
    膜结构设计-膜结构十大品牌-etfe设计-充气膜结构
    诺科膜结构
    遨都膜结构设计
    中国膜结构网
    中国空间膜结构协会

    QQ|申请友链|Archiver|手机版|中国膜结构论坛

    GMT+8, 2021-3-8 02:42 , Processed in 0.323948 second(s), 27 queries .

    Powered by 中国膜结构网->膜材采购->膜结构设计->膜结构安装->膜结构维修

    © 2014-2020 膜结构协会->进口膜材->国产膜材->PVDF膜材->PTFE膜材->ETFE膜材.

    快速回复 返回顶部 返回列表