関連ページ  
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
<?xml version="1.0" encoding="utf-8"?>
<mx:Window
	xmlns:mx="http://www.adobe.com/2006/mxml"
	width="600"
	height="300"
	horizontalAlign="center"
	verticalAlign="middle"
	type="utility"
	systemChrome="none"
	transparent="true"
	showFlexChrome="false"
	alwaysInFront="true"
	creationComplete="initControl(event)"
	keyDown="moveThisWindow(event)"
	mouseMove="mouseAction(event)"
	mouseUp="mouseEnd(event)"
>

<mx:Script>
<![CDATA[
// *********************************************************
// ● horizontalAlign と verticalAlign で画像を中心に
//   持って行って、サイズに余裕を持たせる事によって、
//   ドラッグ時のイベントを取得しやすいようにしています
//
// ● type=utility なので、タスクバーに非表示です
//
// alwaysInFront=true で常に前面で表示します
// transparent=true は、背景を透明にするのに必要
// showFlexChrome は、false で、Windows 枠無し
//
// ● keyDown="moveThisWindow(event)" で、上下キーによって
//    ウインドウをデスクトップ内の範囲で移動させます
// ● マウスイベントを使用して、dr.png 画像をドラッグする
//    事によって、ウインドウを移動させます
//    ドラッグ開始のみ、画像の mouseDown で処理します
// *********************************************************

	import mx.events.*;

	private var flg:Boolean = false;
	private var offsetBaseX:int = 265;
	private var offsetBaseY:int = 90;
	private var offsetX:int;
	private var offsetY:int;
	private var me:LboxWindow;
	private var currentDirectory:String;

	// *****************************************************
	// 初期処理
	// *****************************************************
	private function initControl(e:FlexEvent):void {

		me = this;
		data.setFocus();

	}

	// *****************************************************
	// 上下キーによる移動
	// *****************************************************
	private function moveThisWindow(e:KeyboardEvent):void {

		var x:int = mx.core.Application.application.win.nativeWindow.x;
		var y:int = mx.core.Application.application.win.nativeWindow.y;
		var width:int = this.nativeWindow.width;
		var height:int = this.nativeWindow.height;

		if ( e.keyCode == 37 ) {
			x -= 10;
			if ( x < 0 ) {
				x = 0;
			}
		}
		if ( e.keyCode == 38 ) {
			y -= 10;
			if ( y < 0 ) {
				y = 0;
			}
		}
		if ( e.keyCode == 39 ) {
			x += 10;
			if ( x > mx.core.Application.application.rect.width - width ) {
				x = mx.core.Application.application.rect.width - width;
			}
		}
		if ( e.keyCode == 40 ) {
			y += 10;
			if ( y > mx.core.Application.application.rect.height - height ) {
				y = mx.core.Application.application.rect.height - height;
			}
		}

		mx.core.Application.application.win.nativeWindow.x = x;
		mx.core.Application.application.win.nativeWindow.y = y;

	}

	// *****************************************************
	// ドラッグ開始
	// *****************************************************
	private function mouseStart(e:MouseEvent):void {

		offsetX = offsetBaseX + e.localX;
		offsetY = offsetBaseY + e.localY;
		flg = true;

	}

	// *****************************************************
	// ドラッグ終了
	// *****************************************************
	private function mouseEnd(e:MouseEvent):void {

		flg = false;

	}

	// *****************************************************
	// マウスによる Windpow 移動
	// *****************************************************
	private function mouseAction(e:MouseEvent):void {

		if ( flg ) {
			e.currentTarget.nativeWindow.x += e.currentTarget.mouseX - offsetX;
			e.currentTarget.nativeWindow.y += e.currentTarget.mouseY - offsetY;
		}

	}

	// *********************************************************
	// 外部からドラッグ開始
	// *********************************************************
	private function Check_DragEnter(e:NativeDragEvent):void {

		var clip:Clipboard = e.clipboard;
		if ( clip.hasFormat( ClipboardFormats.FILE_LIST_FORMAT ) ) {
			NativeDragManager.acceptDragDrop(e.currentTarget as InteractiveObject);
		}
	}

	// *********************************************************
	// 外部からドロップ
	// *********************************************************
	private function Check_DropFile(e:NativeDragEvent):void {

		var clip:Clipboard = e.clipboard;
		var file_list:Array;
		file_list = clip.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;

		// 先頭のファイルのみ使用
		data.text = file_list[0].nativePath;

		// 単純に Alert を実行すると、メインウインドウが非表示なので
		// 表示されません。このウインドウを親として表示すると、表示されますが
		// 非表示にしていたフォームの枠の範囲が、モーダル時の処理されて
		// 範囲が目視されるようになります
		mx.controls.Alert.show(
			me.offsetBaseX.toString(),
			"ドラッグコントロール用オフセット",
			mx.controls.Alert.OK,
			me
		)
		// me で、private 変数が参照できるのは、
		// me を LboxWindow として定義しているからです。
		// me を Window として定義した場合は、LboxWindow でキャストする必要があります
		/*
			mx.controls.Alert.show(
				LboxWindow(me).offsetBaseX.toString(),
				"ドラッグコントロール用オフセット",
				mx.controls.Alert.OK,
				me
			)
		*/

	}

	// *********************************************************
	// 「ファイルを開くダイアログ」でテキストファイルの処理
	// *********************************************************
	public function openTextFile():void {

		var fileToOpen:File = new File();
		var txtFilter:FileFilter = new FileFilter("Text", "*.as;*.css;*.html;*.txt;*.xml");
		
		try {
			fileToOpen.browseForOpen("テキストファイルを開く", [txtFilter]);
			fileToOpen.addEventListener(Event.SELECT, fileSelected);
		}
		catch (error:Error) {
			trace("Failed:", error.message);
		}

	}

	// *********************************************************
	// 読み込み
	// *********************************************************
	private function fileSelected(event:Event):void 
	{

		// 対象ファイルを表示
		data.text = File(event.target).nativePath;
		trace(File(event.target).name);

		var stream:FileStream = new FileStream();

		// ↓shift_jis のエイリアス
		// csShiftJIS、csWindows31J、ms_Kanji、shift-jis、x-ms-cp932、x-sjis
		// shift_jis として読み込む
		stream.open(File(event.target), FileMode.READ);
		var str:String = stream.readMultiByte((event.target).size, "shift_jis");
		stream.close();

		// utf8n としてカレントに別ファイルに書き込む
		var targetFile:String = currentDirectory + "\\" + File(event.target).name + ".utf8n.txt";
		var fileOut:File = new File(targetFile);
		stream.open(fileOut, FileMode.WRITE);
		stream.writeUTFBytes(str);
		stream.close();

		// utf8 としてカレントに別ファイルに書き込む
		targetFile = currentDirectory + "\\" + File(event.target).name + ".utf8.txt";
		fileOut = new File(targetFile);
		stream.open(fileOut, FileMode.WRITE);
		stream.writeByte(0xef);
		stream.writeByte(0xbb);
		stream.writeByte(0xbf);
		stream.writeUTFBytes(str);
		stream.close();

	}

	// *********************************************************
	// カレントディレクトリの取得
	// *********************************************************
	public function appHandler(event:InvokeEvent):void {

		currentDirectory = event.currentDirectory.nativePath;
		trace(currentDirectory);

	}


]]>
</mx:Script>


<mx:Image id="dr" source="@Embed('dr.png')" 
	mouseDown="mouseStart(event)"
/>

<mx:HBox>
	<mx:TextInput id="data" width="400"
		nativeDragEnter="Check_DragEnter(event)"
		nativeDragDrop="Check_DropFile(event)"
	/>
	<mx:Button  
		id="btn"  
		label="参照"  
		styleName="blackButton"
		click="openTextFile()"
	/>
</mx:HBox>


</mx:Window>