Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > Flash Приложения: AIR, Zinc и тд.

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 14.08.2007, 16:42
kotmaker вне форума Посмотреть профиль Отправить личное сообщение для kotmaker Найти все сообщения от kotmaker
  № 1  
Ответить с цитированием
kotmaker

Регистрация: Aug 2007
Сообщений: 8
По умолчанию Сворачивание/разворачивание окна exe (Zinc)

Имеется следующая проблема. Экзешник цинковый открывается на полный экран, путем прописывание в первый фрэйм:

Код:
mdm.Application.maximize();
Далее идет код по проверке уже открытых файлов этого экзешника. Надо чтобы экзешник закрывался в случае, если один уже открыт, и наводился фокус на уже открытое окно. То есть если оно свернуто - то необходимо его развернуть. Вот собственно код:

Код:
windowList = mdm.System.getWindowList();
main_name = "Тесты ПДД";
file_open = 0;
zakr = false;
for (i=0; i<windowList.length; i++) {
	if (windowList[i][0] == main_name) {
		num = i;
		file_open++;
		zakr = true;
		mdm.System.setWindowFocus(windowList[i][1]);
	} else {
		if (windowList[i][0] == "My Flash Window") {
			file_open++;
			if (file_open == 2) {
				zakr = true;
				mdm.System.setWindowFocus(windowList[i][1]);
			}
		}
	}
}
if (zakr) {
	mdm.Application.exit();
}
насчет двойного цусловия поясню - почему-то если окно развернуто, то оно в getWindowList() прописывается как My Flash Window, а если свернуто в таск бар - "Тесты по ПДД"

Так вот проблема возникает, в том случае, если одно окно свернуто в таскбар, а второе открывается. Второе окно, проверяя открытые файлы, находит уже открытый файл с именем "Тесты ПДД" и переводит на него фокус. А после закрывает себя. Так вот фокус вроде бы переводится, кнопка первого окна становится внизу нажатой, но само окно не отображается. Если кнопку внизу нажать, происходит стандартная анимация сворачивания виндоуз, и кнопка отжимается. И лишь потом, когда нажимаешь на кнопку - срабатывает разворачивание. В чем может быть проблема, подскажите, пожалуйста.

PS
Окно сворачивается нажатием на кнопку с кодом:
Код:
mdm.Application.minimize();

Старый 14.08.2007, 20:58
alexcon314 вне форума Посмотреть профиль Отправить личное сообщение для alexcon314 Найти все сообщения от alexcon314
  № 2  
Ответить с цитированием
alexcon314
listener

модератор форума
Регистрация: Jun 2006
Сообщений: 3,260
Записей в блоге: 28
Отправить сообщение для alexcon314 с помощью ICQ
Попробуй так:
Код:
mdm.Application.doEvents();
mdm.Application.enableExitHandler();
mdm.Application.onAppExit = exit;
mdm.Forms.MainForm.title = "form";
hwnd = mdm.System.Registry.load("AppHwnd");
if (hwnd && hwnd != "none") {
	// шлем WM_SYSCOMMAND с wParam = SC_RESTORE и lParam = 1
	mdm.System.sendMessage(hwnd, 0x0112, 0xF120, 1);
	// ставим фокус
	mdm.System.setWindowFocus(hwnd);
	flag = false;
	exit();
} else {
	var wList = mdm.System.getWindowList();
	var i = 0;
	while (wList[i][0] != "form") {
		i++;
	}
	mdm.System.Registry.save("AppHwnd", wList[i][1]);
	flag = true;
}
function exit() {
	if (flag) {
		mdm.System.Registry.save("AppHwnd", "none");
	}
	mdm.Application.exit();
}
При запуске прога пишет в реестр хэндл своего окна. Второй экземляр при запуске читает из реестра этот хэндл и шлет мессаги на ресторе и сетфокус первому экземпляру, а сам отваливает. Первый экземпляр при закрытии вытирает из реестра хэндл.
Да, еще. незачем две проверки делать при выяснении хэндла окна. достаточно одной на формтитле.
Конечно, сохранять хэндл необязательно в реестр, просто это в данной ситуации удобно.


Последний раз редактировалось alexcon314; 15.08.2007 в 01:16.
Старый 15.08.2007, 11:00
kotmaker вне форума Посмотреть профиль Отправить личное сообщение для kotmaker Найти все сообщения от kotmaker
  № 3  
Ответить с цитированием
kotmaker

Регистрация: Aug 2007
Сообщений: 8
Спасибо огромное. Помогло! Моё почтение.

И сразу возникает вопрос. Дело в том, что хэндл из реестра не удаляется. И последующее запускание окна не приводит ни к чему. Скрипт находит себе подобных в реестре и закрывается. Даже если больше такого окна нет открытого. Так вот вопрос - как удалять инфу из реестра? И, даже если получится удалить из реестра, что будет в случае критического завершения программы.. например перезагрузке системы. В реестре инфа ведь все равно останется?


Последний раз редактировалось kotmaker; 15.08.2007 в 11:52.
Старый 15.08.2007, 14:07
alexcon314 вне форума Посмотреть профиль Отправить личное сообщение для alexcon314 Найти все сообщения от alexcon314
  № 4  
Ответить с цитированием
alexcon314
listener

модератор форума
Регистрация: Jun 2006
Сообщений: 3,260
Записей в блоге: 28
Отправить сообщение для alexcon314 с помощью ICQ
о работе с реестром см.
http://flasher.ru/forum/showthread.php?t=81193&page=6 пост №60
Совершенно правильный вопрос.
Хэндл при завершении работы (штатном) самого первого экземпляра меняется на запись "none". Удалять ключ AppHwnd совсем не обязательно.
Для нештатных ситуаций такой способ не подходит.
Поэтому
Код:
mdm.Application.doEvents();
formTitle = mdm.Forms.MainForm.title = "form";
appTitle = mdm.Application.title = "app";
var wList = mdm.System.getWindowList();
var appList:Array = new Array();
var i = 0;
while (wList[i][1]) {
	if (wList[i][0] == formTitle || wList[i][0] == appTitle) {
		appList.push(wList[i][1]);
	}
	i++;
}
hwnd = appList[1];
if (hwnd) {
	mdm.System.sendMessage(hwnd, 0x0112, 0xF120, 1);
	mdm.System.setWindowFocus(hwnd);
	mdm.Application.exit();
}
Здесь все основано на том факте, что в списке окон wList окно второго экземпляра приложения находится выше чем окно ранее запущенного экземпляра. и при добавлении в массив appList хэндл уже запущенного окна (если таковое присутствует) оказывается под номером 1, а хэндл второго под номером 0. Действительно, должен признать, что в этом случае нужно проверять наличие в списке wList и титла на кнопке приложения в таскбаре: когда оно свернуто принудительно только так его можно найти. Поэтому присутствует строчка mdm.Application.title="...", где устанавливается титл на этой кнопке.
Должно работать. В принципе, это твой исходный вариант, только переработанный.
FormTitle и ApplicationTitle можно указать статически в самом компиляторе. Но в этом случае к ним не получишь доступ так просто. И придется писать в условии сравнения титлов сам титл. Не поручусь, что это всегда работает, особенно когда титл русский или необычные символы там есть. Поэтому, лучше назначать их динамически в коде.


Последний раз редактировалось alexcon314; 15.08.2007 в 14:50.
Старый 15.08.2007, 16:24
kotmaker вне форума Посмотреть профиль Отправить личное сообщение для kotmaker Найти все сообщения от kotmaker
  № 5  
Ответить с цитированием
kotmaker

Регистрация: Aug 2007
Сообщений: 8
Последний вариант срабатывал только в случае, если первое окно развернуто (не в таскбаре). Оказывается фишка в том, что если окно свернуто, то в getWindowList() оно отображается как "My Flash Application", а если развернуто - "form" (то есть так, как мы задали ему в mdm.Forms.MainForm.title = "form"). А решилось это просто. Добавил строчку

Код:
mdm.Application.title = "form";
и стало теперь и окно так называться, и кнопка внизу в таскбаре. И все встало на свои места. Спасибо тебе за помощь.

Старый 15.08.2007, 17:28
alexcon314 вне форума Посмотреть профиль Отправить личное сообщение для alexcon314 Найти все сообщения от alexcon314
  № 6  
Ответить с цитированием
alexcon314
listener

модератор форума
Регистрация: Jun 2006
Сообщений: 3,260
Записей в блоге: 28
Отправить сообщение для alexcon314 с помощью ICQ
Вроде все то же и я писал, и код рабочий вроде...
Чего-то я не понял твой последний пост...
Кроме последних двух предложений


Последний раз редактировалось alexcon314; 15.08.2007 в 17:30.
Старый 16.08.2007, 00:03
kotmaker вне форума Посмотреть профиль Отправить личное сообщение для kotmaker Найти все сообщения от kotmaker
  № 7  
Ответить с цитированием
kotmaker

Регистрация: Aug 2007
Сообщений: 8
Какой-то я невнимательный, действительно. Сейчас читаю, что написал, и получается что глупо. Твой код действительно правильный Еще раз спасибо.

Старый 25.03.2008, 19:22
chingachgoog вне форума Посмотреть профиль Найти все сообщения от chingachgoog
  № 8  
Ответить с цитированием
chingachgoog
Banned
[+4 01.02.09]
[+1 01.02.09]
 
Аватар для chingachgoog

блогер
Регистрация: Nov 2006
Адрес: Moscow
Сообщений: 2,145
Записей в блоге: 7
Не понимаю, что эта строчка делает:

Код:
mdm.Application.doEvents();
?

Старый 26.03.2008, 12:20
alexcon314 вне форума Посмотреть профиль Отправить личное сообщение для alexcon314 Найти все сообщения от alexcon314
  № 9  
Ответить с цитированием
alexcon314
listener

модератор форума
Регистрация: Jun 2006
Сообщений: 3,260
Записей в блоге: 28
Отправить сообщение для alexcon314 с помощью ICQ
если вы о примерах в этом топике, то как их автор должен признаться, что причина вставки этой строчки в код мной уже забыта . помню что где-то без этой строчки чего-то не работало, а как включил - заработало. косяк был вобщем. речь шла об обработке системных сообщений посылаемых окну дочерней формы. точнее не вспомню сейчас. но с тех пор я не гнушаюсь вставлять эту строчку, если собираюсь работать с окном через send/postMessage. пардон за сбивчивые объяснения. если вспомню конкретный пример - выложу.

эта строчка судя по мануалу "заставляет" окно приложения обрабатывать любые сообщения из системной очереди.

вариант: выяснить запущен ли уже в данный момент экземпляр приложения можно при помощи LocalConnection


Последний раз редактировалось alexcon314; 26.03.2008 в 13:43.
Старый 26.03.2008, 14:52
chingachgoog вне форума Посмотреть профиль Найти все сообщения от chingachgoog
  № 10  
Ответить с цитированием
chingachgoog
Banned
[+4 01.02.09]
[+1 01.02.09]
 
Аватар для chingachgoog

блогер
Регистрация: Nov 2006
Адрес: Moscow
Сообщений: 2,145
Записей в блоге: 7
Ну да, можно было бы что-то типа такого сделать

Код:
myData=new Date()
myData.getTime()
lc = new LocalConnection();
lc.send("lc_name", "methodToExecute", myData);

lc.methodToExecute = function(USL) {
  if (String(myData)==String(USL)){
		clearTimeout(TO)
	}
};

lc.connect("lc_name");

lc.onStatus = function(infoObject) {
    if (infoObject.level=='status'){
		TO=setTimeout(function(){
							   fscommand("quit") // собственно любая функция закрытия
							   },50)
    }
}
Но мне кажется это менее надежно чем код выше.

add:
хотя как знать...
оставил тут включенным цинк и запустил отдельно экзешник - он вырубился этим кодом! Т.к. цинк внутри себя (!) прокручивает флешку и она оказалась первой.


Последний раз редактировалось chingachgoog; 11.04.2008 в 20:28.
Создать новую тему Ответ Часовой пояс GMT +4, время: 17:36.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 17:36.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.