Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Позиция диалогового окна, Помогите поместить над трейем 
:(
    Опции темы
navodri
Дата 9.7.2010, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 173
Регистрация: 26.10.2007

Репутация: нет
Всего: -1



Хочу поместить диалоговое окно в нижнем правом углу, над трейем, как это делает QIP (всплывающие сообщения). Но мое окно перекрывает трей. Прошу помощи.

Код

var
 trayHandle: HWND;
 trayRect, dlgRect: TRect;
 x, y: integer;

...

  WM_INITDIALOG:
    begin
     trayHandle := FindWindow('Shell_TrayWnd', nil);
     if trayHandle <> 0 then GetWindowRect(trayHandle, trayRect);

     y:= GetSystemMetrics(SM_CYSCREEN);
     x := GetSystemMetrics(SM_CXSCREEN);
     GetWindowRect(Hwin, dlgRect);
     dec(y, dlgRect.Bottom - dlgRect.TopLeft.y); //Вот здесь у меня что-то неправильно?..

     SetWindowPos(Hwin, HWND_TOPMOST,
      x - (dlgRect.Right - dlgRect.left),
      y,
      dlgRect.Right - dlgRect.Left,
      dlgRect.Bottom - dlgRect.Top,
      SWP_SHOWWINDOW or SWP_NOACTIVATE or SWP_NOSIZE);
    end;



PM MAIL WWW   Вверх
Maks1509
Дата 9.7.2010, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 22.8.2007
Где: г. Тольятти

Репутация: 3
Всего: 5



Код

  trayHandle := FindWindow('Shell_TrayWnd', nil);
  if (trayHandle <> 0) then
  begin

    GetWindowRect(trayHandle, trayRect);

    y := GetSystemMetrics(SM_CYSCREEN);
    x := GetSystemMetrics(SM_CXSCREEN);

    GetWindowRect(hWnd, dlgRect);
    SetWindowPos(
      hWnd,
      HWND_TOPMOST,
      x - (dlgRect.Right - dlgRect.Left),
      trayRect.Top - (dlgRect.Bottom - dlgRect.Top)
      {y - (trayRect.Bottom - trayRect.Top) - (dlgRect.Bottom - dlgRect.Top)},
      0,
      0,
      SWP_NOACTIVATE or SWP_NOSIZE
    );

  end;


?
PM MAIL ICQ   Вверх
navodri
Дата 9.7.2010, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 173
Регистрация: 26.10.2007

Репутация: нет
Всего: -1



Спасибо! А как раположить второе окно, выше предыдущего?
PM MAIL WWW   Вверх
Maks1509
Дата 9.7.2010, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 22.8.2007
Где: г. Тольятти

Репутация: 3
Всего: 5



Зависит от твоего способа реализации. Как вариант, завести массив дескрипторов всплывающих окон. Если надо отобразить окно, проходимся по всему массиву, считываем координаты каждого окна оттуда и к примеру увеличиваем нашу переменную с высотой всех наших всплывающих окон. Не знаю, можно посмотреть исходные коды ICQ мессенджеров как там реализовано все это. Сложно сказать на этот счет.
PM MAIL ICQ   Вверх
navodri
Дата 9.7.2010, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 173
Регистрация: 26.10.2007

Репутация: нет
Всего: -1



Я понял, хорошо. С этим буду думать. 
По ходу вопрос: а как сделать "всплывающее" с низу окно? Понимаю, что в таймере придется реализовывать SetWindowPos. Есть у кого-то пример?
PM MAIL WWW   Вверх
Maks1509
Дата 9.7.2010, 23:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 22.8.2007
Где: г. Тольятти

Репутация: 3
Всего: 5



Высоту всплывающего окна и системой панели вычисляешь, получится какое-то значение. Ну в цикле можно через while какую-нибудь переменную уменьшать на 1, которая первоначально была равна высоте экрана, до значения = высота экрана - высота всплывающего окна - высота системной панели. По этому результирующему значению выводишь свое всплывающее окно. 
smile 
PM MAIL ICQ   Вверх
Keeper89
Дата 9.7.2010, 23:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 14
Всего: 58



Ребяты, запоминать координаты левого верхнего угла нового окошка не проще?

А анимацию можно сделать с помощью AnimateWindow (#1#2).

Это сообщение отредактировал(а) Keeper89 - 9.7.2010, 23:58


--------------------
PM MAIL WWW   Вверх
navodri
Дата 11.7.2010, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 173
Регистрация: 26.10.2007

Репутация: нет
Всего: -1



Итак, с позицией окна разобрались. Теперь бы как-нибудь прояснить ситуацию в таймере с функцией SetWindowPos. Вообще не понимаю, как это сделать?

Код

const
 ID_TIMER_POPUPWINDOW = 300;

function DlgProc(hWin: HWND; uMsg: UINT; wp: WPARAM; lp: LPARAM): bool; stdcall;
var
 trayHandle: HWND;
 trayRect, dlgRect: TRect;
 x, y: integer;
 leaveTop: Integer;
begin
 Result := False;
  case uMsg of
   WM_INITDIALOG:
    begin

     trayHandle := FindWindow('Shell_TrayWnd', nil);
      if (trayHandle <> 0) then begin
       GetWindowRect(trayHandle, trayRect);
       y := GetSystemMetrics(SM_CYSCREEN);
       x := GetSystemMetrics(SM_CXSCREEN);
       GetWindowRect(hWin, dlgRect);
       SetWindowPos(hWin, HWND_TOPMOST, x - (dlgRect.Right - dlgRect.Left),
        trayRect.Top - (dlgRect.Bottom - dlgRect.Top), 0, 0, SWP_NOACTIVATE or SWP_NOSIZE);
      end;
     SetTimer(hWin, ID_TIMER_POPUPWINDOW, 1, nil);
    end;

   WM_TIMER: //Таймер
    case LOWORD(wp) of
     ID_TIMER_POPUPWINDOW:
      begin
      //Выезжаем вверх
      leaveTop := trayRect.Top - 200;
       while dlgRect.Top > leaveTop do begin
        dlgRect.Top := dlgRect.Top-2;

        SetWindowPos(); //Вот здесь помогите!

       end;
        KillTimer(hWin, ID_TIMER_POPUPWINDOW);
      end;
    end;

   WM_DESTROY, WM_CLOSE:
    begin
     PostQuitMessage(0);
    end;
 end;
end;


PM MAIL WWW   Вверх
Snowy
Дата 12.7.2010, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 30
Всего: 484



Цитата(navodri @  9.7.2010,  13:57 Найти цитируемый пост)
Хочу поместить диалоговое окно в нижнем правом углу, над трейем
Как человек, у которого трей уже лет 10 находится в левом нижнем углу, могу сказать "ну-ну..."
Также не учтён вариант с несколькими мониторами, когда имеет место быть точка отсчёта <> 0. В данном случае ширина или высота экрана не есть координата края.
Также не учитывается автохайд. Если панель спряталась, то какой смысл вычитать её высоту?
Нужно не экран мерять, а десктоп. Координаты правого нижнего угла которого найти несложно:
Код
  x := GetSystemMetrics(SM_CXVIRTUALSCREEN) - GetSystemMetrics(SM_XVIRTUALSCREEN);
  y := GetSystemMetrics(SM_CYVIRTUALSCREEN) - GetSystemMetrics(SM_YVIRTUALSCREEN);

PM MAIL   Вверх
navodri
Дата 12.7.2010, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 173
Регистрация: 26.10.2007

Репутация: нет
Всего: -1



2Snowy: Спасибо. Об этом и не подумал. Учту.

Ребята, пожалуйста, помогите решить тему с выезжанием окна вверх. Сам не справлюсь:

Код

 WM_TIMER:
    case LOWORD(wp) of
     ID_TIMER_POPUPWINDOW:
      begin
      //Выезжаем вверх
      leaveTop := trayRect.Top - dlgRect.Top;
       while dlgRect.Top > leaveTop do begin
        dlgRect.Top := dlgRect.Top-2;

        SetWindowPos();

       end;
        KillTimer(hWin, ID_TIMER_POPUPWINDOW);
      end;
    end;


Это сообщение отредактировал(а) navodri - 12.7.2010, 12:47
PM MAIL WWW   Вверх
Snowy
Дата 12.7.2010, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 30
Всего: 484



А в чём проблема-то?
Навскидку вижу, что окно у тебя не выезжает потому, что нет вызова цикла обработки сообщений.
Но проще воспользоваться AnimateWindow, чем городить велосипед.
А, учитывая, что таких окошек у тебя может быть несколько, то выезжать вручную будет к тому же и нелепо.
Юзай AnimateWindow. Так и проще и корректней.
PM MAIL   Вверх
navodri
Дата 12.7.2010, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 173
Регистрация: 26.10.2007

Репутация: нет
Всего: -1



Вроде, всё сделал правильно, но не работает. Помогите!

Код

const
 ID_TIMER_POPUPWINDOW = 300;

function DlgProc(hWin: HWND; uMsg: UINT; wp: WPARAM; lp: LPARAM): bool; stdcall;
var
 trayHandle: HWND;
 trayRect, dlgRect: TRect;
 x, y: integer;
 leaveTop: Integer;
begin
 Result := False;
  case uMsg of

   WM_INITDIALOG:
    begin
     trayHandle := FindWindow('Shell_TrayWnd', nil);
      if (trayHandle <> 0) then begin
       GetWindowRect(trayHandle, trayRect);
       x := GetSystemMetrics(SM_CXVIRTUALSCREEN) - GetSystemMetrics(SM_XVIRTUALSCREEN);
       y := GetSystemMetrics(SM_CYVIRTUALSCREEN) - GetSystemMetrics(SM_YVIRTUALSCREEN);
       GetWindowRect(hWin, dlgRect);
      end;
     SetTimer(hWin, ID_TIMER_POPUPWINDOW, 1, nil);
    end;

   WM_TIMER:
    case LOWORD(wp) of
     ID_TIMER_POPUPWINDOW:
      begin
       leaveTop := trayRect.Top - (dlgRect.Bottom - dlgRect.Top);
        while dlgRect.Top > leaveTop do begin
         dlgRect.Top := dlgRect.Top-2;
         SetWindowPos(hWin, HWND_TOPMOST, x - (dlgRect.Right - dlgRect.Left), dlgRect.Top, 0, 0, SWP_NOACTIVATE or SWP_NOSIZE);
       end;
        KillTimer(hWin, ID_TIMER_POPUPWINDOW);
      end;
    end;

   WM_DESTROY, WM_CLOSE:
    begin
     PostQuitMessage(0);
    end;
 end;
end;


Это сообщение отредактировал(а) navodri - 12.7.2010, 17:51
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0901 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.