関連ページ  
2次ウインドウで完全透過アプリケーション :【AIR Flex】


ブラウザでダウンロード

AIR のウインドウ (1) -- メインウインドウ で、テストした完全透過のフォームを、
2次ウインドウに実装して使用しており、以下のような機能のサンプルも付加してあります

1) フォーム上のアイコンを使って(完全透過)フォーム全体をドラッグで移動させる
2) 画像にポップアップメニューを実装
2) エクスプローラからのファイルのドラッグドロップ
3) 「ファイルを開く」ダイアログによるファイル選択
4) SHIFT_JIS のテキストファイルを UTF8N または、UTF8 に変換する
5) カレントディレクトリの取得
6) 2次ウインドウからの Alert.show の実行


2次ウインドウの処理
マウスドラッグでの移動は、OS がサポートするタイトルバーでの動きよりは雑になります。
キーボードでも動くので、両方利用すれば不便は無いと思いますが、きちんとした処理は
今のところ思いつきません。

処理サンプルとして有用そうな、テキストファイルの一連の処理を実装してみました。
あと、普通に Alert を実行すると表示しない(親の状態に依存する)ので注意が必要です。
LboxWindow.mxml
001.<?xml version="1.0" encoding="utf-8"?>
002.<mx:Window
003.    xmlns:mx="http://www.adobe.com/2006/mxml"
004.    width="600"
005.    height="300"
006.    horizontalAlign="center"
007.    verticalAlign="middle"
008.    type="utility"
009.    systemChrome="none"
010.    transparent="true"
011.    showFlexChrome="false"
012.    alwaysInFront="true"
013.    creationComplete="initControl(event)"
014.    keyDown="moveThisWindow(event)"
015.    mouseMove="mouseAction(event)"
016.    mouseUp="mouseEnd(event)"
017.>
018. 
019.<mx:Script>
020.<![CDATA[
021.// *********************************************************
022.// ● horizontalAlign と verticalAlign で画像を中心に
023.//   持って行って、サイズに余裕を持たせる事によって、
024.//   ドラッグ時のイベントを取得しやすいようにしています
025.//
026.// ● type=utility なので、タスクバーに非表示です
027.//
028.// alwaysInFront=true で常に前面で表示します
029.// transparent=true は、背景を透明にするのに必要
030.// showFlexChrome は、false で、Windows 枠無し
031.//
032.// ● keyDown="moveThisWindow(event)" で、上下キーによって
033.//    ウインドウをデスクトップ内の範囲で移動させます
034.// ● マウスイベントを使用して、dr.png 画像をドラッグする
035.//    事によって、ウインドウを移動させます
036.//    ドラッグ開始のみ、画像の mouseDown で処理します
037.// *********************************************************
038. 
039.    import mx.events.*;
040. 
041.    private var flg:Boolean = false;
042.    private var offsetBaseX:int = 265;
043.    private var offsetBaseY:int = 90;
044.    private var offsetX:int;
045.    private var offsetY:int;
046.    private var me:LboxWindow;
047.    private var currentDirectory:String;
048. 
049.    // *****************************************************
050.    // 初期処理
051.    // *****************************************************
052.    private function initControl(e:FlexEvent):void {
053. 
054.        me = this;
055.        data.setFocus();
056. 
057.    }
058. 
059.    // *****************************************************
060.    // 上下キーによる移動
061.    // *****************************************************
062.    private function moveThisWindow(e:KeyboardEvent):void {
063. 
064.        var x:int = mx.core.Application.application.win.nativeWindow.x;
065.        var y:int = mx.core.Application.application.win.nativeWindow.y;
066.        var width:int = this.nativeWindow.width;
067.        var height:int = this.nativeWindow.height;
068. 
069.        if ( e.keyCode == 37 ) {
070.            x -= 10;
071.            if ( x < 0 ) {
072.                x = 0;
073.            }
074.        }
075.        if ( e.keyCode == 38 ) {
076.            y -= 10;
077.            if ( y < 0 ) {
078.                y = 0;
079.            }
080.        }
081.        if ( e.keyCode == 39 ) {
082.            x += 10;
083.            if ( x > mx.core.Application.application.rect.width - width ) {
084.                x = mx.core.Application.application.rect.width - width;
085.            }
086.        }
087.        if ( e.keyCode == 40 ) {
088.            y += 10;
089.            if ( y > mx.core.Application.application.rect.height - height ) {
090.                y = mx.core.Application.application.rect.height - height;
091.            }
092.        }
093. 
094.        mx.core.Application.application.win.nativeWindow.x = x;
095.        mx.core.Application.application.win.nativeWindow.y = y;
096. 
097.    }
098. 
099.    // *****************************************************
100.    // ドラッグ開始
101.    // *****************************************************
102.    private function mouseStart(e:MouseEvent):void {
103. 
104.        offsetX = offsetBaseX + e.localX;
105.        offsetY = offsetBaseY + e.localY;
106.        flg = true;
107. 
108.    }
109. 
110.    // *****************************************************
111.    // ドラッグ終了
112.    // *****************************************************
113.    private function mouseEnd(e:MouseEvent):void {
114. 
115.        flg = false;
116. 
117.    }
118. 
119.    // *****************************************************
120.    // マウスによる Windpow 移動
121.    // *****************************************************
122.    private function mouseAction(e:MouseEvent):void {
123. 
124.        if ( flg ) {
125.            e.currentTarget.nativeWindow.x += e.currentTarget.mouseX - offsetX;
126.            e.currentTarget.nativeWindow.y += e.currentTarget.mouseY - offsetY;
127.        }
128. 
129.    }
130. 
131.    // *********************************************************
132.    // 外部からドラッグ開始
133.    // *********************************************************
134.    private function Check_DragEnter(e:NativeDragEvent):void {
135. 
136.        var clip:Clipboard = e.clipboard;
137.        if ( clip.hasFormat( ClipboardFormats.FILE_LIST_FORMAT ) ) {
138.            NativeDragManager.acceptDragDrop(e.currentTarget as InteractiveObject);
139.        }
140.    }
141. 
142.    // *********************************************************
143.    // 外部からドロップ
144.    // *********************************************************
145.    private function Check_DropFile(e:NativeDragEvent):void {
146. 
147.        var clip:Clipboard = e.clipboard;
148.        var file_list:Array;
149.        file_list = clip.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
150. 
151.        // 先頭のファイルのみ使用
152.        data.text = file_list[0].nativePath;
153. 
154.        // 単純に Alert を実行すると、メインウインドウが非表示なので
155.        // 表示されません。このウインドウを親として表示すると、表示されますが
156.        // 非表示にしていたフォームの枠の範囲が、モーダル時の処理されて
157.        // 範囲が目視されるようになります
158.        mx.controls.Alert.show(
159.            me.offsetBaseX.toString(),
160.            "ドラッグコントロール用オフセット",
161.            mx.controls.Alert.OK,
162.            me
163.        )
164.        // me で、private 変数が参照できるのは、
165.        // me を LboxWindow として定義しているからです。
166.        // me を Window として定義した場合は、LboxWindow でキャストする必要があります
167.        /*
168.            mx.controls.Alert.show(
169.                LboxWindow(me).offsetBaseX.toString(),
170.                "ドラッグコントロール用オフセット",
171.                mx.controls.Alert.OK,
172.                me
173.            )
174.        */
175. 
176.    }
177. 
178.    // *********************************************************
179.    // 「ファイルを開くダイアログ」でテキストファイルの処理
180.    // *********************************************************
181.    public function openTextFile():void {
182. 
183.        var fileToOpen:File = new File();
184.        var txtFilter:FileFilter = new FileFilter("Text", "*.as;*.css;*.html;*.txt;*.xml");
185.         
186.        try {
187.            fileToOpen.browseForOpen("テキストファイルを開く", [txtFilter]);
188.            fileToOpen.addEventListener(Event.SELECT, fileSelected);
189.        }
190.        catch (error:Error) {
191.            trace("Failed:", error.message);
192.        }
193. 
194.    }
195. 
196.    // *********************************************************
197.    // 読み込み
198.    // *********************************************************
199.    private function fileSelected(event:Event):void
200.    {
201. 
202.        // 対象ファイルを表示
203.        data.text = File(event.target).nativePath;
204.        trace(File(event.target).name);
205. 
206.        var stream:FileStream = new FileStream();
207. 
208.        // ↓shift_jis のエイリアス
209.        // csShiftJIS、csWindows31J、ms_Kanji、shift-jis、x-ms-cp932、x-sjis
210.        // shift_jis として読み込む
211.        stream.open(File(event.target), FileMode.READ);
212.        var str:String = stream.readMultiByte((event.target).size, "shift_jis");
213.        stream.close();
214. 
215.        // utf8n としてカレントに別ファイルに書き込む
216.        var targetFile:String = currentDirectory + "\\" + File(event.target).name + ".utf8n.txt";
217.        var fileOut:File = new File(targetFile);
218.        stream.open(fileOut, FileMode.WRITE);
219.        stream.writeUTFBytes(str);
220.        stream.close();
221. 
222.        // utf8 としてカレントに別ファイルに書き込む
223.        targetFile = currentDirectory + "\\" + File(event.target).name + ".utf8.txt";
224.        fileOut = new File(targetFile);
225.        stream.open(fileOut, FileMode.WRITE);
226.        stream.writeByte(0xef);
227.        stream.writeByte(0xbb);
228.        stream.writeByte(0xbf);
229.        stream.writeUTFBytes(str);
230.        stream.close();
231. 
232.    }
233. 
234.    // *********************************************************
235.    // カレントディレクトリの取得
236.    // *********************************************************
237.    public function appHandler(event:InvokeEvent):void {
238. 
239.        currentDirectory = event.currentDirectory.nativePath;
240.        trace(currentDirectory);
241. 
242.    }
243. 
244. 
245.]]>
246.</mx:Script>
247. 
248. 
249.<mx:Image id="dr" source="@Embed('dr.png')"
250.    mouseDown="mouseStart(event)"
251./>
252. 
253.<mx:HBox>
254.    <mx:TextInput id="data" width="400"
255.        nativeDragEnter="Check_DragEnter(event)"
256.        nativeDragDrop="Check_DropFile(event)"
257.    />
258.    <mx:Button 
259.        id="btn" 
260.        label="参照" 
261.        styleName="blackButton"
262.        click="openTextFile()"
263.    />
264.</mx:HBox>
265. 
266. 
267.</mx:Window>