LRESULT HexView::OnKeyDown(UINT nVirtualKey, UINT nRepeatCount, UINT nFlags) { BOOL fForceUpdate = FALSE; bool fCtrlDown = IsKeyDown(VK_CONTROL); bool fShiftDown = IsKeyDown(VK_SHIFT); size_w oldoffset = m_nCursorOffset; fForceUpdate = !IsKeyDown(VK_SHIFT); if(nVirtualKey == VK_CONTROL || nVirtualKey == VK_SHIFT || nVirtualKey == VK_MENU) return 0; switch(nVirtualKey) { case VK_ESCAPE: fForceUpdate = TRUE; break; case VK_INSERT: if(fCtrlDown) { OnCopy(); } else if(fShiftDown) { OnPaste(); } else { if(m_nEditMode == HVMODE_INSERT) m_nEditMode = HVMODE_OVERWRITE; else if(m_nEditMode == HVMODE_OVERWRITE) m_nEditMode = HVMODE_INSERT; NotifyParent(HVN_EDITMODE_CHANGE); } return 0; case 'z': case 'Z': m_nSubItem = 0; if(fCtrlDown) Undo(); return 0; // CTRL+Y redo case 'y': case 'Y': m_nSubItem = 0; if(fCtrlDown) Redo(); return 0; case VK_DELETE: // can only erase when in Insert mode if(m_nEditMode == HVMODE_INSERT || CheckStyle(HVS_ALWAYSDELETE) && (m_nEditMode == HVMODE_INSERT || m_nEditMode == HVMODE_OVERWRITE) && SelectionSize() == 0) { ForwardDelete(); } else if(m_nEditMode != HVMODE_READONLY) { BYTE b[] = { 0 }; FillData(b, 1, SelectionSize()); } return 0; case VK_BACK: // can only erase when in Insert mode if(m_nEditMode == HVMODE_INSERT || CheckStyle(HVS_ALWAYSDELETE) && (m_nEditMode == HVMODE_INSERT || m_nEditMode == HVMODE_OVERWRITE)) { BackDelete(); } else { //PostMessage(m_hWnd, WM_KEYDOWN, INPUT inp = { INPUT_KEYBOARD }; inp.ki.wVk = VK_LEFT; SendInput(1, &inp, sizeof(inp)); } return 0; case VK_LEFT: //if ctrl held down, then scroll the viewport around! if(IsKeyDown(VK_CONTROL)) { PostMessage(m_hWnd, WM_HSCROLL, SB_LINEUP, 0L); return 0; } if(m_nCursorOffset > 0) m_nCursorOffset--; m_fCursorAdjustment = FALSE; break; case VK_RIGHT: //if ctrl held down, then scroll the viewport around! if(IsKeyDown(VK_CONTROL)) { PostMessage(m_hWnd, WM_HSCROLL, SB_LINEDOWN, 0L); return 0; } if(m_nCursorOffset < m_pDataSeq->size()) { m_nCursorOffset++; if(m_nCursorOffset == m_pDataSeq->size() && m_pDataSeq->size() % m_nBytesPerLine == 0) m_fCursorAdjustment = TRUE; else m_fCursorAdjustment = FALSE; } break; case VK_UP: //if ctrl held down, then scroll the viewport around! if(IsKeyDown(VK_CONTROL)) { PostMessage(m_hWnd, WM_VSCROLL, SB_LINEUP, 0L); return 0; } if(m_nCursorOffset > (unsigned)m_nBytesPerLine) m_nCursorOffset -= m_nBytesPerLine; break; case VK_DOWN: //if ctrl held down, then scroll the viewport around! if(IsKeyDown(VK_CONTROL)) { PostMessage(m_hWnd, WM_VSCROLL, SB_LINEDOWN, 0L); return 0; } m_nCursorOffset += min((size_w)m_nBytesPerLine, m_pDataSeq->size() - m_nCursorOffset); // if in the last partial line, don't go to end of file, rather // stay at "bottom" of file/window if(m_nCursorOffset >= m_pDataSeq->size() && !m_fCursorAdjustment) { // test if in a partial line if( oldoffset % m_nBytesPerLine < m_pDataSeq->size() % m_nBytesPerLine || m_pDataSeq->size() % m_nBytesPerLine == 0) { m_nCursorOffset = oldoffset; fForceUpdate = TRUE; } } break; case VK_HOME: //if ctrl held down, then scroll the viewport around! if(fCtrlDown) { m_nCursorOffset = 0; PostMessage(m_hWnd, WM_VSCROLL, SB_TOP, 0L); } else { if(m_fCursorAdjustment && m_nCursorOffset > 0) m_nCursorOffset--; m_nCursorOffset -= m_nCursorOffset % m_nBytesPerLine; } m_fCursorAdjustment = FALSE; break; case VK_END: if(IsKeyDown(VK_CONTROL)) { m_nCursorOffset = m_pDataSeq->size(); if(m_nCursorOffset % m_nBytesPerLine == 0) m_fCursorAdjustment = TRUE; PostMessage(m_hWnd, WM_VSCROLL, SB_BOTTOM, 0L); } else { // if not already at very end of line if(m_fCursorAdjustment == FALSE) { if(m_pDataSeq->size() - m_nBytesPerLine >= m_nCursorOffset && m_pDataSeq->size() >= m_nBytesPerLine) { m_nCursorOffset += m_nBytesPerLine - (m_nCursorOffset % m_nBytesPerLine); m_fCursorAdjustment = TRUE; } else { m_nCursorOffset += m_pDataSeq->size()-m_nCursorOffset; } } if(m_nCursorOffset >= m_pDataSeq->size() && m_pDataSeq->size() % m_nBytesPerLine == 0) m_fCursorAdjustment = TRUE; } break; case VK_PRIOR: // pageup m_nCursorOffset -= min(m_nCursorOffset, (size_w)m_nBytesPerLine * m_nWindowLines); break; case VK_NEXT: // pagedown m_nCursorOffset += min(m_pDataSeq->size() - m_nCursorOffset, (size_w)m_nBytesPerLine * m_nWindowLines); if(m_nCursorOffset >= m_pDataSeq->size() && m_pDataSeq->size() % m_nBytesPerLine == 0) { m_fCursorAdjustment = TRUE; } break; case VK_TAB: m_nWhichPane ^= 1; fForceUpdate = TRUE; if(m_ColourList[HVC_SELECTION] != m_ColourList[HVC_SELECTION2]) { InvalidateRange(m_nSelectionStart, m_nSelectionEnd); } break; default: // don't know what this key is, so exit return 0; } m_nSubItem = 0; if(m_nCursorOffset != oldoffset || fForceUpdate) { // SHIFT key being held down? if(IsKeyDown(VK_SHIFT)) { // extend the selection m_nSelectionEnd = m_nCursorOffset; InvalidateRange(oldoffset, m_nSelectionEnd); } else if(nVirtualKey != VK_TAB) { // clear any selection if(m_nSelectionEnd != m_nSelectionStart) InvalidateRange(m_nSelectionEnd, m_nSelectionStart); m_nSelectionEnd = m_nCursorOffset; m_nSelectionStart = m_nCursorOffset; } ScrollToCaret(); NotifyParent(HVN_CURSOR_CHANGE); if(nVirtualKey == VK_NEXT || nVirtualKey == VK_PRIOR) { RefreshWindow(); } } return 0; }
BOOL HexView::GetHighlightCol(size_w offset, int pane, BOOKNODE *itemStart, HEXCOL *col1, HEXCOL *col2, bool fModified, bool fMatched, bool fIncSelection) { //int idx = -1; //int m_nNumHighlights = m_Highlight->nNumItems; //HIGHLIGHT *Highlight = m_Highlight->Highlight; BOOKNODE *hi = itemStart; size_w selstart = min(m_nSelectionStart, m_nSelectionEnd); size_w selend = max(m_nSelectionStart, m_nSelectionEnd); int nSchemeIdxFG; int nSchemeIdxBG; BOOL fGotFocus = GetFocus() == m_hWnd ? TRUE : FALSE; fGotFocus = GetAncestor(GetForegroundWindow(), GA_ROOTOWNER) == GetParent(m_hWnd); fGotFocus = fGotFocus && IsWindowEnabled(GetParent(m_hWnd)); //TRACEA("FG = %x (me=%x)\n", GetForegroundWindow(), m_hWnd); if(pane == 0) { nSchemeIdxFG = (((offset + m_nDataShift)% m_nBytesPerLine) / m_nBytesPerColumn) & 1 ? HVC_HEXEVEN : HVC_HEXODD; nSchemeIdxBG = HVC_BACKGROUND; } else { nSchemeIdxFG = HVC_ASCII; nSchemeIdxBG = HVC_BACKGROUND; } // modified bytes override normal settings if(fModified && CheckStyle(HVS_SHOWMODS)) nSchemeIdxFG = HVC_MODIFY; if(fMatched) { //nSchemeIdxFG = HVC_BACKGROUND; nSchemeIdxBG = HVC_MATCHED; } // search forward to find the highlight under specified offset for(hi = itemStart; hi; hi = hi->next) { if(offset >= hi->bookmark.offset && offset < hi->bookmark.offset + hi->bookmark.length) { break; } } /* // search forward to find the highlight under specified offset for(int i = highidx; i < m_nNumHighlights && i != -1; i++) { // find the nearest highlight if(offset >= Highlight[i].nRangeStart && offset < Highlight[i].nRangeEnd) { idx = i; //break; } }*/ // matched a highlight...check if its a stack of highlights if(hi)//idx != -1) { // if this is a stack of highlights, iterate down through the stack looking // for a highlight which overlaps /* while(Highlight[idx].Stack != 0) { m_nNumHighlights = Highlight[idx].Stack->nNumItems; Highlight = Highlight[idx].Stack->Highlight; for(int i = m_nNumHighlights-1; i >= 0; i--) { if(offset >= Highlight[i].nRangeStart && offset < Highlight[i].nRangeEnd) { idx = i; break; } } }*/ } // found a highlight? set the colour if(hi && offset >= hi->bookmark.offset && offset < hi->bookmark.offset + hi->bookmark.length)// >= 0) { //col1->colFG = Highlight[idx].colFG; //col1->colBG = Highlight[idx].colBG; col1->colFG = hi->bookmark.col; col1->colBG = hi->bookmark.backcol; //col1->colFG = RGB(255,255,255); //col1->colBG = RGB(128,128,128); *col2 = *col1; if(fModified) { col1->colFG = GetHexColour(HVC_MODIFY); col2->colFG = GetHexColour(HVC_MODIFY); } } // no highlight, use the default window scheme else { col1->colFG = GetHexColour(nSchemeIdxFG); col1->colBG = GetHexColour(nSchemeIdxBG); *col2 = *col1; } // if at the end of the highlight, need to paint in two colours //if(idx != -1 && offset == Highlight[idx].nRangeEnd - 1) if(hi && offset == hi->bookmark.offset + hi->bookmark.length - 1) { /*int idx2 = -1; // search backwards again for(int i = idx - 1; i >= 0; i--) { if(offset >= Highlight[i].nRangeStart && offset < Highlight[i].nRangeEnd - 1) { idx2 = i; break; } } if(idx2 != -1) { col2->colFG = Highlight[idx2].colFG; col2->colBG = Highlight[idx2].colBG; } else { col2->colBG = GetHexColour(nSchemeIdxBG); }*/ } // selected data overrides everything else! if(fIncSelection && offset >= selstart && offset < selend) { // selected colour is next sequential index if(fGotFocus) nSchemeIdxFG++; //nSchemeIdxFG = nSchemeIdxBG; //nSchemeIdxBG++; //nSchemeIdxFG++; //nSchemeIdxBG++; if(nSchemeIdxBG == HVC_MATCHED) nSchemeIdxFG = HVC_MATCHEDSEL; //nSchemeIdxBG = HVC_SELECTION; if(pane != m_nWhichPane) { //if(nSchemeIdxBG == HVC_BACKGROUND) nSchemeIdxBG = HVC_SELECTION; // nSchemeIdxFG++; // nSchemeIdxBG++; } else { //if(nSchemeIdxBG == HVC_BACKGROUND) nSchemeIdxBG = HVC_SELECTION; } if(!fGotFocus) { nSchemeIdxBG = HVC_SELECTION3; //nSchemeIdxFG = HVC_SELECTION4; } if(CheckStyle(HVS_INVERTSELECTION)) { col1->colBG = 0xffffff & ~col1->colBG; col1->colFG = 0xffffff & ~col1->colFG; } else { //col1->colFG = MixRgb(GetHexColour(HVC_SELECTION), GetHexColour(nSchemeIdxFG)); //col1->colBG = MixRgb(GetHexColour(HVC_SELECTION), GetHexColour(nSchemeIdxBG)); //if(!fModified) col1->colFG = !hi || fModified ? GetHexColour(nSchemeIdxFG) :col2->colBG; col1->colBG = GetHexColour(nSchemeIdxBG); //col1->colFG = GetHexColour((idx == -1) ? nSchemeIdxFG : HVC_BOOKSEL); //col1->colBG = idx == -1 ? col1->colBG : 0xffffff & ~col1->colFG; } #ifdef SELECTION_USES_HIGHLIGHT if(m_fHighlighting) { col1->colFG = 0xffffff & ~GetHexColour(HVC_BOOKMARK_FG); col1->colBG = 0xffffff & ~GetHexColour(HVC_BOOKMARK_BG); } #endif if(offset < selend - 1 && selend > 0) *col2 = *col1; } // take into account any offset/shift in the datasource offset += m_nDataShift;//Start; if((offset + 1) % (m_nBytesPerLine) == 0 && offset != 0) { col2->colFG = col1->colFG; col2->colBG = GetHexColour(HVC_BACKGROUND); } return TRUE; }