powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
44 сообщений из 44, показаны все 2 страниц
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35427367
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет!

Как предотвратить повторный запуск приложения - весьма освещенный вопрос. Что интересно во многих случаях люди просят активировать окно приложения, которое пытаются повторно запустить и практически ни разу на этот вопрос не отвечено, кроме случая, когда для предотвращения повторного запуска приложения использован метод FindWindow, но он же был отмечен как наименее подходящий для задачи, т.к. заголовок окна может меняться.
Ну а теперь вопрос - как "поднять"(активировать) свернутое окно приложения чтоб не сообщать юзеру ошибку, если я использую семафор (или мутекс)?

спасибо
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35427407
piva
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дык все уже разжевано давно
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35427481
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дык в том числе читал и там. Нету тама поднятия уже запущенного приложения. Есть тока каменты по поводу и все. Или я провтыкал? Тогда или покажите где там сабж или объясните в чем прикол!
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35427578
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CTAC-KO...Ну а теперь вопрос - как "поднять"(активировать) свернутое окно приложения чтоб не сообщать юзеру ошибку, если я использую семафор (или мутекс)?
Развернуть изнутри элементарно
Код: plaintext
_screen.WindowState =  2 
Развернуть из внешнего приложения сложнее. Надо послать окну приложения (по HWND найденному FindWindow) сообщение. Попробуй через
MSDNBOOL ShowWindow(HWND hWnd, int nCmdShow)
Parameters

hWnd
[in] Handle to the window.
nCmdShow
[in] Specifies how the window is to be shown. This parameter is ignored the first time an application calls ShowWindow, if the program that launched the application provides a STARTUPINFO structure. Otherwise, the first time ShowWindow is called, the value should be the value obtained by the WinMain function in its nCmdShow parameter. In subsequent calls, this parameter can be one of the following values.
SW_FORCEMINIMIZE
Windows 2000/XP: Minimizes a window, even if the thread that owns the window is hung. This flag should only be used when minimizing windows from a different thread.
SW_HIDE
Hides the window and activates another window.
SW_MAXIMIZE
Maximizes the specified window.
SW_MINIMIZE
Minimizes the specified window and activates the next top-level window in the Z order.
SW_RESTORE
Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when restoring a minimized window.
SW_SHOW
Activates the window and displays it in its current size and position.
SW_SHOWDEFAULT
Sets the show state based on the SW_ value specified in the STARTUPINFO structure passed to the CreateProcess function by the program that started the application.
SW_SHOWMAXIMIZED
Activates the window and displays it as a maximized window.
SW_SHOWMINIMIZED
Activates the window and displays it as a minimized window.
SW_SHOWMINNOACTIVE
Displays the window as a minimized window. This value is similar to SW_SHOWMINIMIZED, except the window is not activated.
SW_SHOWNA
Displays the window in its current size and position. This value is similar to SW_SHOW, except the window is not activated.
SW_SHOWNOACTIVATE
Displays a window in its most recent size and position. This value is similar to SW_SHOWNORMAL, except the window is not actived.
SW_SHOWNORMAL
Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.

Return Value

If the window was previously visible, the return value is nonzero.

If the window was previously hidden, the return value is zero.
SW_SHOWMAXIMIZED = 3
SW_SHOWNORMAL = 1
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35427646
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо.
Я в принципе и так знаю что для поднятия проги из другой нужен hWnd и соотв. команда. Не в этом проблема. Проблема как раз именно в определении hWnd. Ну и в том что такого решения я пока не видел, а только просьбы об этом.
Т.е. нужно от хендла мутекса или семафора перейти както, наверное, к ProcessID потом от него искать его же форточку и расчехлять.
Получается что пока единственным осуществимым выходом является поиск окна по заголовку: найдем - развернем, а нет - и че тогда?
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35427660
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CTAC-KOСпасибо.
Я в принципе и так знаю что для поднятия проги из другой нужен hWnd и соотв. команда. Не в этом проблема. Проблема как раз именно в определении hWnd. Ну и в том что такого решения я пока не видел, а только просьбы об этом.
Т.е. нужно от хендла мутекса или семафора перейти както, наверное, к ProcessID потом от него искать его же форточку и расчехлять.
Получается что пока единственным осуществимым выходом является поиск окна по заголовку: найдем - развернем, а нет - и че тогда?
Мутексы и семафоры объекты ядра Windows. У них нет процесса-владельца, поэтому ProcessID по ним не узнать.
Тут многое зависит от того как приложения изначально между собой связаны. Вполне возможно что одно другому может передать заранее свой HWND, можно думаю по ProcessID на HWND выйти. Как точно это сделать сходу не скажу, т.к. сам редко с таким сталкиваюсь, пиши что конкретно у тебя происходит, как процессы меж собой взаимосвязаны.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35427693
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да никак никакие процессы не связаны. Единственная задача - при попытке повторного запуска молча активировать окно уже запущенной программы. Все.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35427724
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
подумалось:
одним из способов определения что прога уже запущена является создание залоченного файла и попытка его удалить/открыть и тп непозволительности. Можно при запуске создавать файл, но не лочить от чтения, в который сливать свой HWND, тогда при повторном запуске искать в том файле этот HWND и по нему расчехлять уже запущенное приложение. По-идее наиболее простой вариант решения.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35427744
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CTAC-KOДа никак никакие процессы не связаны. Единственная задача - при попытке повторного запуска молча активировать окно уже запущенной программы. Все.
Если FindWindow() не подходит, то тогда надо копать сюда:
1. Найти процесс созданный из этого же EXE, для этого перебрать все процессы и получить полный путь к создавшему его EXE, в итоге получить ProcessID первого запущенного. Перебор процессов через API функцию CreateToolhelp32Snapshot()
2. По ProcessID получить HWND. Как это делается не знаю. Можно у Сишников в форуме поспрашивать, они WinAPI чаще используют.

На фоксе писать это будет очень муторно, т.к. там куча структур используется.

Второй вариант использовать именованные области памяти и хранить там HWND. Т.е. прога запускается, проверяет что если такая область памяти уже есть то считывает оттуда HWND, если нет то создает и записывает туда свое HWND. Этот вариант по моему на фоксе вообще не написать, только на Си писать и DLL/FLL делать. Есть исходник простенького класса на С++, который похожее делает. Могу поделится.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35427757
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CTAC-KO Можно при запуске создавать файл, но не лочить от чтения, в который сливать свой HWND, тогда при повторном запуске искать в том файле этот HWND и по нему расчехлять уже запущенное приложение. По-идее наиболее простой вариант решения. Попробуй. Должно заработать.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35427771
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TВторой вариант использовать именованные области памяти и хранить там HWND. Т.е. прога запускается, проверяет что если такая область памяти уже есть то считывает оттуда HWND, если нет то создает и записывает туда свое HWND. Этот вариант по моему на фоксе вообще не написать, только на Си писать и DLL/FLL делать. Есть исходник простенького класса на С++, который похожее делает. Могу поделится.блин, только вот подумал о таком варианте (чтобы не файл), а как оказывается не все так просто. Думал это типа стандартное что-то, типа атома. В таком случае вариант с созданием файла - наилучший и самый простой по ходу.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35427886
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как вариант - хранение hwnd (или чего угодно иного) в файле подкачки только вот не понял как в обычной памяти это сделать. файл подкачки обычно есть у всех, но может случиться и так, что он будет отключен...
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35427924
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CTAC-KOкак вариант - хранение hwnd (или чего угодно иного) в файле подкачки только вот не понял как в обычной памяти это сделать. файл подкачки обычно есть у всех, но может случиться и так, что он будет отключен...
Это тот самый мой второй вариант с именованной общей областью памяти. Если файл подкачки будет отключен, то думаю глюки будут не только в твоем софте.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35428270
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CTAC-KOДык в том числе читал и там. Нету тама поднятия уже запущенного приложения. Есть тока каменты по поводу и все. Или я провтыкал? Тогда или покажите где там сабж или объясните в чем прикол!

А в конце этой статьи дополнительные ссылки не смотрел?

Как вывести приложение на передний план
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35428435
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМА в конце этой статьи дополнительные ссылки не смотрел?конечно смотрел.
В свою очередь позвольте спросить: а Вы читали что я тут писал и спрашивал? Я по семафору определяю есть ли приложение, а искать окно по Caption/Title - нехорошо, об этом сказано не раз на этом же форуме.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35428455
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМА в конце этой статьи дополнительные ссылки не смотрел?конечно смотрел.
В свою очередь позвольте спросить: а Вы читали что я тут писал и спрашивал? Я по семафору определяю есть ли приложение, а искать окно по Caption/Title - нехорошо, об этом сказано не раз на этом же форуме.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35428462
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сорри за дубль - зто не я... это фаерфокс чето намутил...
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35428609
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CTAC-KO ВладимирМА в конце этой статьи дополнительные ссылки не смотрел?конечно смотрел.
В свою очередь позвольте спросить: а Вы читали что я тут писал и спрашивал? Я по семафору определяю есть ли приложение, а искать окно по Caption/Title - нехорошо, об этом сказано не раз на этом же форуме.
Вообще-то, Вы как-то выборочно читаете. Точнее, даже не пытаетесь адаптировать ИДЕИ под то, что Вам кажется более правильным. Либо Вам должны выложить "на блюдечке" готовое решение, либо "это не правильное решение". А самостоятельно-то думать собираетесь?

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

Вторая статья - активиация любого приложения по его заголовку. Если очень хочется, можно определить заголовок по HWND ранее сохраненного окна. Или же в качестве одного из реквизитов хранить этот заголовок. Динамически меняя значение заголовка в реквизите, если он реально изменился в приложении.

Но, разумеется, можете выдумать и свой собственный способ.

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

Как правило, после уточнения, когда же это реально может понадобиться, оказывается, что это может понадобиться в одном случае из 100. И ради 1% так мучиться?
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35428667
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМВообще-то, Вы как-то выборочно читаете. Точнее, даже не пытаетесь адаптировать ИДЕИ под то, что Вам кажется более правильным. Либо Вам должны выложить "на блюдечке" готовое решение, либо "это не правильное решение". А самостоятельно-то думать собираетесь? CTAC-KOподумалось:
одним из способов определения что прога уже запущена является создание залоченного файла и попытка его удалить/открыть и тп непозволительности. Можно при запуске создавать файл, но не лочить от чтения, в который сливать свой HWND, тогда при повторном запуске искать в том файле этот HWND и по нему расчехлять уже запущенное приложение. По-идее наиболее простой вариант решения. CTAC-KOкак вариант - хранение hwnd (или чего угодно иного) в файле подкачки и еще как вариант - хранение hwnd в реестре.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35428672
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а непосредственно реализацией я сейчас и занят втч...
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35428771
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема в том, что Вы все время выдумываете "ходы", а простейшие решения считаете чем-то "не правильным". Точнее, вообще их не замечаете.

Простейшее решение - открыть окно по его заголовку.

Что надо для этого сделать:

1) Заголовок окна должен быть уникальным иначе есть риск открыть "не то" приложение
2) Необходимо иметь способ быстро определить заголовок нужного окна

Как это реализовать?

Создать таблицу-хранилище, где ключем для поиска будет набор уникальных идентификаторов нужного приложения, а искомым значением - заголовок окна.

Дальше объяснять?
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35429979
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да у меня все проще - у меня нет нескольких приложений, оно всего одно.
Вообще способ с таблицей не подошел для меня в том плане, что я использую mysql как сервер и там трудности (для меня) насчет rlock(). Да создать таблицу можно, вставить данные и все такое, а вот залочить запись... Идея хорошая, но я ее сразу же отмел по причине что не знаю как там можно, если вообще можно, лочить запись, иначе бы такое уже б давно использовал, как раз с целью узнать кто в данный момент юзает прогу и тд и тп.
Поэтому найпростейшим вариантом пока оказалось создавать файл с хэндлом окна локально.

Я интересовался в целом, как поднять приложение не зная заранее хэндл окна и не используя поиск окошек по названию для избежания повторного запуска, а используя для этого мутекс или семафор, которые хранить хэндл окна не будут. Я думал что можно через мутекс или семафор выйти на создавшее их приложение и его активировать (развернуть), т.к. создает его, мутекс или семафор, то самое приложение, которое не надо больше 1 копии за раз запускать.

То что есть другие варианты подхода к этому делу - это безусловно хорошо и интересно, но еще интереснее самому что-то сваять, свое, а по ходу научиться чему-то еще. Если ничего придумать не получается, то по крайней мере можно в большей мере изучить определенный вариант и понять почему именно так сделано, а не иначе.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35430543
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хмм... Основная идея предложенного решения была подробно описана по ссылке.

Необходимо иметь "нечто" (объект, процесс, блокировку) которое обладает следующими свойствами:

1. Формируется одним и только одним процессом. Не обязательно автоматически. Можно и вручную
2. Можно увидеть и проанализировать из других процессов
3. Автоматически (обязательно!) уничтожается при закрытии процесса его породившего

Применительно к FoxPro и файлам DBF всем этим условиям удовлетворяет процесс ручной блокировки записи. Как следствие, именно на этом и построен алгоритм.

Поищите в MySQL "нечто", что также удовлетворяет приведенным условиям. Это вовсе не обязательно должна быть блокировка. Это может быть некий объект или какой-либо другой процесс.

Возможно, MySQL способен проанализировать реквизиты всех коннектов, а в строке подключения, как правило, можно вставить комментрий по которому идентифицировать нужное приложение.

Реквизит соединения, разумеется, не называется "комментарием". Это просто реквизит, который не обязателен для заполнения и никак не влияет на собственно организацию соединения. Например, для MS SQL в качестве комментария в строке подключения можно использовать опции APP или WSID. Поищите аналогичные опции в строке подключения MySQL.

Но это просто как один из возможных вариантов.

Другой вариант. Вы можете использовать тот же объект Mutex или семафор, а в таблице MySQL хранить имя этих объектов. Разумеется с добавлением идентификатора компьютера, например, по SYS(0). Далее просто пытаетесь создать еще один объект Mutex по заданным реквизитам на том же компьютере. Если объект есть, то достаем из той же таблицы Caption главной формы и активизируем это окно. Все просто. Факт наличия объекта Mutex с определенным именем становится своеобразной "блокировкой".

Можно придумать и другие варианты. Надо просто сделать "шаг в сторону" от стереотипных решений. Хотя и предложенные варианты довольно стереотипны.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35430602
авторчто я использую mysql как сервер и там трудности (для меня) насчет rlock().

для MSSQL есть 2 способа
1. считаем при проверке логина master..sysprocesses
2. устанавливаем и считываем лог-ю блокировку
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35430618
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМХмм... Основная идея предложенного решения была подробно описана по ссылке.

Необходимо иметь "нечто" (объект, процесс, блокировку) которое обладает следующими свойствами:

1. Формируется одним и только одним процессом. Не обязательно автоматически. Можно и вручную
2. Можно увидеть и проанализировать из других процессов
3. Автоматически (обязательно!) уничтожается при закрытии процесса его породившего
...
Ему надо еще:
4. Вывести пользователю окно первого запущенного процесса при запуске второго.

Остальное как я понял у него заработало. А тут проблема отсутствия какой либо связи между проверяющим процессом и процессом первого запущенного экземпляра. Все экземпляры проверяют объект блокировки, но этот объект никак не идентифицирует того какой экземпляр его создал/заблокировал.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35430687
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T ВладимирМХмм... Основная идея предложенного решения была подробно описана по ссылке.

Необходимо иметь "нечто" (объект, процесс, блокировку) которое обладает следующими свойствами:

1. Формируется одним и только одним процессом. Не обязательно автоматически. Можно и вручную
2. Можно увидеть и проанализировать из других процессов
3. Автоматически (обязательно!) уничтожается при закрытии процесса его породившего
...
Ему надо еще:
4. Вывести пользователю окно первого запущенного процесса при запуске второго.

Остальное как я понял у него заработало. А тут проблема отсутствия какой либо связи между проверяющим процессом и процессом первого запущенного экземпляра. Все экземпляры проверяют объект блокировки, но этот объект никак не идентифицирует того какой экземпляр его создал/заблокировал.
Ну, еще раз...

Чтобы вывести окно надо:

1. Знать, что процесс существует
2. Знать заголовок окна и быть уверенным в его уникальности

Создаем таблицу, в которой есть:

1. Идентификатор процесса (Не обязательно одно поле. Это может быть набор полей)
2. Заголовок окна этого процесса (Может меняться при выполнении приложения, главное поддерживать его актуальность)

Факт наличия записи в этой таблице не является условием существования процесса. Необходимо "нечто", что является неоспоримым подтверждением существования процесса. Для таблиц DBF в FoxPro - это факт блокировки такой записи. Для серверов баз данных надо придумывать что-то другое.

Возвращаемся к тому, с чего я начал...
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35430696
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Итак, нечто собственное таки разработал. Метод исключения повторного запуска основан на создании в файле подкачки как бы переменной с уникальным именем, в которой хранится идентификатор окна приложения. При запуске прверяется, нет ли в переменной идентификатора и если есть, знач повторный запуск и окно активируется. Мутекс и семафор отдыхают :)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
**************************************************
* запись хендла окна приложения в файл подкачки
**************************************************
FUNCTION SaveHWnd
	LPARAMETERS tcPrgID
	IF EMPTY(m.tcPrgID) OR VARTYPE(m.tcPrgID)#'C'
	   tcPrgID = PROGRAM( 0 )
	ENDIF

	LOCAL lnHWnd, lcHWnd, lnCFMHandle, lnWFMHandle

	DECLARE integer GetActiveWindow In Win32API 
	* получим handle нашего окна
	lnHWnd = GetActiveWindow()
	IF m.lnHWnd =  0 
	   CLEAR DLLS 'GetActiveWindow'
	   RETURN .F.
	ELSE
	   lcHWnd = TRANSFORM(m.lnHWnd)
	ENDIF

	DECLARE INTEGER CreateFileMapping IN kernel32.DLL INTEGER hFile, ;
         INTEGER lpFileMappingAttributes, INTEGER flProtect, ;
         INTEGER dwMaximumSizeHigh, INTEGER dwMaximumSizeLow, ;
         STRING lpName

	DECLARE INTEGER MapViewOfFile IN kernel32.DLL ;
         INTEGER hFileMappingObject, INTEGER dwDesiredAccess, ;
         INTEGER dwFileOffsetHigh, INTEGER dwFileOffsetLow, ;
         INTEGER dwNumberofBytesToMap

	DECLARE INTEGER GetLastError IN kernel32.DLL

	DECLARE INTEGER lstrcpy IN kernel32.DLL ;
         INTEGER lpString1, STRING @lpString2

	DECLARE INTEGER UnmapViewOfFile IN kernel32.DLL ;
         INTEGER lpBaseAddress

	DECLARE INTEGER CloseHandle IN kernel32.DLL INTEGER hObject

	#DEFINE page_writeread  4 
	#DEFINE page_readwrite  4 
	#DEFINE file_map_read  4 
	#DEFINE file_map_write  2 

	* FFFFFFFF ( 2 ^ 32 ) means: Use the Windows NT pagefile as the memory-
	* mapped file.
	* Otherwise, you could substitute a handle that you have created.
	#DEFINE usepagefile 0xFFFFFFFF 

	* This says: Create a file-mapping object from the pagefile,
	* using a default security descriptor, giving Read/Write access
	* to the committed region, with a maximum size of  4096  bytes,
	* named szeName, and return the handle to this file-mapping
	* object in variable 'handle'.
	lnCFMHandle = createfilemapping(usepagefile,  0 , page_readwrite,  0 , ;
          4096 , m.tcPrgID)
	IF m.lnCFMHandle =  0 
		*WAIT WINDOW "CreateFileMapping failed - LastError: " ;
            + TRANSFORM(getlasterror())
		RETURN .F.
	ENDIF

	* This says: Given the handle obtained above, give full access
	* to the file-mapping object, starting at offset  0 , and map the
	* entire file into my process address space.
	lnWFMHandle = mapviewoffile(m.lnCFMHandle, file_map_write,  0 ,  0 ,  0 )
	IF m.lnWFMHandle =  0 
		*WAIT WINDOW "MapViewOfFile failed - LastError: " ;
            + TRANSFORM(getlasterror())
		RETURN .F.
	ENDIF

	* Now, the file can be treated just like a memory address.
	* Use lstrcpy to copy the FoxPro string to addhandle, the
	* starting address of the mapped view.

	* The text you want to write to the shared memory-mapped
	* file goes here.

	lstrcpy(m.lnWFMHandle, @lcHWnd)

	* When we've finished with it, unmap the file-mapping object
	* from our address space and release the handle.
	*=UnmapViewOfFile (m.lnWFMHandle)
	
	* этот хендл не закрываю, чтобы текст в памяти висел
	*=CloseHandle(m.lnCFMHandle )

CLEAR DLLS 'CreateFileMapping', 'MapViewOfFile', 'GetLastError',;
			'lstrcpy', 'UnmapViewOfFile', 'CloseHandle', 'GetActiveWindow'
RETURN .T.
ENDFUNC
**************************************************
* чтение хендла окна приложения из файла подкачки
**************************************************
FUNCTION ReadHWnd
	LPARAMETERS tcPrgID
	IF EMPTY(m.tcPrgID) OR VARTYPE(m.tcPrgID)#'C'
	   tcPrgID = PROGRAM(0)
	ENDIF

	LOCAL lnHWnd, lcHWnd, lnCFMHandle, lnWFMHandle

	DECLARE INTEGER CreateFileMapping IN kernel32.DLL INTEGER hFile, ;
         INTEGER lpFileMappingAttributes, INTEGER flProtect, ;
         INTEGER dwMaximumSizeHigh, INTEGER dwMaximumSizeLow, ;
         STRING lpName

	DECLARE INTEGER MapViewOfFile IN kernel32.DLL ;
         INTEGER hFileMappingObject, INTEGER dwDesiredAccess, ;
         INTEGER dwFileOffsetHigh, INTEGER dwFileOffsetLow, ;
         INTEGER dwNumberofBytesToMap

	DECLARE INTEGER GetLastError IN kernel32.DLL

	DECLARE INTEGER lstrcpy IN kernel32.DLL ;
         STRING @lpString1, INTEGER lpString2

	DECLARE INTEGER UnmapViewOfFile IN kernel32.DLL ;
         INTEGER lpBaseAddress

	DECLARE INTEGER CloseHandle IN kernel32.DLL INTEGER hObject

	#DEFINE page_writeread 4
	#DEFINE page_readwrite 4
	#DEFINE file_map_read 4
	#DEFINE file_map_write 2

	* FFFFFFFF (2^32) means: Use the Windows NT pagefile as the memory-
	* mapped file.
	* Otherwise, you could substitute a handle that you have created.
	#DEFINE usepagefile 0xFFFFFFFF 

	* This says: Create a file-mapping object from the pagefile,
	* using a default security descriptor, giving Read/Write access
	* to the committed region, with a maximum size of 4096 bytes,
	* named szeName, and return the handle to this file-mapping
	* object in variable 'handle'.
	lnCFMHandle = createfilemapping(usepagefile, 0, page_readwrite, 0, ;
         4096, m.tcPrgID)
	IF m.lnCFMHandle = 0
		*WAIT WINDOW "CreateFileMapping failed - LastError: " ;
            + TRANSFORM(getlasterror())
		RETURN 0
	ENDIF

	* This says: Given the handle obtained above, give full access
	* to the file-mapping object, starting at offset 0, and map the
	* entire file into my process address space.
	lnWFMHandle = mapviewoffile(m.lnCFMHandle, file_map_write, 0, 0, 0)
	IF m.lnWFMHandle = 0
		*WAIT WINDOW "MapViewOfFile failed - LastError: " ;
            + TRANSFORM(getlasterror())
		RETURN 0
	ENDIF

	* Now, the file can be treated just like a memory address.
	* Use lstrcpy to copy the FoxPro string to addhandle, the
	* starting address of the mapped view.

	lcHWnd = SPACE(254)
	lstrcpy(@lcHWnd,m.lnWFMHandle)

	* When we've finished with it, unmap the file-mapping object
	* from our address space and release the handle.
	=UnmapViewOfFile (m.lnWFMHandle)
	=CloseHandle(m.lnCFMHandle)

CLEAR DLLS 'CreateFileMapping', 'MapViewOfFile', 'GetLastError',;
			'lstrcpy', 'UnmapViewOfFile', 'CloseHandle', 'GetActiveWindow'

RETURN VAL(m.lcHWnd)
ENDFUNC

**************************************************
* подъем приложения по окну
**************************************************
FUNCTION AppWndActivate
	LPARAMETERS tnHWND
	LOCAL llResult
	IF VARTYPE(m.tnHWND)#'N' OR EMPTY(m.tnHWND)
		tnHWND = VAL(ReadHWnd())
	ENDIF
	IF m.tnHWND > 0 
		#DEFINE SW_NORMAL     1 
		#DEFINE SW_MAXIMIZE   3 
		#DEFINE SW_MINIMIZE   6 

		DECLARE Long BringWindowToTop in Win32API Long
		DECLARE Long ShowWindow in Win32API Long, Long
	
		BringWindowToTop(m.tnHWND)
		ShowWindow(m.tnHWND,SW_MAXIMIZE)

		CLEAR DLLS 'BringWindowToTop', 'ShowWindow'
		llResult = .T.
	ENDIF
	RETURN m.llResult
ENDFUNC
ну а собственно в начальных строках приложения
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
   * если прога уже запущена
   LOCAL lnAppHWnd
   lnAppHWnd = ReadHWnd('MY_APP_HWND')
   IF m.lnAppHWnd #  0  
      MESSAGEBOX('Програма уже запущена', 16 ,'Ошибка')
      IF NOT AppWndActivate(m.lnAppHWnd)
	 * не удалось поднять окно
	 MESSAGEBOX('Не удается активировать окно приложения', 48 ,'Ошибка')
      ENDIF
      RETURN .F.
   ENDIF

   IF NOT SaveHWnd()
      MESSAGEBOX('Ошибка функции SaveHWnd('MY_APP_HWND')', 16 ,'Ошибка')
      RETURN .F.
   ENDIF
я, лично, задаю при вызове функций ReadHWnd/SaveHWnd в качестве параметра свой идентификатор приложения ("переменной") - 'MY_APP_HWND', а если это не нужно, тогда можно вызывать функции без параметров и тогда будет использовано имя ехе-шенга.

Владимир, можете теперь дополнить свою статью моим примером :)

PS В принципе можно объеденить 2 функции (ReadHWnd/SaveHWnd) в одну, добавив при вызове параметр, но мне лень :)
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35430773
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CTAC-KOВладимир, можете теперь дополнить свою статью моим примером :)
Слишком сложно, громоздко и не очевидно. Такие решения можно использовать, но рекомендовать их я бы ни в коем случае не стал. Оно даже для простого понимания довольно сложно, не говоря уже о реализации.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35430910
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ CTAC-KOВладимир, можете теперь дополнить свою статью моим примером :)
Слишком сложно, громоздко и не очевидно. Такие решения можно использовать, но рекомендовать их я бы ни в коем случае не стал. Оно даже для простого понимания довольно сложно, не говоря уже о реализации.
Согласен что для фокса действительно сложно выглядит, но из-за кучи объявлений API функций и их констант. Что касается реализации тут все очень просто и понятно если писать на Си:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
BOOL SaveHWnd(LPCTSTR pcszName)
{
 BOOL lRet = FALSE;
 HANDLE hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,  0 ,  4 , pcszName);
 if(hFileMap != NULL) 
 {
   pvMem = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS,  0 ,  0 ,  0 );
   if(pvMem != NULL)
   {
      HWND lnHWnd = GetActiveWindow();
      CopyMemory(pvMem, &lnHWnd,  4 );
 }
 return lRet;
}
Поэтому настоятельно рекомедую автору разобраться с WinAPI проектами в MSVС++ (ничего там сложного нет) и делать DLL/FLL, а функции из них юзать фоксом. И писать легче будет, т.к. в MSVС есть inellisence подсказки, да и со структурами танцев с бубном исполнять не надо. Все-таки WinAPI под Си заточено, а не под фокс.

CTAC-KO
Код: plaintext
1.
2.
3.
4.
...
	IF EMPTY(m.tcPrgID) OR VARTYPE(m.tcPrgID)#'C'
	   tcPrgID = PROGRAM( 0 )
	ENDIF
...

Не знаю как у тебя, у меня во всех проектах PROGRAM(0) = "START" :)
Используй лучше sys(16, 0) оно имя EXE вернет (когда из EXE вызовешь) и полный путь.
Передавая только имя проги ты автоматом запрещает вызывать такую же прогу из другой папки (возможно работающую с другой базой).
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35430929
piva
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для целей отлова hwnd нужного окна я юзал область USER_DATA главного окна фокса - или таблу где-нить в общедоступном месте - запись лочил и писал в нее hwnd - если заблокирована - читал hwnd - SetForegoundWindow в усе
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35430957
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну да... что тут скажешь...
то, что использованы матералы с MSDN, ссылку я выше приводил, то это, безусловно, говорит как раз о неоднозначности.
а громоздко потому что лишнего много - убери каменты и ненужные DEFINE-ы, и все, текста станет вполовину меньше.
впрочем не хотите статью дополнять - и не надо. кому будет надо и тут найдет.

Знаете почему в америкосии большинство талантливых ученых довольно быстро угасают? Потому что там в научной среде развит консерватизм, который не приемлет нового, обо что они и разбиваются... Этот же консерватизм, я считаю, является признаком старости - когда человек не приемлет нового и пробовать альтернативное не хочет. Ему не надо. Вот есть у него телефонный аппарат сталинских времен из несгораемой платмассы и не нужен ему кнопочный, тем более радио-телефон, уж не говоря о мобильном. И тд и тп.

кстати, вот сложил 2 функции в одну. Вызов функции без второго параметра или с 0 означет чтение, а с 1 - запись:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
**********************************************************
* запись/чтение хендла окна приложения из файла подкачки
**********************************************************
FUNCTION SaveReadHWnd
	LPARAMETERS tcPrgID, tnMode
	*tnMode= 0  - Read
	*tnMode= 1  - Save
	
	IF EMPTY(m.tcPrgID) OR VARTYPE(m.tcPrgID)#'C'
	   tcPrgID = PROGRAM( 0 )
	ENDIF

	IF VARTYPE(m.tnMode)#'N' OR m.tnMode# 0  AND m.tnMode# 1 
	   tnMode =  0 
	ENDIF

	LOCAL lnHWnd, lcHWnd, lnCFMHandle, lnWFMHandle

	DECLARE INTEGER CreateFileMapping IN kernel32.DLL INTEGER hFile, ;
         INTEGER lpFileMappingAttributes, INTEGER flProtect, ;
         INTEGER dwMaximumSizeHigh, INTEGER dwMaximumSizeLow, ;
         STRING lpName

	DECLARE INTEGER MapViewOfFile IN kernel32.DLL ;
         INTEGER hFileMappingObject, INTEGER dwDesiredAccess, ;
         INTEGER dwFileOffsetHigh, INTEGER dwFileOffsetLow, ;
         INTEGER dwNumberofBytesToMap

	DECLARE INTEGER GetLastError IN kernel32.DLL

	IF m.tnMode= 0 
	* для чтения
		DECLARE INTEGER lstrcpy IN kernel32.DLL ;
	         STRING @lpString1, INTEGER lpString2
	ELSE
	* для записи
		DECLARE INTEGER lstrcpy IN kernel32.DLL ;
	         INTEGER lpString1, STRING @lpString2

		DECLARE integer GetActiveWindow In Win32API 
		* получим handle нашего окна
		lnHWnd = GetActiveWindow()
		IF m.lnHWnd =  0 
		   CLEAR DLLS 'GetActiveWindow'
		   RETURN .F.
		ELSE
		   lcHWnd = TRANSFORM(m.lnHWnd)
		   CLEAR DLLS 'GetActiveWindow'
		ENDIF
	ENDIF

	DECLARE INTEGER UnmapViewOfFile IN kernel32.DLL ;
         INTEGER lpBaseAddress

	DECLARE INTEGER CloseHandle IN kernel32.DLL INTEGER hObject

	#DEFINE page_writeread  4 
	#DEFINE page_readwrite  4 
	#DEFINE file_map_read  4 
	#DEFINE file_map_write  2 

	* FFFFFFFF ( 2 ^ 32 ) means: Use the Windows NT pagefile as the memory-
	* mapped file.
	* Otherwise, you could substitute a handle that you have created.
	#DEFINE usepagefile 0xFFFFFFFF 

	* This says: Create a file-mapping object from the pagefile,
	* using a default security descriptor, giving Read/Write access
	* to the committed region, with a maximum size of  4096  bytes,
	* named szeName, and return the handle to this file-mapping
	* object in variable 'handle'.
	lnCFMHandle = createfilemapping(usepagefile,  0 , page_readwrite,  0 , ;
          4096 , m.tcPrgID)
	IF m.lnCFMHandle =  0 
		*WAIT WINDOW "CreateFileMapping failed - LastError: " ;
            + TRANSFORM(getlasterror())
		RETURN IIF(m.tnMode= 0 , 0 ,.F.)
	ENDIF

	* This says: Given the handle obtained above, give full access
	* to the file-mapping object, starting at offset  0 , and map the
	* entire file into my process address space.
	lnWFMHandle = mapviewoffile(m.lnCFMHandle, file_map_write,  0 ,  0 ,  0 )
	IF m.lnWFMHandle =  0 
		*WAIT WINDOW "MapViewOfFile failed - LastError: " ;
            + TRANSFORM(getlasterror())
		RETURN IIF(m.tnMode= 0 , 0 ,.F.)
	ENDIF

	* Now, the file can be treated just like a memory address.
	* Use lstrcpy to copy the FoxPro string to addhandle, the
	* starting address of the mapped view.

	IF m.tnMode= 0 
		lcHWnd = SPACE( 254 )
		lstrcpy(@lcHWnd,m.lnWFMHandle)
	ELSE
		lstrcpy(m.lnWFMHandle, @lcHWnd)
	ENDIF

	* When we have finished with it, unmap the file-mapping object
	* from our address space and release the handle.
	=UnmapViewOfFile (m.lnWFMHandle)

	* в режиме записи этот хендл не закрываю, чтобы текст в памяти висел
	IF m.tnMode= 0 
		=CloseHandle(m.lnCFMHandle)
	ENDIF

CLEAR DLLS 'CreateFileMapping', 'MapViewOfFile', 'GetLastError',;
			'lstrcpy', 'UnmapViewOfFile', 'CloseHandle', 'GetActiveWindow'

RETURN IIF(m.tnMode= 0 ,VAL(m.lcHWnd),.T.)
ENDFUNC

**************************************************
* подъем приложения по окну
**************************************************
FUNCTION AppWndActivate
	LPARAMETERS tnHWND
	LOCAL llResult
	IF VARTYPE(m.tnHWND)#'N' OR EMPTY(m.tnHWND)
		tnHWND = VAL(SaveReadHWnd())
	ENDIF
	IF m.tnHWND > 0 
		#DEFINE SW_NORMAL     1 
		#DEFINE SW_MAXIMIZE   3 
		#DEFINE SW_MINIMIZE   6 

		DECLARE Long BringWindowToTop in Win32API Long
		DECLARE Long ShowWindow in Win32API Long, Long
	
		BringWindowToTop(m.tnHWND)
		ShowWindow(m.tnHWND,SW_MAXIMIZE)

		CLEAR DLLS 'BringWindowToTop', 'ShowWindow'
		llResult = .T.
	ENDIF
	RETURN m.llResult
ENDFUNC
использование соответственно такое:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
   * если прога уже запущена
   LOCAL lnAppHWnd
   lnAppHWnd = SaveReadHWnd('MY_APP_HWND')
   IF m.lnAppHWnd #  0  
      * собственно сообщение можно не сообщать
      *MESSAGEBOX('Программа уже запущена', 16 ,'Ошибка')
      IF NOT AppWndActivate(m.lnAppHWnd)
	 * не удалось поднять окно. врядли такое произойдет, но тогда
            * здесь можно просто сказать что прога уже работает
            MESSAGEBOX('Программа уже запущена', 16 ,'Ошибка')
	 *MESSAGEBOX('Не удается активировать окно приложения', 48 ,'Ошибка')
      ENDIF
      RETURN .F.
   ENDIF

   IF NOT SaveReadHWnd('MY_APP_HWND', 1 )
      MESSAGEBOX('Ошибка функции SaveHWnd()', 16 ,'Ошибка')
      RETURN .F.
   ENDIF
кстати я там ошибку допустил, в предидущем варианте, надо было 'MY_APP_HWND' не в MESSAGEBOX втавлять, а в SaveHWnd().
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35430997
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T CTAC-KO
Код: plaintext
1.
2.
3.
4.
...
	IF EMPTY(m.tcPrgID) OR VARTYPE(m.tcPrgID)#'C'
	   tcPrgID = PROGRAM( 0 )
	ENDIF
...

Не знаю как у тебя, у меня во всех проектах PROGRAM(0) = "START" :)
Используй лучше sys(16, 0) оно имя EXE вернет (когда из EXE вызовешь) и полный путь.
Передавая только имя проги ты автоматом запрещает вызывать такую же прогу из другой папки (возможно работающую с другой базой). в таком случае можно пользовать как и я - с передачей параметра-наименования переменной. впрочем можно и вместо PROGRAM(0) заюзать
Код: plaintext
CHRTRAN(SUBSTR(SYS( 16 , 0 ),RAT('\',SYS( 16 , 0 ))+ 1 ),'.','_')
от последнего слеша.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35431038
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кстати, если в случае с заменой PROGRAM(0) на sys(16) переимонвать ехе, то это даст возможность второго запуска. А если не заменять, тогда в случае нескольких проектов со стартовой программой Start их нельзя будет вместе запустить. Поэтому передача имени переменной - лучший вариант. собственно с семафором, к примеру, так и сделано.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35431061
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CTAC-KO
Код: plaintext
CHRTRAN(SUBSTR(SYS( 16 , 0 ),RAT('\',SYS( 16 , 0 ))+ 1 ),'.','_')

Можно проще:
Код: plaintext
1.
2.
? JustStem(SYS( 16 , 0 ))
? JustFname(SYS( 16 , 0 ))

Я бы все-таки SYS(16,0) с полным путем брал для разрешения запуска разных копий одной проги из двух разных папок, хотя может тебе оно и не надо.

CTAC-KO... то, что использованы матералы с MSDN, ссылку я выше приводил, то это, безусловно, говорит как раз о неоднозначности.
Найди книгу Джефри Рихтера "Программирование Windows", почитай - поймешь как виндовс устроен, как приложения работают, какие объекты ядра есть. Думаю много интересного для себя найдешь. Там в т.ч. и то что ты использовал подробно описано.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35431065
XAndy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В своих прогах отказался от запрета повторного вызова программ. Просто вывожу сообщение, что программа уже запущена на компьютере, действительно желаете запустить второй экземпляр программы? Бывает удобнее иметь пару экземпляров.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35431304
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T ВладимирМ CTAC-KOВладимир, можете теперь дополнить свою статью моим примером :)
Слишком сложно, громоздко и не очевидно. Такие решения можно использовать, но рекомендовать их я бы ни в коем случае не стал. Оно даже для простого понимания довольно сложно, не говоря уже о реализации.
Согласен что для фокса действительно сложно выглядит, но из-за кучи объявлений API функций и их констант. Что касается реализации тут все очень просто и понятно если писать на Си:

Дело вовсе не в количестве кода (на FoxPro решение через блокировку записи требует тоже довольно много кода), а в бессмысленности самого решения.

Термин "бессмысленный" я употребил не в смысле "не нужный", а в смысле "очень узко-специализированный". Т.е. "не имеющий смысла" при более широкой постановке задачи. Попробую пояснить что я имею в виду.

Исходная цель всей задачи сводилась к следующей постановке:

- Приложение запускается на одном и только одном компьютере
- Если приложение уже было запущено необходимо вывести ранее запущенное приложение на передний план.

Задача разбивается на 2:

1) Определить тот факт, что приложение на данном компьютере уже запущено
2) Вывести на передний план ранее запущенное приложение

Для FoxPro первый вопрос решается банальным созданием локальной таблицы DBF на данном компьютере и ее блокировкой. Смысл "идти лесом" в область файлов подкачки от меня ускользает. Ну, разве что, эта простая идея просто не пришла в голову.

Второй вопрос, строго говоря, вообще решен не был. Дело в том, что API-функции не дают гарантии вывода приложения на передний план. На самом деле, такой гарантии не дает никакое решение.

Автор настолько увлекся решением первой части задачи, что не потрудился уточнить, как он будет решать вторую ее часть. Если бы он "покопался" в форумах, то нашел бы кучу упоминаний о том, что API-функции при определенных условиях просто не срабатывают. Речь идет даже не о выводе другого приложения на передний план, а о выводе текущего приложения на передний план. Особенно об As Top-Level формах.

А это значит, что основная задача вообще не решена. Приложение на передний план при определенных условиях просто не выводится. И какая разница, как он получил ссылку на это приложение?

Теперь зайдем с другой стороны.

Хорошо, предположим, что задача решена. Мы никогда не нарвемся на ситуацию, при которых API-функции вывода приложения на передний план не сработают. Однако любое решение, по возможности, должно быть "массштабируемым". Т.е. его должно быть относительно легко модифицировать для решения несколько других задач в той же области. О чем речь?

Задача повтороного запуска приложения сводится к тому, как именно определяется термин "повторный запуск". В данном случае понималось очень узкое значение. Только на данном компьютере. А если расширить до "только с данным логином и паролем"? Ну, наверное, придется писать в файл подкачки дополнительную информацию (формировать имя приложения) или ... заводить специальную таблицу .

Опять вернулись к банальному решению "старых консерваторов". И был смысл "огород городить"?

Вот и получается, что данное решение очень узко-специализированное. Причем использовались методы решения "не естесственные" для FoxPro. В то время, как есть более "простые" и "естесственные" (с точки зрения того же FoxPro) пути решения.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35431441
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМТермин "бессмысленный" я употребил не в смысле "не нужный", а в смысле "очень узко-специализированный". Т.е. "не имеющий смысла" при более широкой постановке задачи.
...
Только на данном компьютере. А если расширить до "только с данным логином и паролем"?
Именованная проекция файла один из немногих способов межпроцессного обмена данными. Он далеко не "очень узко-специализированный". Спросите у сишников в форуме насколько это "экзотика". И очень удивитесь узнав что это "классика".
Что касается масштабируемости - добавьте в имя объекта логин и все.

Кстати данное решение в данном случае ничем не отличается от использования именованного мьютекса (приведенного в примерах ) проекция файла это тоже именованный объект ядра Windows, только другой, позволяющий кроме проверки его существования еще и данные передать.

ВладимирМВторой вопрос, строго говоря, вообще решен не был. Дело в том, что API-функции не дают гарантии вывода приложения на передний план. На самом деле, такой гарантии не дает никакое решение.
Есть такое начиная с XP кажется. Разработчики софта так активно используют всплывающие окошки, что MS пришлось в XP переделать алгоритм вывода окна на первый план и передачи ему фокуса. В XP если окно на первый план не выйдет, то хоть на панели задач моргать будет, замечали наверно.

ВладимирМ...Причем использовались методы решения "не естесственные" для FoxPro. В то время, как есть более "простые" и "естесственные" (с точки зрения того же FoxPro) пути решения.
Про "не естесственные" согласен.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35431530
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИменованная проекция файла один из немногих способов межпроцессного обмена данными. Он далеко не "очень узко-специализированный". Спросите у сишников в форуме насколько это "экзотика". И очень удивитесь узнав что это "классика".
Не удивлюсь. У них ведь нет никакого другого "хранилища данных". Точнее, они исходят из предположения, что такого хранилища нет. Поэтому вполне естесственно использовать как "хранилище" различные области памяти.

Dima TКстати данное решение в данном случае ничем не отличается от использования именованного мьютекса (приведенного в примерах ) проекция файла это тоже именованный объект ядра Windows, только другой, позволяющий кроме проверки его существования еще и данные передать.

Обратите внимание, сколько пришлось потратить места и времени, чтобы объяснить, что такое объект Mutex и как его использовать. При том, что было просто выброшено много чего и описывался один объект.

А теперь представьте, сколько надо потратить времени и места, на объяснение что такое "именованная проекция файла" и как с ним вообще работать.

Кроме того, в статье объект Mutex описывался потому, что уж очень часто на него ссылаются. Но там же описываются и ограничения его использования. А "рекомендуемое" решение приводилось дальше.

Если предполагается работать в какой-то среде, то логично использовать инструменты этой среды. А прибегать к другим инструментам только в том случае, если существующие инструменты не предоставляют необходимой функциональности. В данном случае среда имеет необходимую функциональность для решения поставленной задачи.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35431710
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ Dima TИменованная проекция файла один из немногих способов межпроцессного обмена данными. Он далеко не "очень узко-специализированный". Спросите у сишников в форуме насколько это "экзотика". И очень удивитесь узнав что это "классика".
Не удивлюсь. У них ведь нет никакого другого "хранилища данных". Точнее, они исходят из предположения, что такого хранилища нет. Поэтому вполне естесственно использовать как "хранилище" различные области памяти.
Создать файл произвольной структуры (в т.ч. DBF), записать в него и заблокировать в нем кусок не намного сложнее.

ВладимирМОбратите внимание, сколько пришлось потратить места и времени, чтобы объяснить, что такое объект Mutex и как его использовать. При том, что было просто выброшено много чего и описывался один объект.
А это плохо именно тем что приходится описывать основы. Вы же не расписывали что такое DBF, как переход по записям организован и т.д. Мьютексы, семафоры, проекции в память, процессы, потоки, файлы, папки и т.д. это объекты операционной системы предназначенные для эффективного написания программного кода в любой среде программирования под Win, и если разработчик приложений для этой ОС принципиально считает что знать ее возможности ему не надо, что это инструментарий для других сред программирования, это в первую очередь ограничивает возможности самого разработчика.

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

Можно конечно изо всех сил выкручиваться средствами фокса, но это в итоге приведет к тому что появится задача на которую такой разработчик скажет что она неразрешима и будет искать сложный обходной маневр. Много ярких примеров из общений c 1Счиками, это в основном теми недоразработчиками кто кроме 1С ничего не программировал. Для некоторых предложение создать файл с чем-то или запустить внешний EXE уже экзотика.

PS Владимир, уже не первый раз спорим об альтернативных решениях давно решенных задач. Если есть желающие изобретать новые велосипеды, то зачем им запрещать это делать? Думаю достаточно показать что уже изобретено. А изобретатель пусть сам решает делать свой или чужой использовать.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35431782
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
XAndyВ своих прогах отказался от запрета повторного вызова программ. Просто вывожу сообщение, что программа уже запущена на компьютере, действительно желаете запустить второй экземпляр программы? Бывает удобнее иметь пару экземпляров.
Тоже ушел в эту сторону. Раньше проблема была в одноименных временных файлах (для отчетов например), от чего и защищался запретом повторного запуска.
Сейчас пришел к такому решению: при запуске в папке TEMP (которая в Win по умолчанию задана) создается подпапка ИМЯEXE и в ней файл-флаг открывается что занято, если таковая занята, то проверяется папка ИМЯEXE2, ИМЯEXE3 и т.д. пока свободная не найдется. Эта папка очищается и ставится рабочей, а дальше в коде просто работа с файлами без путей.
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35432207
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TPS Владимир, уже не первый раз спорим об альтернативных решениях давно решенных задач. Если есть желающие изобретать новые велосипеды, то зачем им запрещать это делать? Думаю достаточно показать что уже изобретено. А изобретатель пусть сам решает делать свой или чужой использовать.
Мое выступление здесь вызвано не тем, что я запрещал, а тем, что человек сказал, что "там решения нет". Т.е. он просто не дал себе труд задуматься. По сути, это тот же описанный тобой 1С-ник, только с другой стороны. Знает как решить задачу через API-функции (на Си), но не знает как решить задачу средствами FoxPro (хотя решение довольно простое)

Вот я и пытался показать, что "велосипед уже изобретен", но человек так этого и не заметил...
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35432231
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я считаю так - если рассматриваются, в том числе в Вашей, Владимир, статье (а особенно по ссылкам в конце статьи), как способы Mutex, Semaphore и вообще даже FindWindow (первые два из которых вообще ничего не могут, кроме как определить что прога уже запущена), то мой вариант гораздо богаче возможностями (но плох, т.к. "слишком многа букаф", за что "аффтар может пайти и убиццо ап стенку"). И мой вариант был призван заменить Mutex/Semaphore, что я с успехом у себя и сделал. А по ходу, при доработке напильником, это вообще может получиться интересная функция.
Ну и что, что окно может в итоге не подняться? Да, может не подняться. А Вы хотите сказать что в Вашем решении с таблицей прям ну 100% гарантия подъема окошка есть? Нету. К чему тогда об этом было сказано как арг против моего решения?
И вообще я тоже сначала сделал файл. И лично мне это не понравилось.
Не пойму я чет - "ай как нихарашо, хреновый у тебя метод, т.к. он юзает выньапи", (мутекс и семафор по ходу выньапи не юзают и все довольны, все смееюццо), а это прям такое чужое как линух и полуось? А чье ваще это самое выньапи? А не та же ли контора вообще вынь создала? И вфп не она ли случаем? И к чему ваще эти MSDN-ы с примерами... Это вот работа в вфп с OpenOffice - да. Это 100% неродное.
Мне вообще все равно, нужн0 оно Вам или нет. Мне - нужн0. И я очень рад что у меня такое получилось и хотел поделиться этой радостью с другими, но, как говориццо, благими намерениями... Я свой бесценный опыт обогатил и очередную цель достиг. Следующий шаг будет - fll на все свои WinAPI, как мне тут посоветовали, правда сомневаюсь что это скоро будет или вообще будет.
ЗЫ безусловно, табличный вариант лучше, но требует, в моем случае, гораздо больше времени на реализацию - т.к. нужно засесть за доки, гугль и искать как в мускуле записи лочаццо. И вот я даже доку читал, но в тех 3х строках, появященных GET_LOCK() нифига не понял. За то нашел что для этого на сервере нужно менять установку AUTOCOMMIT, а это тянет за сосбой изучение этой настройки - какие бока меня будут ждать, и так одно за другое...
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35432269
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМВот я и пытался показать, что "велосипед уже изобретен", но человек так этого и не заметил... вернее только запчасти, если про выньапи.
Я спросил - как поднять приложение, юзаяя мутекс/семафор . Т.к. предположил что есть неосвещенный в прессе вариант нахождения по ним окна приложения.
А Вы сказали - нарисуй себе таблицу. А зачем тогда нужен мутекс/семафор здесь, если таблица сама по себе и есть решение, заменяющее выньапи-решение? Да, так проще, так скромнее - создал во времянке одноименную таблицу и всех делов. Но ведь такое решение никак не связано с мутекс-семафорами, а мне было интересно именно это. Я по этому форуму пошуршал по поводу повторного запуска, а тут пишут про мутекс и семафор, а про то как потом поднять приложение - нема, хотя вопрос задавался.
Я согласен, что вариант с таблицей, даже локальной - хорошее и простое решение, и самое главное родное, фоксовое. И оно позволяет легко и просто решить вопрос нескольких запусков с разными логинами.
А у меня на данном этапе программа ущербна, т.к. не разрешает больше одного раза на одном РС себя запускать, причем факт проверяется раньше запроса логина. И вообще сначала запускается загрузчик, который "освежает" версию, если надо, и он тоже сначала проверяет факт запуска, а логина в нем вообще не предусмотрено. А запуск основной проги мимо лоадера запрещается и это реализовано на атомах, хотя тоже можно было бы на таблицах. Короче извращенец я :)
...
Рейтинг: 0 / 0
Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
    #35432357
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подумалось: я тут для создания велосипеда вместо легкого титанового сплава использовал чугун.
Ну заклинило меня на WinAPI, т.к. распахивание окна другого приложения - это прерогатива WinAPI.
ЗЫ А консерватизм - это не всегда плохо. :) Чет я перегнул малехо... сорри.
...
Рейтинг: 0 / 0
44 сообщений из 44, показаны все 2 страниц
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как "поднять" свернутое окно приложения? Re: повторный запуск приложения
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]