Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2012.01.22;
Скачать: CL | DM;

Вниз

Вопрос про 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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.012 c
2-1318165590
vivaldi
2011-10-09 17:06
2012.01.22
Снижение качества(сжатие)


2-1318325199
jamix
2011-10-11 13:26
2012.01.22
как можно увеличить громкость wav файла?


2-1318256216
toropoff
2011-10-10 18:16
2012.01.22
помогите создать SQL запрос


15-1317710577
TUser
2011-10-04 10:42
2012.01.22
Фестиваль науки


15-1317627402
OW
2011-10-03 11:36
2012.01.22
Задумка. Игра Пираты. Интересно ли будет?