Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > PostMessage срабатывает, а SendMessage нет


Автор: JustCoder 1.1.2007, 21:22
Код библиотеки Tracker.dpr:
Код

library tracker;

uses
  Windows, Messages, Shared;

var
  hKeyBoardHook: THandle = 0;

function KeyBoardHook(nCode, wParam, lParam: Integer): lResult; stdcall;
begin
  if (nCode >= 0) and (GlobalData^.hForm <> 0) then
    //SendMessage(GlobalData^.hForm, WMKeyHook, 0, 0);
    PostMessage(GlobalData^.hForm, WMKeyHook, 0, 0);
  Result:= CallNextHookEx(hKeyBoardHook, nCode, wParam, lParam);
end;

procedure SetHook;
begin
  if hKeyBoardHook = 0 then
    hKeyBoardHook:= SetWindowsHookEx(WH_KEYBOARD, @KeyBoardHook, hInstance, 0);
end;

procedure RemoveHook;
begin
  if hKeyBoardHook <> 0 then
    begin
      UnhookWindowsHookEx(hKeyBoardHook);
      hKeyBoardHook:= 0;
    end;
end;

procedure DLLEntryPoint(dwReason: DWord);
begin
  case dwReason of
    DLL_PROCESS_ATTACH: OpenSharedData;
    DLL_PROCESS_DETACH: CloseSharedData;
  end;
end;

exports
  GetDLLData,
  RemoveHook,
  SetHook;

begin
  DllProc:= @DLLEntryPoint;
  DLLEntryPoint(DLL_PROCESS_ATTACH);
end.

Код юнита Shared.pas:
Код

unit Shared;

interface

uses
  Windows;

type
  PGlobalDLLData = ^TGlobalDLLData;
  TGlobalDLLData = record
    hForm: HWND;
  end;

const
  MapFileName: PAnsiChar = 'Test';
var
  GlobalData: PGlobalDLLData;
  hMap: THandle;
  SA: TSecurityAttributes;
  WMKeyHook: Integer = 0;

procedure GetDLLData(var PGlobalData: PGlobalDLLData);
procedure OpenSharedData;
procedure CloseSharedData;

implementation

procedure GetDLLData(var PGlobalData: PGlobalDLLData);
begin
  PGlobalData:= GlobalData;
end;

procedure OpenSharedData;
var
  Size: Integer;
begin
  Size:= SizeOf(TGlobalDLLData);
  hMap:= CreateFileMapping(DWord(-1), @SA, PAGE_READWRITE, 0, Size, MapFileName);
  GlobalData:= MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, Size);
  if GlobalData = nil then
    CloseHandle(hMap);
end;

procedure CloseSharedData;
begin
  UnmapViewOfFile(GlobalData);
  CloseHandle(hMap);
end;

initialization
  WMKeyHook:= RegisterWindowMessage(MapFileName);
  SA.nLength:= SizeOf(SA);
  SA.bInheritHandle:= True;
  GetMem(SA.lpSecurityDescriptor, SECURITY_DESCRIPTOR_MIN_LENGTH);
  InitializeSecurityDescriptor(SA.lpSecurityDescriptor, 1{SECURITY_DESCRIPTOR_REVISION});
  SetSecurityDescriptorDacl(SA.lpSecurityDescriptor, True, nil, False); //All access
finalization
  FreeMem(SA.lpSecurityDescriptor, SECURITY_DESCRIPTOR_MIN_LENGTH);
end.

Код проекта Project1.dpr: 
Код

unit Unit1;

interface

uses
  Windows, Forms, Shared, Classes, AppEvnts;

type
  TForm1 = class(TForm)
    ApplicationEvents1: TApplicationEvents;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  
procedure RemoveHook; external 'Tracker.dll';
procedure SetHook; external 'Tracker.dll';
procedure GetDLLData(var AGlobalData: PGlobalDLLData); external 'Tracker.dll';

var
  Form1: TForm1;
  FData: PGlobalDLLData;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  GetDLLData(FData);
  FData^.hForm:= Handle;
  SetHook;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  RemoveHook;
end;

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
begin
  if Msg.message = WMKeyHook then
    MessageBox(0, 'KeyBoardHook', 'Test', MB_OK);
end;

end.

Пример демонстрирует извещение основного приложения о срабатывании хука на клаву. Суть проблемы заключается в том, что в фунции хука клавиатуры KeyBoardHook вызов PostMessage срабатывает, а SendMessage нет. Исходники примера прикреплены. Попробуйте изменить SendMessage на PostMessage для проверки эффекта. В чём может быть проблема?

Автор: Fin 1.1.2007, 23:10
SendMessage По идее говоря и не должен работать, если у тебя глобальный хук.   

Автор: anwe 3.1.2007, 23:24
SendMessage возвращает управление после получения ответа функции, а PostMessage не ждет ответа, то есть сразу выполняется следующая строка твоей программы.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)