forked from sin365/AxibugEmuOnline
591 lines
27 KiB
C++
591 lines
27 KiB
C++
//
|
||
// メモリビュークラス
|
||
//
|
||
#define WIN32_LEAN_AND_MEAN
|
||
#include <windows.h>
|
||
#include <shellapi.h>
|
||
#include <mbstring.h>
|
||
#include <string>
|
||
using namespace std;
|
||
|
||
#include "VirtuaNESres.h"
|
||
#include "DebugOut.h"
|
||
#include "App.h"
|
||
#include "Pathlib.h"
|
||
|
||
#include "Wnd.h"
|
||
#include "MemoryView.h"
|
||
#include "EmuThread.h"
|
||
|
||
#include "MMU.h"
|
||
|
||
#include "DirectDraw.h"
|
||
|
||
#define OFFSETH 4
|
||
#define OFFSETV 4
|
||
|
||
#define FONTWIDTH 6
|
||
#define FONTHEIGHT 12
|
||
|
||
LOGFONT CMemoryView::m_logFont={ FONTHEIGHT, FONTWIDTH, 0, 0, 0, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET, OUT_TT_PRECIS,
|
||
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE, NULL };
|
||
|
||
#ifndef WM_MOUSEWHEEL
|
||
#define WM_MOUSEWHEEL 0x020A
|
||
#endif
|
||
|
||
WND_MESSAGE_BEGIN(CMemoryView)
|
||
WND_ON_MESSAGE( WM_CREATE, OnCreate )
|
||
WND_ON_MESSAGE( WM_CLOSE, OnClose )
|
||
WND_ON_MESSAGE( WM_DESTROY, OnDestroy )
|
||
WND_ON_MESSAGE( WM_ACTIVATE, OnActivate )
|
||
WND_ON_MESSAGE( WM_SIZE, OnSize )
|
||
WND_ON_MESSAGE( WM_LBUTTONDOWN, OnLButtonDown )
|
||
WND_ON_MESSAGE( WM_MOUSEWHEEL, OnMouseWheel )
|
||
WND_ON_MESSAGE( WM_CHAR, OnChar )
|
||
WND_ON_MESSAGE( WM_KEYDOWN, OnKeyDown )
|
||
WND_ON_MESSAGE( WM_VSCROLL, OnVScroll )
|
||
WND_ON_MESSAGE( WM_PAINT, OnPaint )
|
||
WND_ON_MESSAGE( WM_TIMER, OnTimer )
|
||
|
||
WND_COMMAND_BEGIN()
|
||
WND_COMMAND_END()
|
||
WND_MESSAGE_END()
|
||
|
||
CMemoryView::CMemoryView()
|
||
{
|
||
m_hFont = NULL;
|
||
m_StartAddress = 0;
|
||
|
||
m_CursorX = m_CursorY = 0;
|
||
m_DispLines = 16;
|
||
}
|
||
|
||
CMemoryView::~CMemoryView()
|
||
{
|
||
}
|
||
|
||
BOOL CMemoryView::Create( HWND hWndParent )
|
||
{
|
||
m_logFont.lfCharSet = SHIFTJIS_CHARSET;
|
||
if( !(m_hFont = ::CreateFontIndirect( &m_logFont )) ) {
|
||
m_logFont.lfCharSet = ANSI_CHARSET;
|
||
if( !(m_hFont = ::CreateFontIndirect( &m_logFont )) ) {
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
HWND hWnd = ::CreateWindowEx(
|
||
WS_EX_TOOLWINDOW,
|
||
VIRTUANES_WNDCLASS,
|
||
"MemoryView",
|
||
WS_OVERLAPPEDWINDOW|WS_VSCROLL, // Window拡大縮小可能
|
||
CW_USEDEFAULT,
|
||
CW_USEDEFAULT,
|
||
CW_USEDEFAULT,
|
||
CW_USEDEFAULT,
|
||
hWndParent,
|
||
NULL,
|
||
CApp::GetInstance(),
|
||
(LPVOID)this // This を埋め込む為
|
||
);
|
||
if( !hWnd ) {
|
||
DEBUGOUT( "CreateWindow faild.\n" );
|
||
return FALSE;
|
||
}
|
||
|
||
m_hWnd = hWnd;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void CMemoryView::Destroy()
|
||
{
|
||
if( m_hWnd && IsWindow(m_hWnd) ) {
|
||
// 位置保存
|
||
::GetWindowRect( m_hWnd, &Config.general.rcMemoryViewPos );
|
||
|
||
::DestroyWindow( m_hWnd );
|
||
m_hWnd = NULL;
|
||
}
|
||
|
||
if( m_hFont ) {
|
||
::DeleteObject( m_hFont );
|
||
m_hFont = NULL;
|
||
}
|
||
}
|
||
|
||
WNDMSG CMemoryView::OnCreate( WNDMSGPARAM )
|
||
{
|
||
// DEBUGOUT( "CMemoryView::OnCreate\n" );
|
||
|
||
// ウインドウサイズの設定
|
||
if( RCWIDTH(Config.general.rcMemoryViewPos) > 0 && RCHEIGHT(Config.general.rcMemoryViewPos) > 0 ) {
|
||
::MoveWindow( m_hWnd, Config.general.rcMemoryViewPos.left, Config.general.rcMemoryViewPos.top,
|
||
RCWIDTH(Config.general.rcMemoryViewPos), RCHEIGHT(Config.general.rcMemoryViewPos), FALSE );
|
||
} else {
|
||
RECT rw, rc;
|
||
::GetWindowRect( m_hWnd, &rw );
|
||
::GetClientRect( m_hWnd, &rc );
|
||
INT x = rw.right - rw.left - rc.right + OFFSETH*2+FONTWIDTH*71;
|
||
INT y = rw.bottom - rw.top - rc.bottom + OFFSETV*2+FONTHEIGHT*18;
|
||
::MoveWindow( m_hWnd, 0, 0, x, y, FALSE );
|
||
}
|
||
|
||
RECT rc;
|
||
::GetClientRect( m_hWnd, &rc );
|
||
|
||
// スクロールレンジの設定
|
||
m_DispLines = (RCHEIGHT(rc)-(OFFSETV*2+FONTHEIGHT*2))/FONTHEIGHT;
|
||
if( m_DispLines < 0 )
|
||
m_DispLines = 0;
|
||
|
||
DEBUGOUT( "Display Lines:%d\n", m_DispLines );
|
||
DEBUGOUT( "Scroll Max :%d\n", (0xFFF-m_DispLines)<0?0:(0xFFF-m_DispLines) );
|
||
|
||
SCROLLINFO sif;
|
||
::ZeroMemory( &sif, sizeof(sif) );
|
||
sif.cbSize = sizeof(sif);
|
||
sif.fMask = SIF_ALL;
|
||
sif.nMin = 0;
|
||
sif.nMax = (0x1000-m_DispLines);
|
||
sif.nPos = 0;
|
||
sif.nPage = 1;
|
||
sif.nTrackPos = 1;
|
||
::SetScrollInfo( m_hWnd, SB_VERT, &sif, TRUE );
|
||
m_StartAddress = 0;
|
||
|
||
m_CursorX = m_CursorY = 0;
|
||
|
||
// 表示
|
||
::ShowWindow( m_hWnd, SW_SHOW );
|
||
|
||
// タイマー起動
|
||
::SetTimer( m_hWnd, 1, 50, NULL );
|
||
return TRUE;
|
||
}
|
||
|
||
WNDMSG CMemoryView::OnClose( WNDMSGPARAM )
|
||
{
|
||
// DEBUGOUT( "CMemoryView::OnClose\n" );
|
||
::KillTimer( m_hWnd, 1 );
|
||
::DestroyWindow( m_hWnd );
|
||
return TRUE;
|
||
}
|
||
|
||
WNDMSG CMemoryView::OnDestroy( WNDMSGPARAM )
|
||
{
|
||
// DEBUGOUT( "CMemoryView::OnDestroy\n" );
|
||
// 位置保存
|
||
::GetWindowRect( m_hWnd, &Config.general.rcMemoryViewPos );
|
||
|
||
m_hWnd = NULL;
|
||
return TRUE;
|
||
}
|
||
|
||
WNDMSG CMemoryView::OnActivate( WNDMSGPARAM )
|
||
{
|
||
if( LOWORD(wParam) == WA_INACTIVE ) {
|
||
// DEBUGOUT( "CMemoryView::OnActivate:Inactive\n" );
|
||
::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)TRUE, 0 );
|
||
} else {
|
||
// DEBUGOUT( "CMemoryView::OnActivate:Active\n" );
|
||
::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)FALSE, 0 );
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
WNDMSG CMemoryView::OnSize( WNDMSGPARAM )
|
||
{
|
||
// DEBUGOUT( "CMemoryView::OnSize\n" );
|
||
|
||
m_DispLines = (HIWORD(lParam)-(OFFSETV*2+FONTHEIGHT*2))/FONTHEIGHT;
|
||
if( m_DispLines < 0 )
|
||
m_DispLines = 0;
|
||
|
||
// DEBUGOUT( "Display Lines:%d\n", m_DispLines );
|
||
|
||
SCROLLINFO sif;
|
||
::ZeroMemory( &sif, sizeof(sif) );
|
||
sif.cbSize = sizeof(sif);
|
||
sif.fMask = SIF_POS;
|
||
::GetScrollInfo( m_hWnd, SB_VERT, &sif );
|
||
|
||
sif.fMask = SIF_POS|SIF_RANGE;
|
||
sif.nMin = 0;
|
||
sif.nMax = (0x1000-m_DispLines)<0?0:(0x1000-m_DispLines);
|
||
if( sif.nMin > sif.nPos )
|
||
sif.nPos = sif.nMin;
|
||
if( sif.nMax < sif.nPos )
|
||
sif.nPos = sif.nMax;
|
||
::SetScrollInfo( m_hWnd, SB_VERT, &sif, TRUE );
|
||
|
||
m_StartAddress = sif.nPos * 0x10;
|
||
|
||
if( m_CursorY > m_DispLines-1 )
|
||
m_CursorY = m_DispLines-1;
|
||
if( m_CursorY < 0 )
|
||
m_CursorY = 0;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
WNDMSG CMemoryView::OnLButtonDown( WNDMSGPARAM )
|
||
{
|
||
// DEBUGOUT( "CMemoryView::OnLButtonDown\n" );
|
||
|
||
INT x = LOWORD(lParam);
|
||
INT y = HIWORD(lParam);
|
||
|
||
x -= OFFSETH+FONTWIDTH*6;
|
||
y -= OFFSETV+FONTHEIGHT*2;
|
||
|
||
if( x >= 0 && x < FONTWIDTH*(3*16)
|
||
&& y >= 0 && y < FONTHEIGHT*m_DispLines ) {
|
||
if( (x%(FONTWIDTH*3)) < FONTWIDTH*2 ) {
|
||
m_CursorX = (x / (FONTWIDTH*3))*2;
|
||
m_CursorY = y / FONTHEIGHT;
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
WNDMSG CMemoryView::OnMouseWheel( WNDMSGPARAM )
|
||
{
|
||
// DEBUGOUT( "CMemoryView::OnMouseWheel\n" );
|
||
short zDelta = (short)HIWORD(wParam);
|
||
if( zDelta > 0 ) {
|
||
while( zDelta > 0 ) {
|
||
if( LOWORD(wParam) == MK_CONTROL )
|
||
::SendMessage( hWnd, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0L );
|
||
else
|
||
::SendMessage( hWnd, WM_VSCROLL, MAKELONG(SB_LINEUP, 0), 0L );
|
||
|
||
zDelta -= 30;
|
||
}
|
||
return TRUE;
|
||
} else {
|
||
while( zDelta < 0 ) {
|
||
if( LOWORD(wParam) == MK_CONTROL )
|
||
::SendMessage( hWnd, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0L );
|
||
else
|
||
::SendMessage( hWnd, WM_VSCROLL, MAKELONG(SB_LINEDOWN, 0), 0L );
|
||
zDelta += 30;
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
WNDMSG CMemoryView::OnChar( WNDMSGPARAM )
|
||
{
|
||
// DEBUGOUT( "CMemoryView::OnChar\n" );
|
||
|
||
WORD wScrollNotify = 0xFFFF;
|
||
|
||
CHAR Keys = ::toupper((CHAR)wParam);
|
||
|
||
switch( Keys ) {
|
||
case '0':
|
||
case '1':
|
||
case '2':
|
||
case '3':
|
||
case '4':
|
||
case '5':
|
||
case '6':
|
||
case '7':
|
||
case '8':
|
||
case '9':
|
||
if( m_DispLines ) {
|
||
INT addr = m_StartAddress+(m_CursorX/2)+m_CursorY*16;
|
||
BYTE data = CPU_MEM_BANK[addr>>13][addr&0x1FFF];
|
||
if( !(m_CursorX&1) ) {
|
||
data &= 0x0F;
|
||
data |= (Keys-'0')<<4;
|
||
} else {
|
||
data &= 0xF0;
|
||
data |= (Keys-'0');
|
||
}
|
||
CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data;
|
||
|
||
if( ++m_CursorX > 32-1 ) {
|
||
if( ++m_CursorY > m_DispLines-1 ) {
|
||
wScrollNotify = SB_LINEDOWN;
|
||
m_CursorY = m_DispLines-1;
|
||
}
|
||
if( (m_CursorX/2)+m_CursorY*16+m_StartAddress > 0xFFFF ) {
|
||
m_CursorX = 32-1;
|
||
} else {
|
||
m_CursorX = 0;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case 'A':
|
||
case 'B':
|
||
case 'C':
|
||
case 'D':
|
||
case 'E':
|
||
case 'F':
|
||
if( m_DispLines ) {
|
||
INT addr = m_StartAddress+(m_CursorX/2)+m_CursorY*16;
|
||
BYTE data = CPU_MEM_BANK[addr>>13][addr&0x1FFF];
|
||
if( !(m_CursorX&1) ) {
|
||
data &= 0x0F;
|
||
data |= (Keys-'A'+10)<<4;
|
||
} else {
|
||
data &= 0xF0;
|
||
data |= (Keys-'A'+10);
|
||
}
|
||
CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data;
|
||
if( ++m_CursorX > 32-1 ) {
|
||
if( ++m_CursorY > m_DispLines-1 ) {
|
||
wScrollNotify = SB_LINEDOWN;
|
||
m_CursorY = m_DispLines-1;
|
||
}
|
||
if( (m_CursorX/2)+m_CursorY*16+m_StartAddress > 0xFFFF ) {
|
||
m_CursorX = 32-1;
|
||
} else {
|
||
m_CursorX = 0;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
if( wScrollNotify != 0xFFFF )
|
||
::SendMessage( hWnd, WM_VSCROLL, MAKELONG(wScrollNotify, 0), 0L );
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
WNDMSG CMemoryView::OnKeyDown( WNDMSGPARAM )
|
||
{
|
||
// DEBUGOUT( "CMemoryView::OnKeyDown\n" );
|
||
|
||
WORD wScrollNotify = 0xFFFF;
|
||
|
||
switch( wParam ) {
|
||
case VK_UP:
|
||
m_CursorX &= ~1;
|
||
if( --m_CursorY < 0 ) {
|
||
wScrollNotify = SB_LINEUP;
|
||
m_CursorY = 0;
|
||
}
|
||
break;
|
||
case VK_DOWN:
|
||
m_CursorX &= ~1;
|
||
if( ++m_CursorY > m_DispLines-1 ) {
|
||
wScrollNotify = SB_LINEDOWN;
|
||
m_CursorY = m_DispLines-1;
|
||
}
|
||
break;
|
||
case VK_LEFT:
|
||
if( m_CursorX & 1 ) {
|
||
m_CursorX &= ~1;
|
||
} else
|
||
if( (m_CursorX-=2) < 0 ) {
|
||
if( --m_CursorY < 0 ) {
|
||
wScrollNotify = SB_LINEUP;
|
||
m_CursorX = 0;
|
||
m_CursorY = 0;
|
||
} else {
|
||
m_CursorX = 32-1;
|
||
}
|
||
}
|
||
break;
|
||
case VK_RIGHT:
|
||
m_CursorX &= ~1;
|
||
if( (m_CursorX+=2) > 32-1 ) {
|
||
if( ++m_CursorY > m_DispLines-1 ) {
|
||
wScrollNotify = SB_LINEDOWN;
|
||
m_CursorY = m_DispLines-1;
|
||
}
|
||
if( (m_CursorX/2)+m_CursorY*16+m_StartAddress > 0xFFFF ) {
|
||
m_CursorX = 32-1;
|
||
} else {
|
||
m_CursorX = 0;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case VK_PRIOR:
|
||
m_CursorX &= ~1;
|
||
if( (m_CursorY-16) < 0 ) {
|
||
wScrollNotify = SB_PAGEUP;
|
||
if( m_StartAddress <= 0 ) {
|
||
m_CursorY = 0;
|
||
}
|
||
} else {
|
||
m_CursorY-= 16;
|
||
}
|
||
break;
|
||
case VK_NEXT:
|
||
m_CursorX &= ~1;
|
||
if( (m_CursorY+16) > m_DispLines-1 ) {
|
||
wScrollNotify = SB_PAGEDOWN;
|
||
if( m_StartAddress+m_DispLines*16 >= 0xFFFF ) {
|
||
m_CursorY = m_DispLines-1;
|
||
}
|
||
} else {
|
||
m_CursorY += 16;
|
||
}
|
||
break;
|
||
case VK_HOME:
|
||
wScrollNotify = SB_TOP;
|
||
m_CursorY = 0;
|
||
break;
|
||
case VK_END:
|
||
wScrollNotify = SB_BOTTOM;
|
||
m_CursorY = m_DispLines-1;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
if( wScrollNotify != 0xFFFF )
|
||
::SendMessage( hWnd, WM_VSCROLL, MAKELONG(wScrollNotify, 0), 0L );
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
WNDMSG CMemoryView::OnVScroll( WNDMSGPARAM )
|
||
{
|
||
// DEBUGOUT( "CMemoryView::OnVScroll\n" );
|
||
|
||
SCROLLINFO sif;
|
||
::ZeroMemory( &sif, sizeof(sif) );
|
||
sif.cbSize = sizeof(sif);
|
||
sif.fMask = SIF_POS|SIF_RANGE;
|
||
::GetScrollInfo( m_hWnd, SB_VERT, &sif );
|
||
|
||
switch( LOWORD(wParam) ) {
|
||
case SB_TOP:
|
||
sif.nPos = 0;
|
||
break;
|
||
case SB_BOTTOM:
|
||
sif.nPos = sif.nMax;
|
||
break;
|
||
case SB_PAGEUP:
|
||
sif.nPos -= 16;
|
||
break;
|
||
case SB_PAGEDOWN:
|
||
sif.nPos += 16;
|
||
break;
|
||
case SB_LINEUP:
|
||
sif.nPos--;
|
||
break;
|
||
case SB_LINEDOWN:
|
||
sif.nPos++;
|
||
break;
|
||
case SB_THUMBTRACK:
|
||
sif.nPos = HIWORD(wParam);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
if( sif.nMin > sif.nPos )
|
||
sif.nPos = sif.nMin;
|
||
if( sif.nMax < sif.nPos )
|
||
sif.nPos = sif.nMax;
|
||
sif.fMask = SIF_POS;
|
||
::SetScrollInfo( m_hWnd, SB_VERT, &sif, TRUE );
|
||
|
||
m_StartAddress = sif.nPos * 0x10;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
WNDMSG CMemoryView::OnPaint( WNDMSGPARAM )
|
||
{
|
||
// DEBUGOUT( "CMemoryView::OnPaint\n" );
|
||
|
||
PAINTSTRUCT ps;
|
||
HDC hDC = ::BeginPaint( hWnd, &ps );
|
||
RECT rc;
|
||
::GetClientRect( m_hWnd, &rc );
|
||
::FillRect( hDC, &rc, (HBRUSH)::GetStockObject(WHITE_BRUSH) );
|
||
OnDraw( hDC );
|
||
::EndPaint( hWnd, &ps );
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
WNDMSG CMemoryView::OnTimer( WNDMSGPARAM )
|
||
{
|
||
if( !Emu.IsRunning() )
|
||
return TRUE;
|
||
|
||
HDC hDC = ::GetDC( m_hWnd );
|
||
OnDraw( hDC );
|
||
::ReleaseDC( m_hWnd, hDC );
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void CMemoryView::OnDraw( HDC hDC )
|
||
{
|
||
RECT rc;
|
||
::GetClientRect( m_hWnd, &rc );
|
||
|
||
HFONT hFontOld = (HFONT)::SelectObject( hDC, m_hFont );
|
||
|
||
::SetBkMode( hDC, OPAQUE );
|
||
::TextOut( hDC, OFFSETH, OFFSETV+FONTHEIGHT* 0, "ADDR +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF", 71 );
|
||
::TextOut( hDC, OFFSETH, OFFSETV+FONTHEIGHT* 1, "-----------------------------------------------------------------------", 71 );
|
||
|
||
CHAR szBuf[256];
|
||
INT address = m_StartAddress;
|
||
INT i;
|
||
for( i = 0; i < m_DispLines; i++ ) {
|
||
::wsprintf( szBuf, "%04X ", address&0xFFFF );
|
||
|
||
for( INT d = 0; d < 16; d++ ) {
|
||
CHAR szTemp[16];
|
||
INT addr = address+d;
|
||
::wsprintf( szTemp, "%02X ", CPU_MEM_BANK[addr>>13][addr&0x1FFF] );
|
||
::strcat( szBuf, szTemp );
|
||
}
|
||
::strcat( szBuf, " " );
|
||
for( INT a = 0; a < 16; a++ ) {
|
||
CHAR szTemp[16];
|
||
INT addr = address+a;
|
||
|
||
if( m_logFont.lfCharSet == SHIFTJIS_CHARSET ) {
|
||
::wsprintf( szTemp, "%1c", ::_ismbcprint(CPU_MEM_BANK[addr>>13][addr&0x1FFF])?CPU_MEM_BANK[addr>>13][addr&0x1FFF]:'.' );
|
||
} else {
|
||
::wsprintf( szTemp, "%1c", ::isprint(CPU_MEM_BANK[addr>>13][addr&0x1FFF])?CPU_MEM_BANK[addr>>13][addr&0x1FFF]:'.' );
|
||
}
|
||
::strcat( szBuf, szTemp );
|
||
}
|
||
|
||
::TextOut( hDC, OFFSETH, OFFSETV+FONTHEIGHT*(2+i), szBuf, ::strlen(szBuf) );
|
||
|
||
address += 16;
|
||
address &= 0xFFFF;
|
||
}
|
||
|
||
::TextOut( hDC, OFFSETH, OFFSETV+FONTHEIGHT*(2+i), " ", 71 );
|
||
|
||
// Cursor
|
||
if( m_DispLines ) {
|
||
RECT rcInv;
|
||
rcInv.left = OFFSETH+FONTWIDTH*6+FONTWIDTH*3*(m_CursorX>>1)+FONTWIDTH*(m_CursorX&1)-1;
|
||
rcInv.top = OFFSETV+FONTHEIGHT*2+FONTHEIGHT*m_CursorY;
|
||
rcInv.right = rcInv.left+FONTWIDTH;
|
||
rcInv.bottom = rcInv.top+FONTHEIGHT;
|
||
::InvertRect( hDC, &rcInv );
|
||
|
||
rcInv.left = OFFSETH+FONTWIDTH*55+FONTWIDTH*(m_CursorX>>1)-1;
|
||
rcInv.top = OFFSETV+FONTHEIGHT*2+FONTHEIGHT*m_CursorY;
|
||
rcInv.right = rcInv.left+FONTWIDTH;
|
||
rcInv.bottom = rcInv.top+FONTHEIGHT;
|
||
::InvertRect( hDC, &rcInv );
|
||
}
|
||
|
||
// 元に戻して消す?
|
||
::SelectObject( hDC, hFontOld );
|
||
}
|
||
|