⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chokanmgr.cpp

📁 日本的开源编辑器源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//	$Id: CHokanMgr.cpp,v 1.20 2004/10/11 01:23:05 genta Exp $
/*!	@file
	@brief キーワード補完

	@author Norio Nakatani
	$Revision: 1.20 $
*/
/*
	Copyright (C) 1998-2001, Norio Nakatani
	Copyright (C) 2001, asa-o

	This source code is designed for sakura editor.
	Please contact the copyright holders to use this code for other purpose.
*/
#include "CHokanMgr.h"
#include "debug.h"
#include "CKeyBind.h"
#include "Keycode.h"
#include "CDicMgr.h"
#include "CEditView.h"
#include "mymessage.h"
#include "sakura_rc.h"
#include "etc_uty.h"

	WNDPROC			gm_wpHokanListProc;


LRESULT APIENTRY HokanList_SubclassProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
//#ifdef _DEBUG
//	MYTRACE( "HokanList_SubclassProc() uMsg == %xh\n", uMsg );
//#endif
	// Modified by KEITA for WIN64 2003.9.6
	CDialog* pCDialog = ( CDialog* )::GetWindowLongPtr( ::GetParent( hwnd ), DWLP_USER );
	CHokanMgr* pCHokanMgr = (CHokanMgr*)::GetWindowLongPtr( ::GetParent( hwnd ), DWLP_USER );
//	WORD vkey;
//	WORD nCaretPos;
//	LPARAM hwndLB;
//	int i;
	MSG* pMsg;
	int nVKey;
//	LPARAM lKeyData;
	switch( uMsg ){
	case WM_KEYDOWN:
		nVKey = (int) wParam;	// virtual-key code
//		lKeyData = lParam;			// key data
//		MYTRACE( "WM_KEYDOWN nVKey = %xh\n", nVKey );
		/* キー操作を偽造しよう */
		if (nVKey == VK_SPACE){	//	Space
// novice 2004/10/10
			/* Shift,Ctrl,Altキーが押されていたか */
			int nIdx = getCtrlKeyState();
			if (nIdx == _SHIFT){
				//	Shift + Spaceで↑を偽造
				wParam = VK_UP;
			}
			else if (nIdx == 0) {
				//	Spaceのみで↓を偽造
				wParam = VK_DOWN;
			}
		}
		/* 補完実行キーなら補完する */
		if( -1 != pCHokanMgr->KeyProc( wParam, lParam ) ){
			/* キーストロークを親に転送 */
			::EnableWindow( ::GetParent( ::GetParent( pCDialog->m_hwndParent ) ), TRUE );
//			::ShowWindow( pCDialog->m_hWnd, SW_HIDE );
//			::SetFocus( ::GetParent( ::GetParent( pCDialog->m_hwndParent ) ) );
			return ::PostMessage( ::GetParent( ::GetParent( pCDialog->m_hwndParent ) ), uMsg, wParam, lParam );
		}
		break;
	case WM_GETDLGCODE:
		pMsg = (MSG*) lParam; // pointer to an MSG structure
		if( NULL == pMsg ){
//			MYTRACE( "WM_GETDLGCODE  pMsg==NULL\n" );
			return 0;
		}
//		MYTRACE( "WM_GETDLGCODE  pMsg->message = %xh\n", pMsg->message );
		return DLGC_WANTALLKEYS;/* すべてのキーストロークを私に下さい */	//	Sept. 17, 2000 jepro 説明の「全て」を「すべて」に統一
	}
	return CallWindowProc( (WNDPROC)gm_wpHokanListProc, hwnd, uMsg, wParam, lParam);
}



CHokanMgr::CHokanMgr()
{
//	m_hFont = NULL;
//	m_hFontOld = NULL;
	m_cmemCurWord.SetDataSz( "" );

	m_pcmemKouho = NULL;
	m_nKouhoNum = 0;;
	m_nCurKouhoIdx = -1;
	m_pszCurKouho = NULL;
//	m_pcEditView = NULL;
	m_bTimerFlag = TRUE;
//	hm_wpHokanListProc = FALSE;
	return;
}

CHokanMgr::~CHokanMgr()
{
	if( NULL != m_pcmemKouho ){
		delete m_pcmemKouho;
		m_pcmemKouho = NULL;
	}
	m_nKouhoNum = 0;;
	if( NULL != m_pszCurKouho ){
		delete [] m_pszCurKouho;
		m_pszCurKouho = NULL;
	}

}

/* モードレスダイアログの表示 */
HWND CHokanMgr::DoModeless( HINSTANCE hInstance , HWND hwndParent, LPARAM lParam )
{
	HWND hwndWork;
	hwndWork = CDialog::DoModeless( hInstance, hwndParent, IDD_HOKAN, lParam, SW_HIDE );
	OnSize( 0, 0 );
	/* リストをフック */
	// Modified by KEITA for WIN64 2003.9.6
	::gm_wpHokanListProc = (WNDPROC) ::SetWindowLongPtr( ::GetDlgItem( m_hWnd, IDC_LIST_WORDS ), GWLP_WNDPROC, (LONG_PTR)HokanList_SubclassProc  );

	::ShowWindow( m_hWnd, SW_HIDE );
	return hwndWork;
}

/* モードレス時:対象となるビューの変更 */
void CHokanMgr::ChangeView( LPARAM pcEditView )
{
	m_lParam = pcEditView;
	return;
}

void CHokanMgr::Hide( void )
{
	CEditView* pcEditView;
	::EnableWindow( ::GetParent( ::GetParent( m_hwndParent ) ), TRUE );
//	::DestroyWindow( hwnd );
	::ShowWindow( m_hWnd, SW_HIDE );
	m_nCurKouhoIdx = -1;
	/* 入力フォーカスを受け取ったときの処理 */
	pcEditView = (CEditView*)m_lParam;
	pcEditView->OnSetFocus();
//	m_nCurKouhoIdx = -1;
	return;

}

/*!	初期化
	pcmemHokanWord == NULLのとき、補完候補がひとつだったら、補完ウィンドウを表示しないで終了します。
	Search()呼び出し元で確定処理を進めてください。

	@date 2002.2.17 YAZAKI CShareDataのインスタンスは、CProcessにひとつあるのみ。
*/
int CHokanMgr::Search(
//	HFONT		hFont,
	POINT*		ppoWin,
	int			nWinHeight,
	int			nColmWidth,
	const char*	pszCurWord,
	const char* pszHokanFile,
	int			bHokanLoHiCase,	// 入力補完機能:英大文字小文字を同一視する 2001/06/19 asa-o
	BOOL		bHokanByFile,	// 編集中データから候補を探す 2003.06.23 Moca
	CMemory*	pcmemHokanWord	// 2001/06/19 asa-o
)
{
	CEditView* pcEditView = (CEditView*)m_lParam;
	/*
	||  補完キーワードの検索
	||
	||  ?見つかった候補をすべて返す(改行で区切って返す)
	||  ?指定された候補の最大数を超えると処理を中断する
	||  ?見つかった数を返す
	||
	*/
	if( NULL != m_pcmemKouho ){
		delete m_pcmemKouho;
		m_pcmemKouho = NULL;
	}
	m_nKouhoNum = CDicMgr::HokanSearch(
		pszCurWord,
//		m_pShareData->m_Common.m_bHokanLoHiCase,	/* 入力補完機能:英大文字小文字を同一視する */
		bHokanLoHiCase,								// 引数からに変更	2001/06/19 asa-o
		&m_pcmemKouho,
		0, //Max候補数
		pszHokanFile
	);

	// 2003.05.16 Moca 追加 編集中データ内から候補を探す
	if( bHokanByFile ){
		m_nKouhoNum = pcEditView->HokanSearchByFile(
			pszCurWord,
			bHokanLoHiCase,
			&m_pcmemKouho,
			m_nKouhoNum,
			1024 // 編集中データからなので数を制限しておく
		);
	}
	if( 0 == m_nKouhoNum ){
		m_nCurKouhoIdx = -1;
		return 0;
	}

//	2001/06/19 asa-o 候補が1つの場合補完ウィンドウは表示しない(逐次補完の場合は除く)
	if( 1 == m_nKouhoNum ){
		if(pcmemHokanWord != NULL){
			m_nCurKouhoIdx = -1;
			// 2004.05.14 Moca m_pcmemKouhoの末尾には改行コードがあり、それを削除してコピーするするように
			pcmemHokanWord->SetData( m_pcmemKouho->GetPtr(), m_pcmemKouho->GetLength() - 1 );
			return 1;
		}
	}

//	LOGFONT		lf;
//	HDC			hdc;
//	WNDCLASS	wc;
//	ATOM		atom;
	int			i;

	/* 共有データ構造体のアドレスを返す */
	m_pShareData = CShareData::getInstance()->GetShareData();

//	m_hFont = hFont;
	m_poWin.x = ppoWin->x;
	m_poWin.y = ppoWin->y;
	m_nWinHeight = nWinHeight;
	m_nColmWidth = nColmWidth;
//	m_cmemCurWord.SetData( pszCurWord, lstrlen( pszCurWord ) );
	m_cmemCurWord.SetDataSz( pszCurWord );


	m_nCurKouhoIdx = 0;
//	SetCurKouhoStr();



//	::ShowWindow( m_hWnd, SW_SHOWNA );







	HWND hwndList;
	hwndList = ::GetDlgItem( m_hWnd, IDC_LIST_WORDS );
	::SendMessage( hwndList, LB_RESETCONTENT, 0, 0 );
	char*	pszCR = "\n";
	char*	pszWork;
	char*	pszNext;
	char*	pszTest;
	pszWork = m_pcmemKouho->GetPtr();
	for( i = 0; i < m_nKouhoNum; ++i ){
		pszNext = strstr( pszWork, pszCR );
		if( NULL == pszNext ){
			break;
		}
		pszTest = new char[pszNext - pszWork + 1];
		memcpy( pszTest, pszWork, pszNext - pszWork );
		pszTest[pszNext - pszWork] = '\0';

		::SendMessage( hwndList, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) pszTest );

		delete [] pszTest;
		pszTest = NULL;
		pszWork = pszNext + lstrlen( pszCR );
	}
	::SendMessage( hwndList, LB_SETCURSEL, 0, 0 );


//? この処理はやらないほうが見やすいかも?
//?	/* リストの全アイテム数がリストに収まる時は、リストのサイズを小さくする */
//?	int nItemHeight;
//?	nItemHeight = ::SendMessage( hwndList, LB_GETITEMHEIGHT, 0, 0 );
//?	if( ( m_nKouhoNum + 1 ) * nItemHeight < m_nHeight ){
//?		m_nHeight = ( m_nKouhoNum + 1 ) * nItemHeight;
//?	}else{
//?		if( m_nHeight < 1000 ){
//?			m_nHeight = 1000;
//?		}
//?	}
//?	if( ( m_nKouhoNum + 1 ) * nItemHeight < m_nHeight ){
//?		m_nHeight = ( m_nKouhoNum + 1 ) * nItemHeight;
//?	}
//?


//@@	::EnableWindow( ::GetParent( ::GetParent( m_hwndParent ) ), FALSE );


	int nX;
	int nY;
	int nCX;
	int nCY;
	RECT	rcDesktop;
	//	May 01, 2004 genta マルチモニタ対応
	::GetMonitorWorkRect( m_hWnd, &rcDesktop );

	nX = m_poWin.x - m_nColmWidth;
	nY = m_poWin.y + m_nWinHeight + 4;
	nCX = m_nWidth;
	nCY = m_nHeight;

	/* 下に入るなら */
	if( nY + nCY < rcDesktop.bottom ){
		/* 何もしない */
	}else
	/* 上に入るなら */
	if( rcDesktop.top < m_poWin.y - m_nHeight - 4 ){
		/* 上に出す */
		nY = m_poWin.y - m_nHeight - 4;
	}else
	/* 上に出すか下に出すか(広いほうに出す) */
	if(	rcDesktop.bottom - nY > m_poWin.y ){
		/* 下に出す */
//		m_nHeight = rcDesktop.bottom - nY;
		nCY = rcDesktop.bottom - nY;
	}else{
		/* 上に出す */
		nY = rcDesktop.top;
		nCY = m_poWin.y - 4 - rcDesktop.top;
	}

//	2001/06/19 Start by asa-o: 表示位置補正

	// 右に入る
	if(nX + nCX < rcDesktop.right ){
		// そのまま
	}else
	// 左に入る
	if(rcDesktop.left < nX - nCX + 8){
		// 左に表示
		nX -= nCX - 8;
	}else{
		// サイズを調整して右に表示
		nCX = max((int)(rcDesktop.right - nX) , 100);	// 最低サイズを100くらいに
	}

//	2001/06/19 End

//	2001/06/18 Start by asa-o: 補正後の位置?サイズを保存
	m_poWin.x = nX;
	m_poWin.y = nY;
	m_nHeight = nCY;
	m_nWidth = nCX;
//	2001/06/18 End

	/* はみ出すなら小さくする */
//	if( rcDesktop.bottom < nY + nCY ){
//		/* 下にはみ出す */
//		if( m_poWin.y - 4 - nCY < 0 ){
//			/* 上にはみ出す */
//			/* →高さだけ調節 */
//			nCY = rcDesktop.bottom - nY - 4;
//		}else{
//
//		}
//
//	}
	::MoveWindow( m_hWnd, nX, nY, nCX, nCY, TRUE );
	::ShowWindow( m_hWnd, SW_SHOW );
//	::ShowWindow( m_hWnd, SW_SHOWNA );
	::SetFocus( m_hWnd );
//	::SetFocus( ::GetDlgItem( m_hWnd, IDC_LIST_WORDS ) );
//	::SetFocus( ::GetParent( ::GetParent( m_hwndParent ) ) );


//	2001/06/18 asa-o:
	ShowTip();	// 補完ウィンドウで選択中の単語にキーワードヘルプを表示

//	2003.06.25 Moca 他のメソッドで使っていないので、とりあえず削除しておく
	if( NULL != m_pcmemKouho ){
		delete m_pcmemKouho;
		m_pcmemKouho = NULL;
	}
	return m_nKouhoNum;
}


#if 0
///// 2003.06.25 未使用のようだ。Moca
void CHokanMgr::SetCurKouhoStr( void )
{
	char*	pszCR = "\n";

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -