Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.11.2012, 01:23   #1
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию procedure ..(var msg:TMessage); message MY_MSG; отрабатывает 1 раз!?

Доброго времени!

Имеется собственное оконное сообщение(регистрируется в конструкторе формы), и на него стоит хук.

Конструктор формы:
Код:
procedure TMainForm.FormCreate(Sender: TObject);
var
  d: PInteger;
  aInt: Integer;
begin
  ...
  if IsAlreadyRunning(aInt) then //Если копия ПО существует, то в aInt пишется дескриптор гл. окна
  begin
    PostMessage(aInt, MY_MSG, 0, 0); //Оправляется сообщение с целью "Юзер забыл что ты есть, покажи себя!"
    Application.Terminate; //Убить 2-ю копию. 
  end;

  //Если это первый экземпляр ПО
  hMMF := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, 4096,
    PChar(MMFName));
  RegisterWindowMessage('MY_MSG'); 
  d := MapViewOfFile(hMMF, FILE_MAP_WRITE, 0, 0, 0);
  try
    d^ := Handle;
  finally
    UnmapViewOfFile(d);
  end;
Хук на сообщение:
Код:
procedure TMainForm.MMFHandler(var MSG: TMessage);
begin
  if MSG.MSG = MY_MSG then
  begin
    TrayHideShowBtn.Caption := DM.GetTranslatableConst(TC_TRAY_HIDECAPTION);
    TrayHideShowBtn.ImageIndex := 6;

    Application.MainForm.Show;
    Application.ShowMainForm := true;
    FlashWindow(Application.MainFormHandle, true);
  end;
end;
Хук отрабатывает только 1 раз, почему?
Во второй и 3-й раз, в него даже не заходит отладчик.
Человек_Борща вне форума Ответить с цитированием
Старый 13.11.2012, 01:42   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

там помоему надо добавлять inherited, правда не помню в начале или в конце.
и так же, зачем проверка на тип сообщения? у вас же обработчик строго оного.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 13.11.2012, 15:38   #3
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Код:
inherited
Нужен только для оконных сообщений.

Даже если бы это было не так, все равно сообщение доходило бы до меня, но дальше не шло. Однако, этого не происходит вообще. Хук срабатывает 1 раз, за 1 запуск ПО и больше не отрабатывает.
Человек_Борща вне форума Ответить с цитированием
Старый 13.11.2012, 15:44   #4
Кольша
Далеко не
Участник клуба
 
Аватар для Кольша
 
Регистрация: 11.08.2011
Сообщений: 1,512
По умолчанию

может wm_copydata?и mutex? отлично срабатывает всегда...
Кольша вне форума Ответить с цитированием
Старый 13.11.2012, 16:29   #5
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

Цитата:
в aInt пишется дескриптор гл. окна
Главное окно VCL-приложения и окно главной формы VCL-приложения - не одно и тоже, это совершенно разные окна.

Цитата:
PostMessage(aInt, MY_MSG, 0, 0);
Логично было бы предположить что ниже следует вызов функции

MY_MSG := RegisterWindowMessage('MY_MSG');

А его-то как раз и нет, код зарегистрированного сообщения благополучно похерен, так что непонятно как это вообще работате хотя бы 1 раз.

Цитата:
Application.Terminate; //Убить 2-ю копию.
Terminate ничего не "убивает", всего лишь выставляется флаг завершения, так что выполнение программы боагополучненько продолжается со строчки следующей сразу за комментарием
//Если это первый экземпляр ПО
xoodoo вне форума Ответить с цитированием
Старый 13.11.2012, 17:37   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Код:
Главное окно VCL-приложения и окно главной формы VCL-приложения - не одно и тоже, это совершенно разные окна.
Тогда как правильно сделать? Нужно поставить именно главное окно. Хотя этот код можно и в OnShow поставить.

Далее как правильно регистрировать свое сообщение?
Точнее у меня есть переменная vMY_MSG:THandle в неё я регистрирую RegisterWindowMessage('MY_MSG')

КАк второму приложению узнать, какую команду послать?
Человек_Борща вне форума Ответить с цитированием
Старый 13.11.2012, 21:52   #7
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

Цитата:
vMY_MSG:THandle в неё я регистрирую RegisterWindowMessage('MY_MSG')
В упор не вижу этого в твоем коде.
xoodoo вне форума Ответить с цитированием
Старый 14.11.2012, 18:58   #8
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Кто-нибудь направит на путь истинный?
Есть сабж с RegisterWindowMessage:
Цитата:
procedure TMainForm.WndProc(var MSG: TMessage);
begin
inherited;
if MSG.MSG = MY_MSG then
begin
TrayHideShowBtn.Caption := DM.GetTranslatableConst(TC_TRAY_HID ECAPTION);
TrayHideShowBtn.ImageIndex := 6;

Application.MainForm.Show;
Application.ShowMainForm := true;
FlashWindow(Application.MainFormHan dle, true);
end;
end;

procedure TMainForm.FormCreate(Sender: TObject);
var
d: PInteger;
aInt: Integer;
begin
LoadLangSettings;
MY_MSG := RegisterWindowMessage('MY_MSG ');
if IsAlreadyRunning(aInt) then
begin
PostMessage(aInt, MY_MSG , 0, 0);
Application.Terminate;
end;

hMMF := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, 4096,
PChar(MMFName));

d := MapViewOfFile(hMMF, FILE_MAP_WRITE, 0, 0, 0);
try
d^ := Application.Handle;
finally
UnmapViewOfFile(d);
end;
Нифига не работает -(
Человек_Борща вне форума Ответить с цитированием
Старый 16.11.2012, 22:41   #9
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Такс, отказался от RegisterWindowMessage.
Просто задал константу WM_USER + какое-то число;

Создал пустую форму, в конструкторе которой:
Код:
var
  EmptyForm: TEmptyForm;

implementation

uses MainFormUnit,uConsts;

{$R *.dfm}

procedure TEmptyForm.FormCreate(Sender: TObject);
var
  d: PInteger;
  aInt: Integer;
begin
  if IsAlreadyRunning(aInt) then
  begin
    PostMessage(aInt, MY_MSG, 0, 0);
    Application.Terminate;
  end;

  hMMF := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, 4096,
    PChar(MMFName));

  d := MapViewOfFile(hMMF, FILE_MAP_WRITE, 0, 0, 0);
  try
    d^ := MainForm.Handle;
  finally
    UnmapViewOfFile(d);
  end;
end;

procedure TEmptyForm.FormDestroy(Sender: TObject);
begin
  CloseHandle(hMMF);
end;
Фукнкция:
Код:
var
  myDir: string;
  hMMF: Thandle; // Идентификатор MMF

function IsAlreadyRunning(out aResult: Integer): Boolean;

implementation


function IsAlreadyRunning(out aResult: Integer): Boolean;
var
  hmMMF: Thandle;
  pReadInt: PInteger;
begin
  aResult := -1;
  hmMMF := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, PChar(MMFName));
  try
    Result := (hmMMF <> 0);
    if Result then // if true...
    begin
      pReadInt := MapViewOfFile(hmMMF, FILE_MAP_ALL_ACCESS, 0, 0, 0);
      try
        if (pReadInt <> nil) then
          aResult := pReadInt^; //<<- ПРОБЛЕМА! 
      finally
        UnmapViewOfFile(pReadInt);
      end;
    end;
  finally
    CloseHandle(hmMMF);
  end;
end;
Суть в том, что код работает только 1 раз.
В IsAlreadyIsRunning в aResult каждый раз новые числа лезут, а должно быть одно и тоже.
Может я не правильно читаю оттуда?
Человек_Борща вне форума Ответить с цитированием
Старый 17.11.2012, 14:17   #10
Кольша
Далеко не
Участник клуба
 
Аватар для Кольша
 
Регистрация: 11.08.2011
Сообщений: 1,512
По умолчанию

Чем вас mutex'ы не устраивают?Я их предложил уже давненько..
Кольша вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
SendMessage параметр msg Fatal Error Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 22.06.2012 19:05
var p:procedure Кольша Мультимедиа в Delphi 4 04.01.2012 21:36
The message resource is present but the message is not found in the string/message table Apokal Win Api 0 19.05.2011 18:06
jbutton.setEnabled не отрабатывает sashonk Общие вопросы по Java, Java SE, Kotlin 1 27.11.2010 07:04
TMessage для кнопки spamer Общие вопросы Delphi 14 17.08.2009 23:08