网站首页 > 物联资讯 > 技术分享

精通 VC++ 实效编程280例 - 01 窗口

2016-09-28 00:00:00 广州睿丰德信息科技有限公司 阅读
睿丰德科技 专注RFID识别技术和条码识别技术与管理软件的集成项目。质量追溯系统、MES系统、金蝶与条码系统对接、用友与条码系统对接

窗口是屏幕上的一个矩形区域。窗口分为3种:重叠窗口、弹出窗口和子窗口。每个窗口都有由系统绘制的“非客户区”和应用程序绘制的“客户区”。在 MFC 中,CWnd 类为各种窗口提供了基类。

1 通过 HWND 获得 CWnd 指针

通过 HWND 获得 Cwnd 指针可以调用 Cwnd::FromHandle 函数。

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

2 获得应用程序主窗口的指针

主窗口指针保存在 CWinThread::m_pMainWnd 中。可以首先调用 AfxGetApp 函数获得应用程序的指针,然后通过应用程序指针获得主窗口的指针。

1 2 3 4 5 6 7 8 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 函数。

1 2 3 4 5 6 7 8 9 10 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 消息处理函数。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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,     //当 message 值为 WM_SYSCMMAND,参数 wParam 值为 SC_MAXIMIZE、SC_MINIMIZE、

LPARAM lParam = 0 );      //SC_RESTORE 时分别表示最大化窗口、最小化窗口、恢复窗口。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 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 函数关闭窗口。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 函数。

1 2 3 4 5 6 7 8 9 10 11 void CDemoDlg::OnButton7() {     //设置窗口的大小和位置     SetWindowPos(NULL,0,0,320,200,SWP_NOZORDER); }   void CDemoDlg::OnButton8() {     //设置窗口的大小和位置     MoveWindow(0,200,200,320); } 

7 居中显示窗口

使窗口居中显示可以调用 CWnd::CenterWindow 函数。

1 2 3 4 5 void CDemoDlg::OnButton9() {     //居中显示窗口     CenterWindow(); } 

8 顶层显示窗口

使窗口顶层显示,可以调用 CWnd::SetWindowPos 函数,设置对话框窗口的层次为最顶层。

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

9 设置窗口图标

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

1 2 3 4 5 6 7 void CDemoDlg::OnButton11() {     //加载图标     HICON hIcon = AfxGetApp()->LoadIcon(IDI_ICON);     //设置图标     SetIcon(hIcon,FALSE);   //FALSE:设置程序小图标,TRUE:设置任务栏大图标 } 

10 获得和设置窗口的标题

获得和设置窗口标题可以分别调用 CWnd::GetWindowText 和 CWnd::SetWindowText 函数。

1 2 3 4 5 6 7 8 9 10 11 12 13 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 函数。

1 2 3 4 5 6 7 8 9 10 11 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 函数可以分别用来创建矩形、椭圆形、多边形和圆矩形区域。 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 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 函数将其设置为窗口区域。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 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 函数设置窗口的透明度和透明色。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 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 函数。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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函数):

http://guohaiyang.blog.163.com/blog/static/3213403720081027104147/

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 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 的 AnimateWindow 函数。

1 2 3 4 5 6 7 8 9 10 BOOL CDemoDlg::OnInitDialog() {     CDialog::OnInitDialog();     // ...         //窗口居中     CenterWindow();     //显示动画窗口     AnimateWindow(GetSafeHwnd(), 3000, AW_BLEND);     return TRUE; }

18 桌面窗口

获得桌面窗口,可以调用 CWnd::GetDesktopWindow 函数。

1 2 3 4 5 6 7 8 9 10 11 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 最小化桌面所有窗口

Window 中可以利用快捷键 Win+M 最小化所有窗口。因此,可以通过向任务栏窗口发送 ID 为 0x1F5(Win+M) 的 WM_HOTKEY 消息,使桌面所有窗口最小化。首先调用 CWnd::FindWindow 函数获得窗口,然后调用 CWnd::SendMessage 函数向窗口发送消息。

1 2 3 4 5 6 7 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 函数。

1 2 3 4 5 6 7 8 9 10 11 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 函数隐藏或显示窗口。 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 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 函数,枚举所有子窗口。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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 函数。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 //添加全局函数 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); }

 

 

from:http://www.cnblogs.com/iwanc/archive/2013/06/09/2985807.html

RFID管理系统集成商 RFID中间件 条码系统中间层 物联网软件集成