高度な検索
Developer Connection
Member Login ログイン | ご入会 ADC連絡先

Technical Q&A QA1380
Clickable Static Text Item

Q: ヒューマンインタフェースガイドラインに従っていないことは分かっていますが、どうしてもクリック可能な静的テキスト項目が必要です。このため静的テキスト項目を有効にしているのですが、そのコマンドを受け取れません。何が起きているのでしょうか。

A: まず、クリック可能な静的テキスト項目は、適切なヒューマンインタフェースではありません。項目の外見上に、ユーザがそれをクリックしたときの動作やアクションを予想できるものが何もないためです。しかし、それはそれとして...。

静的テキスト項目に kEventControlClick ハンドラをインストールすると、項目内での mouseDown イベントをこのハンドラが受け取ります。このアプローチに関する問題は、それが許容されているものではなく、ヒューマンインタフェースガイドラインのさらに多くのルールに違反することです。ユーザは、項目をクリックした時点からマウスボタンを放すまでの間に気が変わることもあります。Mac OS のルックアンドフィールは、mouseDown ではなく mouseUp を基準としています。ユーザの操作を追跡する通常の動作のあとに、ヒットが成功したと認識されます。

実際の問題は、静的テキストコントロールがヒューマンインタフェースガイドラインに忠実に従って、hitTest メッセージが当該項目に送られると必ず kControlNoPart を返すことから生じます。そのため、追跡プロセスが開始されず、ヒットが成功しないため、その項目に設定したコマンド ID を受け取ることができません。

この問題の洗練された解決方法は、単に kEventControlHitTest イベントに新しいハンドラを与えることです。リスト 1 に示すようなコードになります。

リスト 1: hitTest ハンドラ

pascal OSStatus StaticTextHitTestHandler(
  EventHandlerCallRef nextHandler, EventRef inEvent, void* userData)
  {
OSStatus status = noErr;
  ControlRef theControl;
  HIPoint hiPoint;
  HIRect hiBounds;
  Boolean inBouns;
  ControlPartCode partCode;

  status = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef,
    NULL, sizeof(theControl), NULL, &theControl);
  require_noerr(status, ExitHitTest);

  status = GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint,
    NULL, sizeof(hiPoint), NULL, &hiPoint);
  require_noerr(status, ExitHitTest);

  status = HIViewGetBounds(theControl, &hiBounds);
  require_noerr(status, ExitHitTest);

  inBounds = (CGRectContainsPoint(hiBounds, hiPoint) == 1);
  partCode = (inBounds)?kControlButtonPart:kControlNoPart;
  status = SetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode,
    sizeof(partCode), &partCode);
  require_noerr(status, ExitHitTest);
  
ExitHitTest:
return status;
  }

また、このハンドラはリスト 2 に示すコードでインストールします。

リスト 2: hitTest ハンドラのインストール

  EventTypeSpec eventType = {kEventClassControl, kEventControlHitTest};
  InstallControlEventHandler(staticTextItemControl,
    StaticTextHitTestHandler, 1, &eventType, NULL, NULL);

これを実行すると、コマンドプロセスハンドラでコマンド ID を正しく受け取り、静的テキスト項目はプッシュボタンのように機能します。ただし、追跡時に視覚的なフィードバックがないため、以前として、良いヒューマンインタフェースとはいえません。

ドキュメントの改訂履歴

日付メモ
2004-10-05初版

掲載日: 2004-10-05