Картинки и буфер обмена.

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
AlexBlack
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 324
Зарегистрирован: 18.07.2005 (Пн) 19:14
Откуда: Киефф, Юкрейн...

Картинки и буфер обмена.

Сообщение AlexBlack » 25.03.2006 (Сб) 20:29

Здравствуйте.

Помогите мне загрузить METAFILE, ENHMETAFILE и DIB из буфера обмена виндовс.

Clipboard.GetData не подходит.

Нужно всю полностью информацию о картинке загрузить из буфера обмена.
То есть мне нужно не выводить её, а сохранить так, чтобы потом опять отослать в буфер обмена (даже после перезагрузки).
Получается, мне нужно получить бинар картинки (со всеми хейдерами).

Заранее спасибо.
Красный, но студийный.

http://www.rs-creative.com
Alex_Black@rs-creative.com

Lumen
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 841
Зарегистрирован: 03.12.2005 (Сб) 16:09
Откуда: Брянск

Сообщение Lumen » 26.03.2006 (Вс) 0:08

А если копировать в в буфер не картинку, а сам файл, а потом его из буфера сохранять в файл и оттуда чиать? Конечно мысль бредовая, но ничего другого в голову пока не приходит.

Amed
Алфизик
Алфизик
 
Сообщения: 5346
Зарегистрирован: 09.03.2003 (Вс) 9:26

Сообщение Amed » 26.03.2006 (Вс) 0:19

А зачем это нужно? Опиши подробнее механизм (где и когда нажимается кнопка "копировать", где и когда - "вставить").

VictorVM
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 03.03.2006 (Пт) 6:37

Сообщение VictorVM » 26.03.2006 (Вс) 10:07

На самом деле всё просто. Нужно выяснить, что находится в буфере, а потом скопировать.
Код: Выделить всё

Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Private Sub Form_Click()
Dim bm As BITMAP
Dim rt As RECT
Dim iFormat As Long
Dim hEnhHead As ENHMETAHEADER
Dim Arrstr() As Byte
Dim stroc As String
Dim hMemory As Long
Dim iCount As Long
    ret = OpenClipboard(hwnd): If ret = 0 Then GoTo GoToErr
    Do
        iFormat = EnumClipboardFormats(iFormat)
        Select Case iFormat
            Case CF_TEXT
                hClipMemory = GetClipboardData(CF_TEXT): If hClipMemory = 0 Then Exit Do
                iCount = GlobalSize(hClipMemory) - 1: hMemory = GlobalLock(hClipMemory)
                stroc = Space(iCount): Arrstr = stroc
                CopyMemory Arrstr(0), ByVal hMemory, iCount * 2
                stroc = StrConv(Arrstr, vbUnicode): stroc = Left(stroc, InStr(stroc, Chr(0)) - 1)
                GlobalUnlock hClipMemory
                CloseClipboard
                TextOut hdc, 0, 0, stroc, Len(stroc)
                Exit Do
            Case CF_BITMAP
                hBitmap = GetClipboardData(CF_BITMAP): If hBitmap = 0 Then Exit Do
                CloseClipboard
                Call mGetObject(hBitmap, Len(bm), bm)
                hMyBitmap = CreateBitmapIndirect(bm): hdcMemSrc = CreateCompatibleDC(hdc)
                SelectObject hdcMemSrc, hBitmap
                BitBlt hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMemSrc, 0, 0, SRCCOPY
                Exit Do
            Case CF_ENHMETAFILE
                hEnhMeta = GetClipboardData(CF_ENHMETAFILE): If hEnhMeta = 0 Then Exit Do
                CloseClipboard
                GetEnhMetaFileHeader hEnhMeta, Len(hEnhHead), hEnhHead
                rt.Right = hEnhHead.rclBounds.Right: rt.Bottom = hEnhHead.rclBounds.Bottom
                PlayEnhMetaFile hdc, hEnhMeta, rt
                Exit Do
        End Select
    Loop While iFormat <> 0
GoToErr:
    CloseClipboard
    DeleteEnhMetaFile hEnhMeta
    DeleteObject hMyBitmap
    DeleteDC hdcMemSrc
End Sub

VictorVM
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 03.03.2006 (Пт) 6:37

Сообщение VictorVM » 26.03.2006 (Вс) 10:22

В предыдущем сообщении не весь раздел деклараций приведён.
Замени на этот.
Код: Выделить всё

Private Const CF_BITMAP = 2
Private Const CF_ENHMETAFILE = 14
Private Const SRCCOPY = &HCC0020
Private Type SIZEL
    cx As Long
    cy As Long
End Type
Private Type BITMAP
        bmType As Long
        bmWidth As Long
        bmHeight As Long
        bmWidthBytes As Long
        bmPlanes As Integer
        bmBitsPixel As Integer
        bmBits As Long
End Type
Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type
Private Type RECTL
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type
Private Type ENHMETAHEADER
        iType As Long
        nSize As Long
        rclBounds As RECTL
        rclFrame As RECTL
        dSignature As Long
        nVersion As Long
        nBytes As Long
        nRecords As Long
        nHandles As Integer
        sReserved As Integer
        nDescription As Long
        offDescription As Long
        nPalEntries As Long
        szlDevice As SIZEL
        szlMillimeters As SIZEL
End Type
Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function CloseClipboard Lib "user32" () As Long
Private Declare Function EnumClipboardFormats Lib "user32" (ByVal wFormat As Long) As Long
Private Declare Function mGetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function CreateBitmapIndirect Lib "gdi32" (lpBitmap As BITMAP) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function PlayEnhMetaFile Lib "gdi32" (ByVal hdc As Long, ByVal hemf As Long, lpRect As RECT) As Long
Private Declare Function DeleteEnhMetaFile Lib "gdi32" (ByVal hemf As Long) As Long
Private Declare Function GetEnhMetaFileHeader Lib "gdi32" (ByVal hemf As Long, ByVal cbBuffer As Long, lpemh As ENHMETAHEADER) As Long
Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
Private Const CF_TEXT = 1
Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

AlexBlack
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 324
Зарегистрирован: 18.07.2005 (Пн) 19:14
Откуда: Киефф, Юкрейн...

Сообщение AlexBlack » 26.03.2006 (Вс) 12:50

Amed кнопка "копировать" нажимается сообщением WM_DRAWCLIPBOARD, кнопка "вставить" кликабильна пользоватлем.


Но вот тот код, который привёл VictorVM, не сохраняет информацию, а изображает.

строки:
PlayEnhMetaFile hdc, hEnhMeta, rt

и
BitBlt hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMemSrc, 0, 0, SRCCOPY


А нужно получить, грубо говоря, сами пикселы, а не изображение на контексте устройства.
Красный, но студийный.

http://www.rs-creative.com
Alex_Black@rs-creative.com

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 26.03.2006 (Вс) 14:13

GetCurrentObject(hdc, OBJ_BITMAP)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AlexBlack
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 324
Зарегистрирован: 18.07.2005 (Пн) 19:14
Откуда: Киефф, Юкрейн...

Сообщение AlexBlack » 26.03.2006 (Вс) 16:14

GSerg, смотри....
Когда я запускаю GetClipboardData, ну скажем, c параметром CF_BITMAP, то у меня приходит Handle.
Причём он находиться не в Global-памяти. И не в Local-памяти. Не в HEAP и не в VIRTUAL.
Это Handle на обьект GDI.
Если я хочу её вывести (а я не хочу), то я его бличу на дескриптор устройства.
А зачем мне снова получать Handle на обьект GDI через функцию GetCurrentObject, если он у меня уже есть?

Нужно получить сами биты картинки, по известному хендлу....
Красный, но студийный.

http://www.rs-creative.com
Alex_Black@rs-creative.com

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 26.03.2006 (Вс) 16:34

И сделать с ними что?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Сообщение BV » 26.03.2006 (Вс) 17:07

Ничего не понял...

Нужен GetDIBits? Массив Pixels()?
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

AlexBlack
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 324
Зарегистрирован: 18.07.2005 (Пн) 19:14
Откуда: Киефф, Юкрейн...

Сообщение AlexBlack » 26.03.2006 (Вс) 17:49

Есть HANDLE на GDI обьект.
Нужно всю структуру этого обьекта, скажем, сохранить в файл.
Потом загрузить из этого файла, и снова забросить в память как GDI объект и получить на него HANDLE.
Красный, но студийный.

http://www.rs-creative.com
Alex_Black@rs-creative.com

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 26.03.2006 (Вс) 17:50

А фиг.

Можно сохранить регион и картинку.
Для остального... хотя чё там, для твоих целей сойдёт.

GetObject вернёт объектно-зависимую структуру, которую потом можно засунуть в CreateXXXXXIndirect.
Последний раз редактировалось GSerg 26.03.2006 (Вс) 17:53, всего редактировалось 1 раз.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AlexBlack
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 324
Зарегистрирован: 18.07.2005 (Пн) 19:14
Откуда: Киефф, Юкрейн...

Сообщение AlexBlack » 26.03.2006 (Вс) 17:53

Всё вопросы разрешаются если есть обратная функция функции GetObject.
Что-то в духе CreateObject с заданным форматом.
Красный, но студийный.

http://www.rs-creative.com
Alex_Black@rs-creative.com

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 26.03.2006 (Вс) 17:55

Ну так и есть. CreateXXXXXIndirect.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AlexBlack
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 324
Зарегистрирован: 18.07.2005 (Пн) 19:14
Откуда: Киефф, Юкрейн...

Сообщение AlexBlack » 26.03.2006 (Вс) 17:59

незаметил твоего последнего поста. :)

Это получается что для каждого обьекта нужен свой CreateInderect?
Красный, но студийный.

http://www.rs-creative.com
Alex_Black@rs-creative.com


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 84

    TopList  
cron