窗体位置和大小控制

0339 不可移动的窗体

不可移动的窗体可以通过重载PreTranslateMessage方法来实现,在PreTranslateMessage方法中将鼠标在标题栏按下的消息改为鼠标在非标题栏按下的消息就可以了。

程序代码如下:

BOOL CBKydctDlg::PreTranslateMessage(MSG* pMsg)

{

    if(pMsg->message == WM_NCLBUTTONDOWN)

    {

        pMsg->message = WM_LBUTTONDOWN;

    }

    return CDialog::PreTranslateMessage(pMsg);

}

0340 始终在最上面的窗体

有时会因为打开其他软件,而将正在操作的软件置于其后,为操作带来了不便。要实现将自己的程序永远置前,可以使用API函数SetWindowPos,该函数可以为窗口指定一个新位置和状态。

程序代码如下:

BOOL CTopWindowDlg::OnInitDialog()

{

    …… //此处代码省略

    CRect rect;

    GetClientRect(&rect);

    ::SetWindowPos(AfxGetMainWnd()->m_hWnd,HWND_TOPMOST,rect.left,

        rect.top,rect.right,rect.bottom,SWP_NOMOVE);

    return TRUE;

}

0341 跟随鼠标移动的窗体

要实现跟随鼠标移动的窗体,需要在定时器中获得鼠标和窗体的位置,再通过MoveWindow函数来移动窗体。

程序代码如下:

void CButterflyDlg::OnTimer(UINT nIDEvent)

{

    m_Static.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),

        MAKEINTRESOURCE(IDB_BITMAP1+i))); //设置位图

    CDC* pDC;

    CDC memDC;

    CBitmap    bitmap;

    CBitmap* bmp = NULL;

    COLORREF col;

    CRect rc;

    int x, y;

    CRgn rgn, tmp;

    pDC = GetDC();

    GetClientRect(&rc);

    bitmap.LoadBitmap(IDB_BITMAP1+i); //装载模板位图

    memDC.CreateCompatibleDC(pDC);

    bmp = memDC.SelectObject(&bitmap);

    rgn.CreateRectRgn(0, 0, rc.Width(), rc.Height());

    //计算得到区域

    for(x=0; x<=rc.Width(); x++)

    {

        for(y=0; y<=rc.Height(); y++)

        {

               //将白色部分去掉

               col = memDC.GetPixel(x, y); //得到像素颜色

                if(col == RGB(255,255,255))

                {

                    tmp.CreateRectRgn(x, y, x+1, y+1);

                    rgn.CombineRgn(&rgn,&tmp,RGN_XOR);

                    tmp.DeleteObject();  

            }

        }

    }

    if(bmp)

    {

        memDC.SelectObject(bmp);

    }

    SetWindowRgn((HRGN)rgn,TRUE); //设置窗体为区域的形状

    ReleaseDC(pDC);

    CRect rect;

    CPoint nPoint;

    GetCursorPos(&nPoint);

    GetWindowRect(&rect);

    pOint.x = rect.left;

    pOint.y = rect.top;

    int xRc = (nPoint.x - pOint.x) /8;

    int yRc = (nPoint.y - pOint.y) /8;

    MoveWindow(pOint.x+xRc*i,pOint.y+yRc*i,rect.Width(),rect.Height());  

    i++;

    if(i==8)i=0;

    CDialog::OnTimer(nIDEvent);

}

0342 控制窗体的最大化和最小化

控制窗体的最大化和最小化有两种方法,第一种是在对话框的属性窗口中设置Minimize Box属性和Maximize Box属性,第二种方法是通过PostMessage函数来发送使窗体最大化和最小化的消息。

程序代码如下:

void CMaxAndMinDlg::OnButton1()

{

    PostMessage(WM_SYSCOMMAND,SC_MAXIMIZE,0);

}

void CMaxAndMinDlg::OnButton2()

{

    PostMessage(WM_SYSCOMMAND,SC_MINIMIZE,0);

}

0343 判断窗体是否最小化在任务栏

在判断窗体是否最小化在任务栏之前要判断该实例是否已经存在,可以使用FindWindow函数来实现,FindWindow函数语法如下:

static CWnd* PASCAL FindWindow( LPCTSTR lpszClassName, LPCTSTR lpszWindowName );

参数说明如下。

l     lpszClassName:窗口类名。

l     lpszWindowName:窗口名。

然后使用IsIconic函数判断窗体是否最小化到任务栏中,如图6.2所示。

图6.2 判断窗体是否最小化在任务栏

程序代码如下:

void CMinimizeDlg::OnButton1()

{

    UpdateData(TRUE);

    CWnd *pWndPrev, *pWndChild;

    //根据主窗口类名和主窗口名判断是否已经有实例存在了

    if(pWndPrev = CWnd::FindWindow(_T(NULL),m_Edit))

    {

        //判断是否已经最小化

        if(pWndPrev->IsIconic())

            MessageBox("已经最小化");

        else

            MessageBox("没有最小化");

    }

    else

        MessageBox("窗口不存在");

}

0344 可调整大小的对话框

在编写应用程序时,有时候要根据需要调整对话框的大小。要想使对话框的大小可以调整,需要将对话框的Border属性设置为Resizing。

0345 限制窗体的大小

有时候想要创建可以调整大小的窗体,但是又不希望窗体太大或太小,这时就要对窗体的大小进行限制,可以在对话框的WM_SIZE消息的处理函数中进行设置。

程序代码如下:

void CRestrictRectDlg::OnSize(UINT nType, int cx, int cy)

{

    CDialog::OnSize(nType, cx, cy);

    CRect rect;

    GetWindowRect(&rect);

    if(cx > 400)

        rect.right = rect.left + 400;

    if(cy > 300)

        rect.bottom = rect.top + 300;

    if(cx < 200)

        rect.right = rect.left + 200;

    if(cy < 150)

        rect.bottom = rect.top + 150;

    MoveWindow(&rect);

}

0346 使用鼠标按键调整窗体大小

使用鼠标按键调整窗体大小,就是在窗体的WM_LBUTTONDOWN消息和WM_RBUTTONDOWN消息中放大和缩小窗体。例如单击鼠标左键是窗体缩小,单击鼠标右键是窗体扩大。

程序代码如下:

void CBmpDlg::OnLButtonDown(UINT nFlags, CPoint point)

{

    CRect r;

    GetWindowRect(&r);

    r.right -= 30;

    r.bottom -= 20;

    MoveWindow(r);

    DrawPicture(); //自定义函数,将图片绘制在窗体上

    CDialog::OnLButtonDown(nFlags, point);

}

void CBmpDlg::OnRButtonDown(UINT nFlags, CPoint point)

{

    CRect r;

    GetWindowRect(&r);

    r.right += 30;

    r.bottom += 20;

    MoveWindow(r);

    DrawPicture();

    CDialog::OnRButtonDown(nFlags, point);

}

0347 根据图片大小显示的窗体

根据图片大小显示的窗体是使用控件显示图片后获得控件的大小,再根据控件大小设置窗体的大小。如图6.3所示。

图6.3 根据图片大小显示的窗体

程序代码如下:

void CPictureDlg::OnButton1()

{

    CFileDialog m_filedlg (true,"bmp",NULL,NULL,"位图文件(.bmp)|*.bmp",this);

    if (m_filedlg.DoModal() == IDOK)

    {

        CString str = m_filedlg.GetPathName();

        GetDlgItem(IDC_STATIC)->SetWindowText(str);

        HBITMAP m_hbitmap = (HBITMAP)::LoadImage(GetModuleHandle(NULL),str,

                 IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_DEFAULTCOLOR);

        m_Picture.SetBitmap(m_hbitmap);

        CRect rect;

        m_Picture.GetWindowRect(rect);

        CRect m_rect;

        GetWindowRect(m_rect);

        m_rect.right = rect.right + 10;

        m_rect.bottom = rect.bottom + 10;

        MoveWindow(m_rect);

        CenterWindow();

    }

}

0348 获取当前鼠标点处的控件

在开发程序时,有时需要捕捉当前鼠标点处的控件,以获得其相关信息。可以在程序中使用窗口对象的WindowFromPoint 实现。效果如图6.4所示。

程序相关代码如下:

void CGetWndDlg::OnMouseMove(UINT nFlags, CPoint point)

{

    CWnd * pWnd = WindowFromPoint(point);

    if (AfxIsValidAddress(pWnd,sizeof(CWnd)))

    if (::IsChild(m_hWnd,pWnd->m_hWnd))

    {

        CString str;

        pWnd->GetWindowText(str);

        SetWindowText(str);

    }

    CDialog::OnMouseMove(nFlags, point);

}

BOOL CGetWndDlg::PreTranslateMessage(MSG* pMsg)

{

    if (pMsg->message==WM_MOUSEMOVE)

    {

        CPoint point(LOWORD(pMsg->lParam),HIWORD(pMsg->lParam));

        ::ClientToScreen(pMsg->hwnd,&point);

        OnMouseMove(0,point);

    }

    return CDialog::PreTranslateMessage(pMsg);

}

图6.4 获取当前鼠标点处的控件

0349 在标题栏上绘制控件的简单方法

在设计程序界面时,通常需要在标题栏上进行绘图操作。例如,在标题栏上绘制最大化、最小化、关闭按钮等控件。绘制这些控件时,最简单的方法是调用CDC的DrawFrameControl方法,该方法可以绘制系统提供的常用控件,非常方便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值