标题的问题

解决方案 »

  1.   

    BOOL Cspeed1View::OnEraseBkgnd(CDC* pDC)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    CDC mdc;
    mdc.CreateCompatibleDC(pDC);

    CBitmap bmp;
    bmp.LoadBitmap(IDB_BG); CBitmap *old = mdc.SelectObject(&bmp); pDC->BitBlt(0,0,800,600,&mdc,0,0,SRCCOPY); mdc.SelectObject(old);
    mdc.DeleteDC(); bmp.DeleteObject(); return true;
    //return CFormView::OnEraseBkgnd(pDC);
    }
    或者直接在ON_DRAW里画
      

  2.   

    call GetWindowLong(hMain, GWL_WNDPROC). This function returns pointer to old window procedure and we want to store it for further use. Place this code in CBackgroundImageApp::InitInstance() just before showing the Main Frame.HWND hMain = pMainFrame->GetWindow(GW_CHILD)->GetSafeHwnd();
    pfnOldWndProc = (WNDPROC)GetWindowLong(hMain, GWL_WNDPROC);
    SetWindowLong(hMain, GWL_WNDPROC, (long)pfnNewWndProc);Now we have sub-classed window, but the window procedure is missing. Lets write it now. The window procedure should handle at least two messages to work well :WM_ERASEBKGND 
    WM_SIZE 
    First message is sent when Windows wants application to draw its background - we'll use this to draw our image. Second message is also important because when you resize window image should also change its size to fit into new window size. Our window proc would look like this :LRESULT CALLBACK pfnNewWndProc(HWND hwnd, 
           UINT uMsg, WPARAM wParam,LPARAM lParam)
    {
        // local variables goes here    switch (uMsg)   {
            case WM_SIZE :
                // ...
            case WM_ERASEBKGND :
                // ...
                return 1;
            default :
                return CallWindowProc(pfnOldWndProc,
                    hwnd, uMsg, wParam, lParam);
        }
    }Important note
    Returing 1 from WM_ERASEBKGND case is very important because it tells Windows that we already erased window and it has nothing to do, otherwise Windows would erase this window again with standard background, which I suppose is not we wanted to achieve.What about other messages ?
    Here is the moment we are using stored old window procedure pointer. We simply call old procedure and return its result. So lets look closer to the WM_SIZE and WM_ERASEBKGND cases.WM_SIZE - Simply force window background to redraw itself by sending WM_ERASEBKGND to it :SendMessage(hwnd, WM_ERASEBKGND, (WPARAM)GetDC(hwnd), 0);
    return 1;WM_ERASEBKGND - Code below will simply BitBlt the bitmap. Because the window size generally very rarely is the same as image size BitBlt() becomes StretchBlt(). Finally it looks like below :hcompdc = CreateCompatibleDC(hdc);
    SelectObject(hcompdc, hBmp);
    GetClientRect(hwnd, &rect);if (0 == StretchBlt(hdc, 
        rect.left, rect.top, rect.right, rect.bottom,
        hcompdc, 0, 0, 1152, 864, SRCCOPY))
        MessageBox(hwnd, "error",
            "while StretchBlt", MB_OK);DeleteDC(hcompdc);
    return 1;
    Where :hdc, hcompdc - Device context 
    hBmp - bitmap handle 
    It is very important to invoke DeleteDC() because we don't want to cause memory leaks.Final notes
      

  3.   

    SDI projects created using MFC come with a default white background color. This sample code implements any color the programmer desires after the creation of an SDI framework using the MFC wizard for project creation.Ctrl+W pops up the MFC classwizard property sheet. 
    Select the Message Maps tab. 
    From the drop-down list box under the Class Name static control, select the CxxxView option (xxx = Your project's name; for example, CNnoyeView). 
    Make sure CxxxView is also selected in the Object ID's list box. 
    Select the WM_ERASEBKGND option in the Messages list box. 
    Click the Add Function button. The Class Wizard adds the "OnEraseBkgnd" member function. 
    Click the Edit Code button. Add the following code before the return CView::OnEraseBkgnd(pDC) statement. 
    CBrush brNew(RGB(0,0,255));  //Creates a blue brush
    CBrush* pOldBrush = (CBrush*)pDC->SelectObject(&brNew);CRect rc;
    pDC->GetClipBox(rc); // Gets the co-ordinates of the client
                         // area to repaint.
    pDC->PatBlt(0,0,rc.Width(),rc.Height(),PATCOPY);
                         // Repaints client area with current brush.
    pDC->SelectObject(pOldBrush);return TRUE;    // Prevents the execution of return
                    // CView::OnEraseBkgnd(pDC) statement