当前位置:C++技术网 > 资讯 > 实现界面画面启动程序

实现界面画面启动程序

更新时间:2018-12-19 15:22:02浏览次数:1+次

    在看本文之前,希望你看下《worker线程与UI线程的学习》《手写VC向导代码》两文,如果你没有很好的基础的话。为了浅析好这个小程序,我特意写的那两篇文章。   

    首先创建一个基于对话框的工程,工程名为Splash。我们从CWnd类派生一个子类CSplashWnd,作为系统启动界面的窗口。我们这个类不手写实现,直接利用VC的类向导。然后我们添加WM_PAINT消息。

    写入代码:

void CSplashWnd::OnPaint() 
{
    CPaintDC dc(this); // device context for painting
    BITMAP bm;
    GetObject(hbmp,sizeof(bm),&bm);
    CDC memdc;
    memdc.CreateCompatibleDC(&dc);
    memdc.SelectObject(hbmp);
    dc.BitBlt(0,0,bm.bmWidth,bm.bmHeight,&memdc,0,0,SRCCOPY);
    // Do not call CWnd::OnPaint() for painting messages
}

    关于BitBlt()与CreateCompatibleDC()两个函数还有下面的LoadImage函数,我在《学习心得之八------实现从磁盘读入图片文件》中解释了,你可以去那里看看。在这里我补充句,CreateCompatibleDC函数就是创建兼容的DC,实际上就是将函数的参数拷贝给调用这个函数的另一个DC。

    接下来我们添加个显示窗口的函数ShowSplashWindow():

void CSplashWnd::ShowSplashWindow()
{
    UpdateWindow();//更新窗口
    SetTimer(1,1,NULL);
}

    然后就是定时器函数的消息响应:

void CSplashWnd::OnTimer()
{
    KillTimer(1);
    Sleep(5000);
    SendMessage(WM_CLOSE);
    //CWnd::OnTimer(nIDEvent);
}

    然后就是消息响应函数OnCreate()(该函数是windows消息句柄),这个函数主要就是改变窗口界面的位置,如果不添加这个函数,那么,最后得结果就是界面窗口会在屏幕的左上角。我们添加这个函数来移动界面窗口,使它居中:

int CSplashWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
     if (CWnd::OnCreate(lpCreateStruct) == -1)
         return -1;
    
     // TODO: Add your specialized creation code here
     CenterWindow();
     return 0;
}

    下面就是添加函数以创建界面窗口了:不过我们先添加一个CWnd类的变量,用它来调用CreateEx函数来创建窗口。同时添加一个HBITMAP类的变量hbmp。

BOOL CSplashWnd::Create(CWnd* pParentWnd)
{
    hbmp=(HBITMAP)::LoadImage(AfxGetInstanceHandle(),"mr.bmp",IMAGE_BITMAP,
        0,0,LR_LOADFROMFILE|LR_DEFAULTCOLOR|LR_DEFAULTSIZE);
    BITMAP bm;
    GetObject(hbmp,sizeof(bm),&bm);
    
    //创建默认窗体
    LPCTSTR pszWndClass=AfxRegisterWndClass(0);
    VERIFY(m_wndbase.CreateEx(0,pszWndClass, _T(""),WS_POPUP,CW_USEDEFAULT,
        CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, NULL, 0));
    //创建图片大小窗体
    pszWndClass=AfxRegisterWndClass(0,AfxGetApp()->LoadStandardCursor(IDC_ARROW));
    VERIFY(CreateEx(0,pszWndClass,_T(""),WS_POPUP|WS_VISIBLE,0,0,
        bm.bmWidth,bm.bmHeight,m_wndbase.GetSafeHwnd(),NULL));
    ::SetWindowPos(m_wndbase.GetSafeHwnd(),HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
    return true;
}

    在这里CreateEx函数的两种重载形式都用上了,第一个帮我们创建窗口,第二个就是将我们创建的窗体适应我们加载启动界面的图片。在这里我们加载了一个“mr.bmp"的图片,但是首先你得先在项目的文件夹中加载这个图片哦!

    我的工程是在C盘里的MyProjects里,工程名叫Splash。在里面加上个“mr.bmp”图片,就好了。

    下面我们手写一个类CSplashThread,该类派生自CWinThread类,我们利用这个类来创建UI界面线程(请看《worker线程与UI线程的学习》),双击CSplashWnd类,进入头文件,我们在其间写入代码,不过你得注意哦!CSplashThread类中除了构造函数,析构函数外,还有两个虚函数哦!那就是InitInstance()与ExitInstance()函数,这两个虚函数是必备的。接着我们在这个类的头文件中,声明一个CSplashWnd类的变量-m_mysplash。我们利用这个变量,在CSplashThread类的InitInstance()函数中调用Create函数与ShowSplashWindow函数。

BOOL CSplashThread::InitInstance()
{
    m_mysplash.Create();
    m_mysplash.ShowSplashWindow();
    return TRUE;
}

    最后就是创建UI界面线程了,不过我们得在CSplashApp类的InitInstance函数中实现,至于理由,你可以在《学习心得之七(续)-字体启动程序的设计》或《学习心得之七》两文中找到相关解释哦!

    我们看看需写入的代码:

CSplashThread* pSplashThread = (CSplashThread*) AfxBeginThread(RUNTIME_CLASS(CSplashThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
if (pSplashThread == NULL)
{
       MessageBox(NULL,"创建闪屏失败!","提示",MB_OK);
       return FALSE;
}
pSplashThread->ResumeThread();

    我们创建的CSplashThread类就是为了这里的函数AfxBeginThread的返回值,用来创建UI界面线程。

    看看实现结果吧!