Страница 3 из 5
Re: Копирование экрана
Добавлено: 15 окт 2009, 12:52
atavin-ta
Всё-таки, можно через Bitblt?
--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
" писал(а):На cout внимания не обращай, т.к. они использованы для отладочного вывода ссообщений в случае ошибки. Можешь заменить на WINAPI-шный MessageBox или что там есть специфического в Борланде (ShowMessage?)
Воще не надо. Трассировщиком прогоню без свяких мессаг, за то в релизе точно не останутся. Контрольный же TImage останется. Его назначение - дать юзверю возможность ещё раз проверить правльность выделения фрагмента. В окне TImageа ещё можно будет поменять масштаб на крупный и проскролить картинку по обеим осям.
Re: Копирование экрана
Добавлено: 15 окт 2009, 13:19
BBB
atavin-ta писал(а):Всё-таки, можно через Bitblt?
А в чем проблема-то? Почему нельзя?
Я нашел свой пробный (тестовый) кусок. Но он писан был на MS C++, MFC. Там используется не BitBlt, а StretchBlt. Чтобы как раз отмасштабировать на всю клиентскую область окна. В общем, писалось это досаточно давно, вываливаю кусок кода as is.
Код именно "тестовый", так как каждый раз в прилагаемом обработчике OnPaint картинка грузится из файла. Т.е. цель этого кода - именно убедиться, что картинка рисуется в окне.
Код: Выделить всё
void CBitmapIggle::OnPaint()
{
// CStatic::OnPaint ();
CPaintDC dc (this); // device context for painting
// load IDB_BITMAP1 from file
HBITMAP hBMP = 0;
if (hBMP == 0) {
GFL_ERROR iGFLerror;
GFL_LOAD_PARAMS rLoadParams;
//---------------------
if ((iGFLerror = gflLibraryInit ()) != GFL_NO_ERROR) {
return;
};
gflGetDefaultLoadParams (&rLoadParams);
if ((iGFLerror = gflLoadBitmapIntoDDB (
"D:\\TEMP\\IMG_5324_TRUNCATED.JPG",
&hBMP, // GFL_BITMAP ** bitmap,
&rLoadParams, // GFL_LOAD_PARAMS * params,
NULL // &rInformations // GFL_FILE_INFORMATION * informations,
)) != GFL_NO_ERROR) {
return;
};
gflLibraryExit ();
};
if (hBMP)
{
HDC hImageDC;
hImageDC = CreateCompatibleDC (dc.m_ps.hdc);
// Select the bitmap into the in-memory DC
HBITMAP hOldBitmap = 0;
hOldBitmap = (HBITMAP)SelectObject (hImageDC, hBMP);
// Find a centerpoint for the bitmap in the client area
CRect rect;
GetClientRect (&rect);
int nX = 0;
int nY = 0;
// Copy the bits from the in-memory DC into the on-
// screen DC to actually do the painting. Use the centerpoint
// we computed for the target offset.
BITMAP bm;
GetObject (hBMP, sizeof(bm), &bm); // get size of bitmap
::SetStretchBltMode (dc.m_ps.hdc, HALFTONE);
::StretchBlt (dc.m_ps.hdc, nX, nY, rect.Width (), rect.Height (),
hImageDC,
0, 0,
bm.bmWidth,bm.bmHeight,
SRCCOPY);
DeleteObject ((HBITMAP)SelectObject (hImageDC, hOldBitmap));
DeleteDC (hImageDC); // добавлено 16.10.2009 (похоже, ошибочка была - не было этого вызова)
};
}; // CBitmapIggle::OnPaint()
Re: Копирование экрана
Добавлено: 16 окт 2009, 06:53
atavin-ta
Различие в назначении bitblt и strechblt я знаю. Мне лучше файл снять в натуральном масштабе (пиксел в пиксел), а масштабирование поручить каждому компу, на который буду грузить, так как размеры TImageов у всех разные. И я знаю, как реализовать масштабирование средствами TImageа. Поэтому лучше bitblt. Так пойдёт:
Код: Выделить всё
void CopyRect(TImage *Image, RECT Rect, AnsiString s)
{
HDC DisplayContext;
HDC ImageContext;
HBITMAP Handle;
Image->Picture->Bitmap->Width =Rect.right -Rect.left;
Image->Picture->Bitmap->Height=Rect.bottom-Rect.top;
DisplayContext=GetDeviceContext(NULL);
ImageContext=CreateCompatibleDC(DisplayContext);
Handle=(HBITMAP)SelectObject(ImageContext,*Image->Picture->Bitmap->Handle);
BitBlt(DisplayContext,Rect.left,Rect.top,Rect.right-Rect.left,Rect.bottom-Rect.top,ImageContext,0,0);
DeleteObject ((HBITMAP)SelectObject(ImageContext, Handle));
DeleteDC(ImageContext);
DeleteDC(DisplayContext);
Image->Picture->Bitmap->SaveToFile(s);
}
?
Re: Копирование экрана
Добавлено: 16 окт 2009, 09:43
BBB
atavin-ta писал(а):Так пойдёт?
Эээ... Ну так пробуй!

))
Походу, я в своем примере ошибочку нашел. Не освобождается hImageDC, созданный через CreateCompatibleDC (нет вызова DeleteDC).
Но у тебя ImageContext как раз удаляется.
Но зато также удаляется DisplayContext, чего делать, как я понимаю, как раз не стоит. Т.к. DisplayContext не создавался тобой, а был получен через GetDeviceContext.
Я, правда, не очень понял, что такое GetDeviceContext (это не что-то специфическое для Борланда?)
Может, для DisplayContext надо сделать ReleaseDC?
Re: Копирование экрана
Добавлено: 16 окт 2009, 10:10
atavin-ta
" писал(а):получен через GetDeviceContext.
Я, правда, не очень понял, что такое GetDeviceContext (это не что-то специфическое для Борланда?)
Может, для DisplayContext надо сделать ReleaseDC?
Учи API! Это одна из функций создания контекста на основе хендла окна.
Re: Копирование экрана
Добавлено: 16 окт 2009, 10:57
Romeo
" писал(а):Учи API! Это одна из функций создания контекста на основе хендла окна.
atavin-ta, это ты учи API
GetDeviceContext - это не Win API функция, а примочка VCL.
Re: Копирование экрана
Добавлено: 16 окт 2009, 11:01
atavin-ta
Какой к фигам вцл? Я так под мелкософтом писал. И у Петзолда видел. А унего вцл не рассмотрен.
Re: Копирование экрана
Добавлено: 16 окт 2009, 11:08
Romeo
Что-то путаешь.
1. MSDN 2005 функции не знает.
2. Все ссылки в google ведут в код, написанный на Delphi. Если бы эта функция была Win API, то первая же ссылка в поисковике вела бы в online версию MSDN.
Если тебе этих аргументов не достаточно, то скажи в каком хедере в Microsoft Visual Studio эта функция лежит либо из какой системной библиотеке Windows она экспортируется. Думаю, ты на этот вопрос ответить не сможешь.
P.S. Только давай без объяснений на страницу. Мне нужны только факты либо короткий ответ "Не бейте, облажался"

Re: Копирование экрана
Добавлено: 16 окт 2009, 11:10
BBB
Romeo писал(а):
1. MSDN функции GetDeviceContext не знает.
2. Все ссылки в google ведут в код, написанный на Delphi.
Во-во. У меня та же фигня.
MSDN на GetDevice... дает только GetDeviceCap

Re: Копирование экрана
Добавлено: 16 окт 2009, 11:33
atavin-ta
Спросите у Чарлза Петзода.