Значение wparam в GetMessage не соответствует ожиданиям (Delphi XE4)
У меня есть приложение-служба Delphi XE4 в разработке. Служба запускает потоки для некоторых длительных задач, и потоки сообщают о состоянии обратно с помощью вызова PostThreadMessage.
Основной цикл ServiceExecute выглядит следующим образом:
procedure TScanService.ServiceExecute(Sender: TService);
var
CurrentMessage: TMsg;
begin
LogServerEvent('ServiceExecute', 'Starting');
while not Terminated do
begin
if not PeekMessage(CurrentMessage, 0, WM_NULL, msgHigh, PM_NOREMOVE) then
begin
Sleep(1000);
Continue;
end;
GetMessage(CurrentMessage, 0, WM_NULL, msgHigh);
LogServerEvent('ServiceExecute', 'CurrentMessage.message', IntToStr(CurrentMessage.message));
LogServerEvent('ServiceExecute', 'CurrentMessage.wParam', IntToStr(CurrentMessage.wParam));
LogServerEvent('ServiceExecute', 'CurrentMessage.lParam', IntToStr(CurrentMessage.lParam));
В ветке отправка сообщения выглядит так:
gThreadNumber: Integer;
LogThreadEvent('Execute', 'Found Notice, Thread number: ' + IntToStr(gThreadNumber));
PostThreadMessage(ParentThreadID, msgFound, gThreadNumber, 6);
Сообщение приходит нормально, и номер сообщения правильный (msgFound = WM_USER + 1); однако я послал 0, 6 для wParam, lParam, и я получил 4, 0. Чего мне не хватает?
Примечание. В коде работают только 2 потока, и один из них представляет собой таймер, который использует другой номер сообщения и ничего не отправляет, когда это происходит.
1 ответ
В TService
код вы можете найти этот код:
const
CM_SERVICE_CONTROL_CODE = WM_USER + 1;
....
procedure TService.Controller(CtrlCode: DWord);
begin
PostThreadMessage(ServiceThread.ThreadID, CM_SERVICE_CONTROL_CODE, CtrlCode, 0);
if ServiceThread.Suspended then ServiceThread.Resume;
end;
Так TService
отправляет сообщения с тем же номером сообщения, что и ваши сообщения. Как вы можете отличить их? Ну, ты не можешь.
Из документации для WM_USER
:
Используется для определения личных сообщений для использования классами частного окна, обычно в форме WM_USER+x, где x - целочисленное значение.
Обычно это используется для сообщений, отправляемых окну, и значение сообщения зависит от класса. Пока я читаю TService
В коде разработчики взяли точку зрения, что они полностью контролируют очередь сообщений и имеют право определять смысл своих личных сообщений. Конечным результатом этого является то, что вы не можете использовать сообщения потока в WM_USER
диапазон, потому что они были зарезервированы TService
учебный класс.
Ваши основные варианты:
- Отправляйте свои сообщения в окно.
- использование
RegisterWindowMessage
обеспечить уникальность идентификатора сообщения. - Прекратите использовать сообщения Windows (не специально предназначенные для использования в службе) и общайтесь, используя какой-либо другой механизм.