Конференция "WinAPI" » Вот есть PostMessage и SendMessage
 
  • tippa © (03.04.10 16:23) [0]
    Вот есть PostMessage и SendMessage.
    Правильно ли я мыслю?->

    Первое ставит сообщение в очередь и код идет выполняться дальше, то есть
    PostMessage(H,BM_CLICK,0,0);
    //дальнейший код


    Здесь "//дальнейший код" может быть выполнен до того, как нажмется кнопка. Если я хочу чтобы "//дальнейший код" выполнялся только после нажатия кнопки, я должен после PostMessage вставить Application.ProcessMesseges;
    PostMessage(H,BM_CLICK,0,0);
    Application.ProcessMesseges;
    //дальнейший код



    Функция SendMessage шлет сообщение сразу, то есть
    SendMessage(H,BM_CLICK,0,0);
    //дальнейший код


    здесь "//дальнейший код" не начнет выполнятся пока не нажмется клаваша.

    Получается что код
    PostMessage(H,BM_CLICK,0,0);
    Application.ProcessMesseges;


    эквивалентен коду
    SendMessage(H,BM_CLICK,0,0);



    верно?
  • DVM © (03.04.10 16:30) [1]
    Ну вобщем верно.
  • Игорь Шевченко © (03.04.10 18:48) [2]

    > верно?


    нет
  • Игорь Шевченко © (03.04.10 18:54) [3]
  • DVM © (03.04.10 19:38) [4]

    > Игорь Шевченко ©   (03.04.10 18:48) [2]


    > нет

    Я не вижу никаких принципиальных отличий [0] от [3]. Кроме разве что в [3] более подробно и рассматривается SendNotifyMessage и прочие функции.

    Единственно в [0] мне не нравится вот это:

    PostMessage(H,BM_CLICK,0,0);
    Application.ProcessMesseges;

    Притягивание за уши асинхронного к синхронному. И проблемы возможны.
  • Игорь Шевченко © (03.04.10 19:39) [5]
    DVM ©   (03.04.10 19:38) [4]

    Мое "Нет" относится к тому, что код неэквивалентен. И он действительно неэквивалентен :)
  • DVM © (03.04.10 19:48) [6]

    > Игорь Шевченко ©   (03.04.10 19:39) [5]

    Ааа. Я подумал, что это относится к

    > Правильно ли я мыслю?
  • Игорь Шевченко © (03.04.10 19:56) [7]

    > Правильно ли я мыслю?->


    > здесь "//дальнейший код" не начнет выполнятся пока не нажмется
    > клаваша.


    Дальнейший код не будет выполняться, пока не вернется вызов оконной процедуры, а нажмется ли при этом клавиша - а фиг его знает.
  • DVM © (03.04.10 20:07) [8]

    > Дальнейший код не будет выполняться, пока не вернется вызов
    > оконной процедуры

    Скорее всего он это и имел в виду просто так не совсем аккуратно написал. По крайней мере я понял как про возврат функции. О кнопке даже и не думал.
  • Германн © (04.04.10 02:19) [9]

    > Игорь Шевченко ©   (03.04.10 19:39) [5]
    >
    > DVM ©   (03.04.10 19:38) [4]
    >
    > Мое "Нет" относится к тому, что код неэквивалентен. И он
    > действительно неэквивалентен :)
    >

    Именно так. И прежде всего потому, что обработка сообщения посланного через SendMessage будет выполнена сразу, даже если в очереди сообщений сему окну на сей момент уже есть другие сообщения. Т.е. влезет первым в очередь как VIP-клиент. А PostMessage просто встанет в очередь как добропослушный гражданин Виндовс.
  • Leonid Troyanovsky © (04.04.10 07:23) [10]

    > Германн ©   (04.04.10 02:19) [9]

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

    У синхронных сообщений своя очередь.

    --
    Regards, LVT.
  • Leonid Troyanovsky © (04.04.10 09:23) [11]

    > tippa ©   (03.04.10 16:23)  

    > Получается что код
    > PostMessage(H,BM_CLICK,0,0);
    > Application.ProcessMesseges;
    > эквивалентен коду
    > SendMessage(H,BM_CLICK,0,0);

    Попытаюсь составить краткое резюме:

    Выполнение первого варианта зависит от текущего состояния
    очереди асинхронных сообщений.
    Например, после  ProcessMessages может оказаться, что h уже
    невалиден, бо и кнопки никакой нет.

    SendMessage ставит сообщение в очередь синхронных сообщений,
    позволяющих делать описанное в статье по ссылке [3],
    в отличии, скажем Perform, напрямую зовущей оконную процедуру.

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

    --
    Regards, LVT.
  • Игорь Шевченко © (04.04.10 11:42) [12]
    Leonid Troyanovsky ©   (04.04.10 09:23) [11]


    > Для однопоточного приложения нужда в посланиях собственным
    > окнам весьма экзотична


    Ну почему же ? Для реализации паттерна "сделай что-то там, только потом, но не забудь".
  • Leonid Troyanovsky © (04.04.10 12:05) [13]

    > Игорь Шевченко ©   (04.04.10 11:42) [12]

    > Ну почему же ? Для реализации паттерна "сделай что-то там,
    >  только потом, но не забудь".

    Все уже сделано до нас: TApplicationEvents.OnIdle.

    --
    Regards, LVT.
  • Игорь Шевченко © (04.04.10 12:28) [14]
    Leonid Troyanovsky ©   (04.04.10 12:05) [13]

    Не понял. Обработка сообщений может касаться отдельных форм и какой смысл тащить весь этот огород в Application.OnIdle ?
  • Leonid Troyanovsky © (04.04.10 12:54) [15]

    > Игорь Шевченко ©   (04.04.10 12:28) [14]

    > Не понял. Обработка сообщений может касаться отдельных форм
    > и какой смысл тащить весь этот огород в Application.OnIdle

    Я про TApplicationEvents.
    Все просто: кладешь на форму, и метод формы назначаешь.

    Можно и в рантайм создать, обработчик - снова метод формы.

    --
    Regards, LVT.
  • Дмитрий С © (04.04.10 17:03) [16]

    > Для однопоточного приложения нужда в посланиях собственным
    > окнам весьма экзотична

    Я использую PostMessage(Handle, WM_USER+1, к примеру) собственной формы в обработчике OnShow. А в обработчике сообщения WM_USER+1 выполняю код, который необходимо выполнить сразу после появления формы на экране, например, обновление списка.
    Это как пример. Можно, конечно, первый OnIdle после OnShow обработать, но с сообщением, имхо проще и нагляднее.
  • Leonid Troyanovsky © (04.04.10 18:04) [17]

    > Дмитрий С ©   (04.04.10 17:03) [16]

    > Я использую PostMessage(Handle, WM_USER+1, к примеру) собственной
    > формы в обработчике OnShow.

    А чего б в OnShow коду не выполниться?

    --
    Regards, LVT.
  • Игорь Шевченко © (04.04.10 19:12) [18]
    Leonid Troyanovsky ©   (04.04.10 18:04) [17]

    А в OnShow форма еще не видна.

    Сравни поведение в двух случаях:

    type
     TForm1 = class(TForm)
       procedure FormShow(Sender: TObject);
     end;

    procedure TForm1.FormShow(Sender: TObject);
    begin
     Sleep(3000);
    end;



    и

    const
      UM_SLEEP = WM_APP + 1;
    type
     TForm1 = class(TForm)
       procedure FormShow(Sender: TObject);
     private
       procedure UmSleep (var Message: TMessage); message UM_SLEEP;
     end;

    procedure TForm1.FormShow(Sender: TObject);
    begin
     PostMessage(Handle, UM_SLEEP, 0, 0);
    end;

    procedure TForm1.UmSleep(var Message: TMessage);
    begin
     Sleep(3000);
    end;

  • Leonid Troyanovsky © (04.04.10 19:59) [19]

    > Дмитрий С ©   (04.04.10 17:03) [16]

    > Я использую PostMessage(Handle, WM_USER+1, к примеру) собственной
    > формы в обработчике OnShow. А в обработчике сообщения WM_USER+1
    > выполняю код, который необходимо выполнить сразу после появления
    > формы на экране, например, обновление списка.

    > Игорь Шевченко ©   (04.04.10 19:12) [18]

    > А в OnShow форма еще не видна.

    И обновление списка не выполнится?

    Ну, пусть так.
    TForm.UpdateActions - там оно выполнится наверняка.

    --
    Regards, LVT.
 
Конференция "WinAPI" » Вот есть PostMessage и SendMessage
Есть новые Нет новых   [134431   +16][b:0][p:0.001]