![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
GetClipboardData(CF_BITMAP) и GlobalLock
Джо © (2006-10-16 17:19:00)Прототип кода:
procedure TForm24.Button1Click(Sender: TObject);
var
H: Cardinal;
P: Pointer;
begin
OpenClipboard(Handle);
try
if IsClipboardFormatAvailable(CF_BITMAP) then
begin
H := GetClipboardData(CF_BITMAP);
if H = 0 then
RaiseLastOSError;
P := GlobalLock(H);
if P = nil then //
RaiseLastOSError; // The Handle is invalid
GlobalUnlock(H);
end
finally
CloseClipboard();
end;
end;
Перед выполнением кода делаем PrintScreen, получаем соответствующий Exception в выделенном комментариями месте.
Что я упустил и где сел в лужу?
Джо (2006-10-16 18:12:00) [1]> [11] clickmaker © (16.10.06 18:09)
>
> > в чем "затык" с CF_BITMAP
>
> в том, что собственно данных там нет, а есть указатель на
> данные - HBITMAP.
Да, теперь понял. Спасибо за помощь.
Внимательнее нужно мне было MSDN читать :)
Джо (2006-10-16 18:11:00) [2]> [10] guav © (16.10.06 18:09)
> > Отчего же тогда работает с CF_TEXT или CF_DIB?
>
> Наверное от того, что там хендл не на память, а GDI шный
> хендл. видимо, может быть и такое.
Кажется, немного стал "вьезжать" в суть. :) Эх, хотелось унифицированно как-то подойти... Спасибо за помощь.
guav (2006-10-16 18:09:00) [3]> Отчего же тогда работает с CF_TEXT или CF_DIB?
Наверное от того, что там хендл не на память, а GDI шный хендл. видимо, может быть и такое.
Кстати, по ссылке [4] написано, что CF_DIB создаётся автоматически из CF_BITMAP.
clickmaker (2006-10-16 18:09:00) [4]
> в чем "затык" с CF_BITMAP
в том, что собственно данных там нет, а есть указатель на данные - HBITMAP. А в случае с CF_DIB - есть.
clickmaker (2006-10-16 18:08:00) [5]
> [7] Джо © (16.10.06 18:02)
не парься :)
Джо (2006-10-16 18:08:00) [6]Объясню задачу чуть более развернуто.
Регистрируется свой ClipboardViewer.
В момент, когда данные в клипборде изменяются нужно делать следующее:
1. Определяем все доступные в клипборде форматы.
2. Для каждого формата получается указатель на глобальную область памяти, где они хранятся.
3. Данные для каждого формата копируются в свой буфер.
Для этого и нужен GlobalLock/GlobalUnlick. Не пойму, в чем "затык" с CF_BITMAP.
Джо (2006-10-16 18:02:00) [7]> [6] clickmaker © (16.10.06 18:00)
>
> > [5] Джо © (16.10.06 17:58)
>
> да, кстати, когда CF_BITMAP, GlobalLock не нужно
> Т.е. можно так
> Bmp := TBitmap.Create;
> Bmp.Handle := GetClipboardData(CF_BITMAP);
Да как же без GlobalLock? Мне ведь нужно зафиксировать этот GlobalMemoryObject на время, пока я буду копировать данные в свой буфер из клипборда. Иначе, что станется, если в процессе копирования данных, данные в клипборде изменятся?
clickmaker (2006-10-16 18:00:00) [8]
> [5] Джо © (16.10.06 17:58)
да, кстати, когда CF_BITMAP, GlobalLock не нужно
Т.е. можно так
Bmp := TBitmap.Create;
Bmp.Handle := GetClipboardData(CF_BITMAP);
Джо (2006-10-16 17:58:00) [9]> [4] guav © (16.10.06 17:54)
>
> По-твоему, это должно работать:
Отчего же тогда работает с CF_TEXT или CF_DIB?
guav (2006-10-16 17:54:00) [10]> Чего же он, подлец, не хочет память фиксировать с GlobalLock?
По-твоему, это должно работать:
procedure TForm1.Button3Click(Sender: TObject);
var
P: Pointer;
begin
P := GlobalLock(Image1.Picture.Bitmap.Handle);
if P = nil then //
RaiseLastOSError; // The Handle is invalid
end;
?
Тут вроде как написано что CF_BITMAP содержит " handle to a bitmap " (а CF_DIB - " A memory object containing a BITMAPINFO structure followed by the bitmap bits. " ) http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/dataexchange/clipboard/clipboardformats.asp
Джо (2006-10-16 17:46:00) [11]> [1] clickmaker © (16.10.06 17:32)
> попробуй CF_DIB
Нет, нужен именно CF_BITMAP.
> Там вместо GlobalLock идёт GetObject, т.е. вместо хендла
> памяти хендл битмапа.
Чего же он, подлец, не хочет память фиксировать с GlobalLock? вот что непонятно... И мне нужно именно GlobalLock, дабы получить указатель на область памяти.
guav (2006-10-16 17:35:00) [12]Почему бы не исследовать, как это делается в этом коде:
procedure TForm1.Button2Click(Sender: TObject);
begin
Image1.Picture.Bitmap.Assign(Clipboard);
end;
Там вместо GlobalLock идёт GetObject, т.е. вместо хендла памяти хендл битмапа.
clickmaker (2006-10-16 17:32:00) [13]попробуй CF_DIB