Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
1-1277483138
TheEd
2010-06-25 20:25
2012.01.22
Форма, лежащая всегда внизу


4-1253714670
MTsv DN
2009-09-23 18:04
2012.01.22
LoadLibrary on 64bit


3-1270289204
prezervogaz
2010-04-03 14:06
2012.01.22
Кодировка параметров SQL-запросов


15-1318001461
Leon-Z
2011-10-07 19:31
2012.01.22
MySQL & ODBC ???


2-1318237920
NBAH1990
2011-10-10 13:12
2012.01.22
Программная настройка подключения по локальной сети





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский