窗口是屏幕
上的一个矩形区域
.窗口
分为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::GetWindowText
和CWnd::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,CreatePolygonRgn
和CreateRoundRectRgn
函数来创建矩形,椭圆形,多边形和圆矩形区域
.
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)
扩展风格,然后调用SDK
的SetLayeredWindowAttributes
函数设置窗口的透明和透明色
.
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::CreateRectRgn
和CRgn::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
最小化所有窗口.因此,可通过向任务栏窗口
发送ID
为0x1F5(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::GetDesktopWindow
和CWnd::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,调用SDK
的EnumWindows
函数.
//添加全局函数
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);
}