正文

第十一课:Windows样式2007-09-24 12:19:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/lym51/29633.html

分享到:

第十一课:Windows样式

一、首先回忆一下WinMain一课中的创建一个窗口的几个步骤。

二、首先回忆一下MFC一课中程序执行的顺序。

三、修改Windows样式:

1.  CMainFrame::PreCreateWindow中修改:

在窗口产生之前,会调用它的成员函数PreCreateWindow,此时窗口还没有产生,相当于一栋大楼修建之前,在它的设计图纸上修改它的式样,然后按照修改后的图纸去修建大楼。

a.     直接修改CREATESTRUCT(让最大化按钮不可用)

  cs.style &= ~WS_MAXIMIZEBOX;   //去掉窗口的最大化按钮

b.     重新注册WNDCLASS(修改窗口的图标及背景)

对于窗口的图标、背景等,不能直接修改。需要重新注册WNDCLASS。我们以修改图标为例,在资源面板中添加一个图标,其IDIDI_ICON1

i.                 AfxRegisterWndClass函数:

cs.lpszClass=::AfxRegisterWndClass(NULL,NULL,NULL,                                      AfxGetApp()->LoadIcon(IDI_ICON1));

ii.              重新填写WNDCLASS

WNDCLASS wndClass;

wndClass.style=CS_HREDRAW;

wndClass.lpfnWndProc=(WNDPROC)::DefWindowProc;

wndClass.cbClsExtra=0;

wndClass.cbWndExtra=0;

 wndClass.hInstance=::AfxGetInstanceHandle();

wndClass.hIcon=LoadIcon(::AfxGetInstanceHandle(),

MAKEINTRESOURCE(IDI_ICON1));

 wndClass.hCursor=LoadCursor(NULL,IDC_NO);

LOGBRUSH lgbr;

lgbr.lbStyle=BS_SOLID;

lgbr.lbColor=RGB(255,255,0);

lgbr.lbHatch=HS_CROSS;

wndClass.hbrBackground=CreateBrushIndirect(&lgbr);

wndClass.lpszMenuName=NULL;

 wndClass.lpszClassName="It315";

RegisterClass(&wndClass);

cs.lpszClass="It315";

此时会发现窗口的图标改变了,但背景和光标没有变。应将此段代码拷入CXxxView::PreCreateWindow中。

iii.          利用GetClassInfo函数:

   WNDCLASS wndclass;

    ::GetClassInfo(AfxGetInstanceHandle(),cs.lpszClass,&wndclass);

    wndclass.hIcon=::LoadIcon(::AfxGetInstanceHandle(),

MAKEINTRESOURCE(IDI_ICON1));

    wndclass.lpszClassName="It315";

    ::RegisterClass(&wndclass);

    cs.lpszClass="It315";

2.  在窗口产生以后修改:

CMainFrame::OnCreate

a.     去掉最大化按钮:

 SetWindowLong(m_hWnd,GWL_STYLE,

::GetWindowLong(m_hWnd,GWL_STYLE) & ~WS_MAXIMIZEBOX);

b.     修改图标:

SetClassLong(m_hWnd,GCL_HICON,(long)AfxGetApp()->LoadIcon(IDI_ICON1))

3.  制作动画图标:

a.     在资源面板中添加三个图标,其IDIDI_ICON1IDI_ICON2 IDI_ICON3

b.     定义一个成员变量 ,用于装入三个图标的句柄:  

HICON          m_hIcon[3];

c.     CMainFrame的构造函数中装入三个图标的句柄: 

   m_hIcon[0]=AfxGetApp()->LoadIcon(IDI_ICON1);

    m_hIcon[1]=AfxGetApp()->LoadIcon(IDI_ICON2);

    m_hIcon[2]=AfxGetApp()->LoadIcon(IDI_ICON3);

d.     CMainFrame::OnCreate中设置定时器:

      SetTimer(1,200,NULL);

e.     加入WM_TIMER的消息响应函数OnTimer,在其中加入代码:

      static i=0;

        SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcon[i]);

        i=++i%3;

四、贴图:

在资源面板中装入一幅位图,其IDIDB_BITMAP1,在CXxxView::OnDraw中贴图。

贴图必须以如下步骤进行:

1.  产生一个兼容DC

  CDC dccompatible;

    dccompatible.CreateCompatibleDC(pDC);

2.  装入位图:

  CBitmap bmp;

    bmp.LoadBitmap(IDB_BITMAP1);

3.  将位图选入兼容DC

  dccompatible.SelectObject(&bmp);

4.  将兼容DC上的内容拷入当前DC上:

      CRect rect;

    GetClientRect(&rect);

pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dccompatible,0,0,SRCCOPY);

说明:

1.  BitBlt会按11的比例将位图拷入,如果想在CxxxView上显示整个位图,可以用StretchBlt函数:

   BITMAP bitmap;

    bmp.GetBitmap(&bitmap);

    pDC->StretchBlt(0,0,rect.Width(),rect.Height(),

&dccompatible,0,0,

bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);

2.  系统在发出WM_PAINT消息之前,会发出WM_EARSEBKGND消息,去执行真正的刷新背景的操作,可将以上代码剪贴到WM_EARSEBKGND消息的响应函数OnEraseBkgnd中去。然后将原来的return CView::OnEraseBkgnd(pDC);改为return true;

五、操作状态栏:

1.  在状态栏显示鼠标坐标:

CxxxView中加入WM_MOUSEMOVE的响应函数OnMouseMove,加入代码:

CString str;

str.Format("X=%d,Y=%d",point.x,point.y);

((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str);

此种方法要将CMainFrame中的m_wndStatusBar改为public类型,再在CxxxView的执行文件中加入#include "MainFrm.h"。它破坏了CMainFrame的封装性,不建议使用。改用下面的方法:

((CFrameWnd*)GetParent())->SetMessageText(str);

或者

(CFrameWnd*)AfxGetApp()->m_pMainWnd)->GetMessageBar()->SetWindowText(str);

2.  加入自定义状态栏,显示系统时间:

a.     在资源面板中加入一个字符串资源,其IDIDS_TIME

b.     IDS_TIME加入CMainFrame中控制状态栏的数组static UINT indicators[]中,IDS_TIME在数组中的序号决定自定义状态栏的位置。

c.     CMainFrame::OnCreate中设置定时器和自定义状态栏的大小:

  SetTimer(2,1000,NULL);

   CTime tm=CTime::GetCurrentTime();

    CString str=tm.Format("%H:%M:%S");

    CClientDC dc(this);

    CSize sz=dc.GetTextExtent(str);

    m_wndStatusBar.SetPaneInfo(2,111,SBPS_POPOUT,sz.cx);

    m_wndStatusBar.SetPaneText(2,str);

d.     OnTimer中加入代码:

    if(2==nIDEvent)

      CTime tm=CTime::GetCurrentTime();

        CString str=tm.Format("%H:%M:%S");

        m_wndStatusBar.SetPaneText(2,str);

else

…………

3.  在状态栏中加入进度条:

a.     CmainFrame中定义成员变量,用于产生进度条:

     CProgressCtrl    m_ctrlProg;

b.     在资源面板中加入一个字符串资源,其IDIDS_PROGRESS

c.     IDS_ PROGRESS加入CMainFrame中控制状态栏的数组static UINT indicators[]

d.     CMainFrame中加入WM_PAINT的响应函数CMainFrame::OnPaint()

  CRect rect;

    m_wndStatusBar.GetItemRect(2,&rect);

    if(m_ctrlProg.m_hWnd)

    {  

     m_ctrlProg.SetWindowPos(NULL,rect.left,rect.top,

rect.Width(),rect.Height(),SWP_NOZORDER);

    }

  else 

   m_ctrlProg.Create(WS_CHILD|WS_VISIBLE,rect,&m_wndStatusBar,111);

e.     OnTimer中加入触发进度条的代码:

      m_ctrlProg.StepIt();


阅读(4695) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册