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

📄 cimagelistmgr.cpp

📁 日本的开源编辑器源码
💻 CPP
字号:
//	$Id: CImageListMgr.cpp,v 1.14 2003/10/04 09:43:16 genta Exp $
/*!	@file
	@brief ImageListの取り扱い

	@author genta
	@date Oct. 11, 2000 genta
	$Revision: 1.14 $

*/
/*
	Copyright (C) 2000-2001, genta
	Copyright (C) 2001, GAE

	This source code is designed for sakura editor.
	Please contact the copyright holders to use this code for other purpose.
*/
#include "CImageListMgr.h"
#include "sakura_rc.h"
#include "CRunningTimer.h"
#include "etc_uty.h"

//	Jul. 21, 2003 genta 他でも使うので関数の外に出した
//	Oct. 21, 2000 JEPRO 設定
const int MAX_X = 32;
const int MAX_Y = 12;	//2002.01.17

/*!	領域を指定色で塗りつぶす

	@author Nakatani
*/
static void FillSolidRect( HDC hdc, int x, int y, int cx, int cy, COLORREF clr)
{
//	ASSERT_VALID(this);
//	ASSERT(m_hDC != NULL);

	RECT rect;
	::SetBkColor( hdc, clr );
	::SetRect( &rect, x, y, x + cx, y + cy );
	::ExtTextOut( hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL );
}

//	Destructor
CImageListMgr::~CImageListMgr()
{
	//	2003.07.21 Image Listの代わりに描画用bitmapを解放
	if( m_hIconBitmap != NULL ){
		DeleteObject( m_hIconBitmap );
	}
}

/*
	@brief Image Listの作成
	
	リソースまたはファイルからbitmapを読み込んで
	描画用に保持する.
	
	@param hInstance [in] bitmapリソースを持つインスタンス
	@param hWnd [in] 未使用
	
	@date 2003.07.21 genta ImageListの構築は行わない.代わりにbitmapをそのまま保持する.
*/
bool CImageListMgr::Create(HINSTANCE hInstance, HWND hWnd)
{
	MY_RUNNINGTIMER( cRunningTimer, "CImageListMgr::Create" );
	if( m_hIconBitmap != NULL ){	//	既に構築済みなら無視する
		return true;
	}

	HBITMAP	hRscbmp;	//	リソースから読み込んだひとかたまりのBitmap
	HBITMAP	hFOldbmp;	//	SetObjectで得られた1つ前のハンドルを保持する
	HDC		dcFrom;		//	描画用
	int		nRetPos;	//	後処理用
	m_cx = m_cy  = 16;

	nRetPos = 0;
	do {
		//	From Here 2001.7.1 GAE
		//	2001.7.1 GAE リソースをローカルファイル(sakuraディレクトリ) my_icons.bmp から読めるように
		char	szPath[_MAX_PATH], szExeDrive[_MAX_DRIVE], szExeDir[_MAX_DIR];

		// sakura.exe のパスを取得
		::GetModuleFileName( ::GetModuleHandle(NULL), szPath, sizeof(szPath) );

		// (sakuraディレクトリ) my_icons.bmp の文字列を作成
		_splitpath( szPath, szExeDrive, szExeDir, NULL, NULL );
		//	@@TEST@@
		wsprintf( szPath, "%s%s" FN_TOOL_BMP, szExeDrive, szExeDir );	//Jul.04, 2001 JEPRO toolbar.bmp→my_icons.bmp に名前変更
		hRscbmp = (HBITMAP)::LoadImage( NULL, szPath, IMAGE_BITMAP, 0, 0,
			LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS );

		if( hRscbmp == NULL ) {	// ローカルファイルの読み込み失敗時はリソースから取得
			//	このブロック内は従来の処理
			//	リソースからBitmapを読み込む
			//	2003.09.29 wmlhq 環境によってアイコンがつぶれる
			//hRscbmp = ::LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_MYTOOL ) );
			hRscbmp = (HBITMAP)::LoadImage( hInstance, MAKEINTRESOURCE( IDB_MYTOOL ), IMAGE_BITMAP, 0, 0,
				LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS  );
			if( hRscbmp == NULL ){
				//	Oct. 4, 2003 genta エラーコード追加
				//	正常終了と同じコードだとdcFromを不正に解放してしまう
				nRetPos = 2;
				break;
			}
		}
		//	To Here 2001.7.1 GAE
		m_hIconBitmap = hRscbmp;

		//	透過色を得るためにDCにマップする
		//	2003.07.21 genta 透過色を得る以外の目的では使わなくなった
		dcFrom = CreateCompatibleDC(0);	//	転送元用
		if( dcFrom == NULL ){
			nRetPos = 1;
			break;
		}

		//	まずbitmapをdcにmapする
		//	こうすることでCreateCompatibleBitmapで
		//	hRscbmpと同じ形式のbitmapを作れる.
		//	単にCreateCompatibleDC(0)で取得したdcや
		//	スクリーンのDCに対してCreateCompatibleBitmapを
		//	使うとモノクロBitmapになる.
		hFOldbmp = (HBITMAP)SelectObject( dcFrom, hRscbmp );
		if( hFOldbmp == NULL ){
			nRetPos = 4;
			break;
		}

		m_cTrans = GetPixel( dcFrom, 0, 0 );//	取得した画像の(0,0)の色を背景色として使う
		
		//	2003.07.21 genta
		//	ImageListへの登録部分は当然ばっさり削除
		
		//	もはや処理とは無関係だが,後学のためにコメントのみ残しておこう
		//---------------------------------------------------------
		//	BitmapがMemoryDCにAssignされている間はbitmapハンドルを
		//	使っても正しいbitmapが取得できない.
		//	つまり,DCへの描画命令を発行してもその場でBitmapに
		//	反映されるわけではない.
		//	BitmapをDCから取り外して初めて内容の保証ができる

		//	DCのmap/unmapが速度に大きく影響するため,
		//	横長のBitmapを作って一括登録するように変更
		//	これによって250msecくらい速度が改善される.
		//---------------------------------------------------------

	}while(0);	//	1回しか通らない

	//	後処理
	switch( nRetPos ){
	case 0:
		//	Oct. 4, 2003 genta hRscBmpをdcFromから切り離しておく必要がある
		//	アイコン描画変更時に過って削除されていた
		SelectObject( dcFrom, hFOldbmp );
	case 4:
		DeleteDC( dcFrom );
	case 2:
	case 1:
		//	2003.07.21 genta hRscbmpは m_hIconBitmap としてオブジェクトと
		//	同じだけ保持されるので解放してはならない
		break;
	}

	return nRetPos == 0;
}


/*! ビットマップの表示 灰色を透明描画

	@author Nakatani
	@date 2003.07.21 genta 以前のCMenuDrawerより移転復活
	@date 2003.08.27 Moca 背景は透過処理に変更し、colBkColorを削除
*/
void CImageListMgr::MyBitBlt(
	HDC drawdc, 
	int nXDest, 
	int nYDest, 
	int nWidth, 
	int nHeight, 
	HBITMAP bmp, 
	int nXSrc, 
	int nYSrc
) const
{
	COLORREF colToTransParent = m_cTrans;	/* BMPの中の透明にする色 */
//	HBRUSH	brShadow, brHilight;
	HDC		hdcMask;
	HBITMAP bmpMask;
	HBITMAP bmpMaskOld;
	HDC		hdcMem;
	HBITMAP	bmpMemOld;
	HDC		hdcMem2;
	HBITMAP bmpMem2;
	HBITMAP bmpMem2Old;
	// create a monochrome memory DC
	hdcMask = CreateCompatibleDC(0);
	bmpMask = CreateCompatibleBitmap( hdcMask, nWidth, nHeight);
	bmpMaskOld = (HBITMAP)SelectObject( hdcMask, bmpMask);
	/* 元ビットマップ用DC */
	hdcMem = ::CreateCompatibleDC( drawdc );
	bmpMemOld = (HBITMAP)::SelectObject( hdcMem, bmp );
	/* 作業用DC */
	hdcMem2 = ::CreateCompatibleDC( drawdc );
	bmpMem2 = CreateCompatibleBitmap( drawdc, nWidth, nHeight);
	bmpMem2Old = (HBITMAP)SelectObject( hdcMem2, bmpMem2);

	// build a mask
//	2003.09.04 Moca bmpMaskとbmpの転送する大きさが同じなので不要
//	PatBlt( hdcMask, 0, 0, nWidth, nHeight, WHITENESS);
	SetBkColor( hdcMem, colToTransParent );
	BitBlt( hdcMask, 0, 0, nWidth, nHeight, hdcMem, nXSrc,nYSrc, SRCCOPY);

	/* マスク描画(透明にしない部分だけ黒く描画) */
	::SetBkColor( drawdc, RGB( 255, 255, 255 ) /* colBkColor */ ); // 2003.08.27 Moca 作画方法変更
	::SetTextColor( drawdc, RGB( 0, 0, 0 ) );
	// 2003.08.27 Moca 作画方法変更
	::BitBlt( drawdc, nXDest, nYDest, nWidth, nHeight, hdcMask, 0, 0, SRCAND /* SRCCOPY */ ); 

	/* ビットマップ描画(透明にする色を黒くしてマスクとOR描画) */
	::SetBkColor( hdcMem2, colToTransParent/*RGB( 0, 0, 0 )*/ );
	::SetTextColor( hdcMem2, RGB( 0, 0, 0 ) );
	::BitBlt( hdcMem2, 0, 0, nWidth, nHeight, hdcMask, 0, 0, SRCCOPY );
	::BitBlt( hdcMem2, 0, 0, nWidth, nHeight, hdcMem, nXSrc,nYSrc, SRCINVERT/*SRCPAINT*/ );
	::BitBlt( drawdc, nXDest, nYDest, nWidth, nHeight, hdcMem2,  0, 0, /*SRCCOPY*/SRCPAINT );

	::SelectObject( hdcMask, bmpMaskOld );
	::DeleteObject( bmpMask );
	::DeleteDC( hdcMask );
	::SelectObject( hdcMem, bmpMemOld );
	::DeleteDC( hdcMem );
	::SelectObject( hdcMem2, bmpMem2Old );
	::DeleteObject( bmpMem2 );
	::DeleteDC( hdcMem2 );
	return;
}

/*! メニューアイコンの淡色表示

	@author Nakatani
	
	@date 2003.07.21 genta 以前のCMenuDrawerより移転復活
	@date 2003.08.27 Moca 背景色は透過処理する
*/
void CImageListMgr::DitherBlt2( HDC drawdc, int nXDest, int nYDest, int nWidth, 
                        int nHeight, HBITMAP bmp, int nXSrc, int nYSrc) const
{
	HDC		hdcMask;
	HBITMAP	bmpMask;
	HBITMAP	bmpMaskOld;
	HDC		hdcMem;
	HBITMAP	bmpMemOld;
	HDC		hdcMem2;
	HBITMAP bmpMem2;
	HBITMAP bmpMem2Old;

	//COLORREF colToTransParent = RGB( 192, 192, 192 );	/* BMPの中の透明にする色 */
	COLORREF colToTransParent = m_cTrans;

	// create a monochrome memory DC
	hdcMask = CreateCompatibleDC(0);
	bmpMask = CreateCompatibleBitmap( hdcMask, nWidth, nHeight);
	bmpMaskOld = (HBITMAP)SelectObject( hdcMask, bmpMask);

	hdcMem = CreateCompatibleDC(0);
	bmpMemOld = (HBITMAP)SelectObject( hdcMem, bmp);

	//	Jul. 21, 2003 genta
	//	hdcMemに書き込むと元のbitmapを破壊してしまう
	hdcMem2 = ::CreateCompatibleDC( drawdc );
	bmpMem2 = CreateCompatibleBitmap( drawdc, nWidth, nHeight);
	bmpMem2Old = (HBITMAP)SelectObject( hdcMem2, bmpMem2);

	// build a mask
	//	2003.09.04 Moca bmpMaskとbmpの転送する大きさが同じなので不要
	//PatBlt( hdcMask, 0, 0, nWidth, nHeight, WHITENESS);
	SetBkColor( hdcMem, colToTransParent );
	BitBlt( hdcMask, 0, 0, nWidth, nHeight, hdcMem, nXSrc,nYSrc, SRCCOPY);
	SetBkColor( hdcMem, RGB( 255, 255, 255 ) );
	BitBlt( hdcMask, 0, 0, nWidth, nHeight, hdcMem, nXSrc,nYSrc, SRCPAINT);

	// Copy the image from the toolbar into the memory DC
	// and draw it (grayed) back into the toolbar.
    //SK: Looks better on the old shell
	// 2003.08.29 Moca 作画方法を変更
	COLORREF coltxOld = ::SetTextColor( drawdc, RGB(0, 0, 0) );
	COLORREF colbkOld = ::SetBkColor( drawdc, RGB(255, 255, 255) );
	::SetBkColor( hdcMem2, RGB(0, 0, 0));
	::SetTextColor( hdcMem2, ::GetSysColor( COLOR_BTNHILIGHT ) );
	::BitBlt( hdcMem2, 0, 0, nWidth, nHeight, hdcMask, 0, 0, SRCCOPY );
	::BitBlt( drawdc, nXDest+1, nYDest+1, nWidth, nHeight, hdcMask, 0, 0, SRCAND );
	::BitBlt( drawdc, nXDest+1, nYDest+1, nWidth, nHeight, hdcMem2, 0, 0, SRCPAINT);
	::SetTextColor( hdcMem2, ::GetSysColor( COLOR_BTNSHADOW ) );
	::BitBlt( hdcMem2, 0, 0, nWidth, nHeight, hdcMask, 0, 0, SRCCOPY );
	::BitBlt( drawdc, nXDest, nYDest, nWidth, nHeight, hdcMask, 0, 0, SRCAND );
	::BitBlt( drawdc, nXDest, nYDest, nWidth, nHeight, hdcMem2, 0, 0, SRCPAINT);
	::SetTextColor( drawdc, coltxOld );
	::SetBkColor( drawdc, colbkOld );

	// reset DCs
	SelectObject( hdcMask, bmpMaskOld);
	DeleteDC( hdcMask );

	SelectObject( hdcMem, bmpMemOld);
	DeleteDC( hdcMem );

	//	Jul. 21, 2003 genta
	::SelectObject( hdcMem2, bmpMem2Old );
	::DeleteObject( bmpMem2 );
	::DeleteDC( hdcMem2 );

	DeleteObject( bmpMask );
	return;

}

/*! @brief アイコンの描画

	指定されたDCの指定された座標にアイコンを描画する.

	@param index [in] 描画するアイコン番号
	@param dc [in] 描画するDevice Context
	@param x [in] 描画するX座標
	@param y [in] 描画するY座標
	@param fstyle [in] 描画スタイル
	@param bgColor [in] 背景色(透明部分の描画用)

	@note 描画スタイルとして有効なのは,ILD_NORMAL, ILD_MASK
	
	@date 2003.07.21 genta 独自描画ルーチンを使う
	@date 2003.08.30 genta 背景色を指定する引数を追加
	@date 2003.09.06 genta Mocaさんの背景色透過処理に伴い,背景色引数削除
*/
bool CImageListMgr::Draw(int index, HDC dc, int x, int y, int fstyle ) const
{
	if( m_hIconBitmap == NULL )
		return false;
	
	if( fstyle == ILD_MASK ){
		DitherBlt2( dc, x, y, cx(), cy(), m_hIconBitmap,
		( index % MAX_X ) * cx(), ( index / MAX_X ) * cy());
	}
	else {
		MyBitBlt( dc, x, y, cx(), cy(), m_hIconBitmap,
		( index % MAX_X ) * cx(), ( index / MAX_X ) * cy());
	}
	return true;
}

/*!	アイコン数を返す

	@date 2003.07.21 genta 個数を自分で管理する必要がある.
*/
int CImageListMgr::Count() const
{
	return MAX_X * MAX_Y;
}
/*[EOF]*/

⌨️ 快捷键说明

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