本文涉及到的技术有:
1. 动态创建按钮
2. 将按钮创建到系统桌面上
3. 动态响应创建的桌面上按钮
4. 获取屏幕尺寸
5. 实时显示系统时间(这里不是标准实现,标准使用定时器)

先来看酷狗的效果图:

上图是桌面显示歌词。


上图是酷狗控制酷狗的窗口,这个在以前的版本是固定在桌面的,就和我们本文所要讲述的一样,因为那样不方便,所以酷狗现在改为窗口了,可以拖动。可以拖动的窗口实现就是一般的窗口了。这里我们要讲述固定在桌面的按钮实现。

再来看看我们实现的效果图:(当然这里没有考虑美观,只实现功能,如果感兴趣,你可以看完本文后继续研究美化)
 


上图左边图片是点击按钮后动态创建到桌面一个按钮,单击“显示时间”按钮后,会在屏幕右上角实时显示上图右边的时间。

下面来讲述如何实现:

1. 首先创建一个普通的MFC工程,此处就不用细说了,不熟的话,自己先熟悉哦。
2. 然后在“类视图”的项目名中右击,“添加”->“类”,在弹出的对话框中,选择“MFC类”,单击“添加”即可弹出如下对话框,如下图:

输入类名,在基类中可以选择"CWnd"或者"CButton",然后单击“完成”即可创建一个窗口类。
3. 给新创建的窗口类添加一个鼠标点击消息“LButtonDown”响应。方法:在“类视图”中右击类名,单击“属性”,在属性对话框中,选择消息页,找到“WM_LBUTTONDOWN”,添加一个鼠标左键按下的消息处理函数。
消息处理函数代码如下,实现屏幕右上角实时显示时间:

void CDeskBtn::OnLButtonDown(UINT nFlags, CPoint point)
{
    /* - 创建桌面窗口绘图对象,传入NULL则表示创建桌面绘图对象。
       - 传入什么指针则创建什么样的绘图对象。
       - 如果是按钮窗口则在按钮上绘制,如果是主窗口则在主窗口绘制等等,NULL则表示桌面
    */
    CWindowDC desk(NULL);
    int i=0;
    desk.SetTextColor(RGB(255,255,0));// - 设置文本颜色
    desk.SetBkColor(RGB(0,0,0));      // - 设置文本背景颜色
    TCHAR tip[255]={0};
    SYSTEMTIME st;  // - 系统时间结构体
    POINT pointScr; // - 点结构体
    pointScr.x = GetSystemMetrics(SM_CXSCREEN);// - 获得屏幕宽度
    pointScr.y = GetSystemMetrics(SM_CYSCREEN);// - 获取屏幕高度
    while(i<10000000)
    {
        Sleep(100);
        GetLocalTime(&st); // - 获取当前系统时间
        /* - 格式化时间 - *、
        wsprintf(tip,_T("当前时间:%4d年%2d月%2d日 %2d:%2d:%2d\0\0"),
            st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);

        /* - 将要显示的区域先刷黑,以免文字残留 - */
        desk.FillRect(CRect(pointScr.x-300,20,60,20),&CBrush(RGB(0,0,0)));
        desk.TextOut(pointScr.x-300,20,tip);// - 打印文字到屏幕右上角

        i++;
    }
}

4. 在主对话框类中添加桌面按钮类对象作为成员,需要先包含这个桌面按钮类头文件,然后添加成员如下:

CDeskBtn m_DeskBtn;

5.在主对话框的按钮单击响应函数中,加入创建桌面按钮和显示按钮的代码,如下:

m_DeskBtn.Create(_T("Button"),_T("显示时间"),WS_CHILD|BS_PUSHBUTTON,CRect(400,400,600,600),GetDesktopWindow(),10000);
m_DeskBtn.ShowWindow(SW_SHOWNORMAL);

    Create函数是创建一个窗口,第一个参数使用Button指定窗口类为按钮,第二个参数显示按钮的文字,第三个参数传入WS_CHILD|BS_PUSHBUTTON风格参数表示创建子窗口和按钮风格,第四个参数指定窗口的位置和大小,CRect局部对象一次性指定,第五个参数传入GetDesktopWindow函数返回的桌面窗口指针作为要创建的桌面按钮的父窗口,这个决定按钮可以创建到桌面,第六个参数指定按钮的ID,可以自定义一个,不要与已有的冲突即可。

    以上是动态创建的按钮,如果不想使用Create动态创建,可以事先在主窗口中放入桌面按钮,然后在主窗口按钮单击后,将d调用SetParent(NULL)函数将桌面按钮的父窗口设置为桌面,这样窗口启动后,这个桌面按钮就出现在桌面了,而不是在主窗口了。其他的与动态创建按钮一样。
    具体的代码解释在注释中写清楚了,如果还有问题,请留言。