标题的问题
解决方案 »
- 刚开始学VC,用什么书好啊?谢谢
- 求socket课户端和服务器端程序
- 使用了Xtreme的MenuBar之后,我用GetMenu得不到主菜单对象了…………
- 请问简单问题
- WINDOWS如何编程新建目录?
- 请教各位,在创建主窗口时,风格 WS_CLIPCHILDREN 详细的意思是什么,具体是什么样一种风格呀
- 打印机救急,请高手帮助
- 请问高手什么错误可能导致 isapi 死锁
- 手动添加cpp与h文件到工程里后,显示-No such file or directory
- SendMessage()和PostMessage()的区别是什么。截获消息是指什么,该如何去做。先谢了。
- 100分求助!还是关于多重继承的this指针的问题,帮忙看一下为什么下面的小例子执行出错。
- 基础问题请教 stdafx.h
{
// 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里画
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
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