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

自動プリント用のプリンタ設定の保存

プリンタIDは、特定のプリントキューを指定する一意の内部表現です。ユーザは、同じユーザ表示名の複数のプリントキューを作成できますが、各キューのプリンタIDは一意になります。特定のプリントキュー、そしてひいては特定のプリンタを確実に参照するには、常にプリンタIDを使用する必要があります。PMPrinterデータタイプは、この2つの概念を巧妙に1つのパッケージにまとめます。このテクニカルノートでは、ユーザが選択したプリンタを保存しておけるように、PMPrinterを保存し、復元する方法を説明します。

通常、プリントするのにプリンタIDを知っている必要はありません。しかし、一部の限定的な状況においては、選択されたプリンタを保存しておき、必要なときに自動的にそのプリンタを使用することが理に適う場合があります(たとえば、販売情報管理(POS)アプリケーションのレシートをプリントするなど)。環境設定にはPMPrinterを保存できないので、プリンタIDが、必要な永続的参照を提供します。つまり、プリンタIDを使用することで、そのプリントキューが存続する限り有効なプリントキューへの参照を保存できます。





プリント情報を収集する

アプリケーションについて想定されるワークフローに応じて、プリントに使用する元のPMPrinterを取得するための方法はいくつかあります。

1つの方法としては、利用可能なプリンタのリストを取得し、ユーザにプリンタを1つ選ばせる方法があります。この方法は、アプリケーションの利用者がプリントオプションにあまり関心がなく、プリントすることだけが目的の場合に適しています。「利用可能なプリンタから選択する」でこの方法を説明します。

2つめの方法は、標準の「プリント設定」ダイアログボックスおよび「ページ設定」ダイアログボックスを使用して、ユーザにプリンタおよびプリント設定を選択させる方法です。この方法では、ユーザがプリンタを選択できる上に、ほかのオプション(たとえば、用紙サイズやレイアウトなど)も設定できます。この場合、プリンタの選択に加えてすべてのプリント設定も保存する必要があるかもしれません。「「プリント設定」ダイアログと「ページ設定」ダイアログからプリント設定を取得する」でこの方法を説明します。

どちらの場合も、肝心なのは環境設定のプリンタ選択を保存し、復元することです。これは「プリント設定の保存と読み込み」で説明します。

利用可能なプリンタから選択する

利用可能なプリンタのリストは、PMServerCreatePrinterListを呼び出して取得できます。この呼び出しからは、検出できたすべてプリンタをすべて含むPMPrintersのCFArrayが返されます。リスト1に、PMPrintersのCFArrayをプリンタ名のCFArrayに変換して、ユーザに表示する方法を示します。

注:PMServerCreatePrinterListから返されるリストは、「プリントとファックス」環境設定パネルを使ってプリンタを追加した際に取得できるリストほどには完全でない可能性があります。ただし、ユーザが(手動または自動で)すでに設定したプリンタは、常にこのリストに表示されます。

リスト1:利用可能なプリンタのリストの取得

OSStatus CreatePMPrintersAndPrinterNames( CFArrayRef *outPrinters, CFArrayRef *outPrinterNames )
{
  *outPrinters = NULL;
  *outPrinterNames = NULL;
  // PMPrintersのリストを取得
  OSStatus err = PMServerCreatePrinterList( kPMServerLocal, outPrinters );
  if( err == noErr )
  {
    CFIndex i, count = CFArrayGetCount( printers );
    // プリンタ名を保持するために別の配列を作成する。この配列を使用して、ユーザにプリンタを選択させる
    // メニューまたはリストを作成できる。
    CFMutableArrayRef printerNames = CFArrayCreateMutable( NULL, count, kCFTypeArrayCallBacks );
    if( printerNames )
    {
      for(i = 0; i < count; ++i)
      {
        PMPrinter printer = (PMPrinter)CFArrayGetValueAtIndex( printers, i );
        CFStringRef name = PMPrinterGetName( printer );
        CFArrayAppendValue( printerNames, name );
      }
    }
    *outPrinterNames = printerNames;
  }
  return err;
}

先頭に戻る

「プリント設定」ダイアログと「ページ設定」ダイアログからプリント設定を取得する

標準の「プリント」ダイアログを使用してユーザがプリンタおよびプリント設定を選択できるようにすればさらに柔軟性が増します。そうすることで、ユーザは、プリントジョブのすべてのプリント設定をカスタマイズすることが可能になり、以降のプリントジョブのテンプレートとしてそれらの設定を保存できるようになります。ユーザが最初にプリントした後、そのプリント設定を保存し、後でその設定を使用することができます。リスト2に、「プリント」ダイアログを表示し、後で再利用できるようにプリンタおよびプリント設定を取得する方法を示します。

リスト2:「プリント」ダイアログのプリンタ情報を保存する

OSStatus CreatePageFormat( PMPageFormat * outFormat )
{
  PMPrintSession printSession;
  OSStatus err;
  Boolean accepted;

  // ページのフォーマットを作成するために、
  // ユーザに「ページ設定」を使用してページフォーマットを設定させる。
  *outFormat = NULL;

  err = PMCreateSession( &printSession );
  if( !err )
  {
    // セッションを作成できたので、ページフォーマットを作成しデフォルトに設定する。
    err = PMCreatePageFormat( outFormat );
    if( !err )
      err = PMSessionDefaultPageFormat( printSession, *outFormat );

    // 「ページ設定」ダイアログを表示する。ユーザが取り消すか、
    // エラーが発生した場合、作成したページフォーマットを破棄し、
    // NULLフォーマット、およびPMSessionPageSetupDialogから返された
    // 任意のエラーを返す。
    err = PMSessionPageSetupDialog( printSession, *outFormat, &accepted );
    if( err || !accepted )
    {
      PMRelease( *outFormat );
      *outFormat = NULL;
    }

    PMRelease( printSession );
  }
  return err;
}

OSStatus CreatePrintSettings( PMPageFormat ioFormat, PMPrinter * outPrinter, PMPrintSettings * outSettings)
{
  PMPrintSession printSession;
  OSStatus err;
  Boolean accepted = false;

  *outPrinter = NULL;
  *outSettings = NULL;

  // 「プリント設定」とプリンタの選択を作成するために、ユーザに
  // 「プリント」ダイアログを使用して、それらの設定を作成させる。
  err = PMCreateSession( &printSession );
  if( !err )
  {
    // 現在のプリンタに照らして「ページフォーマット」を検証する。これによって
    // フォーマットが更新される場合もある。
    err = PMSessionValidatePageFormat( printSession, ioFormat, kPMDontWantBoolean );

    // プリント設定を作成し、デフォルトに設定する。
    if( !err )
      err = PMCreatePrintSettings( outSettings );
    if( !err )
      err = PMSessionDefaultPrintSettings( printSession, *outSettings );

    // 「プリント」ダイアログを表示する。
    if( !err )
      err = PMSessionPrintDialog( printSession, *outSettings, ioFormat, &accepted );
    if( !err && accepted )
    {
      // ユーザが受け入れた場合、選択したプリンタを保持し、
      // このセッション以降も存続するようにする。
      // プリンタ取得時にエラーが発生した場合、
      // NULLのままとなる
      err = PMSessionGetCurrentPrinter( printSession, outPrinter );
      if( !err )
        PMRetain( *outPrinter );
    }
    else
    {
      // エラーが発生したか、ユーザによって操作が取り消された。
      // そのため、設定を破棄しNULLにする。
      // PMPrinterはまだ設定されていないため、NULLのままとなる。
      PMRelease( *outSettings );
      *outSettings = NULL;
    }

    PMRelease( printSession );
  }
  return err;
}

先頭に戻る

プリント設定の保存と読み込み

ユーザが以前に選択したプリンタへの参照を保存するもっとも簡単な方法は、CFPreferencesを使用することです。プリンタIDは、CFStringとして返され、フラット化されたすべてのプリンタデータはCFDataRefとして返されます。どちらもCFPreferencesを使用して簡単に保存しておけます。リスト3に、これらの設定を環境設定に保存する方法を示します。またリスト4に、環境設定からプリンタおよびプリント設定を復元する方法を示します。

警告:ユーザは実行時に、プリンタの構成を容易に変更できるので、コードにおいては、使用しているプリンタが存在しなくなるような状況に備えておく必要があります。そのような場合、コードのなかでユーザに新しいプリンタを選択させるようにします。「プリンタIDを検証する」に有効性を確認する方法の1つを示します。

リスト3:環境設定にプリント設定を保存する

OSStatus SavePrintSettings( PMPrintSession inSession, PMPrintSettings inSettings, PMPageFormat inFormat )
{
  CFStringRef printerID;
  PMPrinter printer;
  CFDataRef flatSettings, flatFormat;
  OSStatus err, tempErr;

  // 処理を始める前に、プリントセッションから現在のプリンタを取得する必要がある。
  // プリンタの取得でエラーが発生した場合、単純にそのエラーを返し、ほかには何もしない。
  err = PMSessionGetCurrentPrinter( inSession, &printer );
  if( err == noErr )
  {
    // PMSessionGetCurrentPrinterが正常に戻ってきた場合、セッションが有効である限りプリンタは有効である。
    // したがって、プリンタ名も有効であると想定する。
    printerID = PMPrinterGetID( printer );
    CFPreferencesSetAppValue( kPrinterID, printerID, kCFPreferencesCurrentApplication );
    CFRelease( printerID );

    tempErr = PMFlattenPrintSettingsToCFData( inSettings, &flatSettings );
    if( tempErr == noErr )
    {
      // プリント設定をフラット化できる場合、環境設定に保存する
      CFPreferencesSetAppValue( kPrintSettings, flatSettings, kCFPreferencesCurrentApplication );
      CFRelease( flatSettings );
    }
    else
    {
      // プリント設定をフラット化できない場合、環境設定から削除する
      CFPreferencesSetAppValue( kPrintSettings, NULL, kCFPreferencesCurrentApplication );
    }

    tempErr = PMFlattenPageFormatToCFData( inFormat, &flatFormat );
    if( tempErr == noErr )
    {
      // ページフォーマットをフラット化できる場合、環境設定に保存する
      // フラット化できない場合、別のプリンタにページフォーマットを再利用できる
      CFPreferencesSetAppValue( kPageFormat, flatFormat, kCFPreferencesCurrentApplication );
      CFRelease( flatFormat );
    }
  }

  return err;
}

リスト4:環境設定からプリント設定を復元する

void CopyPrintSettings( CFStringRef * outPrinterID, PMPrintSettings * outSettings, PMPageFormat * outFormat )
{
  CFDataRef flatSettings, flatFormat;

  *outPrinterID = CFPreferencesCopyAppValue( kPrinterID, kCFPreferencesCurrentApplication );
  *outSettings = NULL;
  *outFormat = NULL;

  // CFPreferencesを通じてプリンタIDを読み込む
  if( *outPrinterID != NULL )
  {
    flatSettings = CFPreferencesCopyAppValue( kPrintSettings, kCFPreferencesCurrentApplication );
    flatFormat = CFPreferencesCopyAppValue( kPageFormat, kCFPreferencesCurrentApplication );

    // フラット化解除のエラーが発生した場合、対応する設定はNULLになり、設定が
    // なかったことを示すので、フラット化解除エラーは無視する。
    if( flatSettings != NULL )
    {
      PMUnflattenPrintSettings( flatSettings, outSettings );
      CFRelease( flatSettings );
    }

    if( flatFormat != NULL )
    {
      PMUnflattenPageFormatWithCFData( flatFormat, outFormat );
      CFRelease( flatFormat );
    }
  }
}

先頭に戻る

プリンタIDを検証する

ユーザは、アプリケーションの実行中を含め、いつでもプリント設定を再構成できるため、シームレスな動作をさせるためには、プリント操作を行う前に、利用するプリンタを必ず確認する必要があります。これを実現するには、プリンタIDからPMPrinterを再作成する必要があります。標準の「プリント」ダイアログボックスおよびデフォルト設定では、自動的に正しいプリンタが選択されるため、一般的な状況ではこれは不要です。

リスト5:プリンタIDの有効性を確認する

// この関数は、プリンタを検証する方法の1つを示す。
// これよりも賢明な方法としては、プリンタの作成を試み、
// 成功した場合はそのプリンタを使用し、失敗した
// 場合は、ユーザに設定を更新させる。
Boolean IsValidPrinter( CFStringRef inPrinterID )
{
  PMPrinter printer = PMPrinterCreateFromPrinterID( inPrinterID );
  Boolean valid = printer != NULL;
  // エラーが返されるだけなので、PMReleaseにNULLを渡しても問題ない。
  // NULLでないプリンタを確実に解放することだけが目的であるため、
  // エラーを無視して問題ない。
  PMRelease( printer );
  return valid;
}

先頭に戻る

ドキュメント改訂履歴

日付メモ
2007-03-29初版

掲載日: 2007-03-29




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.