Title
最終更新日:1999/02/26
目次



●Access97 − レポートでページごとの集計を表示する

テキストコントロール(金額小計)をページフッターに用意する。
ページヘッダーフ_Format時に初期化し、詳細_Printで、加算する

Private Sub ページヘッダー_Format(Cancel As Integer, FormatCount As Integer)
	'金額小計の初期化
	Me!金額小計 = 0
End Sub

Private Sub 詳細_Print(Cancel As Integer, PrintCount As Integer)
	'金額小計の計算
	Me!金額小計 = Me!金額小計 + Me!金額
End Sub


●Win32 − DIBビットマップの反転

int DrawBMP(HDC hdc, RECT rc, int wx, int wy, char *szBuf, BOOL bUpdown, BOOL bMirror)
{
	int A, B, C, D;
	if (bUpdown == FALSE && bMirror == FALSE) {
		A = 0; B = 0; C = rc.right; D = rc.bottom;
	}
	if (bUpdown == FALSE && bMirror ==TRUE) {
		A = rc.right; B = 0; C = -rc.right; D = rc.bottom;
	}
	if (bUpdown == TRUE && bMirror == FALSE) {
		A = rc.right; B = rc.bottom; C = -rc.right; D = -rc.bottom;
	}
	if (bUpdown == TRUE && bMirror == TRUE) {
		A = 0; B = rc.bottom; C = rc.right; D = -rc.bottom;
	}
	
	StretchDIBits(hdc,//デバイスコンテキスト
		A, B, //転送先座標
		C, D, //幅、高さ
		0, 0, //転送元座標
		wx, wy, //転送元幅、高さ
		(char *)szBuf,//ビットマップデータ開始のアドレス
		lpbmp_info, //BITMAPINFO構造体へのポインタ
		DIB_RGB_COLORS,
		SRCCOPY);
	return 0;
}

●MFC - ビットマップ反転

void Foo::Foo(CBitmap& Bitmap) 
{
	if(Bitmap.GetSafeHandle()!=NULL){
		BITMAP bm;
		Bitmap.GetObject(sizeof(BITMAP), &bm);
		BYTE *bits1 = new BYTE[bm.bmWidthBytes*bm.bmHeight];
		BYTE *bits2 = new BYTE[bm.bmWidthBytes*bm.bmHeight];

		//ビットマップのビット列を取得
		int n=Bitmap.GetBitmapBits(bm.bmWidthBytes*bm.bmHeight, bits1);
		BYTE *p1 = bits1;
		BYTE *p2 = bits2;
		p2 += (bm.bmWidthBytes*bm.bmHeight);
		for(int i=0; i<bm.bmHeight; i++){
			for(int j=0; j<bm.bmWidthBytes; j++, p1++, p2--){
				*p2 = *p1;//一番上と一番下を入れ替える
			}
		}
		//新しいビット列をセット
		Bitmap.SetBitmapBits(bm.bmWidthBytes*bm.bmHeight, bits2);
		delete[]bits1;
		delete[]bits2;
		//Invalidate();
	}	
}


●MFC − Threadダイアログのサンプル

VCプロジェクトにCMyThreadを追加。
適当なダイアログCWaitDlgを追加。
メニューなどにコマンド追加して、ダイアログを起動する。

//------------------------------------------------------
// MyThread.H : ヘッダー ファイル
//------------------------------------------------------

class CWaitDlg;
class CMyThread //: public CWinThread
{
//	DECLARE_DYNCREATE(CMyThread)
public:
	CMyThread();// 動的生成に使用されるプロテクト コンストラクタ
	virtual ~CMyThread();
	void Start();//スレッド開始
// アトリビュート
public:
	CString m_strRoot;
// オペレーション
public:
	void DoCancel();//キャンセル処理
	void Init(CWaitDlg* p,HANDLE h);//初期化処理
// オーバーライド
	// ClassWizard は仮想関数のオーバーライドを生成します。
	//{{AFX_VIRTUAL(CMyThread)
	//}}AFX_VIRTUAL
// インプリメンテーション
protected:
	//ワーカスレッドスタータ
	friend UINT AFX_CDECL CMyThreadFun(LPVOID pParam);
	UINT	Run();		//スレッド実行
	void	WaitForDlgDisp();//ダイアログ同期
	BOOL	Exec();	//処理実行
	// 生成されたメッセージ マップ関数
	//{{AFX_MSG(CMyThread)
		// メモ - ClassWizard は...します。
	//}}AFX_MSG
	//DECLARE_MESSAGE_MAP()
//アトリビュート
protected:
	CWaitDlg* m_pDlg;//進捗状況表示ダイアログクラスへのポインタ
	HANDLE m_hCancelEvent;//キャンセルイベントハンドル
	BOOL	m_bRequestCancel;//キャンセルフラグ
};

//------------------------------------------------------
// MyThread.cpp : インプリメンテーション ファイル
//------------------------------------------------------

#include "stdafx.h"
#include "MyThread.h"
#include "WaitDlg.h"

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

CMyThread::CMyThread()
{
	//メンバ変数初期化
	m_pDlg = NULL;//状況表示ダイアログクラスへのポインタ
	m_hCancelEvent = NULL;//キャンセルイベントハンドル
	m_bRequestCancel = NULL;//キャンセルフラグ
}
CMyThread::~CMyThread()
{
}
void CMyThread::Start()
{
	CWinThread* pThr = AfxBeginThread(CMyThreadFun, this);
	pThr->m_bAutoDelete = TRUE;
}
UINT AFX_CDECL CMyThreadFun(LPVOID pParam)
{
	ASSERT(pParam != NULL);
	return ((CMyThread*)pParam)->Run();
}
UINT CMyThread::Run() 
{
	WaitForDlgDisp();//ダイアログが表示されるまで待つ
	//メイン処理
	int Count=0;
	while(Exec()){
		if(WaitForSingleObject(m_hCancelEvent,0)!=WAIT_TIMEOUT){
			m_pDlg->EndDialog(IDCANCEL);//キャンセル終了
			return 0;
		}
		if(++Count>1000) break;//テスト
	}
	m_pDlg->EndDialog(IDOK);//全部終了
	return 0;
}
void CMyThread::Init(CWaitDlg*	pobjDlg,//状況表示ダイアログへのポインタ
			HANDLE	hCancelEvent)//キャンセルイベントハンドル
{
	//メンバ変数へ保持
	m_pDlg = pobjDlg;
	m_hCancelEvent = hCancelEvent;
}
void CMyThread::DoCancel()
{
	//キャンセルフラグをオン
	m_bRequestCancel = TRUE;
}
void CMyThread::WaitForDlgDisp()
{
	BOOL bRet;
	for(;;){if( m_pDlg != NULL ) break;}
	for(;;){
		if( m_pDlg->m_hWnd != NULL ){
			Sleep(200);
			bRet = IsWindow(m_pDlg->m_hWnd);
			if(bRet!=NULL){	Sleep(200);	break;}
		}
	}
	return;
}
BOOL CMyThread::Exec()	//TRUE:処理継続、FALSE:処理終了OR処理中断
{
	CTime t = CTime::GetCurrentTime ();
	CString msg = t.Format("%c");
	m_pDlg->SetMsgText(msg);
	Sleep(100);	//ダミー処理
	return(TRUE);
}

//------------------------------------------------------
// CWaitDlg.h
//------------------------------------------------------

// ヘッダーファイル追加メンバー
public:
	CString	m_strMsg;
	void SetMsgText(const CString strMsg);
	void Init(CMyThread*,HANDLE);	//初期化
protected:
	virtual void OnCancel(); //Cancel 
	CMyThread* m_pobjThread;//処理スレッドへのポインタ
	HANDLE m_hCancelEvent;//キャンセルイベントハンドル


//------------------------------------------------------
// CWaitDlg.cpp
//------------------------------------------------------

// CWaitDlgコンストラクター
CWaitDlg::CWaitDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CImageLoadDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CImageLoadDlg)
	m_strMsg = _T("");
	//}}AFX_DATA_INIT
	m_pobjThread = NULL;
	m_hCancelEvent = NULL;
}
void CImageLoadDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CImageLoadDlg)
	DDX_Text(pDX, IDC_MSG, m_strMsg);
	//}}AFX_DATA_MAP
}
// 初期化
void CWaitDlg::Init(CMyThread* pobjThread,//スレッドクラスへのポインタ
		HANDLE hCancelEvent)//キャンセルイベントハンドル
{
	//メンバ変数へ保持
	m_pobjThread = pobjThread;
	m_hCancelEvent = hCancelEvent;
}
void CImageLoadDlg::OnCancel() 
{
	//中止確認
	//BOOL  bRet = AfxMessageBox( "本当に中止してもいいですか?",
	//	 MB_OKCANCEL | MB_ICONQUESTION | MB_DEFBUTTON2, 0 );
	//if( bRet == IDCANCEL ){
	//	return;
	//}
	//処理スレッドへキャンセル通知
	SetEvent(m_hCancelEvent);
	m_pobjThread->DoCancel();
	//CDialog::OnCancel();
}
void CImageLoadDlg::SetMsgText(const CString strMsg)
{
	SetDlgItemText(IDC_MSG, strMsg);
}

//------------------------------------------------------
// 使用する方法
//------------------------------------------------------
#include "MyThread.h"
#include "WaitDlg.h"
void Foo()
{
	//ダイアログ(実行)
	CWaitDlg objDlg;
	//処理スレッド生成
	CMyThread	objThread;
	//キャンセル用イベント生成
	HANDLE	hCancelEvent = CreateEvent(NULL,FALSE,FALSE,"CANCEL_EVENT");
	//初期化
	objThread.Init(&objDlg,hCancelEvent);
	objDlg.Init(&objThread,hCancelEvent, theApp.m_nImageWidth, theApp.m_nImageHeight);
	//処理スレッドスタート
	objThread.m_strRoot = theApp.m_strRootDirectory;
	objThread.Start();
	//ダイアログ表示
	int nResponse = objDlg.DoModal();
	if (nResponse == IDOK)
	{
		// TODO: ダイアログが <OK> で消された時のコードを記述してください。
		MessageBox("ok");
	}
	else if (nResponse == IDCANCEL)
	{
		// TODO: ダイアログが <キャンセル> で消された時のコードを記述してください。
		MessageBox("cancel");
	}
	//イベントハンドルクローズ
	CloseHandle(hCancelEvent);
}


●Win32 - デスクトップフォルダーパス取得

#include "winnetwk.h"
#include "shlobj.h"
BOOL GetDeskTopFolderPath(char* pPath)
{
	// デスクトップフォルダー
	char  szPath[MAX_PATH];
	ITEMIDLIST*  pidl;
	LPMALLOC  pMalloc;
	if( SUCCEEDED(SHGetMalloc(&pMalloc)) )    {
		SHGetSpecialFolderLocation( ::GetDesktopWindow(), CSIDL_DESKTOP, &pidl );
		SHGetPathFromIDList( pidl, szPath );
		//MessageBox( NULL, szPath, "デスクトップのフォルダ", MB_OK ) ;
		pMalloc->Free( pidl );
		pMalloc->Release();
		lsrcpy(pPath, szPath);
		return TRUE;
	}
	return FALSE;
}


●Win32 - 拡張子の関連付けアプリを取得

//szFileName : 調べたいファイル名
//lpExeFilePath : 拡張子に対応した実行ファイルパス
BOOL GetExeFilePath(LPCSTR szFileName, LPTSTR lpExeFilePath)
{
	char  str[MAX_PATH]; 
	HINSTANCE hi=FindExecutable( szFileName, NULL, str );
	if(hi>=(HINSTANCE)32){
		lstrcpy(lpExeFilePath, str);
		//MessageBox( NULL, str, szFileName, MB_OK );
		return TRUE;
	}
	else{
		wsprintf(str, "error: %d n%d p%d b%d", hi
		,ERROR_FILE_NOT_FOUND,
		ERROR_PATH_NOT_FOUND ,
		ERROR_BAD_FORMAT );
		//MessageBox( NULL, str, szFileName, MB_OK );
		return FALSE;
	}
}


●Win32 - ショートカットの作成

//lpszShortcutFile : 作成するショートカットフルパス(*.lnkとすること)
//lpszDescription : ディスクリプション
//lpszTargetFile : リンク元のファイルのフルパス
#include "shlobj.h"
BOOL CreateLinkFile(LPCTSTR lpszShortcutFile, LPCTSTR lpszDescription,
	LPCTSTR lpszTargetFile )
{
	BOOL bRet = FALSE;
	HRESULT  hResult;
	IShellLink*  psl; 

	//  COMの初期化
	CoInitialize( NULL );
	//  IShellLink インターフェースの取得
	hResult = CoCreateInstance( CLSID_ShellLink, NULL, 
		CLSCTX_INPROC_SERVER,IID_IShellLink, (void **)&psl );
	if( SUCCEEDED(hResult) ) {
		IPersistFile*  ppf;
		// IPersistFileインターフェースの取得
		hResult = psl->QueryInterface( IID_IPersistFile, (void **)&ppf );
		if( SUCCEEDED(hResult) ) {
			WCHAR  wszShortcutFile[MAX_PATH]; // ユニコード用のバッファ
			// リンク元のファイルのパスをセットする
			hResult = psl->SetPath( lpszTargetFile );
			if( SUCCEEDED(hResult) ) {
				// ショートカットファイルのディスクリプションをセット
				hResult = psl->SetDescription( lpszDescription );
				if( SUCCEEDED(hResult) ) {
					MultiByteToWideChar( CP_ACP, 0, lpszShortcutFile, -1,
							wszShortcutFile, MAX_PATH );
					hResult = ppf->Save( wszShortcutFile, TRUE );
					if( SUCCEEDED(hResult) ) 
						bRet = TRUE;
				}
			}
			ppf->Release();
		}
		psl->Release();
	}
	CoUninitialize();
	return bRet;
}



目次



ご連絡はメールにて


GeoCities Japan