chrome之view

看了点其他东西,结果发现以前看的chrome代码有些忘了,看来写博客确实是好事,能帮助人很容易的回忆起来

 

chrome的是基于wtl的,他的view类比较庞大,具体的子类又分为native和custom

native就是windows的自有空间,比如button,custom的就是directui了,界面里划分出不同的区域,区域显示出类似button的效果

以radiobutton为例,继承关系是view->button->nativebutton->checkboxbutton->radiobutton

nativebutton.h里面 组合了NativeButtonWrapper* native_wrapper_;

在nativebutton的ViewHierarchyChanged()里创建 native_wrapper_ = CreateWrapper();

createwrapper这个是checkbox和radiobutton都要重载的,radio的是

CreateRadioButtonWrapper(this);

 

而这里实际最终调用的就是

  HWND control_hwnd = CreateWindowEx(

      GetAdditionalExStyle(), L"BUTTON",

      L"", WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | BS_RADIOBUTTON,

      0, 0, width(), height(), GetWidget()->GetNativeView(), NULL, NULL, NULL);

所以这里如果想重绘checkbox之类的原生控件的话,就需要在nativexx父窗口里处理相应的wm_paint,drawitem之类,chrome里面默认都没有对原生控件的自绘处理

 

再来看custombutton的textbutton

这套流程走的相当苦闷

首先widghtwin收到mouse消息,然后通过rootview去查鼠标所在位置属于哪个子窗口并通知,

子窗口收到后,发现需要重绘,这时候就会调用schedulepaint,这又是个反方向的找到最终的rootVIEW

并转发到widgtwin,最后调用invalidaterect(最子窗口的区域) ,然后widghtwin就会收到wm_paint,这时候去

执行绘画,绘画过程也是一样的恶心,widghtwin这里beginpaint,然后把整个rootview的所有子窗口全部重画到

一个canvas里去,最后画到dc,endpaint

 

 

view->button->custombutton->textbutton,绘制通过  

 

void WidgetWin::OnPaint(HDC dc) {

  root_view_->OnPaint(hwnd());

}

 

root_view然后将所有的子控件都画到canvas上,

ProcessPaint(&canvas);

这里有个递归调用所有子控件,最终就到了我们想要的Onpaint里面

void TextButton::Paint(gfx::Canvas* canvas, bool for_drag) 

比如接收到鼠标移入移出等需要重绘的时候,控件调用paint通知root_view

 

这里root_view绘画的时候,onpaint并没有直接调用redrawwindow,而是调用了

SchedulePaint(gfx::Rect(ps.rcPaint), false);

schedupaint里,如果在消息到达这里的时候上一次的绘画还没执行,那他会合并这个无效区域,就相当于少画了一次

 

  if (invalid_rect_.IsEmpty())

    invalid_rect_ = r;

  else

    invalid_rect_ = invalid_rect_.Union(r);

 

然后是通过消息的方式去具体执行redraw

 

      pending_paint_task_ = new PaintTask(this);

      MessageLoop::current()->PostTask(FROM_HERE, pending_paint_task_);

 

 

 void Run() {

    if (root_view_)

      root_view_->PaintNow();

  }

 

绘画的时候就是从内存的图里直接画到dc上

这样做的好处就是可合并多个绘画动作,这个mfc的处理里也是类似的

 

这里root_view是个大集合,所有的控件都要addchildview进来的,

widghtwin继承自WindowImpl,是一个windows下window的实现类,通过调用windows api RegisterClassEx,createwindowex创建窗口,并将消息转到wndproc->onwndproc->ProcessWindowMessage

然后子类只要重载ProcessWindowMessage就可以处理消息了,这就相当于转到了wtl的那一套

 

widghtwin里面包含了rootview的一个实例root_view_

 

 

menu也放到这里吧,他实现menu是通过新创建一个大小为0的窗口,然后在这个窗口上注册消息,并弹出具体的menu

 

  TrackPopupMenuEx(menu_, flags, point.x(), point.y(), host_window_->hwnd(),

                   NULL);

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值