SetClipboardData

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

SetClipboardData

Сообщение Eugenio » 13.01.2005 (Чт) 10:57

Первоначальный вопрос - к черту пока, теперь вопрос другой:
Пытаюсь сделать свой формат данных для буфера обмена,
почему при передаче указателя на строку (получен VarPtr) в функцию
SetClipboardData - в буфер ни фига не попадает?
Всю статью про форматы clipboard прочесал - никаких намеков на возможную причину.
Есть ли у меня вопрос? У меня всегда есть вопрос

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

Сообщение GSerg » 13.01.2005 (Чт) 12:52

varptr - это не указатель на строку, указатель на строку strptr.

Если ты делаешь "типа свой формат", то тебе сойдёт обычный string, содержащий такую-то фигню.
Если ты делаешь реально свой формат, то обрати стопы сначала к функции registerclipboardformat.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 13.01.2005 (Чт) 13:37

GSerg писал(а):Если ты делаешь "типа свой формат", то тебе сойдёт обычный string, содержащий такую-то фигню.
Если ты делаешь реально свой формат, то обрати стопы сначала к функции registerclipboardformat.

Случайно, в курсе :) . Я же сказал - "свой формат", без "типа",
не CF_TEXT.
Смысл - в автоматически выводимом контекстном меню в richEdit'ах и всех открытых текстовых прогах не должен быть активен пункт Paste, когда эти данные имеются в буфере.
Нечего им делать в моем текст боксе - это служебные данные, представляющие объект с наименьшими затратами - строка с двумя десятками символов и все. RTB и всякие WordPad'ы с NotePad'ами не среагируют на данные, которые система не может автоконвертнуть в CF_TEXT. Зарегистрированные форматы она, вроде, не автоконвертит. А заменять контекстное меню RTB я не хочу!
Последний раз редактировалось Eugenio 13.01.2005 (Чт) 14:23, всего редактировалось 4 раз(а).
Есть ли у меня вопрос? У меня всегда есть вопрос

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 13.01.2005 (Чт) 14:12

GSerg писал(а):varptr - это не указатель на строку, указатель на строку strptr.

со StrPtr у меня проблема под названием:
VB писал(а):Can't find entry point

поскольку аргумент VarPtr описан, как any -
то я её и попробовал юзать, чтобы получить указатель. Правда, сам не знаю, на что я получил указатель - на contents или на этот, как его, "string descriptor"

Че делать-че делать
Есть ли у меня вопрос? У меня всегда есть вопрос

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

Сообщение GSerg » 13.01.2005 (Чт) 14:15

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

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 13.01.2005 (Чт) 14:20

GSerg писал(а)::shock: :shock: :shock:
Ты чё там делаешь?

Я вон выше как раз вписал чё делаю :)
Есть ли у меня вопрос? У меня всегда есть вопрос

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

Сообщение GSerg » 13.01.2005 (Чт) 14:22

Кто-то из нах двоих извращенец :)
Я не исключаю, что это я, но код позырить бы, а? :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 13.01.2005 (Чт) 14:34

GSerg писал(а):Кто-то из нах двоих извращенец :)
Я не исключаю, что это я, но код позырить бы, а? :)

А чё сразу извращенец?
Есть текст с разметкой. При выполнеии команды меню paste (в главном меню у меня есть Edit->Paste) когда активен совершенно определенный контрол (TreeView), этот текст из буфера должен превращаться в ветку дерева (Node). Когда активен текстбокс в том же окне - при выполнении Paste ни хрена подобного делать не надо, надо вставлять этот текст, очищенный от разметки и служебной части текста (заголовка для nod'а). Придуманное решение:
пусть эта хрень будет в буфере в двух разных форматах - для текст бокса и для tree view (в зависимости от того, какой контрол активен,
процедуры разные) - тогда контекстное меню текстбокса не будет "предлагать" вставить то, что не надо. И на сообщение EM_CANPASTE текстбокс вернет 0, если данные в буфере - мои: очень удобно, чтобы disable'ить и enable'ить уже пункт главного меню, мною вставленный. И вообще эти данные НИКУДА не вставятся, кроме места назначения!
Есть ли у меня вопрос? У меня всегда есть вопрос

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 13.01.2005 (Чт) 14:38

Код: Выделить всё
Public Function PutInClipboard(FORMAT_ID As Variant, StrData As String) As Integer
    Dim CF_FORMAT As Long
   
    Select Case TypeName(FORMAT_ID)
        Case "Long"
            CF_FORMAT = FORMAT_ID
        Case "String"
            CF_FORMAT = RegisterClipboardFormat(FORMAT_ID)
        Case Else
            Exit Function
    End Select
    'open the clipboard
    OpenClipboard MainWindow.hwnd
    'Clear the clipboard
    EmptyClipboard
   
    SetClipboardData CF_FORMAT, StrPtr(StrData)
   
    CloseClipboard
   
    PutInClipboard = 1
End Function
Есть ли у меня вопрос? У меня всегда есть вопрос

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

Сообщение GSerg » 13.01.2005 (Чт) 14:47

Извращенец - это распространённое обозначение нас, программистов, когда мы чё-то делаем через ж :) Обижаться не следует.

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

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 13.01.2005 (Чт) 14:50

Код: Выделить всё
Public Declare Function SetClipboardData Lib "user32" _
(ByVal wFormat As Long, ByVal hMem As Long) As Long
Есть ли у меня вопрос? У меня всегда есть вопрос

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

Сообщение GSerg » 13.01.2005 (Чт) 14:59

Мда, вопрос я задал немного не тот :)

Тот вопрос: ты читал MSDN на предмет того, как ставятся данные в буфер? openclipboard, emptyclipboard, globalalloc (moveable), globallock, copymemory, globalunlock, setclipboarddata, closeclipboard.

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

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 13.01.2005 (Чт) 15:16

вмешаюсь немного в вашу дисскусию.
вот, что в MSDN пишет для копирования например RTF в Word:

Код: Выделить всё
'sRTF represents the rich text formatted string to paste into Word
Dim sRTF As String
sRTF = "{\rtf1\ansi\ansicpg1252\deff0\deftab720{\fonttbl" & _
       "{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}" & _
       "{\f2\froman\fprq2 Times New Roman;}}" & _
       "{\colortbl\red0\green0\blue0;\red255\green0\blue0;}" & _
       "\deflang1033\horzdoc{\*\fchars }{\*\lchars }" & _
       "\pard\plain\f2\fs24 Line 1 of \plain\f2\fs24\cf1" & _
       "inserted\plain\f2\fs24  file.\par }"
         
'Copy the contents of the Rich Text to the clipboard
Dim lSuccess As Long
Dim lRTF As Long
Dim hGlobal As Long
Dim lpString As Long
lSuccess = OpenClipboard(Me.hwnd)
lRTF = RegisterClipboardFormat("Rich Text Format")
lSuccess = EmptyClipboard
hGlobal = GlobalAlloc(GMEM_MOVEABLE Or GMEM_DDESHARE, Len(sRTF))
lpString = GlobalLock(hGlobal)
CopyMemory lpString, ByVal sRTF, Len(sRTF)
GlobalUnlock hGlobal
SetClipboardData lRTF, hGlobal
CloseClipboard
GlobalFree hGlobal
   
'Paste into a new Word document
Dim oWord As Object
Dim oDoc As Object
Set oWord = CreateObject("word.application")
Set oDoc = oWord.Documents.Add
oWord.Selection.Paste
oWord.Visible = True



а это декларации:

Код: Выделить всё
Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function RegisterClipboardFormat Lib "user32" Alias _
    "RegisterClipboardFormatA" (ByVal lpString As String) As Long
Private Declare Function EmptyClipboard Lib "user32" () As Long
Private Declare Function CloseClipboard Lib "user32" () As Long
Private Declare Function SetClipboardData Lib "user32" ( _
    ByVal wFormat As Long, ByVal hMem As Long) As Long
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, _
    ByVal dwBytes As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
    ByVal Destination As Long, Source As Any, ByVal Length As Long)
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" Alias "GlobalFree" ( _
     ByVal hMem As Long) As Long

Private Const GMEM_DDESHARE = &H2000
Private Const GMEM_MOVEABLE = &H2



Наверное надо делать что-то похожее. :?:

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 13.01.2005 (Чт) 15:36

Почему нельзя передать указатель на готовую переменную?
память должна выделяться только в глобальной куче?

Я, просто, видел пример, где в качестве handl'а передавлась переменная, куда записали результат LoadPicture
Есть ли у меня вопрос? У меня всегда есть вопрос

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

Сообщение GSerg » 13.01.2005 (Чт) 15:39

Данные, помещённые в клипбоард, больше не принадлежат приложению. Поэтому так.
Понятия глобальной кучи в 32-битных виндах нет, функции localalloc и globalalloc делают одно и то же...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

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

Сообщение GSerg » 13.01.2005 (Чт) 15:42

Eugenio писал(а):Я, просто, видел пример, где в качестве handl'а передавлась переменная, куда записали результат LoadPicture

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

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 13.01.2005 (Чт) 15:56

Эврика. :)
Есть ли у меня вопрос? У меня всегда есть вопрос

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 13.01.2005 (Чт) 16:13

Однако, результат тот же:
ничего в буфере.
Код: Выделить всё
    OpenClipboard MainWindow.hwnd
    hStrPtr = GetClipboardData(CF_FORMAT)
    lpString = GlobalLock(hStrPtr)
   
    If lpString <> 0 Then
        lLength = lstrlen(lpString)
        If lLength > 0 Then
            sBuffer = Space$(lLength)
            CopyMemory sBuffer, hStrPtr, lLength
        End If
    End If
    GlobalUnlock lpString
    CloseClipboard


lpString = 0
Есть ли у меня вопрос? У меня всегда есть вопрос

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 13.01.2005 (Чт) 16:15

посмотри код, что я раньше запостил. мне кажется что-то ты не так делаешь

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

Сообщение GSerg » 13.01.2005 (Чт) 16:16

Кто будет MSDN читать - ты или я? :)
Я перечислил тебе функции в порядке использования. Используй!
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 13.01.2005 (Чт) 16:18

я думаю, что он - Eugenio :P

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 13.01.2005 (Чт) 16:58

нашел. почти.
Код: Выделить всё
CopyMemory StrPtr(sBuffer), hStrPtr, lLength

вместо того, что я написал раньше:
Код: Выделить всё
CopyMemory ByVal sBuffer, hStrPtr, lLength

К черту примеры из API-GUID'а - можно попасть:)

НО:
- помещается туда строка по 2 байта на символ (всего 364), а обратно копируются только первые байты (182), которые lstrlen интерпретируются, как 91 (длина в символах)
- соответственно, в строке у нас "????" (а может эти вещи друг с другом еще и не связаны)
Последний раз редактировалось Eugenio 13.01.2005 (Чт) 17:03, всего редактировалось 1 раз.
Есть ли у меня вопрос? У меня всегда есть вопрос

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 13.01.2005 (Чт) 17:01

ну так преобразуй строку в ANSI

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 13.01.2005 (Чт) 17:10

Konst_One писал(а):ну так преобразуй строку в ANSI

1. С удовольствием, если покажешь, как.
2. Как себя ведет lstrlen я просто не понимаю - может и после этого она снова вернет "половинную" длину
Есть ли у меня вопрос? У меня всегда есть вопрос

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 13.01.2005 (Чт) 17:17

Код: Выделить всё
Buffer=vba.StrConv(Buffer,vbFromUnicode)


а стандартная конвертация не подойдет :?:

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 13.01.2005 (Чт) 18:28

Разницы - никакой.
На читаемость при получении из буфера (через CopyMemory) это никак не влияет ("Я идиот! Убейте меня, кто-нибудь!???"). не могу сообразить, с чего это.
Как еще можно узнать длину фрагмента в буфере, кроме lstrlen()?
Есть ли у меня вопрос? У меня всегда есть вопрос

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 13.01.2005 (Чт) 18:32

вот че мелкософт о ней пишет

Код: Выделить всё
lstrlen
The lstrlen function returns the length in bytes (ANSI version) or WCHARs (Unicode version) of the specified string (not including the terminating null character).

int lstrlen(
  LPCTSTR lpString   // string to count
);
Parameters
lpString
[in] Pointer to a null-terminated string.
Return Values
The return value specifies the length of the string, in TCHARs. This refers to bytes for ANSI versions of the function or WCHARs for Unicode versions.

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 13.01.2005 (Чт) 18:38

посмотри по UNICODE инфу
проверь свою строку ф-ей IsTextUnicode

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 13.01.2005 (Чт) 19:00

Ладно, придется забить на это. По-видимому, я уже должен был сам разобраться, раз этого не случилось - значит не способен.

Строки в VB хранятся в Unicod, но преобразуются при передаче в качестве аргумента, когда юзается ANSI-версия какой-ндь функции.
у lstrlen я вызываю ANSI-версию (описание прочитал до того, как применять функцию)
Есть ли у меня вопрос? У меня всегда есть вопрос

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

Сообщение GSerg » 13.01.2005 (Чт) 19:22

Ууууу, оптимист... Ты программер или кто? :) Ухватил много - значит, обнаружил сам для себя пробелы. Значит, будет чем заняться завтра :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

След.

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

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

Сейчас этот форум просматривают: Yandex-бот и гости: 1

    TopList