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;
}
Exemple #2
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;
}