http://download.pchome.net/home/remind/7140.html
能做出像这个时钟的透明效果吗??
给思路者:200分。
给代码者:1000分。

解决方案 »

  1.   

    我看了一下这个程序,你的鼠标只要指到没有文字的地方,就可以对下面的窗口进行操作,我觉得他是用setwindowrgn,把窗口的区域设置成:除了有文字或图的地方,其它全部挖空。编程也不是太难,关键是把图像转成rgn(可以每个像素逐一判断,用combinergn来组合成一个大的rgn)。这是我个人的看法,还请各位指教
      

  2.   

    透明是有两种方式的。其中有种是以某种颜色为关键色。
    具体代码我也有。
    void CIconWnd::OnPaint() 
    {
    CPaintDC dc(this); // device context for painting

    if(m_bmp.GetSafeHandle() == NULL)
    return; CRect rect;
    GetClientRect(rect); CXTMemDC memdc(&dc,rect,MASKCLR);
    CDC bmpdc;
    bmpdc.CreateCompatibleDC(&dc);
    CBitmap *oldbmp = bmpdc.SelectObject(&m_bmp);
    memdc.BitBlt(0,0,rect.Width(),rect.Height(),&bmpdc,0,0,SRCCOPY); if(m_flashText)
    {
    CSize size;
    GetTextExtentPoint32(dc.GetSafeHdc(),m_text,
    m_text.GetLength(),&size);

    memdc.SetBkMode(15);
    memdc.SetTextColor(RGB(255,0,0));
    memdc.TextOut(rect.left + rect.Width()/2 - size.cx/2,
    rect.top + rect.Height()/2 - size.cy/2,m_text);
    }
    bmpdc.SelectObject(oldbmp);
    bmpdc.DeleteDC();
    }BOOL CIconWnd::OnInitDialog() 
    {
    CDialog::OnInitDialog();
    SetTimer(101,1000,NULL);
    SetTranslate(m_hWnd,MASKCLR,0,LWA_COLORKEY);
    return TRUE;  // return TRUE unless you set the focus to a control
                  // EXCEPTION: OCX Property Pages should return FALSE
    }void CIconWnd::SetIcon(CString filename)
    {
    HBITMAP hBmp = (HBITMAP)LoadImage( NULL, filename, IMAGE_BITMAP, 0, 0,
    LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
    if(hBmp == NULL)
    return;
    if(m_bmp.GetSafeHandle())
    {
    m_bmp.Detach();
    }
    m_bmp.Attach(hBmp); if(m_hWnd == NULL)
    return;
    BITMAP bm;
    m_bmp.GetBitmap(&bm);
    CRect rect;
    GetWindowRect(rect);
    rect.SetRect(m_x,m_y,m_x + bm.bmWidth,m_y + bm.bmHeight);
    MoveWindow(rect);
    Invalidate();
    }void CIconWnd::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    PostMessage(WM_NCLBUTTONDOWN,
    HTCAPTION,MAKELPARAM(point.x,point.y)); // TODO: Add your message handler code here and/or call default

    CDialog::OnLButtonDown(nFlags, point);
    }void CIconWnd::SetIcon(UINT id)
    {
    if(m_bmp.GetSafeHandle())
    {
    m_bmp.Detach();
    }
    m_bmp.LoadBitmap(id);

    if(m_hWnd == NULL)
    return;
    BITMAP bm;
    m_bmp.GetBitmap(&bm);
    CRect rect;
    GetWindowRect(rect);
    rect.SetRect(rect.left,rect.top,rect.left + bm.bmWidth,rect.top + bm.bmHeight);
    MoveWindow(rect);
    Invalidate();
    }void CIconWnd::OnTimer(UINT nIDEvent) 
    {
    // TODO: Add your message handler code here and/or call default
    m_flashText = !m_flashText;
    this->Invalidate();

    CDialog::OnTimer(nIDEvent);
    }
    这是其中部分,最主要的是
    SetTimer(101,1000,NULL);
    SetTranslate(m_hWnd,MASKCLR,0,LWA_COLORKEY);
    下面一个函数也只是我的一个包装函数。其实这也没什么难的,只是有的人少,不过其实他更强大,
    所以,当我们用一些函数时,要多看msdn,然后举一反三。
      

  3.   

    我也用过setwindowrgn,但是如果像它一样是动的话,我要显示的当前时间,闪动非常厉害。因为要不停地将变化的图像计算成RGN,然后再用setwindowrgn函数。win2000下的窗口透明效果是将整个窗口透明,和这个程序的效果是不同的。欢迎大家讨论。
      

  4.   

    请教wwwllg(wwwllg):
    CXTMemDC是不是自写的类?
    如果m_text经常变化会透明吗?
    SetTranslate(m_hWnd,MASKCLR,0,LWA_COLORKEY)函数中是如何处理的?
    能否发一份源码给我?
    [email protected]
      

  5.   

    我是在2000下运行这个程序的,其实你只要用apispy2.7察看一下就知道了。肯定使用setwindowrgn做成的。我指的那个apispy不是察看api调用的工具,而是一个察看当前鼠标所指的窗口句柄的那个工具。
      

  6.   

    /*-----------------------------------------------------------------------------
      function: CreateRgnFromBmp
      根据位图信息得到不规则区域
      Author:    chs
      Date:      8-12-2003
      Arguments: HBITMAP bmp 位图句柄
      Result:    HRGN  区域句柄
      Algorithm:1、按位图大小创建绘制区域
                 2、取背景图片左下角像素为基准像素
     3、遍历图片每个像素
     4、删除与基准像素相同的区域
     5、返回区域句柄
    -----------------------------------------------------------------------------*/
    HRGN CBgzformDlg::CreateRgnFromBmp(HBITMAP bmp)  {
    BITMAP bmpSize;
    HBITMAP oldbmp;
    HRGN R,R1;//R绘制区域,R1裁减区域
    HDC dcmem;
    COLORREF  transColor;//基准像素信息
    int iWidth,iHeight,oldHeight;// CClientDC dc(this);
    dcmem=CreateCompatibleDC(0);
    oldbmp=HBITMAP(SelectObject(dcmem,bmp));
    SelectObject(dcmem,bmp);  //选择位图

    GetObject(bmp, sizeof(bmpSize), &bmpSize);
    R=CreateRectRgn(0, 0, bmpSize.bmWidth, bmpSize.bmHeight); //按位图大小创建绘制区域
    // oldbmp=HBITMAP(dcmem.SelectObject(&bmp));
    transColor = GetPixel(dcmem,0, 0);  //左下角像素信息

    for (iWidth=0;iWidth<bmpSize.bmWidth;iWidth++)  //循环对比像素信息
    {
    iHeight = 0;
    while (iHeight < bmpSize.bmHeight)
    {

    if (GetPixel(dcmem,iWidth, iHeight) == transColor)
    {
    oldHeight = iHeight;
    while ((iHeight < bmpSize.bmHeight) &&
                        (GetPixel(dcmem,iWidth, iHeight+1)== transColor))
    {
    iHeight++;
    }
    //得到与基准像素信息相同的区域
    R1=CreateRectRgn(iWidth, oldHeight, iWidth + 1, iHeight + 1);
                    CombineRgn(R,R,R1,RGN_DIFF);//在绘制区域中除去该区域
                    DeleteObject(R1);
    }
    iHeight++;
    }

    } SelectObject(dcmem,oldbmp);
    return R;
    }
    BOOL CBgzformDlg::OnInitDialog()
    {加上
        bitmap.LoadBitmap(IDB_BITMAP);
         
        HRGN rgn=CreateRgnFromBmp(HBITMAP(bitmap.GetSafeHandle()));
        ::SetWindowRgn (GetSafeHwnd(),rgn, TRUE);
    }void CBgzformDlg::OnPaint() 
    {//前面的不动,在else后面改为
    else
    {
    //CDialog::OnPaint();
    CPaintDC dc(this);
    CDC dcmem;
    dcmem.CreateCompatibleDC(&dc);
    dcmem.SelectObject(&bitmap);
             BITMAP bmpSize;
             GetObject(bitmap.GetSafeHandle(), sizeof(bmpSize), &bmpSize); dc.BitBlt(0,0,bmpSize.bmWidth,bmpSize.bmHeight,&dcmem,0,0,SRCCOPY);//
    }
    }
    在你的资源中添加位图id为;IDB_BITMAP