воскресенье, 24 октября 2010 г.

Я вас предупреждал: опасности подключения к очереди ввода

Это перевод I warned you: The dangers of attaching input queues. Автор: Реймонд Чен.

Некоторые люди не принимают близко к сердцу мои предупреждения о переключении очередей ввода - номер пять в списке вещей, которые должен знать любой Win32 программист. И тогда они обнаруживают, что их приложения перестают отвечать.
// Код в курсиве неверен
procedure TryToStealFocus(const AWnd: HWND);
var
  FGWnd: HWND;
  FGThread: DWORD;
  CurrentThread: DWORD;
begin
  // Сначала пробуем простой SetForegroundWindow
  SetForegroundWindow(AWnd);
  FGWnd := GetForegroundWindow;
  if FGWnd = AWnd then Exit;

  // Это не сработало - если окно переднего плана принадлежит
  // другому потоку, то подключаемся к этому потоку и пробуем снова
  CurrentThread := GetCurrentThreadId;
  FGThread := GetWindowThreadProcessId(FGWnd, nil);
  if dwFGThread = CurrentThread then Exit;

  AttachThreadInput(CurrentThread, FGThread, True);
  SetForegroundWindow(AWnd); // <- зависает тут
  AttachThreadInput(CurrentThread, FGThread, False);
end;
Их данные использования от клиентов показали, что функция часто зависает на втором вызове SetForegroundWindow. Моё упражнение к вам: объяснить почему (а вот ещё один с такой же проблемой).

(Заметьте, что оба человека пытаются обойти блокировку выскакивания окна на передний план, чтобы они могли плюнуть своим окном в лицо пользователя).

2 комментария:

  1. [i][b]"Заметьте, что оба человека пытаются обойти блокировку выскакивания окна на передний план, чтобы они могли плюнуть своим окном в лицо пользователя"[/b][/i]

    блин, а как же программа от хуавейчика это делает? да ещё и по нескольку раз - так настойчиво, что хочется её прибить. Авторы программ от модемов Huawei известны навязыванием окружающему миру своего стиля общения с компьютором. Одну из их повадок, выключение содержимого окон при перетаскивании, уже удалось побороть: достаточно прописать в куда-нибудь в автозапуск программулину с таким кодом SystemParametersInfo(SPI_SETDRAGFULLWINDOWS,Integer(true),nil,0) а вот со второй пока проблемы.

    ОтветитьУдалить

  2. if WindowState = wsMinimized then
    WindowState := wsNormal;

    SetForegroundWindow(Handle);
    Activate;

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.