Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.88/40: Рейтинг темы: голосов - 40, средняя оценка - 4.88
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800

Как работать с потоками IStream в Visual Basic 6

16.11.2024, 18:08. Показов 13595. Ответов 206
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет! Я недавно узнал о таком чуде как потоки IStream, это такие данные в оперативной памяти вашего процесса EXE типа байтовых массивов только круче. Как я это понял лично. Вот мне очень интересно стало поработать именно со стримами. Если у кого-то есть какие-то наработки в этом плане буду рад, если поделитесь.

Из того, что я пока узнал:

Есть API для создания, чтения и записи стримов - это функции SHCreateMemStream, IStream_Write, IStream_Read и IStream_Size. Это конечно очень интересно всё, но я не нашёл функции для позиционирования IStream_Seek (её что не существует?).

Есть возможность управлять стримами через объявления в TLB, однако мне эта тема не интересна, так как я не люблю подключать всякие там TLB.

Есть возможность управлять потоками IStream через специальную функцию DispCallByVtbl

Хотелось бы подробно разобрать эту тему и научиться:

1. Создавать поток IStream
2. Записывать
3. Считывать
4. Позиционировать
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.11.2024, 18:08
Ответы с готовыми решениями:

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

Как работать в Visual Basic'е с реестром?
Народ, может кто подскажет, как работать в Visual Basic'е с реестром?

Как работать с таблицами Ecxel в Visual Basic?
Как работать с таблицами Ecxel в Visual Basic?

206
Модератор
10061 / 3906 / 885
Регистрация: 22.02.2013
Сообщений: 5,856
Записей в блоге: 79
17.01.2025, 15:56
Студворк — интернет-сервис помощи студентам
HackerVlad, тот код помимо сохранения картинки позволяет указать качество, а также делает скриншот всего экрана. Вот минимальная функция сохранения через GDI+ - аналог твоего кода.
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Private Declare Function GdiplusStartup Lib "gdiplus" (token As Long, inputbuf As Any, Optional ByVal outputbuf As Long = 0) As Long
Private Declare Sub GdiplusShutdown Lib "gdiplus" (ByVal token As Long)
Private Declare Function GdipSaveImageToStream Lib "gdiplus" (ByVal image As Long, ByVal stream As IUnknown, clsidEncoder As Any, encoderParams As Any) As Long
Private Declare Function GdipCreateBitmapFromHBITMAP Lib "gdiplus" (ByVal hbm As Long, ByVal hpal As Long, bitmap As Long) As Long
Private Declare Function GdipDisposeImage Lib "gdiplus" (ByVal image As Long) As Long
Private Declare Function CreateStreamOnHGlobal Lib "ole32" (ByVal hGlobal As Long, ByVal fDeleteOnRelease As Long, ppstm As IUnknown) As Long
Private Declare Function GetHGlobalFromStream Lib "ole32" (ByVal ppstm As IUnknown, hGlobal 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 GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Sub memcpy Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
 
Private Function SaveAsPng(ByVal cImage As IPicture) As Byte()
    Dim cBuf(3) As Currency, hToken As Long, hBmp As Long, cStm As IUnknown, hMem As Long, lSize As Long, bData() As Byte
    
    cBuf(0) = 0.0001@: cBuf(2) = 128439892464716.6982@: cBuf(3) = 338308179558612.6746@
 
    If GdiplusStartup(hToken, cBuf(0)) = 0 And CreateStreamOnHGlobal(0, 1, cStm) >= 0 Then
        If GdipCreateBitmapFromHBITMAP(Me.Picture.Handle, 0, hBmp) = 0 Then
            If GdipSaveImageToStream(hBmp, cStm, cBuf(2), ByVal 0&) = 0 Then
                If GetHGlobalFromStream(cStm, hMem) >= 0 Then
                    lSize = GlobalSize(hMem)
                    ReDim bData(lSize - 1)
                    memcpy bData(0), ByVal GlobalLock(hMem), lSize
                    SaveAsPng = bData
                    GlobalUnlock hMem
                End If
            End If
            GdipDisposeImage hBmp
        End If
        GdiplusShutdown hToken
    End If
    
End Function
Самого кода тут намного меньше, основное - декларации.

Добавлено через 1 минуту
Цитата Сообщение от HackerVlad Посмотреть сообщение
SafeArrayGetDim например же есть
Ты посмотри что она возвращает сначала.
2
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
17.01.2025, 16:27  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
MakeHexString
Промучился целый час короче и не смог заставить работать этот код короче. Всё, сдаюсь, надоело.

Добавлено через 1 минуту
The trick, а вот за функцию SaveAsPng спасибо большое, там хоть всё описано)))
0
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
17.01.2025, 16:41  [ТС]
Итак, я это всё добро оформил в красивый новый проект-пример, показывающий как сохранить картинку в байтовый массив в формате PNG, программным кодом на VB6 этот код конечно и правда оказался даже на 10 строк меньше и будет так же работать в WIndows XP, что тоже немаловажно конечно)
Вложения
Тип файла: zip Convert a picture to PNG byte-array in memory (The trick GDI+).zip (475.8 Кб, 2 просмотров)
1
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
17.01.2025, 16:46  [ТС]
The trick, тут только один вопрос остался по этому коду: почему ты использовал CreateStreamOnHGlobal а не SHCreateMemStream

Добавлено через 1 минуту
Цитата Сообщение от The trick Посмотреть сообщение
тот код помимо сохранения картинки позволяет указать качество, а также делает скриншот всего экрана
Да, ты прав, извини, не заметил сразу просто
0
1406 / 865 / 93
Регистрация: 08.02.2017
Сообщений: 3,694
Записей в блоге: 2
17.01.2025, 16:47
HackerVlad, а тот пример с ADO я не нашел здесь, но я просто, я думаю, раз в том случае у тебя выпало IDE, значит, может работать такой вариант (без ObjPtr)
Visual Basic
1
pPic.SaveAsFile ByVal vbaCastObj(ADOStream, bIID_IStream(0)), True, 0
0
Модератор
10061 / 3906 / 885
Регистрация: 22.02.2013
Сообщений: 5,856
Записей в блоге: 79
17.01.2025, 16:52
Цитата Сообщение от HackerVlad Посмотреть сообщение
The trick, тут только один вопрос остался по этому коду: почему ты использовал CreateStreamOnHGlobal а не SHCreateMemStream
Попробуй заменить и посмотри что получится.

Добавлено через 2 минуты
Цитата Сообщение от HackerVlad Посмотреть сообщение
этот код конечно и правда оказался даже на 10 строк меньше
Размер кода в строках в общем случае не всегда коррелирует с размером бинарного кода на выходе. В коде с msado куча лишних действий выполняется что в конечном итоге оказывается намного дороже. Там только одно создание стрима из msado занимает больше времени чем весь код с GDI+ (не считая самого сжатия)
1
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
17.01.2025, 16:57  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
Попробуй заменить и посмотри что получится.
Всё понял, верю на слова, значит так обязательно надо (такие редкие исключения бывают же).

Добавлено через 2 минуты
Цитата Сообщение от testuser2 Посмотреть сообщение
значит, может работать такой вариант
вылет, сам попробуй, твоя идея рухнула

Добавлено через 1 минуту
Цитата Сообщение от testuser2 Посмотреть сообщение
а тот пример с ADO я не нашел здесь
ну я не помню выкладвыал пример или нет, если нет, то просто скачай этот новый пример который я выложил с GDI+ и просто весь код формы заменить все эти АПИ GDI+ на код через ADOStream, вот и всё

Добавлено через 1 минуту
я вроде же выкладывал пример, там была другая картинка, там была пальма я вспомнил, а не девочка
0
1406 / 865 / 93
Регистрация: 08.02.2017
Сообщений: 3,694
Записей в блоге: 2
17.01.2025, 17:39
Версия без API
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
Function SafeArrayElementsCountVB(Arr As Variant) As Long
    Dim i&, Lb&, Ub&, Cnt&
    On Error GoTo endFunc
    Cnt = (UBound(Arr) - LBound(Arr) + 1)
    For i = 2 To 100
        Lb = LBound(Arr, i)
        Ub = UBound(Arr, i)
        Cnt = Cnt * (Ub - Lb + 1)
    Next
endFunc:
    SafeArrayElementsCountVB = Cnt
End Function
1
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
17.01.2025, 17:47  [ТС]
MakeHexString какая-то нерабочая функция совсем

Добавлено через 3 минуты
Цитата Сообщение от testuser2 Посмотреть сообщение
Версия без API
Это идеальный код конечно, но он не совместим с тем что требует от нас код MakeHexString он требует просто ссылку на массив, а не сам массив
0
1406 / 865 / 93
Регистрация: 08.02.2017
Сообщений: 3,694
Записей в блоге: 2
17.01.2025, 17:48
Цитата Сообщение от HackerVlad Посмотреть сообщение
требует просто ссылку на массив
Так в основной функции на входе байтовый массив
0
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
17.01.2025, 17:48  [ТС]
как заставить MakeHexString работать вообще не понятно короче хоть ты кол на голове чеши
0
1406 / 865 / 93
Регистрация: 08.02.2017
Сообщений: 3,694
Записей в блоге: 2
17.01.2025, 17:52
Должно быть так
Visual Basic
1
2
3
4
5
6
    lLength = SafeArrayElementsCountVB(bData)
    If lLength = 0 Then Exit Function
    
    ReDim bOut(lLength - 1)
    
    lLength = lLength \ 4
0
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
17.01.2025, 18:12  [ТС]
testuser2, да там этот Not Not дурацкий мне сразу не понравился, наверное он всё и портил

Добавлено через 1 минуту
testuser2, Что-то не тое

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
Option Explicit
Private Declare Sub memcpy Lib "kernel32" Alias "RtlMoveMemory" (Dest As Any, Src As Any, ByVal Length As Long)
 
Private Type SAFEARRAYBOUND
    cCount              As Long
    lBound              As Long
End Type
 
Private Type SAFEARRAY
    cDims               As Integer
    fFeatures           As Integer
    cbElements          As Long
    cLocks              As Long
    pvData              As Long
    Bounds              As SAFEARRAYBOUND
End Type
 
' //
' // Get number of elements in array by pointer
' //
Public Function SafeArrayElementsCountVB(Arr As Variant) As Long
    Dim i&, Lb&, Ub&, Cnt&
    On Error GoTo endFunc
    Cnt = (UBound(Arr) - LBound(Arr) + 1)
    For i = 2 To 100
        Lb = LBound(Arr, i)
        Ub = UBound(Arr, i)
        Cnt = Cnt * (Ub - Lb + 1)
    Next
endFunc:
    SafeArrayElementsCountVB = Cnt
End Function
 
Public Function MakeHexString( _
                ByRef bData() As Byte) As String
    Dim lLength As Long
    Dim bOut()  As Byte
    Dim lIndex  As Long
    Dim lChar   As Long
    Dim lSymbol As Long
    Dim lDig    As Long
    Dim lValue  As Long
    
    lLength = SafeArrayElementsCountVB(bData)
    If lLength = 0 Then Exit Function
    
    ReDim bOut(lLength - 1)
    
    lLength = lLength \ 4
    
    ReDim bOut(lLength * 4 - 1)
    
    For lIndex = 0 To lLength - 1
        
        lValue = bData(lIndex)
        
        For lDig = 0 To 1
            
            lSymbol = (lValue And &HF0) \ &H10
            
            Select Case lSymbol
            Case Is < 10:   lSymbol = lSymbol + &H30
            Case Else:      lSymbol = lSymbol + &H37
            End Select
            
            bOut(lChar) = lSymbol
            
            lValue = lValue * &H10
            lChar = lChar + 2
            
        Next
        
    Next
    
    MakeHexString = bOut()
    
End Function
 
Private Sub Command1_Click()
    Dim str As String
    Dim bArray() As Byte
    
    str = "This is a string value 1234567890"
    bArray = str
    
    MsgBox MakeHexString(bArray)
End Sub
Этот код выдаёт просто цифры без латинских букв как надо бы в Hex-кодировке...
0
1406 / 865 / 93
Регистрация: 08.02.2017
Сообщений: 3,694
Записей в блоге: 2
17.01.2025, 18:12
Он она ета функция The trick-а,
https://www.vbforums.com/showt... ost5339285
0
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
17.01.2025, 18:16  [ТС]
Придётся детально разбираться в этом сложном коде, ну и подкинул мне работы The Trick

Добавлено через 2 минуты
testuser2, а у тебя уже есть готовая функция, чтобы не возиться с кодом трика?
0
1406 / 865 / 93
Регистрация: 08.02.2017
Сообщений: 3,694
Записей в блоге: 2
17.01.2025, 18:18
Цитата Сообщение от HackerVlad Посмотреть сообщение
а у тебя уже есть готовая функция, чтобы не возиться с кодом трика?
Я же выкладывал
0
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
17.01.2025, 18:20  [ТС]
Цитата Сообщение от testuser2 Посмотреть сообщение
Я же выкладывал
И где там преобразование в String как у трюкача? нету же!

Добавлено через 43 секунды
testuser2, не понимаю её работы Long и Long и всё

Добавлено через 45 секунд
или ты просто не написал As String? и поэтому так сильно меня сбил с толкку...
0
1406 / 865 / 93
Регистрация: 08.02.2017
Сообщений: 3,694
Записей в блоге: 2
17.01.2025, 18:21
Там просто надо указать тип функции String, я забыл
0
Модератор
10061 / 3906 / 885
Регистрация: 22.02.2013
Сообщений: 5,856
Записей в блоге: 79
17.01.2025, 18:21
Цитата Сообщение от HackerVlad Посмотреть сообщение
Этот код выдаёт просто цифры без латинских букв как надо бы в Hex-кодировке...
А что ты ожидаешь от кривого кода? Ты видел мою функцию MakeHexString? А теперь посмотри на свою.
0
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
17.01.2025, 18:22  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
А что ты ожидаешь от кривого кода?
Ты же не привёл правильного кода, а тут пол дня мучайся из-за этого, я знаю там косяки какие-то, пока не понимаю какие
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
17.01.2025, 18:22

Можно ли научится работать ASP.NET на основе Visual Basic
Всем доброго времени суток. Немножко владею навыками создавть и писать программы на VS 2010 на основе Visual Basic-a, можно ли научится...

Где бесплатно скачать учебник по Visual Basic 6 и Visual Basic .Net ?
Где бесплатно скачать учебник по Visual Basic 6 и Visual Basic .Net

Вычисление значений функции двух переменных в Visual Basic - Visual Basic
Помогите пожалуйста! В среде VB написать программу вычисления значений функции двух переменных. Ориентировочный вид окна программы и...

Как быстро работать с комбинациями стилей текста(жирный, курсив, жирный + курсив и т. д.) в Visual Basic?
Здравствуйте. Я учусь в университете, нам задали написать текстовый редактор. Я использую RichTextBox и мне нужно, чтобы я по нажатию...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
180
Ответ Создать тему
Новые блоги и статьи
сукцессия 43. Вторая научная статья за месяц- прайминг и гатгил
anaschu 25.07.2026
две стороны одной монеты
Более приземисто - Эстафету хвоста в .cdl (деревья эстафеты в сад).
Hrethgir 24.07.2026
В будущем, после написания блока инверсии обхода дерева (эстафеты хвоста), я планирую вернуться к нашему прошлому разговору о том, обладают ли знания целеполаганием. Тогда я пришел к выводу, что. . .
Вот представьте что вам дали бессмертие.
kumehtar 24.07.2026
Вот представьте что вам дали бессмертие, ничего более не меняя. Вообще ничего, только бессмертие в нынешнем виде. Рады были бы? Что бы вы тут делали всё это время? Никакой пенсии. Никакого нового. . .
сукцессия 41
anaschu 24.07.2026
Численная верификация бифуркации в агентной модели лесной сукцессии: от одного параметра к ансамблю Автор: пользователь @Shumilov_AS | Раздел: Прикладная математика / Численные методы Кратко. . .
сукцессия 40. Ансамблевая кластерная параметризаци, часть 1.
anaschu 24.07.2026
Пр# Сопровождение научной статьи ИИ-ассистентом: подготовка публикации и калибровка агентно-ориентированной модели сукцессии микоризных систем **Полевые заметки о двухнедельной совместной работе**. . .
Теория всего 12. ВГК на планете в стратегической игре "терра"
anaschu 21.07.2026
### Главные семантические изменения и дешифровка новой физики 1. **`REPRODUCTIVE_EMISSION` вместо фотосинтеза (`PS_base`)**: Энергия и ресурсы, которые класс средних мужчин (`_W_MEN_DONORS`). . .
Публикация отклонённая на хабре. Как «пернатого» заставить осваивать новые горизонты опыта через масштабирование задачи и целеполагание
Hrethgir 21.07.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11948&stc=1&d=1784657928 Привет Хабр. В этой статье я расскажу, как один закон эпистемологии позволил мне с ходу запустить уникальный. . .
Теория всего 11. Основные параметры
anaschu 21.07.2026
Дешифровка тензорного ядра Soil Chemistry 2. 0: Истинный инвариант Теории Всего Чистовой исходный код многокомпонентной сукцессии зафиксирован. Модель оперирует единым вектором состояния. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru