· Начало · Статистика · WASM.RU · Noir.Ru ·

 WASM Phorum (Оффлайн - 24.11.2003) —› WASM.WIN32 —› Как скопировать bitmap в буфер обмена

Посл.отвђт Сообщенiе


Дата: Окт 17, 2003 08:17:27

Требуется скопировать картинку(по ее hBitmap) в буфер обмена(Clipboard).
Прямая передача hBitmap в функцию SetClipboardData работает, но если закрыть приложение, владеющее hBitmap'ом, то хэндл, содержащийся в буфере обмена, становится недействительным.
Можно создать буфер в памяти(GlobalAlloc с флагом GMEM_MOVEABLE) и скопировать туда картинку. Но каким именно образом? И сработает ли это?
Какие есть альтернативы?


Дата: Окт 17, 2003 09:14:30

Toxic
если закрыть приложение, владеющее hBitmap'ом, то хэндл, содержащийся в буфере обмена, становится недействительным
Брехня. (С) из к/ф "Не уловимые мстители"


Дата: Окт 17, 2003 13:33:15

q_q
Если прога работает то из буфера все вставляется нормально. Как только закрываю(она при выходе уничтожает DC и Bitmap) - ничего нельзя вставить.


Дата: Окт 17, 2003 13:43:54

Toxic
Чтоб не выглядеть голословным.

_295042982__bm2c.rar


Дата: Окт 17, 2003 16:32:05

GMEM_MOVEABLE+GMEM_DDESHARE
dealloc/free его делать не надо


Дата: Окт 17, 2003 23:41:40

q_q
У меня такой же код, только на VB. Очевидно, проблема в виртуальной машине VB. Но теперь хоть ясно, где собака зарыта.

comrade
Это все я знаю. Я хотел узнать, как ИМЕННО копировать, но теперь это, очевидно, не нужно.


Дата: Окт 20, 2003 04:59:50 · Поправил: q_q

Toxic
такой же код, только на VB
VB у меня нет, а на VBA работает такой код (выполнял под Excel'ем, закрывал Excel и вставлял из буфера обмена в mspaint)
Const SRCCOPY = &HCC0020
Const CF_BITMAP = 2
Const CF_PALETTE = 9

Declare Function GetDC Lib "user32" ( _
  ByVal hwnd As Long) As Long
Declare Function ReleaseDC Lib "user32" ( _
  ByVal hwnd As Long, _
  ByVal hdc As Long) As Long
Declare Function CreateCompatibleDC Lib "gdi32" ( _
  ByVal hdc As Long) As Long
Declare Function DeleteDC Lib "gdi32" ( _
  ByVal hdc As Long) As Long
Declare Function CreateCompatibleBitmap Lib "gdi32" ( _
  ByVal hdc As Long, _
  ByVal width As Long, _
  ByVal height As Long) As Long
Declare Function GetStockObject Lib "gdi32" ( _
  ByVal obj As Long) As Long
Declare Function DeleteObject Lib "gdi32" ( _
  ByVal obj As Long) As Long
Declare Function SelectObject Lib "gdi32" ( _
  ByVal hdc As Long, _
  ByVal obj As Long) As Long
Declare Function BitBlt Lib "gdi32" ( _
  ByVal hdcDst As Long, _
  ByVal x As Long, _
  ByVal y As Long, _
  ByVal width As Long, _
  ByVal height As Long, _
  ByVal hdcSrc As Long, _
  ByVal sSrc As Long, _
  ByVal ySrc As Long, _
  ByVal dwRop As Long) As Long
Declare Function OpenClipboard Lib "user32" ( _
  ByVal hwnd As Long) As Long
Declare Function CloseClipboard Lib "user32" () As Long
Declare Function SetClipboardData Lib "user32" ( _
  ByVal wFormat As Long, _
  ByVal hMem As Long) As Long
Declare Function EmptyClipboard Lib "user32" () As Long

Function BitmapToClipboard() As Boolean
  Dim scrDC As Long
  Dim memDC As Long
  Dim bmp As Long
  Dim old As Long
  Dim pal As Long

  BitmapToClipboard = False

  scrDC = GetDC(0)
  If 0 <> scrDC Then
    memDC = CreateCompatibleDC(scrDC)
    If 0 <> memDC Then
      bmp = CreateCompatibleBitmap(scrDC, 200, 200)
      If 0 <> bmp Then
        old = SelectObject(memDC, bmp)
        If 0 <> BitBlt(memDC, 0, 0, 200, 200, scrDC, 0, 0, SRCCOPY) Then
          If 0 <> OpenClipboard(0&) Then
            EmptyClipboard
            If 0 <> SetClipboardData(CF_BITMAP, bmp) Then
              pal = GetStockObject(DEFAULT_PALETTE)
              If 0 <> pal Then
                If 0 <> SetClipboardData(CF_PALETTE, pal) Then
                  BitmapToClipboard = True
                Else
                  MsgBox "SetClipboardData CF_PALETTE failed"
                End If
                DeleteObject pal
              Else
                MsgBox "GetStockObject failed"
              End If
            Else
              MsgBox "SetClipboardData CF_BITMAP failed"
            End If
            CloseClipboard
          Else
            MsgBox "OpenClipboard failed"
          End If
        Else
          MsgBox "BitBlt failed"
        End If
        SelectObject memDC, old
        DeleteObject bmp
      Else
        MsgBox "CreateCompatibleBitmap failed"
      End If
      DeleteDC memDC
    Else
      MsgBox "CreateCompatibleDC failed"
    End If
    ReleaseDC 0, scrDC
  Else
    MsgBox "GetDC failed"
  End If
End Function

Sub TestBitmapToClipboard()
  If BitmapToClipboard Then
    MsgBox "Close app and check clipboard"
  End If
End Sub


Дата: Окт 20, 2003 07:14:17

Зачем так много проверок на ошибки?


Дата: Окт 20, 2003 08:00:40 · Поправил: q_q

comrade
imho сразу весь код лучше, чем потом вставлять проверки если что-то не пойдет.
Вообще я предпочитаю OutputDebugString + DbgView from sysinternals.

PS "Лучше перебздеть, чем недобздеть?"


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.067