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


Автор: ДЫМ 25.11.2012, 22:03
Уважаемые коллеги, требуется ваш совет.

Я писал программу, когда у меня стояла Windows XP. Теперь у меня стоит Windows 7.  Delphi 7 я поставил в Windows 7 внес в мою старую программу нужные мне изменения и откомпилировал заново. Чтобы было понятно, расскажу что делает программка. После запуска моя программка запускает стороннюю программу посредством CreateProcess. Вот в этой запущенной программе мне надо нажать программно кнопку [Сохранить]. Я получаю дескриптор кнопки и посылаю сообщение кнопке (нажатие левой кнопки мыши). Так вот, кнопка не нажимается, однако если моей прогамме установить совместимость с Win XP, то все работает и кнопка нажимается, причем в IDE Delphi по нажатию F9 программка компилируется, запускается и все нормально, кнопка нажимается. Но если убрать совместимость самого Delphi с Win XP, то кнопка перестает нажиматься. Все остальное в программе работает как надо. Я думал, что проблема в SendMessage, попробовал сделать через SendInput, картина такая же, кнопка нажимается только в режиме совместимости с Win XP. Неужели ничего нельзя сделать? Только не предлагайте установить Delphi 2010, там мою программу надо переделывать основательно, читать документацию по новой среде, я пробовал, но решил такой вариант оставить на случай, когда больше уже ничего не поможет. Может быть кто-нибудь сталкивался с подобными проблемами совместимости? 
Вот фрагмент кода, который не работает в Win 7 и работает в Win XP.

Код

procedure PressEnter;
var K: array [0..1] of TInput; 
begin
  ZeroMemory(@K, SizeOf(TInput)*2); 
  K[0].Itype := INPUT_KEYBOARD; 
  K[0].ki.wVk := VK_RETURN; 
  K[1].Itype := INPUT_KEYBOARD;
  K[1].ki.wVk := VK_RETURN;
  K[1].ki.dwFlags := KEYEVENTF_KEYUP; 
  SendInput(2,K[0],SizeOf(TInput)); 
end;

...

CreateProcess(
     nil,
     PChar( fcGetDir(dirTemp)+sNameFile ),  
     nil, nil, False,
    NORMAL_PRIORITY_CLASS, nil, nil,
    si, pi);

    WaitForInputIdle(pi.hProcess, INFINITE); 
//    Sleep(100);
    EnumThreadWindows(pi.dwThreadId, @EnumThrWndProc, 0);


    SetForegroundWindow(MainHandle);
    wndbutton := FindWindowEx(MainHandle, 0, nil, 'Сохранить');

   // вариант с отправкой сообщения

    PostMessage(wndbutton,WM_LBUTTONDOWN,0,0);

    PostMessage(wndbutton,WM_LBUTTONUP,0,0);


  // вариант с SendInput
  PressEnter;



Автор: kami 25.11.2012, 22:44
Приложение, запускаемое через CreateProcess требует повышения прав?
Где анализ того, что вернуло PostMessage и SendInput?

UPD: в следующий раз не знаю, когда появлюсь, посему небольшие пояснения:
по поводу повышения прав: отправка сообщения другому процессу возможна, если этот "другой процесс" имеет IntegrityLevel (грубо говоря - права) равные, или меньше, чем процесс, вызывающий SendMessage. То есть, если в Win7 запустить свое приложение с обычными правами, то оно не сможет отправить сообщение (в том числе - SendInput) в другое приложение, запущенное "от администратора".

по поводу анализа: должно быть что-то типа
Код

res := PostMessage(...);
if res = 0 then
  raiseLastOSError;

И на основании этого уже смотреть, что и как.

UPD2: Читать ремарки в MSDN к функциям PostMessage и SendInput. Ну и значение, возвращаемое CreateProcess не помешает проверять до кучи.

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