[PR]

『新妻LOVELY×CATION』を応援しています!
水無瀬の部屋 > Programming > sample > tools > workthrd > traythrd.cpp
最終更新日: 2007/10/24

   1: //*********************************************************
   2: // プロジェクト: traythrd
   3: //   ファイル名: traythrd.cpp
   4: //*********************************************************
   5: #include <workthrd/traythrd.h>
   6: #include <workthrd/workthrd.h>
   7: #include <dlg/dyndlg.h>
   8: 
   9: 
  10: //---------------------------------------------------------
  11: // マクロ定数 の 定義
  12: //---------------------------------------------------------
  13: #define ID_TRAYICON        ( 1 )          // システムトレイ・アイコン
  14: #define IDT_WAITTHREAD     ( 102 )
  15: #define UM_ICONMESSAGE     ( 1 + WM_APP ) // 0x8001
  16: #define UM_MENUPOPUP       ( 2 + WM_APP )
  17: #define IDM_CANCEL         ( 40000 )
  18: #define PROP_TRAYICON      "PROP_TRAYICON"
  19: #define PROP_THREAD        "PROP_THREAD"
  20: 
  21: 
  22: //---------------------------------------------------------
  23: // 構造体 の 宣言
  24: //---------------------------------------------------------
  25: // busyicon_t
  26: typedef struct busyicon_tag
  27: {
  28: 	      WorkerThreadProc_t  proc;
  29: 	      void               *param;
  30: 	      HICON               hIcon;
  31: 	const char               *message;
  32: } busyicon_t;
  33: 
  34: 
  35: //---------------------------------------------------------
  36: // ファイルスコープ関数 の 宣言
  37: //---------------------------------------------------------
  38: static INT_PTR CALLBACK BusyTrayDlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
  39: static NOTIFYICONDATA *AddWorkingTrayIcon( HWND hWnd, UINT uID, UINT uMessage, HICON hIcon, const char *szTip );
  40: static DLGTEMPLATE *CreateBusyTrayDialogTemplate( void );
  41: static void CALLBACK WatchWorkerThreadProc( HWND hWnd, UINT, UINT uID, DWORD );
  42: static thread_t *GetPropWorkerThread( HWND hWnd );
  43: 
  44: 
  45: //*********************************************************
  46: // RunOnTrayIcon
  47: //*********************************************************
  48: int
  49: RunOnTrayIcon
  50: 	(
  51: 		      WorkerThreadProc_t  proc,   // 実行関数
  52: 		      void               *param,  // 実行関数に渡す引数
  53: 		      HICON               hIcon,  // アイコン
  54: 		const char               *message // メッセージ
  55: 	)
  56: {
  57: 	// パラメタの仮定
  58: 	ASSERT( IsValidCodePtr( proc ) );
  59: 	ASSERT( IsValidIconHandle( hIcon ) );
  60: 	ASSERT( IsValidStringPtr( message ) );
  61: 	ASSERT( strlen( message ) < numof( ((NOTIFYICONDATA *)null)->szTip ) );
  62: 
  63: 	//
  64: 	DLGTEMPLATE *templ = CreateBusyTrayDialogTemplate();
  65: 	if ( ! templ )
  66: 	{
  67: 		return IDABORT;
  68: 	}
  69: 
  70: 	//
  71: 	busyicon_t bi;
  72: 	bi.proc    = proc;
  73: 	bi.param   = param;
  74: 	bi.hIcon   = hIcon;
  75: 	bi.message = message;
  76: 
  77: 	//
  78: 	const INT_PTR result = DialogBoxIndirectParam
  79: 		(
  80: 			GetModuleHandle( null ),
  81: 			templ,
  82: 			HWND_DESKTOP,
  83: 			BusyTrayDlgProc,
  84: 			reinterpret_cast<LPARAM>( &bi )
  85: 		);
  86: 
  87: 	//
  88: 	VERIFY( DestroyDialogTemplate( templ ) );
  89: 
  90: 	return _w64_static_cast<int>( result ); // [_W64]
  91: }//RunOnTrayIcon
  92: 
  93: 
  94: //******************************************************************************************************************
  95: // private
  96: //******************************************************************************************************************
  97: //*********************************************************
  98: // CreateBusyTrayDialogTemplate
  99: //*********************************************************
 100: static
 101: DLGTEMPLATE *
 102: CreateBusyTrayDialogTemplate
 103: 	(
 104: 		void
 105: 	)
 106: {
 107: 	//
 108: 	const DLGTEMPLATEITEMDATA items[] = 
 109: 		{
 110: 			{ CTLCLS_BUTTON, L"OK", WS_CHILD | BS_DEFPUSHBUTTON | WS_GROUP, 0, 0, 0, 1, 1, IDOK },
 111: 		};
 112: 
 113: 	//
 114: 	DLGTEMPLATEHEAD dlg;
 115: 	dlg.style           = WS_POPUP | DS_SETFONT;
 116: 	dlg.dwExtendedStyle = 0;
 117: 	dlg.cdit            = numof( items );
 118: 	dlg.x               = 0;
 119: 	dlg.y               = 0;
 120: 	dlg.cx              = 1,
 121: 	dlg.cy              = 1;
 122: 	dlg.classname       = null;
 123: 	dlg.caption         = L"";
 124: 	dlg.menu            = null;
 125: 	dlg.font            = L"MS Pゴシック";
 126: 	dlg.height          = 9;
 127: 	ASSERT( IsValidDialogTemplateHead( &dlg ) );
 128: 
 129: 	return CreateDialogTemplate( &dlg, items );
 130: }//CreateBusyTrayDialogTemplate
 131: 
 132: 
 133: //******************************************************************************************************************
 134: //
 135: //******************************************************************************************************************
 136: static INT_PTR OnBusyTrayDlgInitDialog( HWND hWnd, LPARAM lParam );
 137: static INT_PTR OnBusyTrayDlgDestroy( HWND hWnd );
 138: static INT_PTR OnBusyTrayDlgIconMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
 139: static INT_PTR OnBusyTrayDlgCommand( HWND hWnd, WPARAM wParam, LPARAM lParam );
 140: static INT_PTR OnBusyTrayDlgWindowPosChanging( HWND hWnd, LPARAM lParam );
 141: 
 142: 
 143: //*********************************************************
 144: // BusyTrayDlgProc
 145: //*********************************************************
 146: static
 147: INT_PTR
 148: CALLBACK
 149: BusyTrayDlgProc
 150: 	(
 151: 		HWND   hWnd,
 152: 		UINT   uMsg,
 153: 		WPARAM wParam,
 154: 		LPARAM lParam
 155: 	)
 156: {
 157: 	// パラメタの仮定
 158: 	ASSERT( IsValidWindow( hWnd ) );
 159: 
 160: 	switch( uMsg )
 161: 	{
 162: 		case WM_INITDIALOG:        return OnBusyTrayDlgInitDialog( hWnd, lParam );
 163: 		case WM_DESTROY:           return OnBusyTrayDlgDestroy( hWnd );
 164: 		case WM_WINDOWPOSCHANGING: return OnBusyTrayDlgWindowPosChanging( hWnd, lParam );
 165: 		case WM_COMMAND:           return OnBusyTrayDlgCommand( hWnd, wParam, lParam );
 166: 		case UM_ICONMESSAGE:       return OnBusyTrayDlgIconMessage( hWnd, uMsg, wParam, lParam );
 167: 		default:                   return false;
 168: 	}
 169: }//BusyTrayDlgProc
 170: 
 171: //*********************************************************
 172: // OnBusyTrayDlgInitDialog - WM_INITDIALOG
 173: // ダイアログが作成された。
 174: // この関数が抜けるまでダイアログは表示されない。
 175: // 明示的にフォーカスを移動した場合は 真 を返す。
 176: // さもなくば 偽 を返す。
 177: //   HWND   wParam …… フォーカスを受け取る予定のコントロール
 178: //   LPARAM lParam …… ダイアログの初期化パラメタ
 179: //*********************************************************
 180: static
 181: INT_PTR
 182: OnBusyTrayDlgInitDialog
 183: 	(
 184: 		HWND   hWnd,
 185: 		LPARAM lParam
 186: 	)
 187: {
 188: 	// パラメタの仮定
 189: 	ASSERT( IsValidWindow( hWnd ) );
 190: 	ASSERT( IsValidPtr( (busyicon_t *)lParam, sizeof( busyicon_t ) ) );
 191: 
 192: 	//
 193: 	const busyicon_t *bi = reinterpret_cast<busyicon_t *>( lParam );
 194: 	
 195: 	// スレッドの作成
 196: 	thread_t *thread = CreateWorkerThread( bi->proc, bi->param );
 197: 	VERIFY( SetProp( hWnd, PROP_THREAD, thread ) );
 198: 	if ( ! thread )
 199: 	{	
 200: 		ERROR_REPORT( "%s(%d) : %s \r\n", __FILE__, __LINE__,
 201: 			"作業用スレッドの作成に失敗" );
 202: 		EndDialog( hWnd, IDABORT );
 203: 		return true;
 204: 	}
 205: 	ASSERT( IsValidWorkerThread( thread ) );
 206: 
 207: 	// 作業中アイコンの登録
 208: 	NOTIFYICONDATA *nid = AddWorkingTrayIcon( hWnd, ID_TRAYICON, UM_ICONMESSAGE, bi->hIcon, bi->message );
 209: 	if ( !nid )
 210: 	{
 211: 		ERROR_REPORT( "%s(%d) : %s \r\n", __FILE__, __LINE__,
 212: 			"作業中アイコンの登録に失敗" );
 213: 		VERIFY( EndDialog( hWnd, IDABORT ) );
 214: 		return true;
 215: 	}
 216: 	VERIFY( SetProp( hWnd, PROP_TRAYICON, nid ) );
 217: 
 218: 	// キャンセル監視
 219: 	if ( IDT_WAITTHREAD != SetTimer( hWnd, IDT_WAITTHREAD, 0, WatchWorkerThreadProc ) )
 220: 	{
 221: 		ERROR_REPORT( "%s(%d) : %s \r\n", __FILE__, __LINE__,
 222: 			"キャンセル監視タイマの起動に失敗 - SetTimer( IDT_WAITTHREAD )" );
 223: 		VERIFY( EndDialog( hWnd, IDABORT ) );
 224: 		return true;
 225: 	}
 226: 
 227: 	// 実行開始
 228: 	ResumeWorkerThread( thread ); 
 229: 
 230: 	//
 231: 	VisibleWindow( hWnd, false );
 232: 
 233: 	return true;
 234: }//OnBusyTrayDlgInitDialog
 235: 
 236: //*********************************************************
 237: // OnBusyTrayDlgDestroy - WM_DESTROY
 238: // まもなくウィンドウが破棄される
 239: // ウィンドウに関連付けた独自リソースを破棄する
 240: // 常に 0L を返す
 241: //*********************************************************
 242: static
 243: INT_PTR
 244: OnBusyTrayDlgDestroy
 245: 	(
 246: 		HWND hWnd
 247: 	)
 248: {
 249: 	// パラメタの仮定
 250: 	ASSERT( IsValidWindow( hWnd ) );
 251: 
 252: 	// タイマの停止
 253: 	KillTimer( hWnd, IDT_WAITTHREAD );
 254: 
 255: 	// 作業中アイコンを破棄する
 256: 	NOTIFYICONDATA *nid = (NOTIFYICONDATA *)RemoveProp( hWnd, PROP_TRAYICON );
 257: 	if ( nid )
 258: 	{
 259: 		VERIFY( DeleteNotifyIcon( nid ) );
 260: 		free( nid );
 261: 	}
 262: 
 263: 	// スレッドを破棄する
 264: 	thread_t *thread = (thread_t *)RemoveProp( hWnd, PROP_THREAD );
 265: 	if ( thread )
 266: 	{
 267: 		VERIFY( DestroyWorkerThread( thread ) );
 268: 	}
 269: 
 270: 	return 0L;
 271: }//OnBusyTrayDlgDestroy
 272: 
 273: //*********************************************************
 274: // OnBusyTrayDlgWindowPosChanging
 275: //*********************************************************
 276: static
 277: INT_PTR
 278: OnBusyTrayDlgWindowPosChanging
 279: 	(
 280: 		HWND   hWnd,
 281: 		LPARAM lParam
 282: 	)
 283: {
 284: 	// パラメタの仮定
 285: 	ASSERT( IsValidWindow( hWnd ) );
 286: 	ASSERT( IsValidPtr( (WINDOWPOS *)lParam, sizeof( WINDOWPOS ) ) );
 287: 
 288: 	//
 289: 	WINDOWPOS *wpos = reinterpret_cast<WINDOWPOS *>( lParam );
 290: 	wpos->flags &= ~SWP_SHOWWINDOW;
 291: 	wpos->flags |=  SWP_HIDEWINDOW;
 292: 
 293: 	return false;
 294: }//OnBusyTrayDlgWindowPosChanging
 295: 
 296: //*********************************************************
 297: // OnBusyTrayDlgIconMessage
 298: //*********************************************************
 299: static
 300: INT_PTR
 301: OnBusyTrayDlgIconMessage
 302: 	(
 303: 		HWND   hWnd,
 304: 		UINT   ,
 305: 		WPARAM wParam,
 306: 		LPARAM lParam
 307: 	)
 308: {
 309: 	// パラメタの仮定
 310: 	ASSERT( IsValidWindow( hWnd ) );
 311: 	ASSERT( IsValidWorkerThread( GetPropWorkerThread( hWnd ) ) );
 312: 	ASSERT( ID_TRAYICON == wParam );
 313: 
 314: 	if ( ID_TRAYICON != wParam )
 315: 	{
 316: 		return false;
 317: 	}
 318: 
 319: 	switch( lParam )
 320: 	{
 321: 		case WM_LBUTTONUP: { PostCommand( hWnd, UM_MENUPOPUP ); return false; }
 322: 		case WM_RBUTTONUP: { PostCommand( hWnd, UM_MENUPOPUP ); return false; }
 323: 		default:           return false;
 324: 	}
 325: }//OnBusyTrayDlgIconMessage
 326: 
 327: 
 328: //******************************************************************************************************************
 329: //
 330: //******************************************************************************************************************
 331: static INT_PTR OnBusyTrayDlgCommandPopupMenu( HWND hWnd );
 332: static INT_PTR OnBusyTrayDlgCommandCancel( HWND hWnd );
 333: 
 334: 
 335: //*********************************************************
 336: // OnBusyTrayDlgCommand - WM_COMMAND
 337: // コマンド項目が選択された
 338: // 返値の意味は要求されたコマンドの種類による
 339: //   LOWORD(wParam) …… 選択されたコマンド項目の識別子
 340: //                     メニューの区切り線が選択された場合は 0 が設定される
 341: //   HIWORD(wParam) …… 通知コード
 342: //                     メッセージが  メニュー  から送信された場合は 0 が設定される
 343: //                     メッセージがアクセラレータから送信された場合は 1 が設定される
 344: //   HWND lParam    …… メッセージがコントロールから送信された場合はメッセージを送信したコントロールのハンドル
 345: //*********************************************************
 346: static
 347: INT_PTR
 348: OnBusyTrayDlgCommand
 349: 	(
 350: 		HWND   hWnd,
 351: 		WPARAM wParam,
 352: 		LPARAM _unuse( lParam )
 353: 	)
 354: {
 355: 	// パラメタの仮定
 356: 	ASSERT( IsValidWindow( hWnd ) );
 357: 	ASSERT( IsValidCommandMessageParam( wParam, lParam ) );
 358: 	ASSERT( IsValidWorkerThread( GetPropWorkerThread( hWnd ) ) );
 359: 
 360: 	switch ( LOWORD(wParam) )
 361: 	{
 362: 		case UM_MENUPOPUP: return OnBusyTrayDlgCommandPopupMenu( hWnd );
 363: 		case IDM_CANCEL:   return OnBusyTrayDlgCommandCancel( hWnd );
 364: 		default:           return false;
 365: 	}
 366: }//OnBusyTrayDlgCommand
 367: 
 368: //*********************************************************
 369: // OnBusyTrayDlgCommandCancel
 370: //*********************************************************
 371: static
 372: INT_PTR
 373: OnBusyTrayDlgCommandCancel
 374: 	(
 375: 		HWND hWnd
 376: 	)
 377: {
 378: 	// パラメタの仮定
 379: 	ASSERT( IsValidWindow( hWnd ) );
 380: 	ASSERT( IsValidWorkerThread( GetPropWorkerThread( hWnd ) ) );
 381: 
 382: 	thread_t *thread = GetPropWorkerThread( hWnd );
 383: 	VERIFY( CancelWorkerThread( thread ) );
 384: 
 385: 	return false;
 386: }//OnBusyTrayDlgCommandCancel
 387: 
 388: //*********************************************************
 389: // OnBusyTrayDlgCommandPopupMenu
 390: //*********************************************************
 391: static
 392: INT_PTR
 393: OnBusyTrayDlgCommandPopupMenu
 394: 	(
 395: 		HWND hWnd
 396: 	)
 397: {
 398: 	// パラメタの仮定
 399: 	ASSERT( IsValidWindow( hWnd ) );
 400: 	ASSERT( IsValidWorkerThread( GetPropWorkerThread( hWnd ) ) );
 401: 
 402: 	HMENU hmenuPopup = CreatePopupMenu();
 403: 	if ( hmenuPopup )
 404: 	{
 405: 		//
 406: 		VERIFY( AppendMenu( hmenuPopup, MFT_STRING, IDM_CANCEL, "キャンセル" ) );
 407: 
 408: 		//
 409: 		PopupMenuCursorPos
 410: 			(
 411: 				hWnd,
 412: 				hmenuPopup,
 413: 				TPM_RIGHTBUTTON | TPM_VERTICAL
 414: 			);
 415: 
 416: 		//
 417: 		VERIFY( DestroyMenu( hmenuPopup ) );
 418: 	}
 419: 
 420: 	return false;
 421: }//OnBusyTrayDlgCommandPopupMenu
 422: 
 423: 
 424: //******************************************************************************************************************
 425: //
 426: //******************************************************************************************************************
 427: //*********************************************************
 428: // AddWorkingTrayIcon
 429: //*********************************************************
 430: static
 431: NOTIFYICONDATA *
 432: AddWorkingTrayIcon
 433: 	(
 434: 		      HWND   hWnd,
 435: 		      UINT   uID,
 436: 		      UINT   uMessage,
 437: 		      HICON  hIcon,
 438: 		const char  *szTip
 439: 	)
 440: {
 441: 	// パラメタの仮定
 442: 	ASSERT( IsValidWindow( hWnd ) );
 443: 	ASSERT( IsValidIconHandle( hIcon ) );
 444: 	ASSERT( IsValidStringPtr( szTip ) );
 445: 	
 446: 	NOTIFYICONDATA *nid = CreateNotifyIconData
 447: 		( 
 448: 			hWnd,
 449: 			uID,      // ID_ICON,
 450: 			uMessage, // UM_ICONMESSAGE,
 451: 			hIcon,
 452: 			szTip     // WAIT_MESSAGE
 453: 		);
 454: 	if ( !nid )
 455: 	{
 456: 		return null;
 457: 	}
 458: 
 459: 	VERIFY( AddNotifyIconRetry
 460: 		(
 461: 			nid,
 462: 			20,
 463: 			500
 464: 		) );
 465: 
 466: 	return nid;
 467: }//AddWorkingTrayIcon
 468: 
 469: 
 470: //******************************************************************************************************************
 471: //
 472: //******************************************************************************************************************
 473: //*********************************************************
 474: // GetPropWorkerThread
 475: //*********************************************************
 476: static
 477: thread_t *
 478: GetPropWorkerThread
 479: 	(
 480: 		HWND hWnd
 481: 	)
 482: {
 483: 	// パラメタの仮定
 484: 	ASSERT( IsValidWindow( hWnd ) );
 485: 
 486: 	thread_t *thread = (thread_t *)GetProp( hWnd, PROP_THREAD );
 487: 	ASSERT( IsValidWorkerThread( thread ) );
 488: 
 489: 	return thread;
 490: }//GetPropWorkerThread
 491: 
 492: 
 493: //******************************************************************************************************************
 494: //
 495: //******************************************************************************************************************
 496: //*********************************************************
 497: // WatchWorkerThreadProc
 498: // スレッドの終了を監視する
 499: // スレッドが終了したらウィンドウを閉じる
 500: //*********************************************************
 501: static
 502: void
 503: CALLBACK
 504: WatchWorkerThreadProc
 505: 	(
 506: 		HWND hWnd,
 507: 		UINT,
 508: 		UINT uID,
 509: 		DWORD
 510: 	)
 511: {
 512: 	// パラメタの仮定
 513: 	ASSERT( IsValidWindow( hWnd ) );
 514: 	ASSERT( IsValidWorkerThread( GetPropWorkerThread( hWnd ) ) );
 515: 
 516: 	// スレッドが終了していたらダイアログも終了
 517: 	const thread_t *thread = GetPropWorkerThread( hWnd );
 518: 	if ( IsWorkerThreadFinished( thread ) )
 519: 	{
 520: 		KillTimer( hWnd, uID );
 521: 
 522: 		VERIFY( EndDialog( hWnd, IDOK ) );
 523: 	}
 524: }//WatchWorkerThreadProc
 525: 
 526: 
 527: //** end **
 528: 

参照:


Google
ご意見・ご感想をお聞かせ下さい。匿名で送信できます。

 * 返信が必要な場合には postmaster@katsura-kotonoha.sakura.ne.jp へ直接メールしてください。

水無瀬の部屋 > sample > tools > workthrd > traythrd.cpp

このページは cpp2web が出力しました。
水無瀬 優 postmaster@katsura-kotonoha.sakura.ne.jp
http://katsura-kotonoha.sakura.ne.jp/prog/code/tools/workthrd/traythrd_cpp.shtml
同人ダウンロード販売
同人ダウンロード販売|DL.Getchu.com