[Cabi@net:workトップページ] [プログラミングの断片]
[メニューアイテムに色を付ける] [デフォルトボタンの枠] [バックグラウンドでも関数実行]


メニューアイテムに色を付けるには?


静的にメニューアイテムに色を付ける場合は 'mctb'リソースを使えばできますが、 ランタイムに行なう方法はあるのでしょうか?
ここではその方法をお教えします。


Macintoshの標準メニュー定義関数 ('MDEF') は メニューカラーインフォメーションテーブルレコードというのを使って メニューアイテムの色を管理しています。 これらは通常、'mctb'リソースの形でプログラマにより用意されます。

しかしながら、リソースによるだけでなく、 プログラム的にもカラーを使うことが可能です。 このことにより、例えばランタイム「カラー」メニュー を作ることなどが可能です。


ここにメニューアイテムに色を付けるサンプルコード (ヘッダ/ソース) を挙げます。
アーカイブファイルも 用意しました。
変更すればメニューバーやメニュータイトルに色を付けることも可能です。
注意:MacOS 8ではかなり変更になっています


//##
//##    File:       SetColorToMenu.h
//##
//##    Author:     Takenori Kabeya
//##
//##    Version:    1.1 - Dec/29/1996
//##
//##    E-mail:     GBH06222@niftyserve.or.jp
//##
//##    NOTE:
//##        You can use this code freely.
//##
//##        See 'Inside Macintosh:Macintosh Toobox Essentials', page 3-98
//##        for more details.
//##
//  SetColorToMenu.c

#pragma once

#ifndef __QUICKDRAW__
    #include    <Quickdraw.h>
#endif

#ifdef  __cplusplus
extern "C" {
#endif

//
//  Set color to menu.
//
//  Input:
//      inMenuID        The menu ID. Not a resource ID.
//      inMenuItem      The index of the menu item to set the color.
//      inColorP        The Color to set.
//      inIsAutoBoldOn  Since too lite color is invisible,
//                      We should do something.
//                      This routine has two methods.
//                      One is setting the menu item style to bold,
//                      The other is reset the color to black.
//                      If inIsAutoBoldOn is true, the former method
//                      will be applied.
//                      If false, the latter.
//
void
SetColorToMenu(
    SInt16          inMenuID,
    SInt16          inMenuItem,
    const RGBColor* inColorP,
    Boolean         inIsAutoBoldOn );

#ifdef  __cplusplus
}
#endif
[Back]
//##
//##    File:       SetColorToMenu.c
//##
//##    Author:     Takenori Kabeya
//##
//##    Version:    1.1 - Dec/29/1996
//##
//##    E-mail:     GBH06222@niftyserve.or.jp
//##
//##    NOTE:
//##        You can use this code freely.
//##
//##        See 'Inside Macintosh:Macintosh Toobox Essentials', page 3-98
//##        for more details.
//##
//  SetColorToMenu.h

#include    "SetColorToMenu.h"

#include    <Menus.h>



#define kAutoBoldStyle          ( bold + condense )
#define kLiteColorThreshold     0xC000



static Boolean
IsColorTooLite(
    const RGBColor* inColorP );



void
SetColorToMenu(
    SInt16          inMenuID,
    SInt16          inMenuItem,
    const RGBColor* inColorP,
    Boolean         inIsAutoBoldOn )
{
    RGBColor    theBlack = { 0x0000, 0x0000, 0x0000 };
    RGBColor    theWhite = { 0xFFFF, 0xFFFF, 0xFFFF };
    
    MCEntry theEntry[3];
    
    //  Entry for the menu title.
    theEntry[0].mctID   = inMenuID;
    theEntry[0].mctItem = 0;            //  means menu title.
    theEntry[0].mctRGB1 = theBlack;     //  means title color.
    theEntry[0].mctRGB2 = theBlack;     //  means bar color.
    theEntry[0].mctRGB3 = theBlack;     //  means default item color.
    theEntry[0].mctRGB4 = theWhite;     //  means background color of menu.
    
    //  Entry for the menu item.
    theEntry[1].mctID   = inMenuID;
    theEntry[1].mctItem = inMenuItem;
    theEntry[1].mctRGB1 = theBlack;     //  means mark color.
//  theEntry[1].mctRGB2 = *inColorP;    //  means item text color.
    theEntry[1].mctRGB3 = theBlack;     //  means shortcut color.
    theEntry[1].mctRGB4 = theWhite;     //  means background color of menu.
                                        //      this field is valid only when
                                        //      background color of menu in title
                                        //      entry or in menu bar entry is
                                        //      empty. Not everytime.
    
    if( inIsAutoBoldOn ) {
        if( IsColorTooLite( inColorP ) ) {  //  too lite color is invisible.
            SetItemStyle( GetMenuHandle( inMenuID ), inMenuItem, kAutoBoldStyle );
            
        }
        else {
            SetItemStyle( GetMenuHandle( inMenuID ), inMenuItem, normal );
        }
        theEntry[1].mctRGB2 = *inColorP;
    }
    else {
        if( IsColorTooLite( inColorP ) ) {
            theEntry[1].mctRGB2 = theBlack;
        }
        else {
            theEntry[1].mctRGB2 = *inColorP;
        }
    }
    
    //  Entry for the termination.
    theEntry[2].mctID = mctLastIDIndic;
    
    SetMCEntries( 3, theEntry );    //  3 means the number of entries.
}



static Boolean
IsColorTooLite(
    const RGBColor* inColorP )
{
    return( kLiteColorThreshold < inColorP->red   &&
            kLiteColorThreshold < inColorP->blue  &&
            kLiteColorThreshold < inColorP->green );
}

[Back]