Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.08.2012, 21:38   #1
Сергей Горбач
 
Регистрация: 06.01.2012
Сообщений: 8
По умолчанию программное изменение размера диалоговых окон

Подскажите, можно ли программно изменить размер и позицию на экране стандартного диалогового окна перед его выводом? Например, обычный размер OpenDialog мне кажется маленьким и я заранее хочу, чтобы оно открывалось с бОльшими размерами и не в центре экрана.
Сергей Горбач вне форума Ответить с цитированием
Старый 21.08.2012, 10:50   #2
ych_del
Форумчанин
 
Аватар для ych_del
 
Регистрация: 06.02.2011
Сообщений: 149
По умолчанию

Немного покурив win32.hlp, на выходе я получил вот такое вот:

Код:
unit Unit1;

interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    OD: TOpenDialog;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
  public
  end;

var
  Form1: TForm1;

function AMsgProc(code, wParam, lParam: Integer): LRESULT; stdcall;

implementation

{$R *.dfm}

const OD_CAPTION_FIND = '~myOpenDialog';
      OD_CAPTION_DEF  = 'Открыть';

var OD_WND: Cardinal;
    H: HHOOK;

//-- Создание формы - ставим хук на диалоговые окна, менюшки и прочее ----------
procedure TForm1.FormCreate(Sender: TObject);
begin
   H := SetWindowsHookEx(WH_SYSMSGFILTER, @AMsgProc, HInstance, 0);
   if H = 0 then ShowMessage(SysErrorMessage(GetLastError));
end;
//-- Закрытие формы - снимаем хук ----------------------------------------------
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   UnhookWindowsHookEx(H);
end;
//-- Вызов диалога открыртия файла ---------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
begin
   OD_WND := 0; // это пригодится ниже
   OD.Title := OD_CAPTION_FIND; // ставим диалогу название, по которому будем его искать
   OD.Execute;
end;

function AMsgProc(code, wParam, lParam: Integer): LRESULT;
var L, T, W, H: Integer; // left, top, width, height
//    P: PChar;
//    M: TMsg;
begin
   if (code = MSGF_DIALOGBOX)and(OD_WND = 0) // если не прописать второе условие,
   then begin                                // будут очень интересные последствия
      {
      M := PMsg(lParam)^;
      OD_WND := M.hwnd;
      P := StrAlloc(255);
      GetClassName(OD_WND, P, 255);
      GetWindowText(OD_WND, P, 255);
      Form1.Caption := StrPas(P);
      StrDispose(P);
      if not SetWindowText(OD_WND, OD_CAPTION) then Form1.Caption := SysErrorMessage(GetLastError);
      }
      OD_WND := FindWindow(nil, OD_CAPTION_FIND); // находим окно диалога откытия файла
      if OD_WND <> 0 then begin
          L := 0; T := 0;
          W := 1000; H := 400;
          SetWindowText(OD_WND, OD_CAPTION_DEF); // устанавливаем ему нормальный заголовок
          SetWindowPos(OD_WND, HWND_TOP, L, T, W, H, SWP_SHOWWINDOW); // ставим в нужную позицию
      end;
      Result := 0;
   end else
      Result := CallNextHookEx(H, code, wParam, lParam);
end;

end.
О чем тут речь?
Мы ставим ловушку на системные сообщения (см. FormCreate). Когда появляется диалоговое окно (if code = MSGF_DIALOGBOX) - ловушка срабатывает. Мы получаем хэндл этого окна (ищем по заведомо идиотскому названию, которое назначили перед показом диалога), и немного извращаемся над ним: во-первых, ставим нормальное название, во-вторых - выставляем в нужную позицию.

Вот, как-то примерно так.

В процедуре закомментирован кусок кода. По хорошему, надо было идти именно по тому пути, который я закомментил, не доделав. Но, так как всё-таки на работе надо заниматься работой, я пошел по пути наименьшего сопротивления
Недостаток такого метода в том, что окошко диалога заметно мигает при перемещении.

Вот тут: http://www.ych-group.ru/232/1231/
Профессиональный конвертор галлюцинаций заказчика в алгоритмическую структуру.
ych_del вне форума Ответить с цитированием
Старый 21.08.2012, 12:35   #3
volvo877
Форумчанин
 
Аватар для volvo877
 
Регистрация: 01.06.2009
Сообщений: 108
По умолчанию

Цитата:
Например, обычный размер OpenDialog мне кажется маленьким и я заранее хочу, чтобы оно открывалось с бОльшими размерами и не в центре экрана.
Напиши наследника от TOpenDialog (или Interceptor-а), перегрузи ему DoShow, и в ней делай все, что тебе заблагорассудится. Изменяй размеры, позицию, и т.д.

Пример я приводил здесь
volvo877 вне форума Ответить с цитированием
Старый 02.09.2012, 12:59   #4
Сергей Горбач
 
Регистрация: 06.01.2012
Сообщений: 8
По умолчанию

Цитата:
Сообщение от volvo877 Посмотреть сообщение
Напиши наследника от TOpenDialog (или Interceptor-а), перегрузи ему DoShow, и в ней делай все, что тебе заблагорассудится. Изменяй размеры, позицию, и т.д.

Пример я приводил здесь
Да, при таком исполнении кода размер и позиция окна меняется корректно, но элементы имеющиеся на форме продолжают иметь старые размеры. Их размеры остаются неизменными же даже при изменении размера при помощи мыши. Как привязать изменение их размеров к размеру формы? Заранее благодарен.
Сергей Горбач вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ввод и вывод выполнить с встроенных диалоговых окон InputBox и MsgBox Anti123 Microsoft Office Excel 3 23.03.2012 18:12
Мигание диалоговых окон в WPF FS-Phil WPF, UWP, WinRT, XAML 0 07.11.2011 19:38
Изменение положения диалоговых окон roperd Общие вопросы Delphi 1 19.07.2011 18:44
Программное открытие изображение, изменение размера, сохранение без потерь chandrasecar Общие вопросы Delphi 4 25.10.2010 19:04
MFC: Создание диалоговых окон Rembo Visual C++ 6 14.11.2008 20:45