Chromium的绘制也要从WM_PAINT的开始
HWNDMessageHandler是Chromium中UI和系统消息的媒介。它来全权处理了。
好了,一个WM_PAINT消息来了。
void HWNDMessageHandler::OnPaint(HDC dc) 中,关键代码如下:
scoped_ptr<gfx::CanvasPaint> canvas( gfx::CanvasPaint::CreateCanvasPaint(hwnd())); delegate_->HandlePaint(canvas->AsCanvas());
class CanvasPaintWin : public gfx::CanvasPaint, public gfx::CanvasSkiaPaint 这里的CanvasPaint其实是CanvasPaintWin 的化身。
CanvasSkiaPaint 的析构会执行
virtual ~CanvasSkiaPaint() { if (!isEmpty()) { skia::PlatformCanvas* canvas = platform_canvas(); canvas->restoreToCount(1); // Commit the drawing to the screen skia::DrawToNativeContext(canvas, paint_dc_, ps_.rcPaint.left, ps_.rcPaint.top, NULL); } if (for_paint_) EndPaint(hwnd_, &ps_); }
看不到主动调用某些函数,而是放到某些对象中去执行,在chromium中非常常见。
好了,绘制的画布搞清楚了,那绘制过程是如何的呢。往回看这句
delegate_->HandlePaint(canvas->AsCanvas())
这里的delegate_声名是 HWNDMessageHandlerDelegate* delegate_;
class VIEWS_EXPORT NativeWidgetWin : public internal::NativeWidgetPrivate,
public HWNDMessageHandlerDelegate
大部分情况下是NativeWidgetWin 的化身了。
继而会走到如下里面
void NativeWidgetWin::HandlePaint(gfx::Canvas* canvas) { delegate_->OnNativeWidgetPaint(canvas); }
class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, public FocusTraversable
void Widget::OnNativeWidgetPaint(gfx::Canvas* canvas) { // On Linux Aura, we can get here during Init() because of the // SetInitialBounds call. if (native_widget_initialized_) GetRootView()->Paint(canvas); }