Расширение проектора: Продолжение 5. Первое приложение.
Ничтоже сумняшеся, написал "блокнот" на флэше.
Что может программа:
-открывать, редактировать и сохранять текстовые файлы;
-сохранять настройки в реестре;
-можно передавать параметры в командной строке, а именно файл, который нужно открыть;
-стандартные хоткеи (Ctrl+S и т.д.)
Вобщем, почти полностью воспроизводит функционал обычного блокнота Windows.
Скачать скомпиленную программу можно здесь:
http://mdm-zinc.narod.ru/notepad.zip
В качестве иллюстрации привожу еще исходник: (AS 2.0)
Код:
import mx.controls.TextArea; import extprojector.*; class gui.Notepad extends MovieClip { private var ta:TextArea; private var isSaved:Boolean = true; private var title:String = "Flash Блокнот: "; private var fileFilter:String = "Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*||"; private var hkSave:Number = 0; private var hkOpen:Number = 0; private var hkNew:Number = 0; private var hkQuit:Number = 0; private var hkPrnt:Number = 0; private var sHeight:Number = 0; private var sWidth:Number = 0; private var sLeft:Number = 0; private var sTop:Number = 0; private var sFile:String = ""; private var sFontName:String = "Lucida Console"; private var sFontSize:String = "14"; private var sFontStyle:String = "normal"; private var sFontWeight:String = "none"; private var sFontUnderline:String = "none"; private var sFontColor:String = "0x000000"; private var sWordWrap:Boolean = false; private var cmd:String = ""; private var regKey:String = "HKEY_CURRENT_USER\\Software\\FlashNotepad2"; public function Notepad() { super(); Stage.align = "TL"; Stage.scaleMode = "NoScale"; FlrunEx.initialize(); FlrunEx.addEventHandler(FlrunEx.EVENT_INIT, this); } private function SIZECHANGED(e:ExtEvent):Void { ta.setSize(e.params[1], e.params[2]); } private function change(e:Object):Void { isSaved = false; } private function INIT(e:ExtEvent):Void { cmd = e.params[0]; FlrunEx.removeEventHandler(FlrunEx.EVENT_INIT, this); ta = _root.createClassObject(TextArea, "ta", 10); ta.addEventListener("change", this); PMenu.removeMainMenu(); PMenu.addEventHandler(PMenu.EVENT_MAINMENUCLICK, this); /*var xml:String = "<menu>"; xml += "<tab label='Файл'>"; xml += "<item label='Создать... Ctrl+N' id='457'/>"; xml += "<item label='Открыть... Ctrl+O' id='458'/>"; xml += "<item label='Сохранить Ctrl+S' id='459'/>"; xml += "<item label='Сохранить как...' id='460'/>"; xml += "<separator/>"; xml += "<item label='Выход Ctrl+Q' id='461'/>"; xml += "</tab>"; xml += "<tab label='Вид'>"; xml += "<item label='Переносить по словам' id='33'/>"; xml += "<item label='Не переносить по словам' id='34'/>"; xml += "<separator/>"; xml += "<item label='Шрифт' id='35'/>"; xml += "</tab>"; xml += "<tab label='Справка'>"; xml += "<item label='О программе' id='1'/>"; xml += "</tab>"; xml += "</menu>"; PMenu.setMainMenu(xml);*/ PMenu.setMainMenuFromResource(602); PMenu.setItemState(459, PMenu.STATE_DISABLED | PMenu.STATE_GRAYED); PMenu.setRightClickMenuView(PMenu.VIEW_NOALL); PMenu.setTextMenuView(PMenu.VIEW_RUSSIAN); hkSave = PInput.registerHotKey(PInput.MOD_CONTROL, "S"); hkOpen = PInput.registerHotKey(PInput.MOD_CONTROL, "O"); hkNew = PInput.registerHotKey(PInput.MOD_CONTROL, "N"); hkQuit = PInput.registerHotKey(PInput.MOD_CONTROL, "Q"); PInput.addEventHandler(PInput.EVENT_HOTKEY, this); PWindow.setIconFomResource(275, "shell32.dll"); PWindow.center(); PWindow.addEventHandler(PWindow.EVENT_SIZECHANGED, this); PWindow.addEventHandler(PWindow.EVENT_CLOSE, this); getSettings(); } private function MAINMENUCLICK(e:ExtEvent):Void { var p:Number = Number(e.params[0]); switch (p) { case 1 : PDialogs.msgBox("Текстовый редактор \"Flash Блокнот\".\nAS version: 2.0\nExtension: lcevt.dll (v 1.0.0.0)\n\nAuthor: alexcon314.\nEmail: alexcon314@rambler.ru", 0, "О программе:"); return; case 458 : open(""); break; case 459 : save(sFile); break; case 460 : save(""); break; case 461 : CLOSE(null); break; case 457 : newFile(); break; case 35 : setFont(); break; case 34 : ta.wordWrap = false; break; case 33 : ta.wordWrap = true; break; } } private function HOTKEY(e:ExtEvent):Void { var p:Number = Number(e.params[0]); switch (p) { case hkOpen : open(); break; case hkSave : save(sFile); break; case hkQuit : CLOSE(null); break; case hkNew : newFile(); break; } } private function setFont():Void { var str:String = PDialogs.FontDialog(); if (!str) return; var tmp:Array = str.split(FlrunEx.dlm); var bgr:String = tmp[5]; var rgb:String = "0x" + bgr.substr(6, 2) + bgr.substr(4, 2) + bgr.substr(2, 2); sFontName = tmp[0]; sFontSize = tmp[1]; sFontStyle = (Number(tmp[3]) == 1 ) ? ("italic") : ("normal"); sFontWeight = (Number(tmp[2]) == 700) ? ("bold" ) : ("none"); sFontUnderline = (Number(tmp[4]) == 1 ) ? ("underline") : ("none" ); sFontColor = rgb; applyFontStyle(); } private function applyFontStyle():Void { ta.setStyle("fontFamily", sFontName); ta.setStyle("fontSize", sFontSize ); ta.setStyle("fontWeight", sFontWeight); ta.setStyle("fontStyle", sFontStyle); ta.setStyle("textDecoration", sFontUnderline); ta.setStyle("color", sFontColor); ta.wordWrap = sWordWrap; } private function getSettings():Void { var isKey:Boolean = PRegistry.keyExists(regKey); if (!isKey) { var tmp:Array = PWindow.getClientRect(); ta.setSize( tmp[2], tmp[3]); applyFontStyle(); PRegistry.createKey(PRegistry.HKCU + "\\Software", "FlashNotepad2"); if (cmd) sFile = cmd; if(!sFile || !open(sFile)) newFile(); return ; } sWidth = PRegistry.getDWORDValue (regKey, "sWidth"); sHeight = PRegistry.getDWORDValue (regKey, "sHeight"); sTop = PRegistry.getDWORDValue (regKey, "sTop"); sLeft = PRegistry.getDWORDValue (regKey, "sLeft"); sFontName = PRegistry.getStringValue(regKey, "sFontName"); sFontSize = PRegistry.getStringValue(regKey, "sFontSize"); sFontStyle = PRegistry.getStringValue(regKey, "sFontStyle"); sFontWeight = PRegistry.getStringValue(regKey, "sFontWeight"); sFontUnderline = PRegistry.getStringValue(regKey, sFontUnderline"); sFontColor = PRegistry.getStringValue(regKey, "sFontColor"); sFile = PRegistry.getStringValue(regKey, "sFile"); sWordWrap = Boolean(PRegistry.getDWORDValue(regKey, "sWordWrap")); if (!PFileSystem.exists(sFile)) sFile = ""; if (cmd) sFile = cmd; applyFontStyle(); PWindow.setRect([sLeft, sTop, sWidth, sHeight]); var tmp:Array = PWindow.getClientRect(); ta.setSize( tmp[2], tmp[3]); ta.wordWrap = sWordWrap; if(!sFile || !open(sFile)) newFile(); } private function saveSettings():Void { var tmp:Array = PWindow.getRect(); if(tmp[0] >= 0 && tmp[1] >= 0){ PRegistry.setDWORDValue(regKey, "sLeft", tmp[0] ); PRegistry.setDWORDValue(regKey, "sTop", tmp[1] ); PRegistry.setDWORDValue(regKey, "sWidth", tmp[2] ); PRegistry.setDWORDValue(regKey, "sHeight", tmp[3]); } PRegistry.setStringValue(regKey, "sFontName", sFontName ); PRegistry.setStringValue(regKey, "sFontSize", sFontSize ); PRegistry.setStringValue(regKey, "sFontStyle", sFontStyle ); PRegistry.setStringValue(regKey, "sFontWeight", sFontWeight ); PRegistry.setStringValue(regKey, "sFontUnderline", sFontUnderline ); PRegistry.setStringValue(regKey, "sFontColor", sFontColor ); PRegistry.setDWORDValue(regKey, "sWordWrap", Number(ta.wordWrap) ); PRegistry.setStringValue(regKey, "sFile", getPathToSave()); } private function newFile():Void { if (checkForSave()) return; PMenu.setItemState(459, PMenu.STATE_DISABLED | PMenu.STATE_GRAYED); PMenu.setItemState(460, PMenu.STATE_ENABLED); ta.text = ""; sFile = ""; PWindow.setTitle(title + "новый документ"); } private function checkForSave():Boolean { if (isSaved) return false; var res:Number = PDialogs.msgBox( "Сохранить изменения в текущем документе?", PDialogs.ICON_QUESTION + PDialogs.BUTTON_YES_NO_CANCEL, title + getFileName(sFile)); if (res == PDialogs.RESULT_CANCEL)return true; if (res == PDialogs.RESULT_NO )return false; save(sFile); return false; } private function open(file:String):Boolean { var fileToOpen:String = file; if (!file) { fileToOpen = PDialogs.OpenFileDialog (fileFilter); } if (!fileToOpen) return false; var pFile:PFile = new PFile(); if (pFile.create(fileToOpen, PFile.ACCESS_READ, PFile.ACCESS_SHARE_READ)) { sFile = fileToOpen; PWindow.setTitle(title + getFileName(sFile)); var sz:Number = pFile.size; var str:String = pFile.readString(sz); if (!str && sz != 0) { PDialogs.errorBox(); pFile.close(); return false; } ta.text = str; isSaved = true; PMenu.setItemState(459, PMenu.STATE_ENABLED); pFile.close(); return true; }else PDialogs.errorBox(); return false; } private function save(file:String):Void { var fileToSave:String = file; if (!file) { fileToSave = PDialogs.SaveFileDialog (fileFilter); } if (!fileToSave) return; var fileName:String = getFileName(fileToSave); var ind:Number = fileName.lastIndexOf("."); if (ind < 0) { fileToSave += ".txt"; fileName += ".txt"; } var pFile:PFile = new PFile(); if (pFile.create(fileToSave, PFile.ACCESS_WRITE, PFile.ACCESS_SHARE_WRITE, PFile.MODE_CREATE_ALWAYS)) { sFile = fileToSave; var len:Number = pFile.writeString(ta.text); if (len != 0) { PWindow.setTitle(title + fileName); pFile.close(); } else PDialogs.errorBox(); } isSaved = true; PMenu.setItemState(459, PMenu.STATE_ENABLED); } private function CLOSE(e:ExtEvent):Void { saveSettings(); if (checkForSave())return; PInput.unregisterHotKey(hkSave); PInput.unregisterHotKey(hkOpen); PInput.unregisterHotKey(hkNew ); PInput.unregisterHotKey(hkQuit); PWindow.close(); } private function getFileName(file:String):String { return file.substr(1 + file.lastIndexOf("\\")) } private function getPathToSave():String { if (sFile.indexOf(":") < 0 && sFile) { // not a full path return FlrunEx.current_dir + "\\" + sFile; }else return sFile; } }
Всего комментариев 23
Комментарии
![]() ![]() |
|
Что-то я не пойму.
notepad.exe - это стандартный неизмененный проектор флеша? А как он тогда с dll-ками общается? |
![]() ![]() |
|
стандартный неизмененный проектор флеша - это libavm.dll (если неустраивает название, можно поменять), lcevt.dll - это сам экстенжн. notepad.exe по сути просто лаунчер. Он стартует проектор, грузит эксенжн и отваливает, больше он ничего не делает. Вобще, он один и тот же для любого приложения, просто с него начинается вся работа.
Мне пришла в голову "гениальная" идея: зачем иметь два экзешника, можно запарить и впасть в непонятки, чего запускать-то? Вот я и переименовал стандартный неизменный проектор в длл. Работает, естественно, он. И общается он с lcevt.dll через шаредобжект, как - описано в предыдущем посте блога за номером 4. А что, вполне приглядное приложение: экзешник, две либы к нему и все. Вот такая вот немудреная маскировка. Можно и через fscommand запускаться, но тут по-неволе окно проектора первым появится, и все усилия по настройке внешнего вида окна, смена меню, иконки, к примеру, будут видны. Это можно использовать, когда с окном ничего делать не предполагается. А так проектор стартуется как хидден, делаем с ним все что нужно и показываем во всей красе. (метод PWindow.show() вызывается здесь неявно в обработчике INIT()). Если запутал, прошу прощения. Есть идеи как сделать лучше - предлагай. ЗЫ. Есть версия блокнота и на AS 3.0, код практически идентичен, либа, лаунчер те же. Кажется удалось добиться соместимости с обоими версиями АС. Версии плеера только 9, 10 и строго не дебуг. На дебуг версиях не работает, под них я экстенжн просто не затачивал. |
|
Обновил(-а) alexcon314 24.02.2010 в 23:09
|
![]() ![]() |
|
Тутор, конечно надо бы... только пока спешить с выпуском не буду. Хочу сделать еще пару приложений тестовых. Опыт разработки блокнота помог выявить много важных моментов. Короче, обкатка.
Вкратце: есть набор классов оболочки (package extprojector); делаем их импорт, кодим, компилим свф; делаем из свф обычный проектор; именуем его libavm.dll (просто сменили имя, можно сразу его задать при создании проектора, блин, сам не могу еще привыкнуть к это фиче))); собираме в одну папочку лаунчер, lcevt.dll, libavm.dll; запускаем лаунчер; У меня все это получилось автоматизировать под FD, ну, то есть, настраиваем пути, работаем как обычно, потом жмем билд, а в постбилде прописан батник на сборку проектора и запуск лаунчера. Тут же смотрим, что получилось в итоге. Вобщем, все компилится, именуется, складывается куда нужно и запускается одной кнопкой прямо из FD. Кастомизация файлов лаунчера и экстенжена возможна своими силами. Сам лаунчер можно обозвать как угодно, резхакером иконку ему поменять и сконфигурять его на запуск проектора с другим именем (не libavm.dll, если оно не устраивает), указать ему инишник, передать параметры запуска и т.п. lcevt.dll в своих ресурсах содержит некоторые необходимые для работы экстенжена данные, ну и опять же резхакером в ее ресурсы можно зашить кастомные данные: иконки, меню, что-то там еще.. не помню, по потребности, вобщем. А, да, можно будет как я предполагаю в будущем в ресы пихать все что хочешь, хоть свф-ы, хоть пдф-ы, хмл-ы, хтмл-ы, скрипты, картинки, музон, фильмы, екзешники (этт я загнул ))) и проч. В классах оболочки будут(уже частично есть) методы для работы с ресурсами длл. Конечно, можно отдельную длл под ресурсы использовать или несколько. Че-то уже не "вкратце" получается. Пока остановлюсь)). |
|
Обновил(-а) alexcon314 25.02.2010 в 14:02
|
![]() ![]() |
|
Цитата:
Наверное, можно сделать раз и навсегда пустой проектор (главное в нем - ФП) и грузить туда уже нужные swf-ки.
Опсс.. наверно я не так тебя понял. Я имею в виду, что совсем пустой проектор - это просто автономный плеер, в принципе можно попробовать запускать лаунчером этот самый плеер с параметром-путем к свфу, тогда должно работать, в принципе.. надо попробовать. Пока такую возможность не предусматривал.. Я про другое сначала подумал: скомпиленный раз и навсегда свф-загрузчик зашиваем в проектор, а приложение как таковое им грузится. Я так делал на цинке. |
|
Обновил(-а) alexcon314 25.02.2010 в 17:21
|
![]() ![]() |
|
Цитата:
А совсем пустой проектор как сделать легально? Я не знаю.
|
![]() ![]() |
|
Цитата:
standalone player? или его нельзя распространять?
|
![]() ![]() |
|
Цитата:
а он что в экзешнике, что в dll-ке остался без изменений
Из твоих слов можно сделать вывод, что я включил проектор-плеер в состав стороннего (по отношению к адобу) модуля, ну типа сделал длл, в ее ресы засунул проектор и использую, а это было бы скорее всего нарушением. Так вот это не так. Переименуйте длл (libavm.dll) в ехе и вы получите проектор чистой воды. Я его, конечно, использую, но по прямому назначению - воспроизводить свф-ролики. И он лежит, как и положено, отдельным файлом, никто его не крал и не ломал. И вообще, хватит о грустном)). В конце концов, можно просто забыть (забить) именовать проектор в ехе))(шутка). |
|
Обновил(-а) alexcon314 26.02.2010 в 22:35
|
![]() ![]() |
|
alexcon314, кстати, а как насчет Линукса? Или проект заточен под Винду?
|
![]() ![]() |
|
В текущем состоянии только под винду. Боюсь, что портировать на линукс будет трудно. Сам код методов, ну типа записать в файл, создать папку и т.п., по идее, портируется, там в большинстве нет ничего сугубо от винды (реестр разве что), ну функции поправить/заменить, вопрос времени. А вот портировать двиг с инжектом в рантайм, перхватом обращений к шаредам и ЛЦ - этот вопрос потребует намного больше усилий. Скорее всего, в том виде, как он есть двиг вообще не портабелен..
ЗЫ. Недавно тут в ветке про цинк отписались, что финбоксы тоже на линуксы не портируют свой проект потому, что.... не знают как перехватить у флэша обращения к файловой системе. О как. Не объединить ли с ними усилия? ![]() ЗЫЫ Хоть бы уж под винду выложить что-нибудь... а ты уж и на линукс замахнулся... Да, тут человек пытался на питоне враппер написать для флэш-плагина, может он чем порадует. |
|
Обновил(-а) alexcon314 31.03.2010 в 15:14
|
![]() ![]() |
|
Не повезло. Меня как раз момент перехвата/подмены обращения ФП к ОС интересовал на Линуксе в первую очередь...
|
![]() ![]() |
|
да ладно.. было бы желание))
https://www.evilfingers.com/publicat....hook.lite.pdf |
![]() ![]() |
|
Добрый день. Жду не дождусь выхода программы. Когда же это случится?
|
![]() ![]() |
|
Надеюсь, что скоро. Месяц-полтора.. Обстоятельства не дают закончить.
|
Последние записи от alexcon314
- Пишем свою оболочку для FP под Windows. Шаг 6. (19.05.2011)
- Пишем свою оболочку для FP под Windows. Шаг 5. (18.05.2011)
- Пишем свою оболочку для FP под Windows. Шаг 4. (18.05.2011)
- Пишем свою оболочку для FP под Windows. Шаг 3. (18.05.2011)
- Пишем свою оболочку для FP под Windows. Шаг 2. (17.05.2011)