static LRESULT OnFavTreeNotify(WindowInfo* win, LPNMTREEVIEW pnmtv) { switch (pnmtv->hdr.code) { // TVN_SELCHANGED intentionally not implemented (mouse clicks are handled // in NM_CLICK, and keyboard navigation in NM_RETURN and TVN_KEYDOWN) case TVN_KEYDOWN: { TV_KEYDOWN* ptvkd = (TV_KEYDOWN*)pnmtv; if (VK_TAB == ptvkd->wVKey) { if (win->tabsVisible && IsCtrlPressed()) { TabsOnCtrlTab(win, IsShiftPressed()); } else { AdvanceFocus(win); } return 1; } break; } case NM_CLICK: { // Determine which item has been clicked (if any) TVHITTESTINFO ht = {0}; DWORD pos = GetMessagePos(); ht.pt.x = GET_X_LPARAM(pos); ht.pt.y = GET_Y_LPARAM(pos); MapWindowPoints(HWND_DESKTOP, pnmtv->hdr.hwndFrom, &ht.pt, 1); TreeView_HitTest(pnmtv->hdr.hwndFrom, &ht); if ((ht.flags & TVHT_ONITEM)) { GoToFavForTVItem(win, pnmtv->hdr.hwndFrom, ht.hItem); } break; } case NM_RETURN: GoToFavForTVItem(win, pnmtv->hdr.hwndFrom); break; case NM_CUSTOMDRAW: return CDRF_DODEFAULT; } return -1; }
static LRESULT OnTocTreeNotify(WindowInfo *win, LPNMTREEVIEW pnmtv) { switch (pnmtv->hdr.code) { case TVN_SELCHANGED: // When the focus is set to the toc window the first item in the treeview is automatically // selected and a TVN_SELCHANGEDW notification message is sent with the special code pnmtv->action == 0x00001000. // We have to ignore this message to prevent the current page to be changed. if (TVC_BYKEYBOARD == pnmtv->action || TVC_BYMOUSE == pnmtv->action) GoToTocLinkForTVItem(win, pnmtv->hdr.hwndFrom, pnmtv->itemNew.hItem, TVC_BYMOUSE == pnmtv->action); // The case pnmtv->action==TVC_UNKNOWN is ignored because // it corresponds to a notification sent by // the function TreeView_DeleteAllItems after deletion of the item. break; case TVN_KEYDOWN: { TV_KEYDOWN *ptvkd = (TV_KEYDOWN *)pnmtv; if (VK_TAB == ptvkd->wVKey) { if (win->tabsVisible && IsCtrlPressed()) TabsOnCtrlTab(win, IsShiftPressed()); else AdvanceFocus(win); return 1; } break; } case NM_CLICK: { // Determine which item has been clicked (if any) TVHITTESTINFO ht = { 0 }; DWORD pos = GetMessagePos(); ht.pt.x = GET_X_LPARAM(pos); ht.pt.y = GET_Y_LPARAM(pos); MapWindowPoints(HWND_DESKTOP, pnmtv->hdr.hwndFrom, &ht.pt, 1); TreeView_HitTest(pnmtv->hdr.hwndFrom, &ht); // let TVN_SELCHANGED handle the click, if it isn't on the already selected item if ((ht.flags & TVHT_ONITEM) && TreeView_GetSelection(pnmtv->hdr.hwndFrom) == ht.hItem) GoToTocLinkForTVItem(win, pnmtv->hdr.hwndFrom, ht.hItem); break; } case NM_RETURN: GoToTocLinkForTVItem(win, pnmtv->hdr.hwndFrom); break; case NM_CUSTOMDRAW: #ifdef DISPLAY_TOC_PAGE_NUMBERS if (win->AsEbook()) return CDRF_DODEFAULT; switch (((LPNMCUSTOMDRAW)pnmtv)->dwDrawStage) { case CDDS_PREPAINT: return CDRF_NOTIFYITEMDRAW; case CDDS_ITEMPREPAINT: return CDRF_DODEFAULT | CDRF_NOTIFYPOSTPAINT; case CDDS_ITEMPOSTPAINT: RelayoutTocItem((LPNMTVCUSTOMDRAW)pnmtv); // fall through default: return CDRF_DODEFAULT; } break; #else return CDRF_DODEFAULT; #endif case TVN_GETINFOTIP: CustomizeTocInfoTip((LPNMTVGETINFOTIP)pnmtv); break; } return -1; }
bool FocusManager::OnKeyEvent(const KeyEvent& event) { // If the focused view wants to process the key event as is, let it be. // On Linux we always dispatch key events to the focused view first, so // we should not do this check here. See also WidgetGtk::OnKeyEvent(). if(focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(event)) { return true; } // Intercept Tab related messages for focus traversal. // Note that we don't do focus traversal if the root window is not part of the // active window hierarchy as this would mean we have no focused view and // would focus the first focusable view. HWND top_window = widget_->GetNativeView(); HWND active_window = ::GetActiveWindow(); if((active_window==top_window || ::IsChild(active_window, top_window)) && IsTabTraversalKeyEvent(event)) { AdvanceFocus(event.IsShiftDown()); return false; } // Intercept arrow key messages to switch between grouped views. KeyboardCode key_code = event.GetKeyCode(); if(focused_view_ && focused_view_->GetGroup()!=-1 && (key_code==VKEY_UP || key_code==VKEY_DOWN || key_code==VKEY_LEFT || key_code==VKEY_RIGHT)) { bool next = (key_code==VKEY_RIGHT || key_code==VKEY_DOWN); std::vector<View*> views; focused_view_->GetParent()->GetViewsWithGroup( focused_view_->GetGroup(), &views); std::vector<View*>::const_iterator iter = std::find(views.begin(), views.end(), focused_view_); DCHECK(iter != views.end()); int index = static_cast<int>(iter - views.begin()); index += next ? 1 : -1; if(index < 0) { index = static_cast<int>(views.size()) - 1; } else if(index >= static_cast<int>(views.size())) { index = 0; } SetFocusedViewWithReason(views[index], kReasonFocusTraversal); return false; } // Process keyboard accelerators. // If the key combination matches an accelerator, the accelerator is // triggered, otherwise the key event is processed as usual. Accelerator accelerator(event.GetKeyCode(), event.IsShiftDown(), event.IsControlDown(), event.IsAltDown()); if(ProcessAccelerator(accelerator)) { // If a shortcut was activated for this keydown message, do not propagate // the event further. return false; } return true; }