Visual C++ Tips

Visual C++のサンプルやヒントを集めました。

ディレクトリ読みクラス BReadDir

ディレクトリ内のファイル名をリストしたり、ソートするクラス。
//  使用例:
//     char dirname1[] = "g:\\temp\\*.jpg";
//     BReadDir dir1(dirname1);  // ディレクトリ
//     dir1.Sort(); // ソート
//     if (dir1.GetCount() == 0)  //ファイル数
//         return -1;
//     char *tp;
//     while (tp = dir1.GetNext()) {  // ファイル名を順に返す


=================================== readdir.h start ======================
// readdir.h

#ifndef __BREADDIRCLASS__
#define __BREADDIRCLASS__


BOOL IsKanji(int c);
int BFileAttr(const char* name);
char* Strrchr(const char* str,char chr) ;


class BReadDir {
private:
	char **m_pdata;
	int m_nPos;
	int m_nCount;
public:
	BReadDir();
	BReadDir(LPCSTR name);
	~BReadDir();

	int Open(LPCSTR name);
	void Close();

	void Sort(int asdesc = 0,int cases = 0);

	int GetCount(){return m_nCount;};
	char *GetFirst();
	char *GetNext();

};

#endif
=================================== readdir.h end ========================

=================================== readdir.cpp start ====================
// readdir.cpp
#include "stdafx.h"
#include "readdir.h"

void QuickSort(char **a, int n, int asdes,int cases,int offset, int length);

BReadDir::BReadDir()
{
	m_nPos = 0;
	m_nCount = 0;
	m_pdata = NULL;
}

BReadDir::BReadDir(LPCSTR name)
{
	Open(name);
}


int BReadDir::Open(LPCSTR name)
{
	
	m_nPos = 0;
	m_nCount = 0;
	m_pdata = NULL;
	HANDLE hdir;
	WIN32_FIND_DATA fdata;
 	hdir = ::FindFirstFile(name,&fdata);
	if (hdir == INVALID_HANDLE_VALUE)
		return 0;

	BOOL ok = 1; 
	int nSize = 0;
	int nCur = 0;
	while (ok) {
		if ( !(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
			if (nSize < nCur + 1) {
				char *tp = new char[(nSize + 256)*sizeof(char*)];
				if (tp == NULL)
					break;
				if (m_pdata) {
					CopyMemory(tp,m_pdata,nSize*sizeof(char*));
					delete [] m_pdata;
				}
				m_pdata = (char**)tp;
				nSize += 256;
			}
			int len = lstrlen(fdata.cFileName) + 1;
			char *tp = new char[len];
			if (tp == NULL)
				break;
			CopyMemory(tp,fdata.cFileName,len);
			m_pdata[nCur++] = tp;
		}
		ok = ::FindNextFile(hdir,&fdata);
	}
	::FindClose(hdir);

	m_nCount = nCur;

    return m_nCount;
}

void BReadDir::Sort(int asdesc,int cases)
{
	if (m_nCount == 0)
		return;
	QuickSort(m_pdata, m_nCount,asdesc,cases,0,0);

}



BReadDir::~BReadDir()
{
	Close();
}


void BReadDir::Close()
{
	if (m_nCount == 0)
		return;
	for (int i = 0; i < m_nCount;i++)
		delete [] m_pdata[i];
	delete [] m_pdata;
	m_nCount = 0;
	m_pdata = NULL;

}


char *BReadDir::GetFirst()
{
	if (m_nCount == 0)
		return NULL;
	m_nPos = 0;
	return m_pdata[m_nPos++];
}

char *BReadDir::GetNext()
{
	if (m_nCount <= m_nPos)
		return NULL;
	return m_pdata[m_nPos++];
}


static int bcmp(char *p1,char *p2, int cases, int offset, int length)
{

	if (p1 == p2)
		return 0;

	char *b1,*b2;
	char buf1[1024],buf2[1024];

	if (cases == 0) {
		lstrcpy(buf1,p1);
		lstrcpy(buf2,p2);
		CharUpper(buf1);
		CharUpper(buf2);
		b1 = buf1; b2 = buf2;
	} else {
		b1 = p1; b2 = p2;
	}

	int len1 = lstrlen(b1) - offset;
	int len2 = lstrlen(b2) - offset;
	if (len1 < 0 || len2 < 0)
		return lstrcmp(b1,b2);
	if (length == 0 || length > len1 || length > len2)
		return lstrcmp(b1+offset,b2+offset);

	return memcmp(b1+offset,b2+offset,length);
}


static void QuickSort(char **a, int n, int asdes, int cases, int offset, int length)
{
	char **i, **j, **l, **r;
	char **st1[32], **st2[32], ***s1, ***s2;
	char *x, *w;

	if(n <= 1)
		return;

	int aflag = asdes == 0 ? 1 : -1; 

	s1 = st1;
	s2 = st2;
	*s1 = a;
	*s2 = a + n - 1;
	do
	{
		l = *s1--;
		r = *s2--;
//		if(r - l < 11)	inssort_c(l, r - l + 1);
//		else
//		{
			do
			{
				i = l;
				j = r;
				x = *(l + (int)((r - l) / 2));
				do
				{
					while(aflag * bcmp(x, *i,cases,offset,length) > 0)	i++;
					while(aflag * bcmp(*j, x,cases,offset,length) > 0)	j--;
					if(i > j)	break;
					w = *i;
					*i++ = *j;
					*j-- = w;
				} while(i <= j);
				if(j - l < r - i)
				{
					if(i < r)
					{
						*(++s1) = i;
						*(++s2) = r;
					}
					r = j;
				}
				else
				{
					if(l < j)
					{
						*(++s1) = l;
						*(++s2) = j;
					}
					l = i;
				}
			} while(l < r);
//		}
	}while (s1 >= st1);
	return;
}



static
unsigned char sjis_tab[256] =
{
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 2x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 3x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 4x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 5x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 6x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 7x */
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 8x */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 9x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* Ax */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* Bx */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* Cx */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* Dx */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* Ex */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,	/* Fx */
};

static BOOL IsKanji(int c) {
	return sjis_tab[c & 0xff];
}


// 戻り値:−1 エラー
//			0 ディレクトリ
//			1 ファイル
int BFileAttr(const char* name)
{
	DWORD rc = GetFileAttributes(name);
	if (rc == (unsigned long)INVALID_HANDLE_VALUE)
		return rc;
	if( rc & FILE_ATTRIBUTE_DIRECTORY) // dir ?
		return 0;
	return 1;
}

char* Strrchr(const char* str,char chr) 
{
	char *tp = NULL;
	int len = lstrlen(str);
	for (int i = 0;i < len;i++) {
		if (IsKanji(str[i])) {
			i++; continue;
		}
		if (str[i] == chr)
			tp = (char*)str + i;
	}
	return tp;
}
=================================== readdir.cpp end ======================








文字列追加クラス CStr

文字列を効率よく追加していく超軽量クラス。ヌル文字も追加可能。 CStringのためだけにMFCを使いたくないときに便利。
//  使用例:
//     CStr str;
//     str.Add("abc",3);    文字列の追加
//     str.AddByte(i);      1バイト追加
//     len = str.GetLength();  長さ
//     char *tp = str.GetBuffer();  文字列ポインタ
//     str.Detach();                バッファの切り離し
//  クラス定義
class CStr
{
public:
	CStr(){m_pData = NULL;m_nSize=m_nCur=0;};
	~CStr(){if (m_pData) delete []m_pData;};
	void Clear(){m_nCur=0;};
	void Detach(){m_pData = NULL;;m_nSize=m_nCur=0;};
	void Add(char *data,int len);
	void AddByte(int data);
	int GetLength(){return m_nCur;};
	char *GetBuffer(){return m_pData;};
private:
	char *m_pData;	// buffer pointer
	int m_nSize;	// buffer size
	int m_nCur;		// current length
};

void CStr::Add(char *data,int len)
{
	if (len <= 0)
		return;
	if (m_nSize <= m_nCur + len ) {
		char *tp = new char[m_nSize+len+2048];
		if (tp == NULL) {
			if (m_pData)
				delete [] m_pData;
			throw "CStr out of space";
		}
		if (m_pData) {
			memcpy(tp,m_pData,m_nCur);
			delete [] m_pData;
		}
		m_pData = tp;
		m_nSize = m_nSize + len + 2048;
	}
	memcpy(m_pData+m_nCur,data,len);
	m_nCur += len;
	m_pData[m_nCur] = 0;
}

void CStr::AddByte(int data)
{
	if (m_nSize <= m_nCur + 1 ) {
		char *tp = new char[m_nSize+2048];
		if (tp == NULL) {
			if (m_pData)
				delete [] m_pData;
			throw "CStr out of space";
		}
		if (m_pData) {
			memcpy(tp,m_pData,m_nCur);
			delete [] m_pData;
		}
		m_pData = tp;
		m_nSize += 2048;
	}
	m_pData[m_nCur] = data & 0x00ff;
	m_nCur++;
	m_pData[m_nCur] = 0;
}

SJIS漢字判定関数

SJIS漢字コードの先頭バイトをチェックして全角かどうか 判定する関数。IsDBCSLeadByte関数と同じ機能。

BOOL iskanji(int c) {

    static
    unsigned char sjis_tab[256] =
    {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 1x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 2x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 3x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 4x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 5x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 6x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 7x */
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     /* 8x */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     /* 9x */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* Ax */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* Bx */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* Cx */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* Dx */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     /* Ex */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,     /* Fx */
    };
    return sjis_tab[c & 0xff];
}

CRichEditViewでフォントの高さの指定

LOGFONT構造体の中のフォントの高さは、論理単位です。 CRichEditViewでフォントの高さをCHARFORMATで 指定するにはtwipsで指定しないとだめです。

1 inch = 72 points
1 twips = 20 points 
	// フォントの高さをpointからtwipsに変換します
	CDC* cDC = GetDC();
	int picy = cDC->GetDeviceCaps(LOGPIXELSY);
	ReleaseDC(cDC);
	int point = -MulDiv(m_logfont.lfHeight,72,picy);
	int twips = point * 20;
	m_defCharFormat.yHeight = twips;
	lstrcpy(m_defCharFormat.szFaceName,m_logfont.lfFaceName);

ファイルのドラッグ&ドロップ方法

ビュー内のファイルを他のアプリケーションにドラッグ&ドロップする例:
#include <afxole.h>                     // OLE サポート

protected:
        COleDataSource m_DropData;


BOOL CBgalApp::InitInstance()
{

        if (!AfxOleInit())
                ASSERT(0);



typedef struct _DROPFILES {
    DWORD pFiles; // offset of file list
    POINT pt;     // drop point (coordinates depend on fNC)
    BOOL fNC;     // see below
    BOOL fWide;   // TRUE if file contains wide characters,
                  // FALSE otherwise
} DROPFILES, FAR * LPDROPFILES;


static HDROP DragCreateFiles (LPCSTR fname)
{

    HDROP hDrop;
    LPDROPFILES lpDropFileStruct;

    // Allocate dynamic memory for the DROPFILESTRUCT data
    // structure and for the extra zero-character identifying
    // that there are no pathnames in the block yet.
        int flen = lstrlen(fname);
    hDrop = (HDROP)GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
            sizeof(DROPFILES) + flen + 2);

   // If unsuccessful, return NULL
   if (hDrop == NULL)
       return(hDrop);

   // Lock block and initialize the data members
   lpDropFileStruct = (LPDROPFILES) GlobalLock(hDrop);
        memset(lpDropFileStruct,0,sizeof(DROPFILES) + flen + 2);
   lpDropFileStruct->pFiles = sizeof(DROPFILES);
   lpDropFileStruct->pt.x = 0;
   lpDropFileStruct->pt.y = 0;
   lpDropFileStruct->fNC = FALSE;
   lpDropFileStruct->fWide = FALSE;

   char* szPathA = (char*) (&lpDropFileStruct[1]);

   lstrcpy(szPathA,fname);

    // Unlock the block and return its handle.
   GlobalUnlock(hDrop);
   return(hDrop);
}

void CBgalView::OnLButtonDown(UINT nFlags, CPoint point)
{

//      COleDataSource
        CBgalDoc* pDoc = GetDocument();
        CString fname = pDoc->GetTitle();
        if (fname == "" || pDoc->m_pDIB == NULL)
                return;

        CString path = pDoc->m_strDirName;
        fname = path + fname;
        HDROP hptr = DragCreateFiles(fname);
        if (hptr == NULL)
                return;


        m_DropData.CacheGlobalData(CF_HDROP,hptr);


        CRect rect(0,0,0,0);
        CBgalApp::m_bDragging = TRUE;
        DROPEFFECT effect = m_DropData.DoDragDrop(DROPEFFECT_COPY | DROPEFFECT_MOVE,
                rect);

        // the ole library eats the button up message,
        // make the CBgalApp::m_bDragging = FALSE;

        PostMessage(WM_LBUTTONUP,nFlags,MAKELONG(point.x,point.y));

}

void CBgalView::OnLButtonUp(UINT nFlags, CPoint point)
{

        CBgalApp::m_bDragging = FALSE;
        CScrollView::OnLButtonUp(nFlags, point);
}

CBEditViewクラス

CBEditView クラスは、テキストを編集するクラスです。 CRichEditViewクラスから派生しています。エディタなどにどうぞ。

// beditView.h : CBEditView クラスの宣言およびインターフェイスの定義をします。
//
/////////////////////////////////////////////////////////////////////////////

// CBEditView クラスの特徴
// CBEditView クラスの特徴は、CRichEditViewクラスに
// 加えて次の機能が追加されています
// 1. Caret 位置をステータスバーに表示
//		Caret 位置をCMainFrameのID_INDICATOR_KANAに表示します
//		ID_INDICATOR_KANA のキャプションを次のように変更してください
//		99999 行, 999 桁, 総行数 99999
// 2. ペースト時にテキストのみ受け付ける
// 3. 不要なオブジェクトのドロップを無視
// 4. フォントの変更
//     void CBEditView::SetFormatChar(LOGFONT* plogfont)
// 5. その他
//		デフォルトでラップ機能オフ
//		少し太いカレットを表示
//		カレントな行、桁、総行数をメンバ変数として保存

struct CCharFormat : public _charformat
{
	CCharFormat();
	BOOL operator==(CCharFormat& cf);
};

struct CParaFormat : public _paraformat
{
	CParaFormat() {cbSize = sizeof(_paraformat);}
	BOOL operator==(PARAFORMAT& pf);
};



class CBEditView : public CRichEditView
{
protected: // シリアライズ機能のみから作成します。
	CBEditView();
	DECLARE_DYNCREATE(CBEditView)

// アトリビュート
public:
	int m_nLine;				// カレント行番号
	int m_nColumn;				// カレント桁番号
	int m_nTotalLine;			// カレント桁番号
protected:	
	CCharFormat m_CharFormat;


// オペレーション
public:

	void SetFormatChar(LOGFONT* plogfont);	// フォントを変更します
// オーバーライド
	// ClassWizard は仮想関数を生成しオーバーライドします。
	//{{AFX_VIRTUAL(CBEditView)
	public:
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	protected:
	virtual void OnInitialUpdate(); // 構築後の最初の1度だけ呼び出されます。
	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
	//}}AFX_VIRTUAL

	// 不要なオブジェクトの貼り付けを禁止します
	virtual HRESULT QueryAcceptData( LPDATAOBJECT lpdataobj,
         CLIPFORMAT FAR * lpcfFormat, DWORD dwReco,
        BOOL bReally, HGLOBAL hMetaFile );


// インプリメンテーション
public:
	virtual ~CBEditView();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:
	void GetCaretPosition(int& nLine, int& nCol, int& nLineTotal);

// 生成されたメッセージ マップ関数
protected:
	//{{AFX_MSG(CBEditView)
	afx_msg void OnEditPaste();
	//}}AFX_MSG
	afx_msg void OnUpdateCaretPos(CCmdUI* pCmdUI);

	DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////




// beditView.cpp : CBEditView クラスの動作の定義を行います。
//

#include "stdafx.h"
#include "beditView.h"
#include "resource.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


CCharFormat::CCharFormat()
{
	cbSize = sizeof(_charformat);
	dwMask = CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_STRIKEOUT|CFM_SIZE|
		CFM_COLOR|CFM_OFFSET|CFM_PROTECTED;
	dwEffects = CFE_AUTOCOLOR;
	yHeight = 0;
	yOffset = 0;
	crTextColor = RGB(0, 0, 0);
	bCharSet = SHIFTJIS_CHARSET;
	bPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
	dwMask |= CFM_FACE;
}

BOOL CCharFormat::operator==(CCharFormat& cf)
{
	return 
	dwMask == cf.dwMask
	&& dwEffects == cf.dwEffects
	&& yHeight == cf.yHeight
	&& yOffset == cf.yOffset
	&& crTextColor == cf.crTextColor
	&& bPitchAndFamily == cf.bPitchAndFamily
	&& (lstrcmpA(szFaceName, cf.szFaceName) == 0);
}

BOOL CParaFormat::operator==(PARAFORMAT& pf)
{
	if(
		dwMask != pf.dwMask
		|| wNumbering != pf.wNumbering
		|| wReserved != pf.wReserved
		|| dxStartIndent != pf.dxStartIndent
		|| dxRightIndent != pf.dxRightIndent
		|| dxOffset != pf.dxOffset
		|| cTabCount != pf.cTabCount
		)
	{
		return FALSE;
	}
	for (int i=0;i<pf.cTabCount;i++)
	{
		if (rgxTabs[i] != pf.rgxTabs[i])
			return FALSE;
	}
	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CBEditView

IMPLEMENT_DYNCREATE(CBEditView, CRichEditView)

BEGIN_MESSAGE_MAP(CBEditView, CRichEditView)
	//{{AFX_MSG_MAP(CBEditView)
	ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
	ON_UPDATE_COMMAND_UI(ID_INDICATOR_KANA, OnUpdateCaretPos)
	//}}AFX_MSG_MAP
	// 標準印刷コマンド
	ON_COMMAND(ID_FILE_PRINT, CRichEditView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CRichEditView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CRichEditView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBEditView クラスの構築/消滅

CBEditView::CBEditView()
{
	// TODO: この場所に構築用のコードを追加してください。

}

CBEditView::~CBEditView()
{
}

BOOL CBEditView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: この位置で CREATESTRUCT cs を修正して Window クラスまたはスタイルを
	//       修正してください。

	return CRichEditView::PreCreateWindow(cs);
}

void CBEditView::OnInitialUpdate()
{
	m_nWordWrap = WrapNone;  // ラップ機能オフ
	WrapChanged();

	CRichEditView::OnInitialUpdate();

}

/////////////////////////////////////////////////////////////////////////////
// CBEditView クラスの印刷

BOOL CBEditView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// デフォルトの印刷準備
	return DoPreparePrinting(pInfo);
}


/////////////////////////////////////////////////////////////////////////////
// CBEditView クラスの診断

#ifdef _DEBUG
void CBEditView::AssertValid() const
{
	CRichEditView::AssertValid();
}

void CBEditView::Dump(CDumpContext& dc) const
{
	CRichEditView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CBEditView クラスのメッセージ ハンドラ

HRESULT CBEditView::QueryAcceptData(LPDATAOBJECT lpdataobj,
	CLIPFORMAT* lpcfFormat, DWORD /*dwReco*/, BOOL bReally, HGLOBAL hMetaPict)
{
	ASSERT(lpcfFormat != NULL);
	if (!bReally) // not actually pasting
		return S_OK;
	// if direct pasting a particular native format allow it
	if (IsRichEditFormat(*lpcfFormat)) {
		*lpcfFormat = CF_TEXT;
		return S_OK;
	}
	// OLE オブジェクトは無視!!!!
	return S_FALSE;
}

void CBEditView::OnEditPaste() 
{
	// テキストのみ貼り付ける!!!!
	GetRichEditCtrl().PasteSpecial(CF_TEXT);	
	
}

void CBEditView::GetCaretPosition(int& nLine, int& nCol,int& nLineTotal)
{
	static int oldStart = -1, oldEnd = -1;
	static enum Direction { left, right } oldDir = right;

	CRichEditCtrl& theEdit = GetRichEditCtrl();

	// If text has been selected with the mouse, determine 
	// the direction of the selection. If the user is dragging
	// to the right, the character of interest is at the end 
	// of the selection. Likewise, a leftward selection means 
	// we want the starting character. 
	// We have to keep track of the last selection to determine 
	// the current selection state.
	// If no characters are selected, newStart will equal newEnd.

	Direction newDir = right;
	long newStart, newEnd, nCurrent;
	theEdit.GetSel(newStart, newEnd);

	if ( (newEnd == oldEnd) && (newStart == oldStart))
		newDir = oldDir;
	else if (oldStart == newStart) 
		newDir = right;
	else if (oldEnd == newEnd)
		newDir = left;
	else if (oldStart == newEnd)
		newDir = left;
	else if (oldEnd == newStart)
		newDir = right;
		
	if (newDir == right)
		nCurrent = newEnd;
	else 
		nCurrent = newStart; 
		
	oldStart = newStart;
	oldEnd = newEnd;
	oldDir = newDir;

	// Determine the current line based on the current character in 
	// the selection. Add one since LineFromChar is zero based.
	nLine = theEdit.LineFromChar(nCurrent) + 1;
	// nLineIndex is the zero based index of the first character in 
	// the nLine line.
	int nLineIndex = theEdit.LineIndex(nLine-1);
		  
	// The caret column position is the line index subtracted from
	// the current position from GetSel.
	nCol = nCurrent - nLineIndex + 1;
	nLineTotal = theEdit.GetLineCount();
}

// カレット位置を更新します
void CBEditView::OnUpdateCaretPos(CCmdUI* pCmdUI)
{
	// Get the current caret position from the helper function then
	// format it into a string for the status bar.
	
	int nLine, nCol,nLineTotal;
	GetCaretPosition(nLine, nCol,nLineTotal);

	if (m_nLine == nLine &&	m_nColumn == nCol &&
		m_nTotalLine == nLineTotal)
		return;

	m_nLine = nLine;
	m_nColumn = nCol;
	m_nTotalLine = nLineTotal;

	CString str;
	wsprintf(str.GetBuffer(40), "%d 行, %d 桁, 総行数 %d",
		nLine, nCol,nLineTotal);
	str.ReleaseBuffer();

	pCmdUI->Enable(TRUE);
	pCmdUI->SetText(str);

    // 少し太いカレットを表示します
    CreateSolidCaret( 3,m_CharFormat.yHeight/12);
    ShowCaret();
}

// 指定されたフォントで全文をフォーマットします
void CBEditView::SetFormatChar(LOGFONT* plogfont)
{

	CRichEditCtrl& theEdit = GetRichEditCtrl();

	// 現在の選択位置を退避します	
	CHARRANGE crange;
	theEdit.GetSel(crange);
	BOOL bmod = theEdit.GetModify();

	// CHARFORMATを使ってフォーマットします
	// フォントの高さをpointからtwipsに変換します
	CDC* cDC = GetDC();
	int picy = cDC->GetDeviceCaps(LOGPIXELSY);
	ReleaseDC(cDC);
	int point = -MulDiv(plogfont->lfHeight,72,picy);
	int twips = point * 20;

	theEdit.SetSel(0,-1);
//	theEdit.SetDefaultCharFormat(m_CharFormat);
	theEdit.GetSelectionCharFormat(m_CharFormat);
	m_CharFormat.yHeight = twips;
	m_CharFormat.bCharSet = plogfont->lfCharSet;
	lstrcpy(m_CharFormat.szFaceName, plogfont->lfFaceName);
	theEdit.SetSelectionCharFormat(m_CharFormat);

	// 選択位置を元に戻します
	theEdit.SetSel(crange);
	theEdit.SetModify(bmod);
}


プログラムコードのご使用上の注意

●プログラムコードを使って発生した損害に関しては、一切の責任を負いません。
●使用、配布に制限はありません。自由にお使いください。
●動作の保証はありません。
●動作を確認したOSは、Windows NT 4.0 とWindows 95のみです。

Home


Copyright 1997 Tatsuo Baba,All rights reserved.