2010-10-05 1 views
1

im пытается отправить сообщение Windows моему приложению Delphi, но im имеет проблемы с методом FindWindow: im получает идентификатор ошибки 0 из метода GetLastError. Im работает с Vista и с того, что ive читает эту ошибку, распространено в XP или более ранних версиях, но должно отлично работать в Vista или Win 7 (может быть, я неправильно понял?).Получение идентификатора ошибки: 0 из метода Windows: FindWindow

Это код им с помощью и его в DLL файл Delphi, написанный на Delphi 5:

procedure SendData(const copyDataStruct: TCopyDataStruct) ; 
var 
    receiverHandle : THandle; 
    res : integer; 
begin 
    receiverHandle := FindWindow(PChar('TMainForm'),PChar('MainForm')) ; 
    if receiverHandle = 0 then 
    begin 
    ShowMessage(format('Error %x finding MainForm', 
    [GetLastError()])); 
    Exit; 
    end; 

    res := SendMessage(receiverHandle, WM_COPYDATA, Integer(receiverHandle), Integer(@copyDataStruct)) ; 
end; 
+0

Параметр 'Параметр wParam' для этого сообщения должен быть дескриптор * отправителя * этого сообщения, не получатель*. Вот как получатель знает, куда отправить свой ответ. Кроме того, нет необходимости вводить типы строковых литералов; компилятор уже знает, что они должны быть PChars. –

ответ

1

Согласно system error codes list, ошибки 0 означает "ERROR_SUCCESS".

Не может быть, что ваше Окно имеет класс TMainWindow, но имеет пустой Caption?

Смотрите замечания для GetWindowText, что внутренне используемые FindWindow когда параметр lpWindowName не равен нулю (это так: вы проходите MainWindow там).

--jeroen

+0

Мое окно - это TForm, и у него есть надпись. Так что не думайте, что это вина. – Roise

+0

Обнаружена ошибка, я изменил заголовок формы после запуска. Второй параметр в FindWindow не должен быть MainForm :) Спасибо за помощь. – Roise

+0

@Roise, это одна из причин, по которой мне не нравится «FindWindow». Он чувствителен к изменениям косметического интерфейса. –

0

Передача пользовательского сообщения всем окнам. Только ваше окно будет знать, как реагировать на него. Затем он может отвечать своим текущим HWND в другом сообщении, поэтому вещателю не нужно его вручную искать. Используйте RegisterWindowMessage() для регистрации уникальных идентификаторов сообщений, которые игнорируют другие приложения. Например:

App 1:

var 
    WM_WHERE_ARE_YOU: UINT = 0; 
    WM_HERE_I_AM: UINT = 0; 
    App2Wnd: HWND = 0; 

procedure TApp1Form.FromCreate(Sender: TObject); 
begin 
    // use whatever string names you want, as long as they match App 2... 
    WM_WHERE_ARE_YOU := RegisterWindowMessage("WhereAreYou"); 
    WM_HERE_I_AM := RegisterWindowMessage("HereIAm"); 
end; 

procedure TApp1Form.WndProc(var Message: TMessage); 
begin 
    if (Message.Msg = WM_HERE_I_AM) and (WM_HERE_I_AM <> 0) then 
    App2Wnd := HWND(Message.LParam) 
    else 
    inherited; 
end; 

procedure TApp1Form.SendData(const copyDataStruct: TCopyDataStruct); 
var 
    res : integer; 

    procedure FindApp2Window; 
    var 
    Ignore: DWORD; 
    begin 
    App2Wnd := 0; 
    if WM_WHERE_ARE_YOU = 0 then Exit; 
    SendMessageTimeout(HWND_BROADCAST, WM_WHERE_ARE_YOU, 0, Longint(Self.Handle), SMTO_NORMAL, 500, Ignore); 
    if App2Wnd = 0 then Application.ProcessMessages; 
    end; 

begin 
    FindApp2Window; 
    if App2Wnd = 0 then 
    begin 
    ShowMessage(Format('Unable to find MainForm'); 
    Exit; 
    end; 
    res := SendMessage(App2Wnd, WM_COPYDATA, Longint(Self.Handle), Longint(@copyDataStruct)); 
    ... 
end; 

App 2:

var 
    WM_WHERE_ARE_YOU: UINT = 0; 
    WM_HERE_I_AM: UINT = 0; 

procedure TApp2Form.FromCreate(Sender: TObject); 
begin 
    // use whatever string names you want, as long as they match App 1... 
    WM_WHERE_ARE_YOU := RegisterWindowMessage("WhereAreYou"); 
    WM_HERE_I_AM := RegisterWindowMessage("HereIAm"); 
end; 

procedure TApp2Form.WndProc(var Message: TMessage); 
begin 
    case Message.Msg of 
    WM_COPYDATA: 
    begin 
     if PCopyDataStruct(Message.LParam)^.dwData = ... then 
     begin 
     ... 
     Message.Result := 1; 
     Exit; 
     end; 
    end; 
    ... 
    else 
    if (Message.Msg = WM_WHERE_ARE_YOU) and (WM_WHERE_ARE_YOU <> 0) then 
    begin 
     if WM_HERE_I_AM <> 0 then 
     PostMessage(HWND(Message.LParam), WM_HERE_I_AM, 0, Longint(Self.Handle)); 
     Exit; 
    end; 
    end; 

    inherited; 
end;