// Tests whether a view is valid, whether it still belongs to the window // hierarchy of the FocusManager. bool FocusManager::ContainsView(View* view) { DCHECK(view); RootView* root_view = view->GetRootView(); if(!root_view) { return false; } Widget* widget = root_view->GetWidget(); if(!widget) { return false; } HWND top_window = widget_->GetNativeView(); HWND window = widget->GetNativeView(); while(window) { if(window == top_window) { return true; } window = ::GetParent(window); } return false; }
void OnScroll(int code, HWND source, bool is_horizontal) { int pos; if(code == SB_ENDSCROLL) { return; } // If we receive an event from the scrollbar, make the view // component focused so we actually get mousewheel events. if(source != NULL) { Widget* widget = parent_->GetWidget(); if(widget && widget->GetNativeView()!=GetFocus()) { parent_->RequestFocus(); } } SCROLLINFO si; si.cbSize = sizeof(si); si.fMask = SIF_POS | SIF_TRACKPOS; GetScrollInfo(scrollbar_, SB_CTL, &si); pos = si.nPos; ScrollBarController* sbc = parent_->GetController(); switch(code) { case SB_BOTTOM: // case SB_RIGHT: pos = parent_->GetMaxPosition(); break; case SB_TOP: // case SB_LEFT: pos = parent_->GetMinPosition(); break; case SB_LINEDOWN: // case SB_LINERIGHT: pos += sbc->GetScrollIncrement(parent_, false, true); pos = std::min(parent_->GetMaxPosition(), pos); break; case SB_LINEUP: // case SB_LINELEFT: pos -= sbc->GetScrollIncrement(parent_, false, false); pos = std::max(parent_->GetMinPosition(), pos); break; case SB_PAGEDOWN: // case SB_PAGERIGHT: pos += sbc->GetScrollIncrement(parent_, true, true); pos = std::min(parent_->GetMaxPosition(), pos); break; case SB_PAGEUP: // case SB_PAGELEFT: pos -= sbc->GetScrollIncrement(parent_, true, false); pos = std::max(parent_->GetMinPosition(), pos); break; case SB_THUMBPOSITION: case SB_THUMBTRACK: pos = si.nTrackPos; if(pos < parent_->GetMinPosition()) { pos = parent_->GetMinPosition(); } else if(pos > parent_->GetMaxPosition()) { pos = parent_->GetMaxPosition(); } break; default: break; } sbc->ScrollToPosition(parent_, pos); si.nPos = pos; si.fMask = SIF_POS; SetScrollInfo(scrollbar_, SB_CTL, &si, TRUE); // Note: the system scrollbar modal loop doesn't give a chance // to our message_loop so we need to call DidProcessMessage() // manually. // // Sadly, we don't know what message has been processed. We may // want to remove the message from DidProcessMessage() MSG dummy; dummy.hwnd = NULL; dummy.message = 0; MessageLoopForUI::current()->DidProcessMessage(dummy); }