void Sprite::OnDraw( Gdiplus::Graphics &g, const Gdiplus::RectF &rcDirty ) { if (!m_bVisible) { return; // 子节点也不会被绘制 } // 前序遍历 让父节点先绘制 //Gdiplus::RectF rc = GetRect(); //if (10 == rc.Width && 10 == rc.Height) //{ // LOGW(<<L"Orignal Size 10 10"); // 检查下有没有多余的重绘 //} if (m_bClipChildren) { Gdiplus::RectF rcClip = GetRect(); rcClip.X = 0.0f; rcClip.Y = 0.0f; g.SetClip(rcClip); } PaintEvent ev; ev.graphics = &g; ev.rcDirty = rcDirty; SendNotify(ePaint, &ev); //this->ClientDraw(g, rcDirty); Sprite *sp = m_firstChild; while(sp) { // 如果需要重绘部分矩形和sp相交则重画它 否则不重画 // 这里还有个问题就是 父矩形必须比子矩形要大 否则可能父的相交不到 而子的相交的到 // 可能要强制这一原理 类似于浏览器 会撑大 Gdiplus::RectF rc2 = sp->GetRect(); Gdiplus::RectF rcAbs = sp->GetAbsRect(); rcAbs.X -= 0.5f; // FIXME 有时无法得到重画导致边界1像素消失 rcAbs.Y -= 0.5f; rcAbs.Width += 1.0f; rcAbs.Height += 1.0f; if (rcDirty.IntersectsWith(rcAbs)) { g.TranslateTransform(rc2.X, rc2.Y); sp->OnDraw(g, rcDirty); g.TranslateTransform(-rc2.X, -rc2.Y); } sp = sp->m_nextSibling; } if (m_bClipChildren) { g.ResetClip(); } }
// http://blog.csdn.net/magic_feng/article/details/6618206 Sprite * Sprite::DispatchMouseEvent(MouseEvent *event) { std::stack<Sprite *> stack; std::stack<Sprite *> reverse; stack.push(this); Sprite *sp = NULL; while(!stack.empty()) { sp = stack.top(); stack.pop(); reverse.push(sp); // visit in reversed order. Sprite *sp2 = sp->m_lastChild; while (sp2) { stack.push(sp2); sp2 = sp2->m_prevSibling; } } while (!reverse.empty()) { sp = reverse.top(); reverse.pop(); Gdiplus::RectF rc = sp->GetAbsRect(); //LOG("HitTest:"<< rc.X << "," <<rc.Y << "," << rc.Width << "," << rc.Height); if (rc.Contains(event->x, event->y)) { MouseEvent e2 = *event; e2.x -= rc.X; e2.y -= rc.Y; sp->OnMouseEvent(g_L, &e2); } } return NULL; }