Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];

Вниз

Как правильно активизировать окно   Найти похожие ветки 

 
DelphiLexx ©   (2006-10-16 11:41) [0]

Мое приложение должно работать в одном экземпляре для этого я используя:

function
 CheckAppRun:
 integer;
var
 Map: THandle;  
begin
 Map := CreateFileMapping($FFFFFFFF, nil, PAGE_READONLY, 0, 32,
   "%af_src_comm_0");
 if Map = 0 then
   Result := -1
 else if GetLastError = ERROR_ALREADY_EXISTS then
   Result := 1
 else
   Result := 0
end;

function
 ActivatePreviousInstance(WndClass: PChar): boolean;
var
 Wnd: HWND;
begin

 Result := false;
 if (CheckAppRun = 1) then
 begin
   if (WndClass <> nil) then
   begin
     {если окно программы указано сделать его активным в системе}
     Wnd := FindWindow(WndClass, nil);
     if (Wnd <> 0) then
     begin
       {Хочу отобразить мое приложение, но оно не отображается}
       SwitchToThisWindow(Wnd, True);
     end;
   end
   else
     MessageBox(0, "Приложение уже запущено!", "Сообщение",
       MB_ICONINFORMATION or MB_OK);
   Result := true;
 end;
end;

if ActivatePreviousInstance("TMainForm") then Halt(1);


Для отображения своего приложения я использовал SwitchToThisWindow(Wnd, True), но оно не отображается. Я использовал ShowWindow(Wnd, SW_SHOWMAXIMIZED) окно отображается, но после такой операции его нельзя свернуть.
Так как же правильно отобразить свое приложение не зависимо от того минимизировано оно или нет?


 
RWolf   (2006-10-16 16:34) [1]

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


 
DelphiLexx ©   (2006-10-16 16:36) [2]


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

Каким образом?


 
clickmaker ©   (2006-10-16 17:03) [3]

if IsIconic(hWnd) then
 ShowWindow(hWnd, SW_RESTORE);
SetForegroundWindow(hWnd);


 
DelphiLexx ©   (2006-10-16 17:09) [4]


> if IsIconic(hWnd) then
>  ShowWindow(hWnd, SW_RESTORE);
> SetForegroundWindow(hWnd);

Если окно приложения свернуто, то твой код не отображает его.


 
RWolf   (2006-10-16 17:17) [5]

> Каким образом?

Как-то так:

     Application.Restore;
     if Application.MainForm.WindowState = wsMinimized then
       Application.MainForm.WindowState := wsNormal;
     Application.MainForm.Visible := True;
     SetForegroundWindow(Application.Handle);


 
Leonid Troyanovsky ©   (2006-10-16 17:22) [6]


> DelphiLexx ©   (16.10.06 17:09) [4]

> Если окно приложения свернуто, то твой код не отображает


Вполне отображает.

Только, окно приложения - это окно класса (windows) TApplication.
Если есть хендл любого другого окна приложения (дельфи, билдер),
то окно приложения можно найти как
happ := GetWindowLong(wnd, GWL_HWNDPARENT)

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2006-10-16 17:26) [7]


> RWolf   (16.10.06 17:17) [5]

> Как-то так:


Не так.
Не foreground приложение не может сделать себя
(другого) foreground.

Т.е., посылка подобных сообщений бесполезна.

--
Regards, LVT.


 
RWolf ©   (2006-10-16 17:39) [8]

мое предложение заключалось в том, что делать foreground-ом приложение будет именно себя, свой экземпляр; см. [1]


 
Leonid Troyanovsky ©   (2006-10-16 17:50) [9]


> RWolf ©   (16.10.06 17:39) [8]
> мое предложение заключалось в том, что делать foreground-
> ом приложение будет именно себя, свой экземпляр; см. [1]


Оное и обсуждалось.
При получении сообщения не-foreground приложение пытается
сделать себя (другого) foreground, что запрещено политикой MS
(и правильно запрещено, IMHO).

--
Regards, LVT.


 
RWolf ©   (2006-10-16 18:01) [10]


> Оное и обсуждалось.При получении сообщения не-foreground
> приложение пытается сделать себя (другого) foreground, что
> запрещено политикой MS(и правильно запрещено, IMHO).


Просто я как раз такой механизм использую для восстановления программы из трея при запуске 2 экземпляра.
Или мы говорим о разных вещах?


 
Leonid Troyanovsky ©   (2006-10-16 18:35) [11]


> RWolf ©   (16.10.06 18:01) [10]

> Или мы говорим о разных вещах?


Мои утверждения вполне, IMHO, применимы
к любым не-foreground windows приложениям.

--
Regards, LVT.


 
gdaujk ©   (2006-10-16 21:09) [12]

...а сколько копий было сломано...

unit gdaOneAppByFileMapping;

interface

var
 MIError: Integer;

const
 MI_ERROR_NONE        = 0;
 MI_ERROR_CREATINGMAP = 1;
 MI_ERROR_MAPPINGFILE = 2;

function GetMEError(): Integer;

implementation

uses Windows, Forms;

var
 hMap: THandle;
 UniqueMes: Integer;

const
 UNIQUE_APP_STR = "{FC9D27F6-D173-4CF6-8A9A-3A2197C72390}"; //желательно изменить

function GetMEError(): Integer;
begin
 Result := MIError;
end;

procedure InitInstance;
var
 pFile: Pointer;
 hApp: HWND;
const
 pFileSize = SizeOf(HWND);
begin
 hMap := CreateFileMapping(INVALID_HANDLE_VALUE,
                            nil,
                            PAGE_READWRITE,
                            0,
                            pFileSize,
                            UNIQUE_APP_STR);
 if GetLastError = ERROR_ALREADY_EXISTS
 then
   begin
     Application.ShowMainForm := False;
     pFile := MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
     if pFile <> nil
     then
       begin
         hApp := HWND(pFile^);
         ShowWindow(hApp, SW_SHOWNORMAL);
         SetForegroundWindow(hApp);
         UnmapViewOfFile(pFile);
       end
     else MIError := MIError or MI_ERROR_MAPPINGFILE;
     Application.Terminate;
   end
 else
   if hMap = 0
   then MIError := MIError or MI_ERROR_CREATINGMAP
   else
     begin
       pFile := MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0);
       if pFile <> nil
       then
         begin
           CopyMemory(pFile, @Application.Handle, pFileSize);
           UnmapViewOfFile(pFile);
         end
       else MIError := MIError or MI_ERROR_MAPPINGFILE;
     end;
end;

initialization
 UniqueMes := RegisterWindowMessage(UNIQUE_APP_STR);
 InitInstance;

finalization
 if hMap <> 0
   then CloseHandle(hMap);

end.


 
Leonid Troyanovsky ©   (2006-10-16 22:15) [13]


> gdaujk ©   (16.10.06 21:09) [12]

>  UNIQUE_APP_STR = "{FC9D27F6-D173-4CF6-8A9A-3A2197C72390}";
>  //желательно изменить


Не желательно, а : Обязательно изменить!

Вообще-то, подобные вещи должны браться из реестра.
Т.е., сделать в HKCU раздел формата
\Software\CompanyName\ProductName\..
где второе, третье и др. брать из Version Info,
ключ ActivatePrevInstance (REG_DWORD) 0x1.
Т.е., имя проекции файла формировать из уникальной цепочки.

Кроме того, для активации предыдущей копии полезно
передавать дополнительно параметры комстроки.
Этого можно добиться, например, перечитыванием mmf
при Application.OnActivate. Хотя, это потребует некоторых
усилий по синхронизации. Например, четыре байта файла
использовать для переменной, которая будет
InterLockedCompareExchange.

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

--
Regards, LVT.


 
gdaujk ©   (2006-10-16 23:06) [14]


> Leonid Troyanovsky ©   (16.10.06 22:15) [13]

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

>

Так предложите. Или хотя бы намекните :-)


 
Leonid Troyanovsky ©   (2006-10-17 20:07) [15]


> gdaujk ©   (16.10.06 23:06) [14]

>> Ну, и для приложений с формами можно предложить

> Так предложите. Или хотя бы намекните :-)


Например:

В CreateWnd (override) главной формы делаем (до inherited)
EnumWindows для поиска окон формы по ее классу, и,
в случае обнаружения такого окна, посылаем ему через
SendMessageTimeOut(wnd, WM_COPYDATA,
параметры комстроки, а также, в cds.dwData - искомый uid.

А в обработчике WM_COPYDATA главной формы полученный uid
сравнивается с собственным, и, в случае равенства,
возвращается (после приема комстроки) Result <> 0.

Т.е., если SendMessageTO успешно - активируем предыдущую копию,
иначе - вызываем inherited для создания окна формы.

Вот, собс-но, вся схема.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2006-10-17 20:20) [16]


> Leonid Troyanovsky ©   (17.10.06 20:07) [15]

> Т.е., если SendMessageTO успешно - активируем предыдущую
> копию,


активируем предыдущую копию и Halt(..),
иначе - вызываем inherited

--
Regards, LVT.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.04 c
15-1162979970
DVM
2006-11-08 12:59
2006.11.26
Подскажите кто пел раньше эту песню.


2-1162908866
m-kirill-2003
2006-11-07 17:14
2006.11.26
Форма и консольное приложение


1-1160956124
Муха
2006-10-16 03:48
2006.11.26
Смена курсора


15-1162746007
ProgRAMmer Dimonych
2006-11-05 20:00
2006.11.26
Глюки The Bat!


15-1162889015
m-kirill-2003
2006-11-07 11:43
2006.11.26
CGI





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский