[PR]

水無瀬の部屋 > Programming > sample > tools > dlg > dyndlg.cpp
最終更新日: 2007/03/29

   1: //*********************************************************
   2: // プロジェクト: TOOLS::DYNDLG
   3: //   ファイル名: dyndlg.cpp
   4: //*********************************************************
   5: #define USE_STRNCPY // [unsafe]
   6: #include <dlg/dyndlg.h>
   7: #include <header/tooldbg.h>
   8: #include <header/toolbase.h>
   9: #include <header/toolsys.h>
  10: 
  11: 
  12: //---------------------------------------------------------
  13: // テスト関数 の 宣言
  14: //---------------------------------------------------------
  15: DECLARE_TESTPROC( test_dyndlg );
  16: 
  17: 
  18: //---------------------------------------------------------
  19: // 定数型マクロ の 定義
  20: //---------------------------------------------------------
  21: #define DBG_ALLOCNAME  "CreateDialogTemplate"
  22: 
  23: // 領域 byte[bufsize] は位置 word[offset] で size バイトの書込をするに十分な領域か?
  24: #define IS_ENOUGH_SIZE( offset, size, bufsize )  (((((offset) * sizeof(WORD)) + (size)) <= (bufsize)))
  25: 
  26: 
  27: //---------------------------------------------------------
  28: // ファイルスコープ関数 の 宣言
  29: //---------------------------------------------------------
  30: static size_t ConstructDialogTemplate( WORD *ptr, size_t bufsize, const DLGTEMPLATEHEAD *src, const DLGTEMPLATEITEMDATA *items );
  31: 
  32: 
  33: //*********************************************************
  34: // CreateDialogTemplate
  35: //*********************************************************
  36: DLGTEMPLATE *
  37: CreateDialogTemplate
  38: 	(
  39: 		const DLGTEMPLATEHEAD     *dlg,
  40: 		const DLGTEMPLATEITEMDATA *items
  41: 	)
  42: {
  43: 	CALLONCE_TESTPROC( test_dyndlg ); // [テスト]
  44: 
  45: 	// パラメタの仮定
  46: 	ASSERT( IsValidDialogTemplateHead( dlg ) );
  47: 	ASSERT( IsValidReadPtr( items, dlg->cdit * sizeof( *items ) ) );
  48: 
  49: 	const size_t size = ConstructDialogTemplate( null, 0, dlg, items );
  50: 	WORD *templ = (WORD *)malloc( size );
  51: 	if ( !templ )
  52: 		return null;
  53: 
  54: 	VERIFY( size == ConstructDialogTemplate( templ, size, dlg, items ) );
  55: 	
  56: 	DBG_LOCK_ALLOCED_MEMORY( templ, DBG_ALLOCNAME ); // [DBG]
  57: 	return reinterpret_cast<DLGTEMPLATE *>( templ );
  58: }//CreateDialogTemplate
  59: 
  60: //*********************************************************
  61: // DestroyDialogTemplate
  62: //*********************************************************
  63: bool
  64: DestroyDialogTemplate
  65: 	(
  66: 		DLGTEMPLATE *dlg
  67: 	)
  68: {
  69: 	CALLONCE_TESTPROC( test_dyndlg ); // [テスト]
  70: 
  71: 	DBG_UNLOCK_ALLOCED_MEMORY( dlg, DBG_ALLOCNAME ); // [DBG]
  72: 	free( dlg );
  73: 
  74: 	return true;
  75: }//DestroyDialogTemplate
  76: 
  77: //*********************************************************
  78: // IsValidDialogTemplateHead
  79: //*********************************************************
  80: bool
  81: IsValidDialogTemplateHead
  82: 	(
  83: 		const DLGTEMPLATEHEAD *dlg
  84: 	)
  85: {
  86: 	CALLONCE_TESTPROC( test_dyndlg ); // [テスト]
  87: 
  88: 	VALID_TEST( IsValidReadPtr( dlg, sizeof( *dlg ) ) );
  89: 	VALID_TEST( 0 <= dlg->cdit );
  90: 	VALID_TEST( 0 <= dlg->cx );
  91: 	VALID_TEST( 0 <= dlg->cy );
  92: 	VALID_TEST( 0 <= dlg->height );
  93: 	VALID_TEST( ( dlg->font && (DS_SETFONT == (dlg->style & DS_SETFONT)))
  94: 	         || (!dlg->font && (         0 == (dlg->style & DS_SETFONT))) );
  95: 
  96: 	return true;
  97: }//IsValidDialogTemplateHead
  98: 
  99: //*********************************************************
 100: // IsValidDialogTemplateItemData
 101: //*********************************************************
 102: bool
 103: IsValidDialogTemplateItemData
 104: 	(
 105: 		const DLGTEMPLATEITEMDATA *item
 106: 	)
 107: {
 108: 	CALLONCE_TESTPROC( test_dyndlg ); // [テスト]
 109: 
 110: 	VALID_TEST( IsValidReadPtr( item, sizeof( *item ) ) );
 111: 	VALID_TEST( WS_CHILD == (WS_CHILD & item->style) );
 112: 	VALID_TEST( 0 <= item->cx );
 113: 	VALID_TEST( 0 <= item->cy );
 114: 
 115: 	return true;
 116: }//IsValidDialogTemplateItemData
 117: 
 118: 
 119: //******************************************************************************************************************
 120: // private
 121: //******************************************************************************************************************
 122: static size_t DialogTemplate_AddDialogMenu(       WORD *ptr, size_t bufsize, size_t offset, const wchar_t *menu );
 123: static size_t DialogTemplate_AddDialogClassName(  WORD *ptr, size_t bufsize, size_t offset, const wchar_t *classname );
 124: static size_t DialogTemplate_AddDialogCaption(    WORD *ptr, size_t bufsize, size_t offset, const wchar_t *caption );
 125: static size_t DialogTemplate_AddDialogFontHeight( WORD *ptr, size_t bufsize, size_t offset, const DLGTEMPLATEHEAD *src );
 126: static size_t DialogTemplate_AddDialogFontName(   WORD *ptr, size_t bufsize, size_t offset, const DLGTEMPLATEHEAD *src );
 127: static size_t DialogTemplate_AddTemplateHead(     WORD *ptr, size_t bufsize, size_t offset, const DLGTEMPLATEHEAD *src );
 128: static size_t DialogTemplate_AddControl(          WORD *buf, size_t bufsize, size_t offset, const DLGTEMPLATEITEMDATA *src );
 129: static size_t DialogTemplate_DoubleWordAlign(     WORD *ptr, size_t bufsize, size_t offset );
 130: static size_t DialogTemplate_AddWord(             WORD *buf, size_t bufsize, size_t offset, WORD word );
 131: 
 132: 
 133: //*********************************************************
 134: // ConstructDialogTemplate()
 135: // ダイアログテンプレートを構築する。
 136: // buffer が null の場合は buffer に出力される バイト数 を返す。
 137: // buffer が指定されていれば実際に出力した バイト数 を返す。
 138: //
 139: // WORD *ptr
 140: //   ダイアログテンプレートを受け取るバッファ
 141: //
 142: // size_t bufsize
 143: //   バッファのバイト数
 144: //
 145: // const DLGTEMPLATEHEAD *src
 146: //   ダイアログ情報構造体
 147: //
 148: // const DLGTEMPLATEITEMDATA *items
 149: //   追加するコントロールの配列
 150: //
 151: // 使用例:
 152: //	const int size = CreateDialogTemplate( null, &dlg, items, numof( items ) );
 153: //	WORD *templ = (WORD *)malloc( size );
 154: //	if ( templ )
 155: //	{
 156: //		VERIFY( size == CreateDialogTemplate( templ, &dlg, items, numof( items ) ) );
 157: //
 158: //		HINSTANCE hInstance = GetModuleHandle( null );
 159: //		DialogBoxIndirect( hInstance, reinterpret_cast<DLGTEMPLATE *>( templ ), HWND_DESKTOP, DlgProc );
 160: //		free( templ );
 161: //	}
 162: //
 163: //*********************************************************
 164: static
 165: size_t // 出力した バイト数
 166: ConstructDialogTemplate
 167: 	(
 168: 		      WORD                *buffer,
 169: 			  size_t               bufsize, 
 170: 		const DLGTEMPLATEHEAD     *dlg,
 171: 		const DLGTEMPLATEITEMDATA *items
 172: 	)
 173: {
 174: 	// パラメタの仮定
 175: 	ASSERT( IsValidDialogTemplateHead( dlg ) );
 176: 	ASSERT( IsValidReadPtr( items, dlg->cdit * sizeof( *items ) ) );
 177: 	ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
 178: 	ASSERT( !buffer || (DESTROY_BUFFER( buffer, bufsize ), true) );
 179: 
 180: 	// ヘッダの追加
 181: 	size_t count = 0; // ワード単位
 182: 	count += DialogTemplate_AddTemplateHead( buffer, bufsize, count, dlg ); // ヘッダの追加
 183: 	count += DialogTemplate_DoubleWordAlign( buffer, bufsize, count );      // 境界整列
 184: 
 185: 	// コントロールの追加
 186: 	ASSERT( (0 == (count & 0x01)) || ( buffer && !IS_ENOUGH_SIZE(count, 1, bufsize) ) );
 187: 	{for( int i = 0; i < dlg->cdit; ++i )
 188: 	{
 189: 		ASSERT( (0 == (count & 0x01)) || ( buffer && !IS_ENOUGH_SIZE(count, 1, bufsize) ) );
 190: 		count += DialogTemplate_AddControl(      buffer, bufsize, count, &items[ i ] ); // コントロールの追加
 191: 		count += DialogTemplate_DoubleWordAlign( buffer, bufsize, count );         // 境界整列
 192: 		ASSERT( (0 == (count & 0x01)) || ( buffer && !IS_ENOUGH_SIZE(count, 1, bufsize) ) );
 193: 	}}
 194: 	ASSERT( (0 == (count & 0x01)) || ( buffer && !IS_ENOUGH_SIZE(count, 1, bufsize) ) );
 195: 
 196: 	
 197: 	// ワード数 から バイト数 へ
 198: 	const size_t bytesize = count * sizeof( *buffer );
 199: 	ASSERT( !buffer || IS_ENOUGH_SIZE(count, 0, bufsize) );
 200: 	ASSERT( !buffer
 201: 		|| (bytesize == ConstructDialogTemplate( null, 0, dlg, items ))
 202: 		|| (bufsize  <  ConstructDialogTemplate( null, 0, dlg, items )) );
 203: 	return bytesize; // バイト数 を返す
 204: }//ConstructDialogTemplate
 205: 
 206: //*********************************************************
 207: // DialogTemplate_AddTemplateHead()
 208: //*********************************************************
 209: static
 210: size_t // 出力した ワード数
 211: DialogTemplate_AddTemplateHead
 212: 	(
 213: 		      WORD            *buffer,
 214: 		      size_t           bufsize,
 215: 			  size_t           offset, 
 216: 		const DLGTEMPLATEHEAD *dlg
 217: 	)
 218: {
 219: 	// パラメタの仮定
 220: 	ASSERT( 0 == offset );
 221: 	ASSERT( IsValidDialogTemplateHead( dlg ) );
 222: 	ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
 223: 
 224: 	//
 225: 	size_t count = 0;
 226: 
 227: 	// ヘッダの設定
 228: 	if ( buffer && IS_ENOUGH_SIZE(offset + count, sizeof( DLGTEMPLATE ), bufsize) )
 229: 	{
 230: 		MakeDialogTemplate
 231: 			(
 232: 				reinterpret_cast<DLGTEMPLATE *>( buffer ),
 233: 				dlg->cdit,
 234: 				dlg->dwExtendedStyle,
 235: 				dlg->style, 
 236: 				dlg->x,
 237: 				dlg->y,
 238: 				dlg->cx,
 239: 				dlg->cy
 240: 			);
 241: 	}
 242: 
 243: 	//
 244: 	if ( !buffer || IS_ENOUGH_SIZE(offset + count, sizeof( DLGTEMPLATE ), bufsize) )
 245: 	{
 246: 		//
 247: 		COMPILE_ASSERT( 0 == (sizeof( DLGTEMPLATE ) % sizeof( *buffer )) );
 248: 		count += sizeof( DLGTEMPLATE ) / sizeof( *buffer );
 249: 		ASSERT( !buffer || ((buffer + offset + count) == ((WORD *)(((DLGTEMPLATE *)(buffer + offset)) + 1))) );
 250: 	}
 251: 
 252: 	// 挿入される順番は意味を持つ
 253: 	count += DialogTemplate_AddDialogMenu(       buffer, bufsize, offset + count, dlg->menu      ); // メニュー の設定
 254: 	count += DialogTemplate_AddDialogClassName(  buffer, bufsize, offset + count, dlg->classname ); // クラス名 の設定
 255: 	count += DialogTemplate_AddDialogCaption(    buffer, bufsize, offset + count, dlg->caption   ); // タイトル の設定
 256: 	count += DialogTemplate_AddDialogFontHeight( buffer, bufsize, offset + count, dlg            ); // フォント・サイズ の設定
 257: 	count += DialogTemplate_AddDialogFontName(   buffer, bufsize, offset + count, dlg            ); // フォント名 の設定
 258: 
 259: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset + count, 0, bufsize) );
 260: 	return count;
 261: }//DialogTemplate_AddTemplateHead
 262: 
 263: 
 264: //******************************************************************************************************************
 265: //
 266: //******************************************************************************************************************
 267: static size_t DialogTemplate_SetResourceID( WORD *buf, size_t bufsize, size_t offset, WORD wID );
 268: static size_t DialogTemplate_AddString(     WORD *buf, size_t bufsize, size_t offset, const wchar_t *text );
 269: 
 270: 
 271: //*********************************************************
 272: // DialogTemplate_AddDialogMenu()
 273: //   ダイアログテンプレートに メニュー を追加する。
 274: //   buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
 275: //   buffer が指定されていれば実際に出力した ワード数 を返す。
 276: //
 277: // WORD *buffer
 278: //
 279: // size_t offset
 280: //   メニュー の 書込位置
 281: //
 282: // const wchar_t *menu
 283: //   書き込む メニュー
 284: //
 285: //*********************************************************
 286: static
 287: size_t // 追加した ワード数 を返す
 288: DialogTemplate_AddDialogMenu
 289: 	(
 290: 		      WORD     *buffer,
 291: 			  size_t    bufsize, 
 292: 		      size_t    offset,
 293: 		const wchar_t  *menu
 294: 	)
 295: {
 296: 	// パラメタの仮定
 297: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
 298: 	ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
 299: 
 300: 	if ( !menu )
 301: 		return DialogTemplate_AddWord(       buffer, bufsize, offset, 0 );
 302: 	else if ( IS_INTRESOURCE( menu ) )
 303: 		return DialogTemplate_SetResourceID( buffer, bufsize, offset, LOWORD( menu ) );
 304: 	else
 305: 		return DialogTemplate_AddString(     buffer, bufsize, offset, menu );
 306: }//DialogTemplate_AddDialogMenu
 307: 
 308: //*********************************************************
 309: // DialogTemplate_AddDialogClassName()
 310: //   ダイアログテンプレート に クラス名 を指定する。
 311: //   buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
 312: //   buffer が指定されていれば実際に出力した ワード数 を返す。
 313: //
 314: // WORD *buffer
 315: //
 316: // size_t offset
 317: //   クラス名 の 書込位置
 318: //
 319: // const wchar_t *classname
 320: //   書き込む クラス名
 321: //
 322: //*********************************************************
 323: static
 324: size_t // 追加した ワード数 を返す
 325: DialogTemplate_AddDialogClassName
 326: 	(
 327: 		      WORD     *buffer,
 328: 			  size_t    bufsize,
 329: 		      size_t    offset, 
 330: 		const wchar_t  *classname
 331: 	)
 332: {
 333: 	// パラメタの仮定
 334: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
 335: 	ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
 336: 	
 337: 	if ( !classname )
 338: 		return DialogTemplate_AddWord(       buffer, bufsize, offset, 0 );
 339: 	else if ( IS_INTRESOURCE( classname ) )
 340: 		return DialogTemplate_SetResourceID( buffer, bufsize, offset, LOWORD( classname ) );
 341: 	else
 342: 		return DialogTemplate_AddString(     buffer, bufsize, offset, classname );
 343: }//DialogTemplate_AddDialogClassName
 344: 
 345: //*********************************************************
 346: // DialogTemplate_AddDialogCaption()
 347: //   ダイアログテンプレートに タイトル を追加する。
 348: //   buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
 349: //   buffer が指定されていれば実際に出力した ワード数 を返す。
 350: //
 351: // WORD *buffer
 352: //
 353: // int offset
 354: //   タイトル文字列 の 書込位置
 355: //
 356: // const wchar_t *caption
 357: //   書き込む タイトル文字列
 358: //
 359: //*********************************************************
 360: static
 361: size_t // 追加した ワード数 を返す
 362: DialogTemplate_AddDialogCaption
 363: 	(
 364: 		      WORD     *buffer,
 365: 			  size_t    bufsize, 
 366: 		      size_t    offset,
 367: 		const wchar_t  *caption
 368: 	)
 369: {
 370: 	// パラメタの仮定
 371: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
 372: 	ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
 373: 
 374: 	return DialogTemplate_AddString( buffer, bufsize, offset, (!caption ? L"" : caption) );
 375: }//DialogTemplate_AddDialogCaption
 376: 
 377: //*********************************************************
 378: // DialogTemplate_AddDialogFontHeight()
 379: //   ダイアログテンプレートに フォントの高さ を追加する。
 380: //   buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
 381: //   buffer が指定されていれば実際に出力した ワード数 を返す。
 382: //
 383: // WORD *buffer
 384: //
 385: // int offset
 386: //   高さ の 書込位置
 387: //
 388: // const DLGTEMPLATE_t *src
 389: //
 390: //*********************************************************
 391: static
 392: size_t // 追加した ワード数 を返す
 393: DialogTemplate_AddDialogFontHeight
 394: 	(
 395: 		      WORD            *buffer,
 396: 			  size_t           bufsize, 
 397: 		      size_t           offset,
 398: 		const DLGTEMPLATEHEAD *src
 399: 	)
 400: {
 401: 	// パラメタの仮定
 402: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
 403: 	ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
 404: 	ASSERT( IsValidReadPtr( src, sizeof( *src ) ) );
 405: 
 406: 	if ( !src->font )
 407: 		return 0;
 408: 
 409: 	return DialogTemplate_AddWord( buffer, bufsize, offset, src->height );
 410: }//DialogTemplate_AddDialogFontHeight
 411: 
 412: //*********************************************************
 413: // DialogTemplate_AddDialogFontName()
 414: //   ダイアログテンプレートに フォント名 を追加する。
 415: //   buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
 416: //   buffer が指定されていれば実際に出力した ワード数 を返す。
 417: //
 418: // WORD *buffer
 419: //
 420: // int offset
 421: //   フォント名 の 書込位置
 422: //
 423: // const DLGTEMPLATE_t *src
 424: //
 425: //*********************************************************
 426: static
 427: size_t // 追加した ワード数 を返す
 428: DialogTemplate_AddDialogFontName
 429: 	(
 430: 		      WORD            *buffer,
 431: 			  size_t           bufsize, 
 432: 		      size_t           offset,
 433: 		const DLGTEMPLATEHEAD *src
 434: 	)
 435: {
 436: 	// パラメタの仮定
 437: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
 438: 	ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
 439: 	ASSERT( IsValidReadPtr( src, sizeof( *src ) ) );
 440: 
 441: 	if ( !src->font )
 442: 		return 0;
 443: 
 444: 	return DialogTemplate_AddString( buffer, bufsize, offset, src->font );
 445: }//DialogTemplate_AddDialogFontName
 446: 
 447: 
 448: //******************************************************************************************************************
 449: //
 450: //******************************************************************************************************************
 451: static size_t DialogTemplate_AddControlClassName( WORD *ptr, size_t bufsize, size_t offset, const wchar_t *classname );
 452: static size_t DialogTemplate_AddControlText(      WORD *ptr, size_t bufsize, size_t offset, const wchar_t *text );
 453: 
 454: 
 455: //*********************************************************
 456: // DialogTemplate_AddControl()
 457: //   ダイアログテンプレートに コントロール を追加する。
 458: //   buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
 459: //   buffer が指定されていれば実際に出力した ワード数 を返す。
 460: //
 461: // WORD *buffer
 462: //
 463: // int offset
 464: //   コントロール の 書込位置
 465: //
 466: // const DLGITEMTEMPLATE_t *src
 467: //   書き込む コントロール の情報を記述した構造体
 468: //
 469: //*********************************************************
 470: static
 471: size_t // 追加した ワード数 を返す
 472: DialogTemplate_AddControl
 473: 	(
 474: 		      WORD                *buffer,
 475: 			  size_t               bufsize,
 476: 		      size_t               offset, 
 477: 		const DLGTEMPLATEITEMDATA *src
 478: 	)
 479: {
 480: 	// パラメタの仮定
 481: 	ASSERT( IsValidDialogTemplateItemData( src ) );
 482: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
 483: 	ASSERT( (0 == (offset & 0x01)) || ( buffer && !IS_ENOUGH_SIZE(offset, 1, bufsize) ) );
 484: 
 485: 	//
 486: 	size_t count = 0;
 487: 
 488: 	// ヘッダの設定
 489: 	if ( buffer && IS_ENOUGH_SIZE(offset, sizeof( DLGITEMTEMPLATE ), bufsize) )
 490: 	{
 491: 		WORD *ptr = (buffer ? buffer + offset : null);
 492: 		MakeDialogItemTemplate
 493: 			(
 494: 				reinterpret_cast<DLGITEMTEMPLATE *>( ptr ),
 495: 				src->id, 
 496: 				src->dwExtendedStyle,
 497: 				src->style | WS_CHILD,
 498: 				src->x,
 499: 				src->y, 
 500: 				src->cx,
 501: 				src->cy
 502: 			);
 503: 	}
 504: 
 505: 	//
 506: 	if ( !buffer || IS_ENOUGH_SIZE(offset, sizeof( DLGITEMTEMPLATE ), bufsize) )
 507: 	{
 508: 		COMPILE_ASSERT( 0 == (sizeof( DLGITEMTEMPLATE ) % sizeof( *buffer )) );
 509: 		count += sizeof( DLGITEMTEMPLATE ) / sizeof( *buffer );
 510: 	}
 511: 
 512: 	// 挿入される順番は意味を持つ
 513: 	count += DialogTemplate_AddControlClassName( buffer, bufsize, offset + count, src->classname ); // クラス名 の設定
 514: 	count += DialogTemplate_AddControlText(      buffer, bufsize, offset + count, src->text      ); // テキスト の設定
 515: 	count += DialogTemplate_AddWord(             buffer, bufsize, offset + count, 0 );              // 未使用のパラメタ
 516: 
 517: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset + count, 0, bufsize) );
 518: 	return count;
 519: }//DialogTemplate_AddControl
 520: 
 521: //*********************************************************
 522: // DialogTemplate_AddControlClassName()
 523: //   ダイアログテンプレートに コントロールのクラス名 を追加する。
 524: //   buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
 525: //   buffer が指定されていれば実際に出力した ワード数 を返す。
 526: //
 527: // WORD *buffer
 528: //
 529: // int offset
 530: //   クラス名 の 書込位置
 531: //
 532: // const wchar_t *classname
 533: //   書き込む クラス名
 534: //
 535: //*********************************************************
 536: static
 537: size_t // 追加した ワード数 を返す
 538: DialogTemplate_AddControlClassName
 539: 	(
 540: 		      WORD     *buffer,
 541: 			  size_t    bufsize, 
 542: 		      size_t    offset,
 543: 		const wchar_t  *classname
 544: 	)
 545: {
 546: 	// パラメタの仮定
 547: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
 548: 	ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
 549: 
 550: 	if ( IS_INTRESOURCE( classname ) )
 551: 		return DialogTemplate_SetResourceID( buffer, bufsize, offset, LOWORD( classname ) );
 552: 
 553: 	return DialogTemplate_AddString(         buffer, bufsize, offset, classname );
 554: }//DialogTemplate_AddControlClassName
 555: 
 556: //*********************************************************
 557: // DialogTemplate_AddControlText()
 558: //   ダイアログテンプレートに コントロール・テキスト を追加する。
 559: //   buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
 560: //   buffer が指定されていれば実際に出力した ワード数 を返す。
 561: //
 562: // WORD *buffer
 563: //
 564: // int offset
 565: //   テキスト の 書込位置
 566: //
 567: // const wchar_t *text
 568: //   書き込む テキスト
 569: //
 570: //*********************************************************
 571: static
 572: size_t // 追加した ワード数 を返す
 573: DialogTemplate_AddControlText
 574: 	(
 575: 		      WORD     *buffer,
 576: 			  size_t    bufsize, 
 577: 		      size_t    offset,
 578: 		const wchar_t  *text
 579: 	)
 580: {
 581: 	// パラメタの仮定
 582: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
 583: 	ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
 584: 
 585: 	if ( !text )
 586: 		return DialogTemplate_AddString(     buffer, bufsize, offset, L"" );
 587: 	else if ( IS_INTRESOURCE( text ) )
 588: 		return DialogTemplate_SetResourceID( buffer, bufsize, offset, LOWORD( text ) );
 589: 	else
 590: 		return DialogTemplate_AddString(     buffer, bufsize, offset, text );
 591: }//DialogTemplate_AddControlText
 592: 
 593: 
 594: //******************************************************************************************************************
 595: //
 596: //******************************************************************************************************************
 597: //*********************************************************
 598: // DialogTemplate_AddString()
 599: //   ダイアログテンプレートに 文字列 を追加する。
 600: //   buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
 601: //   buffer が指定されていれば実際に出力した ワード数 を返す。
 602: //   出力したワード数 には文字列終端文字 '\0' を含む。
 603: //
 604: // WORD *buffer
 605: //
 606: // int offset
 607: //   文字列 の 書込位置
 608: //
 609: // LPCWSTR string
 610: //   書き込む 文字列
 611: //
 612: //*********************************************************
 613: static
 614: size_t // 追加した ワード数 を返す
 615: DialogTemplate_AddString
 616: 	(
 617: 		WORD    *buffer,
 618: 		size_t   bufsize, 
 619: 		size_t   offset,
 620: 		LPCWSTR  string
 621: 	)
 622: {
 623: 	// パラメタの仮定
 624: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
 625: 	ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
 626: 	ASSERT( string ); // 少なくとも null ではない
 627: 
 628: 	// 関数 wcslen() の 返値 count は 文字数 です。
 629: 	const size_t count = wcslen( string );
 630: 	if ( buffer && IS_ENOUGH_SIZE(offset + count + 1, 0, bufsize) )
 631: 	{
 632: 		//
 633: 		// 型 wchar_t が ビルトイン型 となったため 型 wchar_t への キャスト が必要になった。
 634: 		//
 635: 		COMPILE_ASSERT( sizeof(WORD *) == sizeof(wchar_t *) );
 636: 		COMPILE_ASSERT( sizeof(WORD) == sizeof(wchar_t) );
 637: 		wcsncpy( (wchar_t *)buffer + offset, string, 1 + count );
 638: 		buffer[ offset + count ] = '\0';
 639: 	}
 640: 
 641: 	// 1 + count
 642: 	return (!buffer || IS_ENOUGH_SIZE(offset + count + 1, 0, bufsize)) ?  (1 + count)  :  0  ;
 643: }//DialogTemplate_AddString
 644: 
 645: //*********************************************************
 646: // DialogTemplate_SetResourceID()
 647: //   ダイアログテンプレートに アトム値 を追加する。
 648: //   buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
 649: //   buffer が指定されていれば実際に出力した ワード数 を返す。
 650: //
 651: // WORD *buffer
 652: //
 653: // int offset
 654: //   アトム値 の書込位置
 655: //
 656: // WORD wID
 657: //   書き込む アトム値
 658: //
 659: //*********************************************************
 660: static
 661: size_t // 追加した ワード数 を返す
 662: DialogTemplate_SetResourceID
 663: 	(
 664: 		WORD   *buffer,
 665: 		size_t  bufsize, 
 666: 		size_t  offset,
 667: 		WORD    wID
 668: 	)
 669: {
 670: 	// パラメタの仮定
 671: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
 672: 	ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
 673: 
 674: 	size_t count = 0;
 675: 	count += DialogTemplate_AddWord( buffer, bufsize, offset + count, 0xFFFF );
 676: 	count += DialogTemplate_AddWord( buffer, bufsize, offset + count, wID );
 677: 	
 678: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset + count, 0, bufsize) );
 679: 	return count;
 680: }//DialogTemplate_SetResourceID
 681: 
 682: //*********************************************************
 683: // DialogTemplate_AddWord()
 684: //   ダイアログテンプレートに ワード値 を追加する。
 685: //   buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
 686: //   buffer が指定されていれば実際に出力した ワード数 を返す。
 687: //
 688: // WORD *buffer
 689: //
 690: // int offset
 691: //   アトム値 の書込位置
 692: //
 693: // WORD w
 694: //   書き込む ワード値
 695: //
 696: //*********************************************************
 697: static
 698: size_t // 追加した ワード数 を返す
 699: DialogTemplate_AddWord
 700: 	(
 701: 		WORD   *buffer,
 702: 		size_t  bufsize, 
 703: 		size_t  offset,
 704: 		WORD    w
 705: 	)
 706: {
 707: 	// パラメタの仮定
 708: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
 709: 	ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
 710: 
 711: 	if ( buffer && IS_ENOUGH_SIZE(offset, sizeof( w ), bufsize) )
 712: 	{
 713: 		buffer[ offset ] = w;
 714: 	}
 715: 
 716: 	return (!buffer || IS_ENOUGH_SIZE(offset, sizeof( w ), bufsize)) ?  1  :  0  ;
 717: }//DialogTemplate_AddWord
 718: 
 719: //*********************************************************
 720: // DialogTemplate_DoubleWordAlign()
 721: //*********************************************************
 722: static
 723: size_t
 724: DialogTemplate_DoubleWordAlign
 725: 	(
 726: 		WORD   *buffer,
 727: 		size_t  bufsize, 
 728: 		size_t  offset
 729: 	)
 730: {
 731: 	// パラメタの仮定
 732: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
 733: 	ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
 734: 
 735: 	size_t count = 0;
 736: 	if ( 0 != (offset & 0x01) )
 737: 	{
 738: 		count += DialogTemplate_AddWord( buffer, bufsize, offset + count, 0 );
 739: 	}
 740: 	
 741: 	ASSERT( !buffer || IS_ENOUGH_SIZE(offset + count, 0, bufsize) );
 742: 	ASSERT( (0 == ((offset + count) & 0x01)) || ( buffer && !IS_ENOUGH_SIZE(offset + count, 1, bufsize) ) );
 743: 	return count;
 744: }//DialogTemplate_DoubleWordAlign
 745: 
 746: 
 747: //******************************************************************************************************************
 748: // TEST
 749: //******************************************************************************************************************
 750: 
 751: 
 752: #ifdef _DEBUG // デバッグ時のみ
 753: 
 754: 
 755: //*********************************************************
 756: // 
 757: //*********************************************************
 758: DEFINE_TESTPROC( test_dyndlg )
 759: {
 760: #define IDC_STATICICON    ( 100 )
 761: #define IDC_APPNAME       ( 101 )
 762: #define IDC_HOMEPAGE      ( 102 )
 763: #define IDC_SYSRESOURCE   ( 103 )
 764: 	const DLGTEMPLATEITEMDATA items[] = 
 765: 		{
 766: 			{ CTLCLS_STATIC, L"", WS_VISIBLE | WS_CHILD | SS_ICON, 0, 7, 7, 20, 21, IDC_STATICICON },
 767: 			{ CTLCLS_STATIC, L"", WS_VISIBLE | WS_CHILD | SS_LEFT, 0, 30, 7, 1, 8,  IDC_APPNAME },
 768: 			{ CTLCLS_STATIC, L"", WS_VISIBLE | WS_CHILD | SS_LEFT, 0, 30, 16, 1, 8, IDC_HOMEPAGE },
 769: 			{ CTLCLS_STATIC, L"", WS_VISIBLE | WS_CHILD | SS_LEFT, 0, 30, 25, 1, 8, IDC_SYSRESOURCE },
 770: 			{ CTLCLS_BUTTON, L"OK", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | WS_GROUP, 0, 45, 35, 45, 14, IDOK },
 771: 		};
 772: #undef IDC_STATICICON
 773: #undef IDC_APPNAME
 774: #undef IDC_HOMEPAGE
 775: #undef IDC_SYSRESOURCE
 776: 
 777: 	//
 778: 	DLGTEMPLATEHEAD dlg;
 779: 	dlg.style           = DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU;
 780: 	dlg.dwExtendedStyle = 0;
 781: 	dlg.cdit            = numof( items );
 782: 	dlg.x               = 0;
 783: 	dlg.y               = 0;
 784: 	dlg.cx              = 38,
 785: 	dlg.cy              = 56;
 786: 	dlg.classname       = null;
 787: 	dlg.caption         = L"";
 788: 	dlg.menu            = null;
 789: 	dlg.font            = L"MS Pゴシック";
 790: 	dlg.height          = 9;
 791: 
 792: 
 793: 	//---------------------------------------------------------
 794: 	// 定数 の テスト
 795: 	//---------------------------------------------------------
 796: 
 797: 
 798: 	//---------------------------------------------------------
 799: 	// ファイルスコープ関数 の テスト
 800: 	//---------------------------------------------------------
 801: 
 802: 	//
 803: 	{
 804: 		const size_t size = ConstructDialogTemplate( null, 0, &dlg, items );
 805: 		WORD *templ = (WORD *)malloc( size );
 806: 		if ( templ )
 807: 		{
 808: 			VERIFY( size == ConstructDialogTemplate( templ, size, &dlg, items ) );
 809: 			free( templ );
 810: 		}
 811: 	}
 812: 
 813: 	//
 814: 	{
 815: 		const size_t size = ConstructDialogTemplate( null, 0, &dlg, items );
 816: 		WORD *templ = (WORD *)malloc( 10 + size );
 817: 		if ( templ )
 818: 		{
 819: 			VERIFY( size == ConstructDialogTemplate( templ, 10 + size, &dlg, items ) );
 820: 			free( templ );
 821: 		}
 822: 	}
 823: 
 824: 	//
 825: 	{
 826: 		WORD templ[ 1 ];
 827: 		VERIFY( sizeof(templ) >= ConstructDialogTemplate( templ, sizeof(templ), &dlg, items ) );
 828: 	}
 829: 
 830: 
 831: 	//---------------------------------------------------------
 832: 	// 公開関数 の テスト
 833: 	//---------------------------------------------------------
 834: 	{
 835: 		DLGTEMPLATE *templ = CreateDialogTemplate( &dlg, items );
 836: 		if ( templ )
 837: 		{
 838: 			VERIFY( DestroyDialogTemplate( templ ) );
 839: 		}
 840: 	}
 841: 
 842: }//
 843: 
 844: 
 845: #endif // #ifdef _DEBUG
 846: 
 847: 
 848: //** end **

参照:


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

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

水無瀬の部屋 > sample > tools > dlg > dyndlg.cpp

このページは cpp2web が出力しました。
水無瀬 優 postmaster@katsura-kotonoha.sakura.ne.jp
http://katsura-kotonoha.sakura.ne.jp/prog/code/tools/dlg/dyndlg_cpp.shtml
『新妻LOVELY×CATION』を応援しています!