ホームページ開発ツール>Xojo / Real Studio Trial and Error・CocoaのDeclareでファイルIOパネルを拡張する・プラグイン使わない

 Xojo / Real Studio Trial and Error

CocoaのDeclareでファイルIOパネルを拡張する・プラグイン使わない

目次
 はじめに

 以下は、Xojo Cocoaビルドについての話題です。

 前回はシートの利用にあたり、Blocksへの対応にプラグインを利用させて頂きましたが、これを使わない方法があるのか、調べてみました。

 なお検証には、Xojo 2016 Release 3を用いています。(Mac mini mid 2010 + macOS 10.13.6 High Sierra)


 経緯

 まずはXojoに関連するトピックから調べ始めたところ、以下がヒットしました。
(注:回答者はプラグインの作者の方です。なお、以下のトピックはDelegateメソッドに関するもので、今回のケースにそのままは適用できません。)

 参考サイト(1):Objective-C Blocks! ( invoking) - Xojo Forum

 これによると、Blocksはどうも構造体に関係しているようでした。
 ということで、改めてBlocksについて調べてみることにしました。すると、以下がヒットしました。

 参考サイト(2):Objective-CエンジニアのためのObjective-C Blocks入門 - terazzoの日記
 参考サイト(3):[Objective-C] Blocksがややこいのでまとめてみる

 これらサイトで学習させて頂いた結果、
 1. 最低限設定が必要な構造体メンバは、isaとFuncPtr
 2. isaには「__NSGlobalBlock__」を指定(外部の変数は参照していないため)
 3. FuncPtrには、Xojo側のメソッドをAddressOfで指定
でいけるかも、という感触を得ました。

 あと、気を付ける点としては、構造体を値渡しではなく、参照(ポインタ)渡しにすることです。
 ちなみに、構造体の参照渡しは通常の変数と同じく、byRefを使えばいい、ということでした。

 参考サイト(4):Structure

 これらの処理で、ひとまず動作することの確認ができました。


 Xojoでの実装
【ソースコードのコピー&ペーストについて】
ソースコード(グレー背景部分の全文)をコピーし、指定のウィンドウ/クラスにペーストすると、(新規作成して名前等を個別にコピー&ペーストしなくても)復元されます。
ただし、この方法は、メソッドでは問題ないようですが、イベント/アクション/プロパティでは不安定?なので、ペーストできない場合は、各項目のカッコ内を適用して下さい。
  1. 前回プロジェクトをベースとする
  2. AccessoryPanelのConstructorの「elseif type=3 or type=4 then 〜 else」間を、以下に差し替え
    // シート生成(Blocks構造体)
    Declare Sub beginSheetModalForWindow Lib "Cocoa" Selector "beginSheetModalForWindow:completionHandler:" (receiver As Ptr, win As Integer, byRef block As Block_layout)
    blk.isa_ = NSClassFromString("__NSGlobalBlock__")
    blk.invoke = AddressOf didEndSaveSheetCH
    beginSheetModalForWindow(panel, win.Handle, blk)
    
  3. AccessoryPanelのdidEndSaveSheetCHを、以下に置き替え(メソッド名は同一だが、引数が変わっているので注意)
    Private Shared Sub didEndSaveSheetCH(obj As Ptr, rcode As integer)
      // ボタンが押された後の処理(パラメータを抽出して、インスタンスに渡す)
      panelButtonClicked(rcode)
    End Sub
    
  4. 以下をAccessoryPanelにペースト(できなければ共有プロパティに、名前:blk、データ型:Block_layout、を追加)
    Private Shared Property blk as Block_layout
    
  5. 以下をAccessoryPanelの構造体(Structures)に追加
    Private Structure Block_layout
      isa_ As Ptr
      flags As Int32
      reserved As Int32
      invoke As Ptr
      descriptor As Ptr
    End Structure
    
    注)参考サイト(1)で示されているものを使わせて頂きました。
 実行してみたところ、ファイルオープン/保存のシートで、プラグインを使わずにオプション設定が機能することを確認しました。


 おわりに

 今回のケースは、外部変数/戻り値なし、引数で渡ってくる値をXojo側に流すだけ、というシンプルなものだったので、なんとかなったのかもしれません。
 また、コピー/解放用の関数は作っていないので、メモリーリーク等が発生するかもしれません。(外部変数を使わなければ大丈夫?)

 Blocks内部で外部変数を元になんらかの処理をしてreturnで結果を返す、といった処理はお手上げになるかもしれません。
 実用にあたっては、更なる検証が必要かと思われます。


 お世話になったサイト

 貴重な情報をご提供頂いている皆様に、お礼申し上げます。(以下、順不同)

 参考サイト(1):Objective-C Blocks! ( invoking) - Xojo Forum
 参考サイト(2):Objective-CエンジニアのためのObjective-C Blocks入門 - terazzoの日記
 参考サイト(3):[Objective-C] Blocksがややこいのでまとめてみる
 参考サイト(4):Structure


 更新履歴

 2018.07.20 新規作成


[Home]  [MacSoft]  [Donation]  [History]  [Privacy Policy]  [Affiliate Policy]