Useful codes!

To enjoy Smalltalk!


NewStructure

 STAで新しいStructureを追加するサンプルです。TG-INETのご協力によります。

 theDefinition := StructureDictionary new nsKeyName: #DTPBRec. #("Name Selector Offset"#(ioDTBuffer pointerAt: 32) #(ioDTReqCount longAt: 36) #(ioDTActCount byteAt: 45) #(ioFileCreator longWordStringAt: 52) #(ioFileType longWordStringAt: 56) ) do: [:e | theDefinition add: ( StructureElement new name: e@1; selector: e@2; offset: e@3; yourself ). ]. theNamespace := Macintosh. theTemplates := theNamespace at: #Structures ifAbsent: []. theTemplates == nil ifTrue: [ theTemplates := Dictionary new. theNamespace at: #Structures put: theTemplates. ]. theTemplates at:#DTPBRec put: theDefinition. 
Get info from Resource

 各ファイルのアイコンをシステムより得ます。実行する前に PixelMap/bitsPerPixel-.pipo を読み込んで下さい。

"install bitsPerPixel: aValue at first"| storageSize aType parBlock theErr aPixMap | storageSize:= 1024. aType := 3. parBlock := (DTPB fromVolume:(VolumeSpecifier systemVolume)) pointerAt: 32 put: (( String new: storageSize) convertStorageToPointer;storageValue); longAt: 36 put: storageSize; byteAt: 45 put: aType; longWordStringAt: 52 put: 'JEDT'; longWordStringAt: 56 put: 'APPL'. (theErr := <>) = 0 ifTrue:[ aPixMap := (PixelMap new) colorTable:(ColorTable standardColorForPixelDepth: 8); bitsPerPixel:8; bounds:((0@0) @ (32@32)); data: (String fromPointer: (parBlock pointerAt: 32)); draw. ]. 
Get info from Resource

 Resource情報を読み出す例です。下の例では、InternetConfigの作った初期設定ファイル からE-mail addressを読み出します。

fileSpecifier:= FileSpecifier getFile. dcb := fileSpecifier openAsResourceFile: #fsRdPerm. rsc := Resource from1Type: 'ICRP' named: 'Email'. email := String fromHandle: rsc detach. dcb close. ^email
Delete strange menu?

 SmalltalkAgentsでAPLを作成したとき、AppleMenuに他のModuleをLaunch するメニューが残ってしまいます。別に残っていても問題はないですが、 やっぱり消したいときに下の方法が使えます(もっとスマートな方法がある かもしれませんが)。なお、WorkbenchModuleにいるときには、MenuBarを初期化します。

launch 、 Directives Hidden 、 super launch."delete extra menu of Apple menu"3 timesRepeat:[(MenuBar appleMenu at:3) deleteFromMenu]. doQuit 、 Directives Hidden 、 super doQuit. Console ifNotNil:[ MenuBar ShuttingDown;StartingUp]. FileOutProjects

 バージョンアップ等でClassやHierachyの変更があった場合、ProjectをPIPO ではなくTEXTで書き出せたら便利だと思ったことはありませんか?ClassやMethod を書き出すことはできますが、なぜかProject単位ではできないんですよね。 Agentsはあっさりクラス構成を変えるのので、涙をのんだ方々も多いはず?です。
 次のコードをペーストして、Evaluateしてみてください。書き出せるのは ClassとMethodです。もしうまく行かない場合は、ClassのHierachyを確認して、 Class定義の部分のCodeを入れ替えて下さい。ただし、InitializerBlock等は 書き出していません。もし必要ならご連絡下さい。

 | projects names aName target fileOutClasses converted index myIndex subClass superClass |"choose projects"projects := SortedList sortBlock: [:a :b | (a@#ProjectName) < (b@#ProjectName)]. Library instancesDo: [:lib | (lib nsContainer and: [(lib nsContainer at: lib name ifAbsent: []) == lib and: [lib includesKey: #ProjectName]]) ifTrue:[ projects add: lib]. ]. names := {}. projects do:[:each| names add: each name]. (aName:= ListChooser prompt: 'choose' list: names) ifNil:[^nil]."sort classes"target := projects detect: [:p | (p name) = aName]. fileOutClasses := {}. Metaclass allInstancesDo: [:each| each library = target ifTrue:[ fileOutClasses add:each] ]."re_sort classes"converted := fileOutClasses copy. fileOutClasses do: [:each| ( index := converted findFirst:[:p| each subclasses includes:p]) ifNotNil:[ myIndex := converted indexOf:each. subClass := converted at:index. myIndex >= index ifTrue:[ converted at:myIndex put:subClass. converted at:index put:each. ] ]. (index := converted findFirst:[:p| p = each superclass]) ifNotNil: [ myIndex := converted indexOf:each. superClass := converted at:index. index >= myIndex ifTrue:[ converted at:myIndex put:superClass. converted at:index put:each. ] ]. ]."fileOut classes"specifier := FileSpecifier putFile: 'Save Project As:' defaultName: aName,'.st'. specifier isNil ifTrue: [^nil]. (dcb := specifier open) isNil ifTrue: [^nil]. specifier fileCreator: 'QKSA'; fileType: 'TEXT'; updateInformation. (stream := FileStream onDCB: dcb) notNil ifTrue: [ oldDefault := Cursor busy setDefault. stream isOpen ifTrue: [ stream truncate."first, fileOut definitions of classes"converted do: [:each | buffer := String new. buffer nextChunkPut: NewLine,each classDefinition. (description := each description) size ifNotNil: [ buffer nextChunkPut: $(,each nsPathString,') metaclass description: (', description storeString,$). ]. stream nextPutAll: buffer. ]."second, fileOut definitions of methods"converted do: [:each | buffer := String new. each methodsDo: [:method | method fileOutOn: buffer. ]. each soleInstance methodsDo: [:method | method fileOutOn: buffer. ]. stream nextPutAll: buffer. ]. stream flush; close. ]. oldDefault setDefault. ].
LaunchDocECLT from QKS

LaunchDocECLT
・update: Mon, 14 Oct 1996
・ftp://phoenix.qks.com/exchange/Examples/LaunchDocECLT.sea.hqx

 Agentsからドキュメントを起動させるECLTです。Finderでダブルクリックする とファイルが開くのと同じですね。これは非常に便利です!!なおQKSはデフォルト で開く他に、他のAPLで開くこともできるよう、拡張したとのことです。
以下はReadMeの(一部)翻訳です。

-------------------

 Installするには以下の手順に従って下さい。 1)ResEditを使って、LoadDocファイルとSTA(APL)を開いて下さい。そして   LoadDocの"ECLT"リソースをコピーし、STA側にペーストして下さい(もし   コンフリクトがある場合には、リソースに異なるIDを選んで下さい)。   そしてSTAをSAVEして下さい。 2)STAを起動し、ProjectWindowを開き、メニューから"Install External Code"  を選び、ダイアログからSmalltalk(つまり自分自身、このときにLoadDocを   選ばないこと)を選び、さらに"LoadDoc"を選んで下さい。 3)Save environmentして下さい。次回からLauchTheDocument methodが使えます。  なおスタンドアロンでも同様にResourceにコピー&ペーストするとつかえる そうです。  サンプルコードは以下です。appSpecにnilをいれるとDefaultApplication、つまり fileCreatorが立ち上がります。ダイアログでは"cancel for default"となってい ますが、私は成功しませんでした。強制的にnilをいれるか、APLを選ぶ部分をコメ ント文で囲んで下さい。 | fSpec fSSPecPtr err appSpec appCreatorPtr | fSpec := FileSpecifier getFile:'pick a file to ask finder to open'. fSpec notNil ifTrue:[ appCreatorPtr := nil. appSpec := FileSpecifier getFile: 'pick an application to use; cancel for default' ofType:'APPL'. appSpec notNil ifTrue:[ appCreatorPtr := appSpec fileCreator convertStorageToPointer ]. fSSPecPtr := fSpec asFSSpec convertStorageToPointer. err := <>."err inspect."]. ------------------

Back to home