Конференция "WinAPI" » Открытые окна и Область рабочего стола. [D7, WinXP]
 
  • Dmitriy (21.07.09 09:37) [0]
    Доброго времени суток!!!
    С помощью функции SystemParametersInfo() я изменяю область рабочего стола, делая ее уже (с любой из сторон). Как при этом заставить все окрытые на весь экран окна изменить свое положение с учетом новой области?
  • DVM © (21.07.09 10:30) [1]

    > Как при этом заставить все окрытые на весь экран окна изменить
    > свое положение с учетом новой области?

    Вообще этим занимается обычно эксплорер, но можно и самому: перебираешь все окна и задвигаешь внутрь новой рабочей области те из них, которые удовлетворяют необходимым критериям (не скрыты, имеют определенные стили окна и т.д.)
  • DVM © (21.07.09 10:34) [2]

    > Dmitriy

    Вот, если захочешь, разберешься что тут к чему:


    function IsSizeableWindow(hWnd: HWND): boolean;
    begin
     Result := false;
     if IsWindow(hWnd) and IsWindowVisible(hWnd) then
       Result := (GetWindowLong(hWnd,GWL_STYLE) and WS_SIZEBOX) <> 0
    end;

    //------------------------------------------------------------------------------

    function IsMoveableWindow(hWnd: HWND): boolean;
    begin
     Result := false;
     if IsWindow(hWnd) and IsWindowVisible(hWnd) and
          (GetWindowLong(hWnd, GWL_USERDATA) <> magicDWord) and
            ((GetWindowLong(hwnd,GWL_EXSTYLE) and WS_EX_TOOLWINDOW) = 0) and ((GetWindowLong(hwnd,GWL_STYLE) and WS_CHILD) = 0) then
              Result := true;
    end;

    //------------------------------------------------------------------------------

    function EnumWindowsProc (hWnd: HWND; Data: Pointer) : BOOL; stdcall;
    var
     rcWorkArea, rcWindow: TRect;
     dx, dy: integer;
    begin
     rcWorkArea := TRect(Data^);
     if IsMoveableWindow(hWnd) then
       begin

         // Если окно максимизировано, подстраиваем его размеры по рабочей области
         GetWindowRect(hwnd, rcWindow);
         if IsZoomed(hWnd) then
           MoveWindow(hwnd, rcWorkArea.Left, rcWorkArea.Top, rcWorkArea.Right - rcWorkArea.Left, rcWorkArea.Bottom - rcWorkArea.Top, true)
         else
           begin
         // Если высота окна больше высоты рабочей области
         GetWindowRect(hwnd, rcWindow);
         if GetWindowHeight(hWnd) > (rcWorkArea.Bottom - rcWorkArea.Top) then
           begin
             dy:=GetWindowHeight(hWnd)-(rcWorkArea.Bottom - rcWorkArea.Top);
             if IsSizeableWindow(hWnd) then
               MoveWindow(hwnd, rcWindow.Left, rcWorkArea.Top, GetWindowWidth(hWnd), GetWindowHeight(hWnd) - dy, true);
           end;

         // Если ширина окна больше ширины рабочей области
         GetWindowRect(hwnd, rcWindow);
         if GetWindowWidth(hWnd) > (rcWorkArea.Right - rcWorkArea.Left) then
           begin
             dx:=GetWindowWidth(hWnd)-(rcWorkArea.Right - rcWorkArea.Left);
             if IsSizeableWindow(hWnd) then
               MoveWindow(hwnd, rcWorkArea.Left, rcWindow.Top, GetWindowWidth(hWnd)-dx, GetWindowHeight(hWnd), true);
           end;

         // Если окно заезжает за верхний край рабочей области
         GetWindowRect(hwnd, rcWindow);
         if rcWindow.top < rcWorkArea.top then
           begin
             dy := rcWorkArea.top - rcWindow.top;
             if dy > (rcWorkArea.Bottom - rcWindow.Bottom) then
               dy := rcWorkArea.Bottom - rcWindow.Bottom;
             MoveWindow(hwnd, rcWindow.Left, rcWindow.Top + dy, GetWindowWidth(hWnd), GetWindowHeight(hWnd), true);
           end;

         // Если окно заезжает за нижний край рабочей области
         GetWindowRect(hwnd, rcWindow);
         if rcWindow.Bottom > rcWorkArea.Bottom then
           begin
             dy := rcWindow.Bottom - rcWorkArea.Bottom;
             if dy > (rcWindow.Top - rcWorkArea.Top) then
               dy := rcWindow.Top - rcWorkArea.Top;
             MoveWindow(hwnd, rcWindow.Left, rcWindow.Top - dy, GetWindowWidth(hWnd), GetWindowHeight(hWnd), true);
           end;

         // Если окно заезжает за левый край рабочей области
         GetWindowRect(hwnd, rcWindow);
         if rcWindow.Left < rcWorkArea.Left then
           begin
             dx :=  rcWorkArea.Left - rcWindow.Left;
             if dx > (rcWorkArea.Right - rcWindow.Right) then
               dx := rcWorkArea.Right - rcWindow.Right;
             MoveWindow(hwnd, rcWindow.Left+dx, rcWindow.Top, GetWindowWidth(hWnd), GetWindowHeight(hWnd), true);
           end;
         GetWindowRect(hwnd, rcWindow);

         // Если окно заезжает за правый край рабочей области
         if rcWindow.Right > rcWorkArea.Right then
           begin
             dx := rcWindow.Right - rcWorkArea.Right;
             if dx > (rcWindow.Left - rcWorkArea.Left) then
               dx := rcWindow.Left - rcWorkArea.Left;
             MoveWindow(hwnd, rcWindow.Left-dx, rcWindow.Top, GetWindowWidth(hWnd), GetWindowHeight(hWnd), true);
           end;
          end;
       end;
     Result := true;
    end;

    //------------------------------------------------------------------------------

    procedure SetWorkAreaWithMoveWindows;
    var
     rcNewWorkArea: TRect;
     rcTaskBar: TRect;

    begin
     rcNewWorkArea := Rect(0,
                           0,
                           GetSystemMetrics(SM_CXSCREEN),
                           GetSystemMetrics(SM_CYSCREEN));
     GetWindowRect(hTaskBarWnd, rcTaskBar);
     case GetEdge of
       tbeLeft: rcNewWorkArea.Left := rcTaskBar.Right;
       tbeTop:  rcNewWorkArea.Top := rcTaskBar.Bottom;
       tbeRight: rcNewWorkArea.Right := rcTaskBar.Left;
       tbeBottom: rcNewWorkArea.Bottom := rcTaskBar.Top;
     end;
     SystemParametersInfo(SPI_SETWORKAREA, 0, @rcNewWorkArea, SPIF_SENDCHANGE);

     EnumWindows(@EnumWindowsProc, LongInt(@rcNewWorkArea));
    end;

  • Dmitriy (21.07.09 11:00) [3]

    > DVM


    > Вообще этим занимается обычно эксплорер, но можно и самому:
    >  перебираешь все окна и задвигаешь внутрь новой рабочей
    > области те из них, которые удовлетворяют необходимым критериям
    > (не скрыты, имеют определенные стили окна и т.д.)

    А нельзя эксплореру послать сообщение чтоб он этим занялся?

    Что  такое magicDWord в функции IsMoveableWindow?
  • DVM © (21.07.09 11:48) [4]

    > А нельзя эксплореру послать сообщение чтоб он этим занялся?

    Сообщение вряд ли. Заведует всей этой кухней панель задач - можно попробовать программно дернуть ее, она должна подвинуть окна.


    > Что  такое magicDWord в функции IsMoveableWindow?

    Убери это. Это тебе не нужно.
  • Dmitriy (22.07.09 12:33) [5]

    > DVM

    Спасибо!!!! Разобрался что к чему, теперь все окна стали послушными.
  • Юрий Зотов © (22.07.09 12:56) [6]
    Не проверял, но, возможно, все гораздо проще?

    SystemParametersInfo(..., SPIF_SENDCHANGE);

    И все. По идее, окна сами должны встать, куда нужно.
  • DVM © (22.07.09 15:59) [7]

    > Юрий Зотов ©


    > Не проверял, но, возможно, все гораздо проще?

    Скорее всего так и есть. Мой то код писался для управления окнами без эксплорера.
 
Конференция "WinAPI" » Открытые окна и Область рабочего стола. [D7, WinXP]
Есть новые Нет новых   [134434   +27][b:0][p:0.003]