Форум: "Начинающим";
Текущий архив: 2012.01.22;
Скачать: [xml.tar.bz2];
ВнизВопрос про Canvas.CopyRect и фактическую ширину формы. Найти похожие ветки
← →
igorium © (2011-10-07 15:41) [0]Всем привет.
Задача сохранить все, что видно на форме в графический файл.
Грубо говоря сделать принтскрин формы, но проблема усугубляется тем, что форма не помещается на экране, а для её просмотра нужно использовать скрулеры.
Я делаю так:
procedure TTreeForm.bbClick(Sender: TObject);
var Bit : TBitmap;
begin
Bit := TBitmap.Create;
Bit.Width := TreeForm.ClientWidth;
Bit.Height := TreeForm.ClientHeight;
Bit.Canvas.CopyRect(Rect(0, 0, TreeForm.ClientWidth, TreeForm.ClientHeight), TreeForm.Canvas, Rect(0, 0, TreeForm.ClientWidth, TreeForm.ClientHeight));
Bit.SaveToFile("d:\screen.bmp");
end;
Но сохраняется только видимая на экране часть формы.
А у меня форма занимает несколько экранов и нужно, чтобы ВСЯ форма сохранилась в файл.
Что интересно - у меня разрешение экрана 1024х768.
Я пробовал ручками увеличить ширину формы в инспекторе объектов - максимальная длина, которую он выдает - это 1036 пикселей.
Хотя реальная ширина формы у меня будет ~2400 (специально ставлю кнопку с left=400, width=2000)
← →
stas © (2011-10-07 16:06) [1]http://delphimaster.net/view/2-1317964121/
то что-то длинное, то рубашка короткая )
← →
igorium © (2011-10-07 16:20) [2]Ну бывает.
Мне в одной и той же проге надо реализовать:
1) сохранение в файл, чтобы потом можно было обратно выдернуть и подредактировать
2) сохранение в ГРАФИЧЕСКИЙ файл - по сути печать результата.
← →
Игорь Шевченко © (2011-10-07 16:46) [3]GetFormImage
← →
igorium © (2011-10-07 17:25) [4]
> Игорь Шевченко © (07.10.11 16:46) [3]
> GetFormImage
К сожалению не помогло :(
Делал по справкеFormImage := GetFormImage;
FormImage.SaveToFile(ExtractFilePath(ParamStr(0)) + "screen.bmp");
Но результат один к одному как у меня - сохраняет только видимую на момент сохранения часть формы.
← →
Cobalt © (2011-10-07 18:06) [5]Welcome to
function TCustomForm.GetFormImage: TBitmap;
← →
stas © (2011-10-07 21:54) [6]Да скомпонуйте битмэп так как расположены image на форме да и все.
← →
igorium © (2011-10-08 16:15) [7]
> Cobalt © (07.10.11 18:06) [5]
> Welcome to
> function TCustomForm.GetFormImage: TBitmap;
Объясните дураку - почему у меня ничего не работает???
← →
Loginov Dmitry © (2011-10-08 22:41) [8]
> Делал по справке
> FormImage := GetFormImage;
> FormImage.SaveToFile(ExtractFilePath(ParamStr(0)) + "screen.
> bmp");
>
> Но результат один к одному как у меня - сохраняет только
> видимую на момент сохранения часть формы.
Должно работать.
Может с файлами напутал?
← →
Cobalt © (2011-10-08 23:37) [9]пройдись внутрь процедурки.
← →
я (2011-10-09 08:30) [10]
var
tBmp2: TBitmap;
r: Trect;
hDC1: HDC;
hSrcDC: HDC;
hBmp: HBITMAP;
HWN: HWND;
begin
HWN := FindWindow(nil, windowName);
if (HWN > 32) then
begin
// GetWindowRect(HWND, r); //отыскивает размеры рамки ограничивающей прямоугольник определяемого окна
while (IsIconic(HWN)) do
ShowWindow(HWN, SW_SHOWNORMAL); // делает окно активным
sleep(200);
tBmp2 := TBitmap.Create;
tBmp2.PixelFormat := pf24bit;
GetWindowRect(HWN, r);
hDC1 := GetDC(HWN);
hSrcDC := CreateCompatibleDC(hDC1);
hBmp := CreateCompatibleBitmap(hDC1, r.right - r.left, r.bottom - r.top);
SelectObject(hSrcDC, hBmp);
PrintWindow(HWN, hSrcDC, 0);
BitBlt(hDC1, 0, 0, r.right - r.left, r.bottom - r.top, hSrcDC, 0,
0, SRCCOPY);
tBmp2.Handle := hBmp;
tBmp2.PixelFormat := pf24bit;
tBmp2.SaveToFile("E:\testscreen.bmp");
скрин окна приложения, если оно не свернуто, то скрин будет в не зависимости где оно находится и чем закрыто. Бегины не закрыты. Можно без DC делать, тогда код проще.
← →
я (2011-10-09 08:36) [11]
> тем, что форма не помещается на экране, а для её просмотра
> нужно использовать скрулеры.
ох, че то я сомневаюсь что то что не влезло можно спринтить. может программно расширять перед копированием, копировать и снова сжимать до экрана )
← →
igorium © (2011-10-09 16:33) [12]
> Loginov Dmitry © (08.10.11 22:41) [8]
> Должно работать.
> Может с файлами напутал?
Пробовал создать новую форму и играться с ней - такая же ерунда получается. Сохраняется только ВИДИМАЯ часть формы.
Можете посмотреть. Я скинул форму и проект на файлообменник - http://narod.ru/disk/27792385001/delphi.rar.html.
Заодно там есть BMP-файл, который получается.
> Cobalt © (08.10.11 23:37) [9]
> пройдись внутрь процедурки.
Какой процедурки?
Как пройтись?
Ничего не понял :(
> я (09.10.11 08:30) [10]
>...
> скрин окна приложения, если оно не свернуто, то скрин будет
> в не зависимости где оно находится и чем закрыто. Бегины
> не закрыты. Можно без DC делать, тогда код проще.
Пробовал, но программа не смогла скомпилиться.
Ошибка в 2-х местах -HWN := FindWindow(nil, windowName);
PrintWindow(HWN, hSrcDC, 0);
Программа не знает, что такое windowName и PrintWindow.
Хотя в uses стоит Windows...
> я (09.10.11 08:36) [11]
> ох, че то я сомневаюсь что то что не влезло можно спринтить.
> может программно расширять перед копированием, копировать
> и снова сжимать до экрана )
Как расширить и сжать?
Я на все согласен.
Главное, чтоб заработало...
← →
igorium © (2011-10-09 16:36) [13]Почему-то в ссылке в конце добавилась точка.
Исправляю адрес - http://narod.ru/disk/27792385001/delphi.rar.html
← →
igorium © (2011-10-09 16:43) [14]Кстати не у меня одного такие проблемы.
В интернете нашел с десяток тем с подобными вопросами и не в одной не было решение данной проблемы :(
Здесь же у человека та же проблема, только с печатью - http://www.cyberforum.ru/delphi-beginners/thread170892.html
Неужели решения нет ???
← →
igorium © (2011-10-09 17:03) [15]Тут еще проблема в том, что Дельфи понимает под формой то, что видно на экране. Банальное form1.width - это не ширина всей формы, а ширина видимой формы.
Может можно извратиться и программно смещать форму, каждый раз делаю снимок экрана, а потом эти экраны склеивать?
← →
Игорь Шевченко © (2011-10-09 22:41) [16]
> Банальное form1.width - это не ширина всей формы, а ширина
> видимой формы.
Это даже не смешно.
Скомпилируй и проверьunit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
private
procedure WMSize (var Message: TMessage); message WM_SIZE;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.WMSize(var Message: TMessage);
begin
inherited;
Label1.Caption := Format("Form.Width = %d", [Width]);
end;
end.
← →
igorium © (2011-10-09 23:22) [17]
> Игорь Шевченко © (09.10.11 22:41) [16]
> Скомпилируй и проверь
И что я должен увидеть?
Label пишет
"Form.Width = ширина видимой части формы"
← →
Игорь Шевченко © (2011-10-09 23:30) [18]
> И что я должен увидеть?
форму можно растянуть, подвигать...
← →
sniknik © (2011-10-09 23:46) [19]igorium ©
if HorzScrollBar.Tracking
then Label1.Caption := Format("Form.Width = %d", [HorzScrollBar.Range])
else Label1.Caption := Format("Form.Width = %d", [ClientWidth]);
← →
я (2011-10-10 08:24) [20]
> Пробовал, но программа не смогла скомпилиться.
> Ошибка в 2-х местах -
> HWN := FindWindow(nil, windowName);
> PrintWindow(HWN, hSrcDC, 0);
> Программа не знает, что такое windowName и PrintWindow.
> Хотя в uses стоит Windows...
ПринтВиндовс нужно объявить сначала, это АПИ функция, а не функция делфи.
function PrintWindow(HWND: HWND; hdcBlt: HDC; nFlags: DWORD): BOOL; stdcall;
external "user32.dll";
Если стоит Windows в юзес, то FindWindow должно работать, в сравке написано, что оно объявлено там. Хз в чем проблемма. Код 100% рабочий, т.к. я его из работающей свой проги скопировал.
Ну я уверен на 100% что программно форму можно расширить, выше даже чего то об этом написали уже.
← →
я (2011-10-10 08:32) [21]
> HWN := FindWindow(nil, windowName);
может тут все таки ошибка по поводу "windowName"? т.к. у меня это переменная, в которую передается строка с названием окна. Впрочем у меня все сделано для любого приложения, а хендл своей формы думаю можно и подругому получать, если уж никак не работает )
← →
igorium © (2011-10-10 10:24) [22]
> Игорь Шевченко © (09.10.11 23:30) [18]
> форму можно растянуть, подвигать...
Ну а толку с этой возможности...
Да, я могу растянуть форма по размеру экрана и WIDTH у меня будет равна разрешению экрана по горизонтали. А что мне это дает???
> sniknik © (09.10.11 23:46) [19]
> if HorzScrollBar.Tracking
> then Label1.Caption := Format("Form.Width = %d", [HorzScrollBar.
> Range])
> else Label1.Caption := Format("Form.Width = %d", [ClientWidth]);
Вот тут теплее - теперь я могу знать реальные размеры формы.
Но КАК ИХ СОХРАНИТЬ ???
← →
я (2011-10-10 10:42) [23]
form2.Width:=50000;
ха, форма действительно не становится шире экрана. А что на ней на этой форме размещается?
← →
sniknik © (2011-10-10 10:45) [24]> Но КАК ИХ СОХРАНИТЬ ???
развернуть, сохранить, свернуть на место... ну или типа, т.к. вряд ли винда "рисует" не видимые/не нужные в данный момент контролы. (выйдет за границы экрана тоже не будет отрисовывать, ИМХО по логике, не занимался)
или создать канвас по размеру и нарисовать на нем самому... ну как с принтерным делают, формы же печатают. ну или типа, по логике, не занимался т.что кода для "копипаста" нет.
← →
igorium © (2011-10-10 10:47) [25]
> я (10.10.11 08:32) [21]
> > HWN := FindWindow(nil, windowName);
> может тут все таки ошибка по поводу "windowName"? т.к. у
> меня это переменная, в которую передается строка с названием
> окна. Впрочем у меня все сделано для любого приложения,
> а хендл своей формы думаю можно и подругому получать, если
> уж никак не работает )
Спасибо, разобрался.
Но опять 25 - сохраняется только ВИДИМАЯ часть формы.
Вот результат твоего кода - http://i033.radikal.ru/1110/5a/0045b702572d.jpg
← →
igorium © (2011-10-10 10:55) [26]
> я (10.10.11 10:42) [23]
> form2.Width:=50000;
>
> ха, форма действительно не становится шире экрана. А что
> на ней на этой форме размещается?
На форме размещается большое количество (~50-100) динамических панелей, каждую из них можно изменять, удалять.
> sniknik © (10.10.11 10:45) [24]
> развернуть, сохранить, свернуть на место...
Как "развернуть, сохранить, свернуть на место" ???
> sniknik © (10.10.11 10:45) [24]
> или создать канвас по размеру и нарисовать на нем самому.
Да на крайний случай буду делать так.
Просто нужно будет отрисовывать большое количество панелей, на каждом расположено несколько лабелов и картинка.
← →
я (2011-10-10 11:06) [27]Мой код также сделает скрин если форма задвинута за край экрана, это к вопросу о невидимом )
ну если никто не знает как сделать форму шире экрана, то вариантов остается 2:
1) Сделать пустой BMP нужного размера. Программно скролить форму и делать каждый раз срин шот и добавлять каждый кусок в созданый бмп. вместо GetWindowRect(HWND, r); можно юзать GetClientRect(HWND, r);(пишу по памяти, на как то так) - тогда будет скринится только клиентская часть, а рамку пририсовать отдельно.
2)Подумать действительно ли все это так нужно и возможно сделать все как нибудь подругому )
← →
я (2011-10-10 11:12) [28]
> Но опять 25 - сохраняется только ВИДИМАЯ часть формы.
> Вот результат твоего кода - http://i033.radikal.ru/1110/5a/0045b702572d.
> jpg
ну это да, сохраняет он область ограниченную самой формой это факт. Я на 80% уверен, что та часть которая не попала в форму - ее просто не существует в памяти, и если не вывести ее на форму соскринить ее не получится.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2012.01.22;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.005 c