2501,20个窗口常用操作

发布于:2025-02-10 ⋅ 阅读:(53) ⋅ 点赞:(0)

窗口是屏幕上的一个矩形区域.窗口分为3种:覆盖窗口,弹窗和子窗口.每个窗口都有由系统绘画的"非客户区"和应用绘画的"客户区".

MFC中,CWnd类为各种窗口提供了基类.

1,通过窗柄取得CWnd指针

可调用Cwnd::FromHandle函数,通过窗柄取得Cwnd指针.

void CDemoDlg::OnButton1()
{
    HWND hWnd = GetSafeHwnd();
    //取得当前窗口的句柄
    CWnd* pWnd = CWnd::FromHandle(hWnd);
    //通过`窗柄`取得`CWnd`指针
    CString strText = _T("");
    strText.Format("pWnd=0x%X\nthis=0x%X\n",pWnd,this);
    AfxMessageBox(strText);
}

2,取得应用主窗口的指针

CWinThread::m_pMainWnd保存主窗口指针.可首先调用AfxGetApp函数取得应用的指针,然后通过应用指针取得主窗口的指针.

void CDemoDlg::OnButton2()
{
    CDemoApp* pApp = (CDemoApp*)AfxGetApp();
    //取得应用指针
    CWnd* pMainWnd = pApp->m_pMainWnd;
    //取得主窗口指针
    CString strText = _T("");
    strText.Format("pMainWnd=0x%X\nthis=0x%X\n",pMainWnd,this);
    AfxMessageBox(strText);
}

3,取得指定点的窗口

可调用CWnd::WindowFromPoint函数,取得指定点的窗口.
a,在CDemoDlg类中重载CWnd::PreTranslateMessage函数.

BOOL CDemoDlg::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);
}

b,在CDemoDlg类中添加WM_MOUSEMOVE消息处理函数.

void CDemoDlg::OnMouseMove(UINT nFlags, CPoint point)
{
    CWnd* pWnd = WindowFromPoint(point);
    //取得指定点的窗口
    if (pWnd != NULL)
    {
        TRACE("%d\n",pWnd);
        if (IsChild(pWnd))
        {
            CString strText = _T("");
            pWnd->GetWindowText(strText);
            SetWindowText(strText);
        }
    }
    CDialog::OnMouseMove(nFlags, point);
}

4,最大化和最小化窗口

可调用CWnd::SendMessage函数发送最大化或最小化窗口消息,来最大化和最小化窗口.

LRESULT SendMessage(
UINT message,
    //发送的消息,值为`WM_SYSCOMMAND`时表示`系统命令消息`.
WPARAM wParam = 0,
     //当`消息`值为`WM_SYSCMMAND`,参数`字参`值为`SC_MAXIMIZE,SC_MINIMIZE`,
LPARAM lParam = 0 );
    //`SC_RESTORE`时分别表示`最大化窗口,最小化窗口,恢复窗口`.

void CDemoDlg::OnButton3()
{
    //最大化窗口
    SendMessage(WM_SYSCOMMAND,SC_MAXIMIZE,0);
}
void CDemoDlg::OnButton4()
{
    //最小化窗口
    SendMessage(WM_SYSCOMMAND,SC_MINIMIZE,0);
}
void CDemoDlg::OnButton5()
{
    //恢复窗口
    SendMessage(WM_SYSCOMMAND,SC_RESTORE,0);
}

5关闭窗口

可调用CWnd::SendMessage函数,发送WM_CLOSE消息来关闭窗口.框架调用CWnd::OnClose函数处理WM_CLOSE消息.
默认,OnClose调用函数CWnd::DestroyWindow函数来关闭窗口.

void CDemoDlg::OnButton6()
{
    //关闭窗口
    SendMessage(WM_CLOSE,0,0);
}
void CDemoDlg::OnClose()
    //添加`WM_CLOSE`消息处理函数
{
    //判断是否关闭
    if (IDYES == MessageBox(_T("是否关闭窗口?"),NULL,MB_YESNO))
    {
        CDialog::OnClose();
    }
}

6设置窗口的大小和位置

可通过两个方法设置窗口大小和位置:1.调用CWnd::SetWindowPos函数;2.调用CWnd::MoveWindow函数.

void CDemoDlg::OnButton7()
{
    //设置窗口的大小和位置
    SetWindowPos(NULL,0,0,320,200,SWP_NOZORDER);
}
void CDemoDlg::OnButton8()
{
    //设置窗口的大小和位置
    MoveWindow(0,200,200,320);
} 

7居中显示窗口

可调用CWnd::CenterWindow函数居中显示窗口.

void CDemoDlg::OnButton9()
{
    //居中显示窗口
    CenterWindow();
} 

8顶层显示窗口

可调用CWnd::SetWindowPos函数顶层显示窗口,按最顶层设置对话框窗口的层次.

void CDemoDlg::OnButton10()
{
    //设置窗口层次
    SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE);
     //`SWP_NOSIZE`:表示窗口保持当前的大小,`SWP_NOMOVE`:表示窗口保持当前的位置
}

9设置窗口图标

首先调用CWinApp::LoadIcon函数加载图标资源,然后调用CWnd::SetIcon函数设置图标.

void CDemoDlg::OnButton11()
{
    //加载图标
    HICON hIcon = AfxGetApp()->LoadIcon(IDI_ICON);
    //设置图标
    SetIcon(hIcon,FALSE);
    //`假`:设置程序小图标,`真`:设置任务栏大图标
} 

10取得和设置窗口的标题

可分别调用CWnd::GetWindowTextCWnd::SetWindowText函数,取得和设置窗口标题.

void CDemoDlg::OnButton12()
{
    CString strText = _T("");
    GetWindowText(strText);
    //取得窗口标题
    SetDlgItemText(IDC_TEXT,strText);
    //设置编辑框文本
}
void CDemoDlg::OnButton13()
{
    CString strText = _T("");
    GetDlgItemText(IDC_TEXT,strText);
    //取得编辑框文本
    SetWindowText(strText);
    //设置窗口标题
}

11显示或隐藏窗口的标题栏

可调用CWnd::ModifyStyle函数显示或隐藏窗口的标题栏.

void CDemoDlg::OnButton14()
{
    //删除标题栏风格
    ModifyStyle(WS_CAPTION,0,SWP_FRAMECHANGED);
}
void CDemoDlg::OnButton15()
{
    //添加标题栏风格
    ModifyStyle(0,WS_CAPTION,SWP_FRAMECHANGED);
}

12改变窗口形状

标准窗口形状矩形的.要改变窗口的形状,首先调用CRgn类的成员函数创建相应形状的区域,然后调用CWnd::SetWindowRgn函数按窗口区域设置它.
可分别用CRgn类的CreateRectRgn,CreateEllipticRgn,CreatePolygonRgnCreateRoundRectRgn函数来创建矩形,椭圆形,多边形和圆矩形区域.

void CDemoDlg::OnButton16()
{
    CRect rect;
    GetClientRect(rect);
    //创建矩形区域
    CRgn rgn;
    rgn.CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom);
    //设置窗口的区域
    SetWindowRgn((HRGN)rgn,TRUE);
}
void CDemoDlg::OnButton17()
{
    CRect rect;
    GetClientRect(rect);
    //创建椭圆形区域
    CRgn rgn;
    rgn.CreateEllipticRgn(0,0,rect.Width(),rect.Height());
    //设置窗口的区域
    SetWindowRgn((HRGN)rgn,TRUE);
}
void CDemoDlg::OnButton18()
{
    CRect rect;
    GetClientRect(rect);
    CPoint point[6];
    point[0].x = 0;
    point[0].y = rect.Height() / 2;
    point[1].x = rect.Width() / 3;
    point[1].y = 0;
    point[2].x = 2 * rect.Width() / 3;
    point[2].y = 0;
    point[3].x = rect.Width();
    point[3].y = rect.Height() / 2;
    point[4].x = 2 * rect.Width() / 3;
    point[4].y = rect.Height();
    point[5].x = rect.Width() / 3;
    point[5].y = rect.Height();
    //创建多边形区域
    CRgn rgn;
    rgn.CreatePolygonRgn(point,6,ALTERNATE);
    //设置窗口的区域
    SetWindowRgn((HRGN)rgn,TRUE);
}
void CDemoDlg::OnButton19()
{
    CRect rect;
    GetClientRect(rect);
    //创建圆矩形区域
    CRgn rgn;
    rgn.CreateRoundRectRgn(0,0,rect.Width(),rect.Height(),rect.Width() / 2,rect.Height() / 2);
    //设置窗口的区域
    SetWindowRgn((HRGN)rgn,TRUE);
}

13设置窗口的透明区域

设置窗口透明区域,首先调用CRgn::CreateRectRgn创建一个区域,然后调用CRgn::CombineRgn函数,去掉需要透明的区域,最后调用CWnd::SetWindowRgn函数按窗口区域设置它.

void CDemoDlg::OnButton20()
{
    CRect rect1;
    GetWindowRect(rect1);
    CRect rect2;
    GetClientRect(rect2);
    ClientToScreen(rect2);
    CRgn rgn1;
    rgn1.CreateRectRgn(rect1.left,rect1.top,rect1.right,rect1.bottom);
    CRgn rgn2;
    rgn2.CreateRectRgn(rect2.left,rect2.top,rect2.right,rect2.bottom);
    CRgn rgn;
    rgn.CreateRectRgn(0,0,1,1);
    rgn.CombineRgn(&rgn1,&rgn2,RGN_DIFF);
    //设置窗口区域
    SetWindowRgn((HRGN)rgn,TRUE);
}

14透明窗口

要实现透明窗口,首先调用CWnd::ModifyStyleEx函数,添加窗口的WS_EX_LAYERED(0x00080000)扩展风格,然后调用SDKSetLayeredWindowAttributes函数设置窗口的透明和透明色.

void CDemoDlg::OnButton21()
{
    //添加`WS_EX_LAYERED(0x80000)`扩展风格
    ModifyStyleEx(0,0x80000);
    //加载`User32.DLL`动态链接库
    HMODULE hModule = LoadLibrary("User32.DLL");
    if (hModule != NULL)
    {
        typedef BOOL (WINAPI *FUNC)(HWND,COLORREF,BYTE,DWORD);
    //取得`SetLayeredWindowAttributes`函数指针
        FUNC func = (FUNC)GetProcAddress(hModule,"SetLayeredWindowAttributes");
        if (func != NULL)
        {
            func(GetSafeHwnd(),0,128,2);
        }
        FreeLibrary(hModule);
    }
}

15窗口闪烁

可调用CWnd::FlashWindow函数闪烁窗口.

void CDemoDlg::OnButton22()
{
    //设置计时器
    SetTimer(1,1000,NULL);
}
void CDemoDlg::OnButton23()
{
    //关闭计时器
    KillTimer(1);
    //窗口返回原状态
    FlashWindow(FALSE);
}
void CDemoDlg::OnTimer(UINT nIDEvent)
{
    if (nIDEvent == 1)
    {
    //窗口从一个状态闪烁到另一个状态
        FlashWindow(TRUE);
    }
    CDialog::OnTimer(nIDEvent);
}

16图片窗口

要实现图片窗口,首先调用CRgn::CreateRectRgnCRgn::CombineRgn函数创建并合并多个区域,然后调用CWnd::SetWindowRgn函数按窗口区域设置它.

VC对话框如何添加WM_ERASEBKGND消息(OnEraseBkgnd函数):

void CDemoDlg::OnButton24()
{
    CRect rect;
    GetWindowRect(&rect);
    //加载位图
    CBitmap bmp;
    bmp.LoadBitmap(IDB_BITMAP);
    //将位图选入设备环境
    CDC dc;
    CDC *pDC = GetDC();
    dc.CreateCompatibleDC(pDC);
    dc.SelectObject(&bmp);
    //将位图中黑色区域变成透明区域
    CRgn rgn1;
    rgn1.CreateRectRgn(0,0,rect.Width(),rect.Height());
    for (int x = 0;x < rect.Width();x++)
    {
        for (int y = 0;y < rect.Height();y++)
        {
            COLORREF cr = dc.GetPixel(x,y);
            if (cr == RGB(0,0,0))
            {
                CRgn rgn2;
                rgn2.CreateRectRgn(x,y,x+1,y+1);
                rgn1.CombineRgn(&rgn1,&rgn2,RGN_XOR);
            }
        }
    }
    //设置窗口区域
    SetWindowRgn((HRGN)rgn1,TRUE);
    ReleaseDC(pDC);
}
    //添加`WM_ERASEBKGND`消息处理函数
BOOL CDemoDlg::OnEraseBkgnd(CDC* pDC)
{
    CRect rect;
    GetWindowRect(&rect);
    CBitmap bmp;
    bmp.LoadBitmap(IDB_BITMAP);
    CDC dc;
    dc.CreateCompatibleDC(pDC);
    dc.SelectObject(&bmp);
    pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);
    return TRUE;
}

17动画窗口

可调用SDK动画窗口函数,实现动画窗口.

BOOL CDemoDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    //...居中窗口
    CenterWindow();
    //显示动画窗口
    AnimateWindow(GetSafeHwnd(), 3000, AW_BLEND);
    return TRUE;
}

18桌面窗口

可调用CWnd::GetDesktopWindow函数,取得桌面窗口.

void CDemoDlg::OnButton25()
{
    //取得桌面窗口
    CWnd* pWnd = CWnd::GetDesktopWindow();
    //取得窗口大小
    CRect rect;
    pWnd->GetClientRect(rect);
    CString strText = _T("");
    strText.Format(_T("桌面窗口大小:%dX%d"),rect.Width(),rect.Height());
    AfxMessageBox(strText);
}

19最小化桌面所有窗口

窗口中可利用快捷键Win+M最小化所有窗口.因此,可通过向任务栏窗口发送ID0x1F5(Win+M)的WM_HOTKEY消息,来最小化桌面所有窗口.
首先调用CWnd::FindWindow函数取得窗口,然后调用CWnd::SendMessage函数向窗口发送消息.

void CDemoDlg::OnButton26()
{
    //取得任务栏窗口
    CWnd* pWnd = CWnd::FindWindow(_T("Shell_TrayWnd"),NULL);
    //发送`ID`为`0x1F5(Win+M)`的`WM_HOTKEY`消息
    pWnd->SendMessage(WM_HOTKEY,0x1F5);
}

20取任务栏窗口

可调用CWnd::FindWinow函数,取得任务栏窗口.

void CDemoDlg::OnButton27()
{
    //取得任务栏窗口
    CWnd* pWnd = CWnd::FindWindow(_T("Shell_TrayWnd"),NULL);
    //取得窗口大小
    CRect rect;
    pWnd->GetClientRect(rect);
    CString strText = _T("");
    strText.Format(_T("任务栏窗口大小:%dX%d"),rect.Width(),rect.Height());
    AfxMessageBox(strText);
}

21显示或隐藏任务栏

显示或隐藏任务栏;首先调用CWnd::FindWindow函数取得窗口,然后调用CWnd::ShowWindow函数隐藏或显示窗口.

void CDemoDlg::OnButton28()
{
    //取得任务栏窗口
    CWnd* pWnd = CWnd::FindWindow(_T("Shell_TrayWnd"),NULL);
    //隐藏窗口
    if (pWnd->IsWindowVisible())
    {
        pWnd->ShowWindow(SW_HIDE);
    }
}
void CDemoDlg::OnButton29()
{
    //取得任务栏窗口
    CWnd* pWnd = CWnd::FindWindow(_T("Shell_TrayWnd"),NULL);
    //显示窗口
    if (!pWnd->IsWindowVisible())
    {
        pWnd->ShowWindow(SW_SHOW);
    }
}

22枚举桌面所有顶层窗口

BOOL CDemoDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    //...初化列表框控件
    CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST);
    pList->ModifyStyle(LVS_ICON | LVS_SMALLICON | LVS_LIST,LVS_REPORT);
    pList->SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
    pList->InsertColumn(0,_T("窗口类名"),LVCFMT_LEFT,115);
    pList->InsertColumn(1,_T("窗口标题"),LVCFMT_LEFT,150);
    return TRUE;
}

枚举桌面所有顶层窗口两个方法:

a,调用CWnd::GetDesktopWindowCWnd::GetWindow函数:首先调用CWnd::GetDesktopWindow函数,取得桌面窗口,然后调用CWnd::GetWindow函数,枚举所有子窗口.

void CDemoDlg::OnButton30()
{
    CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST);
    pList->DeleteAllItems();
    pList->SetRedraw(FALSE);
    //取得桌面窗口
    CWnd* pDesktopWnd = CWnd::GetDesktopWindow();
    //取得第一个子窗口
    CWnd* pWnd = pDesktopWnd->GetWindow(GW_CHILD);
    while(pWnd != NULL)
    {
        int nItem = pList->GetItemCount();
    //取得窗口类名
        CString strClassName = _T("");
        ::GetClassName(pWnd->GetSafeHwnd(),strClassName.GetBuffer(256),256);
        strClassName.ReleaseBuffer();
        pList->InsertItem(nItem,strClassName);
    //取得窗口标题
        CString strWindowText = _T("");
        ::GetWindowText(pWnd->GetSafeHwnd(),strWindowText.GetBuffer(256),256);
        strWindowText.ReleaseBuffer();
        pList->SetItemText(nItem,1,strWindowText);
    //继续取得下个子窗口
        pWnd =  pWnd->GetWindow(GW_HWNDNEXT);
    }
    pList->SetRedraw(TRUE);
}

b,调用SDKEnumWindows函数.

    //添加全局函数
BOOL CALLBACK EnumWndPorc(HWND hWnd,LPARAM lParam)
{
    if (hWnd == NULL)
    {
        return FALSE;
    }
    CListCtrl* pList = (CListCtrl*)lParam;
    int nItem = pList->GetItemCount();
    //取得窗口类名
    CString strClassName = _T("");
    ::GetClassName(hWnd,strClassName.GetBuffer(256),256);
    strClassName.ReleaseBuffer();
    pList->InsertItem(nItem,strClassName);
    //取得窗口标题
    CString strWindowText = _T("");
    ::GetWindowText(hWnd,strWindowText.GetBuffer(256),256);
    strWindowText.ReleaseBuffer();
    pList->SetItemText(nItem,1,strWindowText);
    return TRUE;
}
void CDemoDlg::OnButton31()
{
    CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST);
    pList->DeleteAllItems();
    pList->SetRedraw(FALSE);
    //枚举窗口
    ::EnumWindows(EnumWndPorc,(LPARAM)pList);
    pList->SetRedraw(TRUE);
}

网站公告

今日签到

点亮在社区的每一天
去签到