Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.60/2086: Рейтинг темы: голосов - 2086, средняя оценка - 4.60
 Аватар для Mikle Quits
787 / 308 / 17
Регистрация: 21.01.2023
Сообщений: 531
02.11.2024, 10:43
Студворк — интернет-сервис помощи студентам
Физика игры - 2D платформера.

Я максимально упростил физику 2D платформера с инерцией, прыжками и аэроконтролом. Можно применять в качестве основы для простой игры. Все основные параметры вынесены в константы и могут регулироваться на свой вкус.
На графику не смотрите - это просто для примера.
Вложения
Тип файла: zip PlatformerPhys.zip (8.3 Кб, 47 просмотров)
3
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.11.2024, 10:43
Ответы с готовыми решениями:

Продам готовые коды и решения на Visual Basic за 400 рублей
душу продаю:cry: Продам коды исходные на VB !!10 лет копил за 400р !!размер тока кодов 312метров там есть все ! мыло контакты удалены....

Коды на Visual Basic
Ребята всем привет,я начел изучать "Visual Basic"! Очень буду благодарен за коды по этому языку, очень интиресный язык)))! Бросайте сюда...

Вывод решения вместо Immediate в textbox (visual basic 6.0)
программа выводит решение в Immediate а я хочу разместить на форме text1 и что бы решение выводилось туда ,менял код менял не че не...

360
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
05.11.2024, 20:48
Модуль для упаковки и распаковки буфера с помощью технологии Delta Compression

Написал новый модуль для упаковки и распаковки буфера с помощью технологии Delta Compression. Сжимает очень хорошо, лучше даже чем CAB, однако медленно упаковывает большие файлы, но зато распаковывает довольно быстро. Это очень хороший алгоритм, в интернете такого кода ещё нигде не было для VB6. Огромная благодарность testuser2. Работает даже в старом Windows XP. Плюс бонусом к этому проекту ещё идут и другие модули для упаковки и распаковки данных. Думаю вам всем будет интересно посмотреть!

Сам модуль:

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
Option Explicit
'////////////////////////////////////////////////////////////////////////////////////
'// Модуль для упаковки и распаковки буфера с помощью технологии Delta Compression //
'// Copyright (c) 05.11.2024 by HackerVlad & testuser2                             //
'// E-mail: vladislavpeshkov@yandex.ru                                             //
'// Обсуждение темы: https://www.cyberforum.ru/visual-basic/thread3183774.html     //
'// Версия: 1.0                                                                    //
'////////////////////////////////////////////////////////////////////////////////////
 
Private Const DELTA_FILE_TYPE_RAW@ = 1 / 10000
Private Const DELTA_FLAG_IGNORE_FILE_SIZE_LIMIT@ = 131072 / 10000 ' &H20000 (0x00020000)
 
Private Declare Function CreateDeltaB Lib "msdelta" (Optional ByVal FileTypeSet As Currency = DELTA_FILE_TYPE_RAW, Optional ByVal SetFlags As Currency, Optional ByVal ResetFlags As Currency, Optional ByVal Src_lpcStart As LongPtr, Optional ByVal Src_uSize As LongPtr, Optional ByVal Src_Editable As Long, Optional ByRef Trg_lpcStart As Any, Optional ByVal Trg_uSize As LongPtr, Optional ByVal Trg_Editable As Long, Optional ByVal SrcOpt_lpcStart As LongPtr, Optional ByVal SrcOpt_uSize As LongPtr, Optional ByVal SrcOpt_Editable As Long, Optional ByVal TrgOpt_lpcStart As LongPtr, Optional ByVal TrgOpt_uSize As LongPtr, Optional ByVal TrgOpt_Editable As Long, Optional ByVal GlbOpt_lpcStart As LongPtr, Optional ByVal GlbOpt_uSize As LongPtr, Optional ByVal GlbOpt_Editable As Long, Optional ByVal lpTargetFileTime As LongPtr, Optional ByVal HashAlgId As Long, Optional ByRef lpDelta As Any) As Long
Private Declare Function ApplyDeltaB Lib "msdelta" (ByVal ApplyFlags As Currency, ByVal Src_lpcStart As LongPtr, ByVal Src_uSize As LongPtr, ByVal Src_Editable As Long, ByRef Dlt_lpcStart As Any, ByVal Dlt_uSize As LongPtr, ByVal Dlt_Editable As Long, ByRef lpTarget As DELTA_OUTPUT) As Long
Private Declare Function DeltaFree Lib "msdelta" (ByVal lpMemory As LongPtr) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
 
'## Раскомментировать в VB6 ##
Private Enum LongPtr
    [_]
End Enum
'#############################
 
Private Type DELTA_OUTPUT
    lpStart As LongPtr
    uSize As LongPtr
End Type
 
' Упаковать (сжать) данные байтового массива
Public Function CompressDeltaB(byteArray() As Byte) As Boolean
    On Error GoTo Quit
    
    Dim DO_Res As DELTA_OUTPUT
    Dim ret As Long
    
    ret = CreateDeltaB(SetFlags:=DELTA_FLAG_IGNORE_FILE_SIZE_LIMIT, Trg_lpcStart:=byteArray(0), Trg_uSize:=UBound(byteArray) + 1, lpDelta:=DO_Res)
    
    If ret Then
        With DO_Res
            ReDim byteArray(.uSize - 1)
            CopyMemory byteArray(0), ByVal .lpStart, .uSize
            DeltaFree (.lpStart)
        End With
        
        CompressDeltaB = True
    End If
Quit:
End Function
 
' Распаковать (извлечь) данные байтового массива
Public Function DeCompressDeltaB(byteArray() As Byte) As Boolean
    On Error GoTo Quit
    
    Dim DO_Res As DELTA_OUTPUT
    Dim ret As Long
    
    ret = ApplyDeltaB(0, 0, 0, 0, byteArray(0), UBound(byteArray) + 1, 0, DO_Res)
    
    If ret Then
        With DO_Res
            If .lpStart Then
                ReDim byteArray(.uSize - 1)
                CopyMemory byteArray(0), ByVal .lpStart, .uSize
                DeltaFree (.lpStart)
            End If
        End With
        
        DeCompressDeltaB = True
    End If
Quit:
End Function
Форма:

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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function IsFileAPI Lib "shlwapi" Alias "PathFileExistsA" (ByVal pszPath As String) As Long
Private Declare Function RtlComputeCrc32 Lib "ntdll.dll" (ByVal dwInitial As Long, ByVal pData As Long, ByVal iLen As Long) As Long
Dim buf() As Byte
 
Public Function Crc32Api(tBuff() As Byte) As Long
    Crc32Api = RtlComputeCrc32(0, VarPtr(tBuff(0)), UBound(tBuff) + 1)
End Function
 
Private Sub Command1_Click()
    Dim FileNo As Integer
    Dim fLen As Long
    
    ' Инициализировать счётчик
    FileNo = FreeFile
    
    ' Открыть файл
    Open App.Path + "\" + Text1.Text For Binary As FileNo
        fLen = LOF(FileNo)
        ReDim buf(fLen - 1)
        Get #FileNo, , buf
    Close FileNo
    
    Print "ubound: " & UBound(buf)
    Print "Контрольная сумма: " & Hex(Crc32Api(buf))
    
    'On Error Resume Next
    'Clipboard.SetText Crc32Api(buf)
End Sub
 
Private Sub Command10_Click()
    Dim tick As Long
    Dim result As Boolean
    
    tick = GetTickCount
    
    result = DeCompressDeltaB(buf)
    Print result
    
    Print (GetTickCount - tick)
    If result = True Then Print "ubound: " & UBound(buf)
End Sub
 
Private Sub Command2_Click()
    Dim tick As Long
    
    tick = GetTickCount
    
    Compress_Huffman_Dynamic buf
    
    Print (GetTickCount - tick)
    Print "ubound: " & UBound(buf)
End Sub
 
Private Sub Command3_Click()
    Dim tick As Long
    
    tick = GetTickCount
    
    DeCompress_Huffman_Dynamic buf
    
    Print (GetTickCount - tick)
    Print "ubound: " & UBound(buf)
End Sub
 
Private Sub Command4_Click()
    Dim tick As Long
    Dim result As Boolean
    
    tick = GetTickCount
    
    result = Compress_NT(buf)
    Print result
    
    Print (GetTickCount - tick)
    If result = True Then Print "ubound: " & UBound(buf)
End Sub
 
Private Sub Command5_Click()
    Dim tick As Long
    Dim result As Boolean
    
    tick = GetTickCount
    
    result = DeCompress_NT(buf)
    Print result
    
    Print (GetTickCount - tick)
    If result = True Then Print "ubound: " & UBound(buf)
End Sub
 
Private Sub Command6_Click()
    Dim FileNo As Integer
    
    ' Инициализировать счётчик
    FileNo = FreeFile
    
    If IsFileAPI(App.Path + "\" + Text2.Text) <> 0 Then Kill App.Path + "\" + Text2.Text
    
    ' Открыть файл
    Open App.Path + "\" + Text2.Text For Binary As FileNo
        Put #FileNo, , buf
    Close FileNo
End Sub
 
Private Sub Command7_Click()
    Dim tick As Long
    
    tick = GetTickCount
    
    Compress_HuffManShortDictRC4 buf, "123BB"
    
    Print (GetTickCount - tick)
    Print "ubound: " & UBound(buf)
End Sub
 
Private Sub Command8_Click()
    Dim tick As Long
    
    tick = GetTickCount
    
    Decompress_HuffmanShortDictRC4 buf, "123BB"
    
    Print (GetTickCount - tick)
    Print "ubound: " & UBound(buf)
End Sub
 
Private Sub Command9_Click()
    Dim tick As Long
    Dim result As Boolean
    
    tick = GetTickCount
    
    result = CompressDeltaB(buf)
    Print result
    
    Print (GetTickCount - tick)
    If result = True Then Print "ubound: " & UBound(buf)
End Sub
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: zip Упаковка и распаковка буфера с помощью технологии Del.zip (136.7 Кб, 27 просмотров)
4
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
11.11.2024, 01:49
Модуль для чтения CAB-архивов

Написал сегодня наконец-то модуль для чтения CAB-архивов. С помощью этого модуля можно прочитать список файлов, внутри CAB-архивов и какой файл занимает сколько байт. Дату и время файлов я не добавил, так как мне это было не надо, но это очень легко сделать самому, немного переделав модуль и пользовательский UDT-массив, для получения данных списка файлов.

Это очень простая реализация, я стремился сделать как можно меньше строк кода, чтобы было. На самом же деле распаковка CAB-архива вообще производится всего лишь одной строкой кода. Для этого надо обращаться к недокументированной, но очень полезной, функции ExtractFiles из библиотеки advpack.dll, которая есть во всех Windows.

Форма:
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
Option Explicit
Private Declare Function ExtractFiles Lib "advpack.dll" Alias "ExtractFilesA" (ByVal CabName As String, ByVal ExpandDir As String, ByVal Flags As Long, ByVal FileList As String, lpReserved As Any, ByVal Reserved As Long) As Long
Private Declare Function SafeArrayGetDim Lib "oleaut32.dll" (arr() As Any) As Long
 
Private Sub Command1_Click()
    Dim arrListCab() As CabInfo
    Dim i As Long
    
    If GetFilesListInCab(Text1.Text, arrListCab) > 0 Then
        If SafeArrayGetDim(arrListCab) > 0 Then
            If List1.ListCount > 0 Then List1.Clear
            
            For i = 0 To UBound(arrListCab)
                List1.AddItem arrListCab(i).cabFileName & "    " & arrListCab(i).cabFileSize & " bytes"
            Next
            
            If List1.ListCount > 0 Then
                List1.Selected(0) = True
                List1.SetFocus
                
                Me.Caption = "UnCab 1.0 by HackerVlad    (" & List1.ListCount & " files)"
            End If
        End If
    Else
        Beep ' err
    End If
End Sub
 
Private Sub Command2_Click()
    Dim str As String
    
    str = Left$(List1.Text, InStr(1, List1.Text, "    ") - 1)
    
    If ExtractFiles(Text1.Text, Text2.Text, 0, str, 0, 0) = 0 Then
        Me.Cls
        Print "Файл из архива успешно извлечён"
    Else
        Me.Cls
        Print "Ошибка"
    End If
End Sub
 
Private Sub Command3_Click()
    If ExtractFiles(Text1.Text, Text2.Text, 0, vbNullString, 0, 0) = 0 Then
        Me.Cls
        Print "Архив полностью успешно извлечён"
    Else
        Me.Cls
        Print "Ошибка"
    End If
End Sub
 
Private Sub Form_DblClick()
    MsgBox GetFilesCountInCab(Text1.Text), vbInformation
End Sub
 
Private Sub Form_Load()
    Text1.Text = App.Path & "\CabFile.cab"
    Text2.Text = App.Path & "\TestUnpacked"
    
    On Error Resume Next
    MkDir App.Path & "\TestUnpacked"
End Sub
 
Private Sub Text1_KeyPress(KeyAscii As Integer)
    If KeyAscii = 13 Then
        KeyAscii = 0
        Command1_Click
    End If
End Sub


Модуль:
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
Option Explicit
'////////////////////////////////////////////
'// Модуль для чтения CAB-архивов          //
'// Copyright (c) 11.11.2024 by HackerVlad //
'// e-mail: vladislavpeshkov@yandex.ru     //
'// Версия 1.0                             //
'////////////////////////////////////////////
 
Private Declare Function SetupIterateCabinet Lib "setupapi" Alias "SetupIterateCabinetA" (ByVal CabinetFile As String, ByVal Reserved As Long, ByVal MsgHandler As Long, ByVal Context As Long) As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, ByVal Source As Long, ByVal Length As Long)
 
Private Const MAXPATH = 260
Private Const NO_ERROR = 0
'
' Notification messages, handled in the callback
' procedure. This class doesn't handle them all.
'
Private Const SPFILENOTIFY_FILEINCABINET = &H11
Private Const SPFILENOTIFY_NEEDNEWCABINET = &H12
Private Const SPFILENOTIFY_FILEEXTRACTED = &H13
 
Private Const sicList = 568
Private Const sicCount = 569
 
Dim mstrFileToExtract As String
Dim mstrOutputPath As String
Dim mstrOutputFile As String
Dim mlngCount As Long
Dim mlngcnt As Long
Dim arrListFilesCab() As CabInfo
 
Public Type CabInfo
    cabFileName As String
    cabFileSize As Long
End Type
 
Private Type FileInCabinetInfo
    NameInCabinet As Long
    FileSize      As Long
    Win32Error    As Long
    DosDate       As Integer
    DosTime       As Integer
    DosAttribs    As Integer
    FullTargetName(0 To MAXPATH - 1) As Byte
End Type
 
Private Enum FILEOP
    FILEOP_ABORT = 0
    FILEOP_DOIT = 1
    FILEOP_SKIP = 2
End Enum
 
Private Function CabinetCallback(ByVal Context As Long, ByVal Notification As Long, ByRef Param1 As FileInCabinetInfo, ByVal Param2 As Long) As Long
    Select Case Notification
        Case SPFILENOTIFY_NEEDNEWCABINET
            CabinetCallback = NO_ERROR
            
        Case SPFILENOTIFY_FILEINCABINET
            Select Case Context
                Case sicCount
                    mlngCount = mlngCount + 1
                    CabinetCallback = FILEOP_SKIP
                    
               Case sicList
                    ' Добавить позицию в массив UDT
                    ReDim Preserve arrListFilesCab(mlngcnt)
                    arrListFilesCab(mlngcnt).cabFileName = fStringFromPointer(Param1.NameInCabinet)
                    arrListFilesCab(mlngcnt).cabFileSize = Param1.FileSize
                    mlngcnt = mlngcnt + 1
                    
                    CabinetCallback = FILEOP_SKIP ' Перебирать список файлов дальше
            End Select
    End Select
End Function
 
Private Function fStringFromPointer(ByVal ptr As Long) As String
    Dim lngLen   As Long
    Dim strBuffer As String
    '
    ' Given a string pointer, copy the value
    ' of the string into a new, safe location.
    '
    lngLen = lstrlen(ptr)
    strBuffer = Space$(lngLen)
    
    CopyMemory ByVal strBuffer, ptr, lngLen
    fStringFromPointer = strBuffer
End Function
 
' Получить список файлов внутри архива CAB
Public Function GetFilesListInCab(ByVal FileName As String, arrCabInfo() As CabInfo) As Long
    mlngcnt = 0
    
    If SetupIterateCabinet(FileName, 0, AddressOf CabinetCallback, sicList) Then
        arrCabInfo = arrListFilesCab
        GetFilesListInCab = mlngcnt
        
        Erase arrListFilesCab
    End If
End Function
 
' Узнать количество файлов внутри архива CAB
Public Function GetFilesCountInCab(ByVal FileName As String) As Long
    mlngCount = 0
    
    If SetupIterateCabinet(FileName, 0, AddressOf CabinetCallback, sicCount) Then
        GetFilesCountInCab = mlngCount
    End If
End Function
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: zip UnCab.zip (27.4 Кб, 29 просмотров)
3
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
21.11.2024, 20:56
Модуль упаковки CAB-архивов

Представляю вашему вниманию новый модуль для упаковки CAB-архивов! Это просто сумасшедший код! Такого кода в Интернете раньше небыло нигде и никогда! 20 лет никто не мог написать этот модуль, а я взял и написал за две недельки.
Visual Basic может многое на самом деле! Можно написать всё что угодно и меня всегда огорчает что в Интернете всего есть только коды на C++, а на VB6 потчи ничего нет толком нормального такого серьёзного. Вот пожалуйста, серьёзный код на VB6. Проверил, полностью работает так же и на TwinBasic. Для того чтобы модуль работал в VB6 придётся подключать надстройку от The Trick под названием CDeclFix. В ТвинБейсике вообще ничего не надо. И так всё работает.

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

В модуле есть возможность упаковывать как один файл, передавая функции параметр String, так и целый список файлов передавая функции сразу массив строк.

Пользуйтесь на здоровье! Достаточно будет написать всего одну строчку кода для упаковки, вызывая функцию CabinetAddFiles.

Форма:
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long
 
' Список файлов в каталоге с помощью VB6
Public Function ListFiles(Directory As String, StrArray() As String, Optional HiddenFiles As Boolean = True, Optional Mask As String = "*.*") As Long
    Dim FileName As String
    Dim cnt As Long
    
    If Right(Directory, 1) <> "\" Then
        Directory = Directory + "\"
    Else
        If Mid(Directory, Len(Directory) - 1, 1) = "\" Then Exit Function
    End If
    
    If HiddenFiles = True Then
        FileName = Dir(Directory + Mask, 7)
    Else
        FileName = Dir(Directory + Mask, vbNormal)
    End If
    
    Do While FileName <> vbNullString
        ReDim Preserve StrArray(cnt)
        StrArray(cnt) = FileName
        cnt = cnt + 1
        
        FileName = Dir$ ' Переход к следующей интерации
    Loop
    
    If cnt > 0 Then ListFiles = cnt
End Function
 
Private Sub Command1_Click()
    Dim tick As Long
    
    tick = GetTickCount
    
    Me.Cls
    Print CabinetAddFiles(Text1.Text, Text2.Text)
    Print (GetTickCount - tick) & " ml"
End Sub
 
Private Sub Command2_Click()
    MsgBox Chr(34) & CabinetExtractFileName(Text1.Text) & Chr(34), vbInformation
End Sub
 
Private Sub Command3_Click()
    MsgBox Chr(34) & CabinetExtractFilePath(Text1.Text) & Chr(34), vbInformation
End Sub
 
Private Sub Command4_Click()
    Dim i As Long
    Dim arrFullFileName() As String
    Dim arrDestinationFileName() As String
    Dim tick As Long
    
    Screen.MousePointer = 11
    
    If List1.ListCount > 0 Then
        For i = 0 To List1.ListCount - 1
            If List1.Selected(i) = True Then
                CabinetInsertArrayString arrFullFileName, App.Path & "\Test\" & List1.List(i)
                CabinetInsertArrayString arrDestinationFileName, "Test\" & List1.List(i)
            End If
        Next
        
        If CabinetIsArrayInitialized(arrFullFileName) = True Then
            ' Добавим в этот список ещё так же файл App.Path & "\test.txt" для примера того что можно добавлять файлы из разных папок
            CabinetInsertArrayString arrFullFileName, App.Path & "\test.txt"
            CabinetInsertArrayString arrDestinationFileName, "Test\SubDir2\test.txt"
            
            Me.Cls
            tick = GetTickCount
            
            ' Упаковать файлы
            Print CabinetAddFiles(Text3.Text, arrFullFileName, arrDestinationFileName)
            Print (GetTickCount - tick) & " ml"
        Else
            Beep
        End If
    End If
    
    Screen.MousePointer = 0
End Sub
 
Private Sub Form_Load()
    Dim arrFiles() As String
    Dim i As Long
    Dim cnt As Long
    
    Text1.Text = App.Path & "\test.cab"
    Text2.Text = App.Path & "\test.txt"
    Text3.Text = App.Path & "\Test\test.cab"
    
    cnt = ListFiles(App.Path & "\Test", arrFiles)
    
    If cnt > 0 Then
        For i = 0 To UBound(arrFiles)
            If arrFiles(i) <> "test.cab" Then
                List1.AddItem arrFiles(i)
            Else
                cnt = cnt - 1
            End If
        Next
        
        Label4.Caption = "Файлов: " & cnt
    End If
End Sub
Код модуля не влез в сообщение, к сожалению, поэтому вам придётся скачать архив.
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: 7z Packaging of CAB archives 1.2.7z (4.35 Мб, 43 просмотров)
3
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
23.11.2024, 10:52
Модуль упаковки CAB-архивов, версия 1.3

Новая версия модуля для упаковки CAB-архивов на VB6 и TwinBasic. Исправил ошибки в модуле, теперь архивы CAB будут читаться всеми архиваторами без ошибок, даже самой старой версией Total Commander.
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: 7z Упаковка CAB-архивов 1.3.7z (4.35 Мб, 16 просмотров)
3
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
04.12.2024, 23:50
Утилита StepCopyer для копирования каждого второго файла из папки в папку

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

Я давно уже задавался вопросом а как копировать файлы, через один файл, через два файла, из папки в папку. И я давно уже решил для себя написать эту очень удобную утилиту, выкладываю её, может кому-то пригодится.

Такой возможности, в Total Commander к сожалению не было, поэтому я написал автору программы Кристиану Гислеру и попросил его добавить такую возможность в известный файловый менеджер. И сегодня Кристиан Гислер по моей просьбе кстати уже выпустил новую версию программы Total Commander с возможностью выделения файлов через один файл, через два файла, через три файла... Только благодаря мне он наконец-то и добавил такую возможность выделять каждый второй файл в папке. Прямо сегодня вышло обновление.

Но так как программу свою я уже давно написал, я решил ей всё же поделиться, будет очень полезно для тех кто не пользуется самой новой версией Total Commander (сегодняшней от 4 декабря 2024), но тем ни менее хочет копировать файлы из папки в папку через один файл. Каждый второй, каждый третий файл...

Поэтому такая мини-утилитка для вас. Так же написал ещё и на ТвинБейсике, однако там почему-то нет кнопки сворачивания формы, что меня удивило... Но тем ни менее я сделал ещё и дубликат проекта на Twin'е потому что там в текстовых полях можно вводить юникодные иероглифы, хотя и на VB6 работает копирование юникодных имён файлов, но нет нормального отображения в текстовых полях. Поэтому прилагается сразу две версии: для vb6 и для Twin Basic конечно же.

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

Программа Step Copyer v. 1.0 by HackerVlad:
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
Option Explicit
Private Declare Function GetFileAttributesEx Lib "kernel32" Alias "GetFileAttributesExW" (ByVal lpFileName As Long, ByVal fInfoLevelId As Long, ByRef lpFileInformation As Any) As Long
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileW" (ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, ByVal lpBuffer As Long, ByVal nNumberOfBytesToWrite As Long, ByRef lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Any) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function SHCreateDirectory Lib "shell32" (ByVal hwnd As Long, ByVal pszPath As Long) As Long
Private Declare Function CopyFile Lib "kernel32" Alias "CopyFileW" (ByVal lpExistingFileName As Long, ByVal lpNewFileName As Long, ByVal bFailIfExists As BOOL) As Long
 
Private Const GetFileExInfoStandard As Long = 0
Private Const FILE_ATTRIBUTE_ARCHIVE = &H20
Private Const INVALID_HANDLE_VALUE As Long = -1
Private Const GENERIC_WRITE As Long = &H40000000
Private Const FILE_SHARE_READ = &H1
Private Const CREATE_ALWAYS = 2
 
Private Type WIN32_FILE_ATTRIBUTE_DATA
    dwFileAttributes    As Long
    ftCreationTime      As Currency
    ftLastAccessTime    As Currency
    ftLastWriteTime     As Currency
    nFileSizeHigh       As Long
    nFileSizeLow        As Long
End Type
 
Private Enum BOOL
    cFalse
    cTrue
End Enum
 
Dim Steps As Byte
Dim DirPath1 As String
Dim DirPath2 As String
Dim INIPath As String
Dim IsProcessed As Boolean
 
Private Function IsDir(ByVal path As String) As Boolean
    Dim tAttr As WIN32_FILE_ATTRIBUTE_DATA
    
    If GetFileAttributesEx(StrPtr(path), GetFileExInfoStandard, tAttr) <> 0 Then
        If (tAttr.dwFileAttributes And vbDirectory) <> 0 Then ' Если это каталог
            IsDir = True
        End If
    End If
End Function
 
Private Sub Command1_Click()
    Dim str As String
    Dim InitDir As String
    
    If IsDir(DirPath1) = True Then
        InitDir = DirPath1
    Else
        InitDir = AppPath
    End If
    
    str = BrowseForFolder(hwnd, "Выберите каталог," & vbNewLine & _
    "из которого, нужно копировать файлы:", _
    InitDir, True, 1.3, 1.5, True, True, True, True, SetFocusTreeView:=True)
    
    If Len(str) > 0 Then
        DirPath1 = str
        Text1.Text = DirPath1
    End If
End Sub
 
Private Sub Command2_Click()
    Dim str1 As String
    Dim str2 As String
    
    str1 = Text1.Text
    str2 = Text2.Text
    
    If str1 <> vbNullString And str2 <> vbNullString Then
        Text1.Text = str2
        Text2.Text = str1
    End If
End Sub
 
Private Sub Command3_Click()
    Dim str As String
    Dim InitDir As String
    
    If IsDir(DirPath2) = True Then
        InitDir = DirPath2
    Else
        InitDir = AppPath
    End If
    
    str = BrowseForFolder(hwnd, "Выберите каталог," & vbNewLine & _
    "куда, нужно копировать файлы:", _
    InitDir, True, 1.3, 1.5, True, True, True, True, SetFocusTreeView:=True)
    
    If Len(str) > 0 Then
        DirPath2 = str
        Text2.Text = DirPath2
    End If
End Sub
 
Private Sub Command4_Click()
    Dim i As Long
    Dim MyArray() As String
    Dim cnt As Long
    Dim Procent As Long
    Dim FileSource As String
    Dim FileDestination As String
    
    If IsProcessed = False Then
        If Right$(DirPath1, 1) = "\" Then
            DirPath1 = Mid(DirPath1, 1, Len(DirPath1) - 1)
        End If
        If Right$(DirPath2, 1) = "\" Then
            DirPath2 = Mid(DirPath2, 1, Len(DirPath2) - 1)
        End If
        
        If IsDir(Text1.Text) = True Then DirPath1 = Text1.Text
        DirPath2 = Text2.Text
        
        If Len(DirPath1) > 0 Then
            If Len(DirPath2) > 0 Then
                IsProcessed = True
                
                If IsDir(DirPath1) = False Then
                    Beep
                    Text1.SetFocus
                    IsProcessed = False
                    Exit Sub
                End If
                
                If IsDir(DirPath2) = False Then
                    If SHCreateDirectory(0, StrPtr(DirPath2)) <> 0 Then
                        MsgBox "Каталог назначения не найден и не может быть создан!", vbExclamation
                        Text2.SetFocus
                        IsProcessed = False
                        Exit Sub
                    End If
                End If
                
                Screen.MousePointer = 13
                Command4.Enabled = False
                Text1.Locked = True
                Text2.Locked = True
                
                If ListFilesOrDirsAPI(DirPath1, MyArray, True) > 0 Then
                    If Steps <> 1 Then
                        For i = 0 To UBound(MyArray) Step Steps
                            cnt = cnt + 1
                            
                            If cnt <= CLng(UBound(MyArray) / Steps) Then
                                Procent = cnt * (100 / CLng(UBound(MyArray) / Steps))
                                If Procent > 100 Then Procent = 100
                                Me.Caption = Procent & "% завершено (" & cnt & " из " & CLng(UBound(MyArray) / Steps) & ")"
                            End If
                            
                            DoEvents
                            
                            FileSource = DirPath1 & "\" & MyArray(i)
                            FileDestination = DirPath2 & "\" & MyArray(i)
                            
                            CopyFile StrPtr(FileSource), StrPtr(FileDestination), cTrue
                        Next
                    Else
                        For i = 0 To UBound(MyArray)
                            cnt = cnt + 1
                            
                            If cnt <= UBound(MyArray) Then
                                Procent = cnt * (100 / UBound(MyArray))
                                If Procent > 100 Then Procent = 100
                                Me.Caption = Procent & "% завершено (" & cnt & " из " & (UBound(MyArray) + 1) & ")"
                            End If
                            
                            DoEvents
                            
                            FileSource = DirPath1 & "\" & MyArray(i)
                            FileDestination = DirPath2 & "\" & MyArray(i)
                            
                            CopyFile StrPtr(FileSource), StrPtr(FileDestination), cTrue
                        Next
                    End If
                Else
                    'Beep
                End If
                
                Text1.Locked = False
                Text2.Locked = False
                IsProcessed = False
                Command4.Enabled = True
                
                Screen.MousePointer = 0
                Me.Caption = "Step Copyer v. 1.0 by HackerVlad"
                Beep
            Else
                MsgBox "Каталог не задан!", vbInformation
            End If
        Else
            MsgBox "Каталог не задан!", vbInformation
        End If
    Else
        Beep
    End If
End Sub
 
Private Sub Form_Load()
    Dim pIn As String
    Dim pOut As String
    Dim StepsStr As String
    
    INIPath = AppPath & "\" & AppEXENameWithoutExtension & ".ini"
    
    pIn = GetPrivateINIString("Paths", "In", INIPath)
    If pIn <> vbNullString Then
        DirPath1 = pIn
        Text1.Text = pIn
    Else
        DirPath1 = Text1.Text
    End If
    
    pOut = GetPrivateINIString("Paths", "Out", INIPath)
    If pOut <> vbNullString Then
        DirPath2 = pOut
        Text2.Text = pOut
    Else
        DirPath2 = Text2.Text
    End If
    
    StepsStr = GetPrivateINIString("CopyMode", "Step", INIPath)
    If StepsStr <> vbNullString Then Steps = StepsStr
    
    If Steps = 3 Then Option1.Value = True
    If Steps = 2 Then Option2.Value = True
    If Steps = 1 Then Option3.Value = True
    If Steps = 0 Then Steps = 2
End Sub
 
Private Sub Form_Unload(Cancel As Integer)
    Dim stringbuffer As String
    Dim hFile As Long
    
    hFile = CreateFile(StrPtr(INIPath), GENERIC_WRITE, FILE_SHARE_READ, ByVal 0&, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, 0)
    
    If hFile <> INVALID_HANDLE_VALUE Then
        stringbuffer = ChrW(&HFEFF) & "; Step Copyer v. 1.0" & vbNewLine & "; Copyright © 2024 by HackerVlad" & vbNewLine & "; e-mail: vladislavpeshkov@yandex.ru" & vbNewLine & vbNewLine & _
        "[Paths]" & vbNewLine & _
        "In = " & DirPath1 & vbNewLine & _
        "Out = " & DirPath2 & vbNewLine & vbNewLine & _
        "[CopyMode]" & vbNewLine & _
        "Step = " & Steps
        
        WriteFile hFile, StrPtr(stringbuffer), LenB(stringbuffer), 0, ByVal 0&
        CloseHandle hFile
    End If
    
    End
End Sub
 
Private Sub Option1_Click()
    Steps = 3
End Sub
 
Private Sub Option2_Click()
    Steps = 2
End Sub
 
Private Sub Option3_Click()
    Steps = 1
End Sub
 
Private Sub Text1_Change()
    Dim strW As String
    
    If IsProcessed = False Then
        strW = Text1.Text
        
        If DirPath1 <> strW Then
            If IsDir(strW) = True Then
                If InStr(1, strW, Chr(&H3F)) = 0 Then
                    DirPath1 = strW
                End If
            End If
        End If
    End If
End Sub
 
Private Sub Text2_Change()
    Dim strW As String
    
    If IsProcessed = False Then
        strW = Text2.Text
        
        If DirPath2 <> strW Then
            If InStr(1, strW, Chr(&H3F)) = 0 Then
                DirPath2 = strW
            End If
        End If
    End If
End Sub
 
Private Sub Text1_KeyPress(KeyAscii As Integer)
    If KeyAscii = 13 Then
        KeyAscii = 0
        Command4_Click
    End If
End Sub
 
Private Sub Text2_KeyPress(KeyAscii As Integer)
    If KeyAscii = 13 Then
        KeyAscii = 0
        Command4_Click
    End If
End Sub
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: zip StepCopyer.zip (411.4 Кб, 34 просмотров)
3
1406 / 865 / 93
Регистрация: 08.02.2017
Сообщений: 3,694
Записей в блоге: 2
14.12.2024, 10:31
Функция логического сравнения строк. Логическое сравнение нужно тогда, когда нужно числа внутри строк сравнивать отдельно от строк, например нужно отсортировать пути файлов и папок, содержащие числа.
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
Private Sub testStrCompLogicalVB()
    Dim s1$, s2$
    s1 = "sa2dfs10f"
    s2 = "sa2dfs9f"
    Debug.Print StrCompLogicalVB(s2, s1) '1 (больше)
End Sub
 
Function StrCompLogicalVB(Str1 As String, Str2 As String) As Long
    Static iStr1%(), iStr2%()
    Dim i1&, i2&, Ln1&, Ln2&, Num1&, Num2&, Char1%, Char2%
    
'    If StrPtr(Str1) = StrPtr(Str2) Then Exit Function
    Ln1 = Len(Str1): Ln2 = Len(Str2)
    If Ln1 <> Ln2 Then
        If Ln1 = 0 Then StrCompLogicalVB = -1: Exit Function
        If Ln2 = 0 Then StrCompLogicalVB = 1: Exit Function
    End If
    ReDim Preserve iStr1(Ln1), iStr2(Ln2)
    CopyMemory iStr1(1), ByVal StrPtr(Str1), LenB(Str1)
    CopyMemory iStr2(1), ByVal StrPtr(Str2), LenB(Str2)
    
    For i1 = 1 To Ln1
        i2 = i2 + 1
        If i2 > Ln2 Then StrCompLogicalVB = 1: Exit Function
        Char1 = iStr1(i1)
        Char2 = iStr2(i2)
        Select Case Char1
        Case Is = Char2
        Case 48 To 57
            Select Case Char2
            Case 48 To 57
                GetNumberFromString Str2, iStr2, Num2, i2
            Case Else: StrCompLogicalVB = -1: Exit Function
            End Select
            GetNumberFromString Str1, iStr1, Num1, i1
            Select Case Num1
            Case Is < Num2: StrCompLogicalVB = -1: Exit Function
            Case Is > Num2: StrCompLogicalVB = 1: Exit Function
            End Select
        Case Is < Char2: StrCompLogicalVB = -1: Exit Function
        Case Is > Char2: StrCompLogicalVB = 1: Exit Function
        End Select
    Next
    If Ln2 > Ln1 Then StrCompLogicalVB = -1: Exit Function
End Function
'Получение числового значения номера из строки sBuf с заданой позиции Ind. Возвращаемое значение - индекс, идущий после строкового значения номера
Private Function GetNumberFromString(sBuf$, iBuf%(), NumOut&, Optional ByVal Ind& = 1) As Long
    Dim Bgn&, NumLen&
    Bgn = Ind: NumLen = 1
    For Ind = Ind + 1 To Len(sBuf) 'Ubound(iStr)
        Select Case iBuf(Ind)
        Case 48 To 57: NumLen = NumLen + 1
        Case Else: Exit For
        End Select
    Next
    NumOut = Mid$(sBuf, Bgn, NumLen)
    GetNumberFromString = Ind
End Function
3
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
19.12.2024, 21:55
Модуль для корректного получения полных путей всех процессов во всех версиях Windows

Итак, я решил написать свой модуль, о котором я так давно мечтал, с функциями, для получения полных путей для всех процессов в системе, даже в учётной записи Гость и даже без особых прав пользователя, без привилегий в системе, даже для всех системных процессов. Это уже окончательная версия моего творчества со всеми исправленными ошибками. Работает быстро. Встроил так же технологию кеширования дисков в системе, для убыстрения чтения, но это опционально.

Функция GetProcessFullPathUniversal - универсальная функция, лучшего всего пользоваться именно ей, для всех версий Windows. Гарантированно точно, правильно определит путь к процессу, даже если папка с программой была переименована и процесс снова был перезапущен из переименнованой папки!

Функция GetProcessFullPathCorrect - функция которая корректно определяет путь к процессу, используется двухступенчатая технология чтения, для 32-битных процессов это функция из psapi.dll, а для 64-битных процессов это чтение структуры PEB с последующем разбором командной строки, специальной API-функцией, для извлечения пути к EXE-процессу.

Функция GetProcessFullPathNt - я написал эту функцию сам, основываясь на трудах fafalone, используется для чтения функция NtQuerySystemInformation с классом SystemProcessIdInformation для получения пути к любым процессам, даже всем системным процессам, без прав администратора. Но эта функция может врать, для обычных процессов, не системных, до Windows 10. Поэтому ей пользоваться постоянно не желательно.

Лучше всего использовать именно функцию GetProcessFullPathUniversal так как именно она, сначала определит версию Windows и в случае если, Windows будет до Windows 10, то тогда будет вызвана сначала функция GetProcessFullPathCorrect и в случае если, эта функция не определит путь к процессу (так как процесс системный), то тогда будет вызвана уже функция GetProcessFullPathNt.

P. S. Предыдущими моими версиями не пользуйтесь, так как они с ошибками. На этом я закончил и больше тут ничего выкладывать не буду уже, итак всё работает идеально теперь уже точно

Модуль:
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
Option Explicit
'/////////////////////////////////////////////////////////////////////////////////
'// Module for correctly get the full path processes in all versions of Windows //
'// Copyright (c) 19.12.2024 by HackerVlad                                      //
'// E-mail: vladislavpeshkov@ya.ru                                              //
'// Version 3.5                                                                 //
'/////////////////////////////////////////////////////////////////////////////////
 
' API declarations ...
Private Declare Function NtQuerySystemInformation Lib "ntdll" (ByVal infoClass As Long, Buffer As Any, ByVal BufferSize As Long, ret As Long) As Long
Private Declare Function GetMem4 Lib "msvbvm60" (ByVal src As Long, dst As Any) As Long
Private Declare Sub PutMem4 Lib "msvbvm60" (ByVal Ptr As Long, ByVal Value As Long)
Private Declare Function GetLogicalDriveStrings Lib "kernel32" Alias "GetLogicalDriveStringsW" (ByVal nBufferLength As Long, ByVal lpBuffer As Long) As Long
Private Declare Function QueryDosDevice Lib "kernel32" Alias "QueryDosDeviceW" (ByVal lpDeviceName As Long, ByVal lpTargetPath As Long, ByVal ucchMax As Long) As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenW" (ByVal lpString As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryW" (ByVal lpBuffer As Long, ByVal uSize As Long) As Long
Private Declare Function GetModuleFileNameExW Lib "psapi" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As Long, ByVal nSize As Long) As Long
Private Declare Function SysAllocStringLen Lib "oleaut32" (ByVal olestr As Long, ByVal Length As Long) As Long
Private Declare Function CommandLineToArgv Lib "shell32" Alias "CommandLineToArgvW" (ByVal lpCmdLine As Long, pNumArgs As Integer) As Long
Private Declare Function LocalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Sub SysFreeString Lib "oleaut32" (ByVal bstr As Long)
Private Declare Sub GetNativeSystemInfo Lib "kernel32" (lpSystemInfo As SYSTEM_INFO)
Private Declare Function IsWow64Process Lib "kernel32" (ByVal hProc As Long, bWow64Process As Long) As Long
 
' Undocumented APIs ...
Private Declare Function NtWow64QueryInformationProcess64 Lib "ntdll" (ByVal ProcessHandle As Long, ByVal InformationClass As Long, ByRef ProcessInformation As Any, ByVal ProcessInformationLength As Long, ByRef ReturnLength As Long) As Long
Private Declare Function NtWow64ReadVirtualMemory64 Lib "ntdll" (ByVal hProcess As Long, ByVal BaseAddress As Currency, ByRef Buffer As Any, ByVal BufferLengthL As Long, ByVal BufferLengthH As Long, ByRef ReturnLength As Currency) As Long
 
' Constants ...
Private Const SystemProcessIdInformation = 88
Private Const ProcessBasicInformation = 0
Private Const STATUS_SUCCESS As Long = 0
Private Const MAX_PATH = 260
Private Const PROCESS_QUERY_INFORMATION = 1024
Private Const PROCESS_VM_READ = 16
Private Const PROCESSOR_ARCHITECTURE_AMD64 As Integer = 9
Private Const PROCESSOR_ARCHITECTURE_IA64 As Integer = 6
 
' Types ...
Private Type UNICODE_STRING
    Length As Integer
    MaxLength As Integer
    lpBuffer As Long
End Type
 
Private Type SYSTEM_PROCESS_ID_INFORMATION
    ProcessId As Long
    ImageName As UNICODE_STRING
End Type
 
Private Type PROCESS_BASIC_INFORMATION_WOW64
    ExitStatus As Long
    Reserved0 As Long
    PebBaseAddress As Currency
    AffinityMask As Currency
    BasePriority As Long
    Reserved1 As Long
    UniqueProcessId As Currency
    InheritedFromUniqueProcessId As Currency
End Type
 
Private Type UNICODE_STRING64
    Length As Integer
    MaxLength As Integer
    Fill As Long
    lpBuffer As Currency
End Type
 
Private Type SYSTEM_INFO
    wProcessorArchitecture As Integer
    wReserved As Integer
    dwPageSize As Long
    lpMinimumApplicationAddress As Long
    lpMaximumApplicationAddress As Long
    dwActiveProcessorMask As Long
    dwNumberOrfProcessors As Long
    dwProcessorType As Long
    dwAllocationGranularity As Long
    wProcessorLevel As Integer
    wProcessorRevision As Integer
End Type
 
' Variables for caching ...
Dim MajorWinVer As Long
Dim ArrDosDevice() As String
Dim IsInitArrDosDevice As Boolean, IsInitMyOSIs64bit As Boolean, MyOSIs64bit As Boolean
 
' Its my function that caches data and replaces the QueryDosDevice call API
Private Function MyQueryDosDeviceCache(ByVal lpDeviceName As String) As String
    Dim countChars As Long, i As Long, cnt As Long
    Dim DosDeviceName As String
    
    If IsInitArrDosDevice = True Then
        For i = 0 To UBound(ArrDosDevice, 2)
            If ArrDosDevice(0, i) = lpDeviceName Then
                MyQueryDosDeviceCache = ArrDosDevice(1, i)
                Exit Function
            End If
        Next
        
        cnt = UBound(ArrDosDevice, 2) + 1 ' Since the position we need has not been found, we need to add a new position
    End If
    
    DosDeviceName = Space$(2048)
    countChars = QueryDosDevice(StrPtr(lpDeviceName), StrPtr(DosDeviceName), 2048)
    
    If countChars > 0 Then
        DosDeviceName = Left$(DosDeviceName, countChars)
        DosDeviceName = Replace$(DosDeviceName, vbNullChar, "")
    End If
    
    ReDim Preserve ArrDosDevice(1, cnt) As String
    ArrDosDevice(0, cnt) = lpDeviceName
    ArrDosDevice(1, cnt) = DosDeviceName
    
    IsInitArrDosDevice = True
    MyQueryDosDeviceCache = DosDeviceName
End Function
 
' Get the full path to the process using the NtQuerySystemInformation function
' Before Windows 10, sometimes it may incorrect to get the path to the process
Public Function GetProcessFullPathNt(ByVal pid As Long, Optional SaveSystemPath As Boolean, Optional Caching As Boolean = True) As String
    Dim ProcName As String, sDrives As String, strBuff As String, DosDeviceName As String
    Dim cbRet As Long, cbMax As Long, cnt As Long, i As Long
    Dim spii As SYSTEM_PROCESS_ID_INFORMATION
    Dim aDrive() As String
    
    If pid = 0 Then
        GetProcessFullPathNt = "[System idle process]"
    ElseIf pid = 4 Then
        GetProcessFullPathNt = "[System]"
    End If
    If pid = 0 Or pid = 4 Then Exit Function
    
    cbMax = MAX_PATH * 2
    PutMem4 VarPtr(ProcName), SysAllocStringLen(0&, cbMax)
    
    spii.ProcessId = pid ' Fafalone wrote this line of code
    spii.ImageName.MaxLength = cbMax ' Fafalone wrote this line of code
    spii.ImageName.lpBuffer = StrPtr(ProcName) ' HackerVlad wrote this line of code
    
    If NtQuerySystemInformation(SystemProcessIdInformation, spii, LenB(spii), cbRet) >= 0 Then ' Technology from fafalone
        ProcName = Left$(ProcName, spii.ImageName.Length / 2)
        GetProcessFullPathNt = ProcName
        
        If SaveSystemPath = False Then
            PutMem4 VarPtr(sDrives), SysAllocStringLen(0&, 2048)
            cnt = GetLogicalDriveStrings(2048, StrPtr(sDrives)) ' HackerVlad's technology of getting all the letters of the drives
            
            If Err.LastDllError = 0 Then
                aDrive = Split(Left$(sDrives, cnt - 1), vbNullChar)
                
                For i = 0 To UBound(aDrive)
                    If Caching = True Then
                        DosDeviceName = MyQueryDosDeviceCache(Left$(aDrive(i), 2)) & "\" ' HackerVlad's caching technology
                    Else
                        PutMem4 VarPtr(strBuff), SysAllocStringLen(0&, 2048)
                        
                        If QueryDosDevice(StrPtr(Left$(aDrive(i), 2)), StrPtr(strBuff), 2048) Then
                            DosDeviceName = Left$(strBuff, lstrlen(StrPtr(strBuff))) & "\"
                        End If
                        
                        SysFreeString StrPtr(strBuff)
                    End If
                    
                    If Left$(ProcName, Len(DosDeviceName)) = DosDeviceName Then
                        GetProcessFullPathNt = Left$(aDrive(i), 2) & Mid$(ProcName, Len(DosDeviceName))
                        Exit Function
                    Else
                        If InStr(1, ProcName, DosDeviceName, vbTextCompare) > 0 Then ' Retrying
                            GetProcessFullPathNt = Replace$(ProcName, DosDeviceName, Left$(aDrive(i), 2) & "\", 1, 1, vbTextCompare)
                            Exit Function
                        End If
                    End If
                Next
            End If
        End If
    End If
End Function
 
' This function should get the correct paths, unlike another functions which can sometimes cheat
Public Function GetProcessFullPathCorrect(ByVal pid As Long) As String
    Dim hProc As Long, lpwstr As Long, CmdStringPtr As Long, lengthPathWinDir As Long, IsProcRunWOW64 As Long
    Dim strProcName As String, strProcName2 As String, PathWinDir As String
    Dim pbi64 As PROCESS_BASIC_INFORMATION_WOW64
    Dim cmd64 As UNICODE_STRING64
    Dim pParam64 As Currency
    Dim cnt As Integer
    
    If pid = 0 Then
        GetProcessFullPathCorrect = "[System idle process]"
    ElseIf pid = 4 Then
        GetProcessFullPathCorrect = "[System]"
    End If
    If pid = 0 Or pid = 4 Then Exit Function
    
    hProc = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, pid)
    
    If hProc > 0 Then
        ' First of all, you need to find out if the OS is 32-bit or 64-bit?
        If IsInitMyOSIs64bit = False Then
            Dim si As SYSTEM_INFO
            
            GetNativeSystemInfo si
            MyOSIs64bit = (si.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64 Or si.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_IA64)
            
            IsInitMyOSIs64bit = True
        End If
        If MyOSIs64bit = True Then IsWow64Process hProc, IsProcRunWOW64
        
        If IsProcRunWOW64 = 1 Or MyOSIs64bit = False Then ' 32-bit process
            strProcName = Space$(MAX_PATH)
            If GetModuleFileNameExW(hProc, 0, StrPtr(strProcName), MAX_PATH) Then
                strProcName = Left$(strProcName, lstrlen(StrPtr(strProcName)))
            End If
        Else ' 64-bit process
            #If Win32 Then
                If NtWow64QueryInformationProcess64(hProc, ProcessBasicInformation, pbi64, Len(pbi64), 0) = STATUS_SUCCESS Then
                    If NtWow64ReadVirtualMemory64(hProc, pbi64.PebBaseAddress + 0.0032@, pParam64, Len(pParam64), 0, 0) = STATUS_SUCCESS Then
                        If NtWow64ReadVirtualMemory64(hProc, pParam64 + 0.0112@, cmd64, Len(cmd64), 0, 0) = STATUS_SUCCESS Then
                            If cmd64.Length > 0 Then
                                strProcName = Space$(cmd64.Length / 2) ' We allocate a buffer of sufficient length
                                NtWow64ReadVirtualMemory64 hProc, cmd64.lpBuffer, ByVal StrPtr(strProcName), cmd64.Length, 0, 0
                                
                                If Len(strProcName) > 0 Then
                                    strProcName2 = strProcName
                                    strProcName = vbNullString
                                    lpwstr = CommandLineToArgv(StrPtr(strProcName2), cnt)
                                    
                                    If lpwstr Then
                                        GetMem4 lpwstr, CmdStringPtr
                                        PutMem4 VarPtr(strProcName), SysAllocStringLen(CmdStringPtr, lstrlen(CmdStringPtr))
                                        LocalFree lpwstr
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            #End If
        End If
        
        CloseHandle hProc
        
        If Left$(strProcName, 12) = "\SystemRoot\" And strProcName <> "\SystemRoot\" Then
            PutMem4 VarPtr(PathWinDir), SysAllocStringLen(0&, MAX_PATH)
            lengthPathWinDir = GetWindowsDirectory(StrPtr(PathWinDir), MAX_PATH)
            PathWinDir = Left$(PathWinDir, lengthPathWinDir)
            
            strProcName = PathWinDir & Mid$(strProcName, 12)
        End If
        If Left$(strProcName, 13) = "%SystemRoot%\" And strProcName <> "%SystemRoot%\" Then
            If Len(PathWinDir) = 0 Then
                PutMem4 VarPtr(PathWinDir), SysAllocStringLen(0&, MAX_PATH)
                lengthPathWinDir = GetWindowsDirectory(StrPtr(PathWinDir), MAX_PATH)
                PathWinDir = Left$(PathWinDir, lengthPathWinDir)
            End If
            
            strProcName = PathWinDir & Mid$(strProcName, 13)
        End If
        If Left$(strProcName, 4) = "\??\" And strProcName <> "\??\" Then
            strProcName = Mid$(strProcName, 5)
        End If
        
        GetProcessFullPathCorrect = strProcName
    End If
End Function
 
' Universal function
Public Function GetProcessFullPathUniversal(ByVal pid As Long, Optional Caching As Boolean = True) As String
    Dim MajorWindowsVersion As Long
    Dim ProcName As String
    
    If pid = 0 Then
        GetProcessFullPathUniversal = "[System idle process]"
    ElseIf pid = 4 Then
        GetProcessFullPathUniversal = "[System]"
    End If
    If pid = 0 Or pid = 4 Then Exit Function
    
    If MajorWinVer = 0 Then
        GetMem4 &H7FFE026C, MajorWindowsVersion ' Get the Windows version
        MajorWinVer = MajorWindowsVersion ' Save
    End If
    
    If MajorWinVer < 10 Then ' Old versions Windows
        ProcName = GetProcessFullPathCorrect(pid) ' Technology from HackerVlad
    Else ' Windows 10 and latter
        GetProcessFullPathUniversal = GetProcessFullPathNt(pid, , Caching) ' Technology from fafalone
        Exit Function
    End If
    
    If InStr(1, ProcName, "\") = 0 Then ' Retrying
        ProcName = GetProcessFullPathNt(pid, , Caching) ' Technology from fafalone
    End If
    
    GetProcessFullPathUniversal = ProcName
End Function
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: zip EnumProc (3).zip (24.2 Кб, 33 просмотров)
2
 Аватар для Argus19
1450 / 467 / 78
Регистрация: 24.09.2017
Сообщений: 2,557
Записей в блоге: 24
21.01.2025, 19:15
HackerVlad, вы ответили в теме WIA Automation на иноземном форуме.
Вот, что я собрал по этой теме:
Вложения
Тип файла: 7z WIA Automation.7z (5.70 Мб, 15 просмотров)
1
 Аватар для Argus19
1450 / 467 / 78
Регистрация: 24.09.2017
Сообщений: 2,557
Записей в блоге: 24
20.02.2025, 13:53
Отправка Email с помощью CDO
Нашёл в интернете способ отправки писем из Excel.
Адаптировал для VB 6.0.
Комментариев достаточно, чтобы сделать вариант "для себя".
Вложения
Тип файла: zip Отправка почты.zip (3.1 Кб, 33 просмотров)
3
 Аватар для Argus19
1450 / 467 / 78
Регистрация: 24.09.2017
Сообщений: 2,557
Записей в блоге: 24
27.02.2025, 11:28
Как написать библиотеку на С++ для программ, написанных на VB 6.0
Иногда, при написании кода, нужно многократно использовать функции и подпрограммы. Если объём кода становится слишком большим, «рябит в глазах». На мой взгляд, лучше использовать свои библиотеки, особенно, если приходится писать разные программы с одними и теми же функциями. Практически, большинство библиотечных функции можно написать и на самом VB 6.0. Это описано в учебниках и я рассматривать это не буду.
При написании собственной библиотеки следует учитывать типы переменных, которые в С++ и VB 6.0 отличаются как по названию, так и по вместимости байт.
За исходный материал я взял статью «Building a Visual C++ Dll for use in Visual Basic», в которой автор описывает проблемы, с которыми он столкнулся при написании библиотеки и как он их решил, добавил статью "Calling a C++ DLL from Visual Basic" и дополнил очень простым примером своей библиотеки, в котором описал, как передать в функцию аргумент по значению, по ссылке и как передать в функцию массив.
Во вложении статья и все необходимые исходники.
https://www.cyberforum.ru/blogs/1083385/9838.html
2
 Аватар для Argus19
1450 / 467 / 78
Регистрация: 24.09.2017
Сообщений: 2,557
Записей в блоге: 24
16.04.2025, 09:11
QR-code генератор.
Стырил на иностранном форуме.
Очень даже может пригодиться.
Я написал автору по поводу обратного преобразования. Он ответил, что сам стырил модуль и модуля для преобразования QR-кода в текст там не было.
Вложения
Тип файла: zip QR-code.zip (14.8 Кб, 44 просмотров)
0
 Аватар для Argus19
1450 / 467 / 78
Регистрация: 24.09.2017
Сообщений: 2,557
Записей в блоге: 24
23.09.2025, 16:24
Библиотека ModbusRTU
Библиотека написана на языке С++ и предназначена для работы с программами, написанными на языке VB 6.0. Работоспособность библиотеки проверена на Windows7 и Windows10.
В состав библиотеки входят функции:
ModRTU_CRC – Подсчёт контрольной суммы CRC16.
openPort – Открытие COM-порта.
closePort – Закрытие COM-порта.
WritePort – Запись в COM-порт байтового массива.
ReadPort – Чтение из COM-порта в байтовый массив.
ieee754 – Преобразование 4х байт из массива во float при передаче старшим байтом вперёд.
ieee754inv - Преобразование 4х байт из массива во float при передаче младшим байтом вперёд. Например, так сделано у прибора ПВТ110RS производства «ОВЕН»
float32ToBuffer – Преобразование числа Single в 4 байта с записью их в массив.
Примеры использования:
float32ToBuffer – В папке «Проверка IEE754». Вводим число с плавающей запятой в текстовое поле и нажимаем кнопку «Start». Ниже появятся байты, в которые преобразуется введённое число с помощью функции float32ToBuffer. И число, преобразованное из байт с помощью функции ieee754.
В папке «ТРМ138» находится исходный код программы, опрашивающей по таймеру, через каждые 10 минут поочерёдно 8 каналов прибора «ТРМ138» производства «ОВЕН».
В обеих программах показаны декларации функций библиотеки и их вызов, а так же реакция на результат работы функций.
https://www.cyberforum.ru/blogs/1083385/10591.html
3
 Аватар для Argus19
1450 / 467 / 78
Регистрация: 24.09.2017
Сообщений: 2,557
Записей в блоге: 24
30.10.2025, 08:54
Для счастливых обладателей 32-битных Widows XP и Widows 7 написал две программы:
https://www.cyberforum.ru/blogs/1083385/10656.html
Одна написана на С++ и просто перекодирует и сохраняет выбранное изображение в формате .bmp, вторая написана на VB 6.0 делает превью выбранного изображения .webp, перекодирует и сохраняет выбранное изображение в форматах .bmp, .gif, .jpeg и .png с потерей прозрачности.
3
 Аватар для Argus19
1450 / 467 / 78
Регистрация: 24.09.2017
Сообщений: 2,557
Записей в блоге: 24
22.11.2025, 19:16
Поиск "дружественных имён" СОМ портов
На странице:
https://norseev.ru/2018/01/04/comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа, СОМ1, СОМ2 и т.п.
Написал автору. Автор страницы ответил, что никогда этим не задавался и дал ссылку:
https://stackoverflow.com/ques... ndows?rq=3
Честно говоря, оказалось слишком сложно. Но получилось.
Затем захотелось получить тоже самое, но уже на VB 6.0. Получение имён СОМ портов с помощью WMI уже было, поэтому попробовал получить имена СОМ портов из реестра. Так не получилось. Не хочет 32-битное приложение работать с 64-битным реестром. Показывает только один СОМ1. Для чего он определяется в Windows10, я так и не понял.
Пришлось работать с функциями Win API. Результат:

=== COM Ports List ===

Port 1:
Name: COM4
Friendly Name: USB-SERIAL CH340 (COM4)
Description: USB-SERIAL CH340

Port 2:
Name: COM1
Friendly Name: Последовательный порт (COM1)
Description: Последовательный порт

Total found: 2 ports


https://www.cyberforum.ru/blogs/1083385/10679.html
3
 Аватар для Argus19
1450 / 467 / 78
Регистрация: 24.09.2017
Сообщений: 2,557
Записей в блоге: 24
19.12.2025, 08:25
Функции VBA6_DLL
Нашёл на иностранном форуме. Не разбирался. Перекодировал "MSSCRIPT.HLP" в .chm.
Думаю, пригодится не только для VBA.
Вложения
Тип файла: zip Функции VBA6_DLL.zip (393.6 Кб, 30 просмотров)
2
186 / 37 / 3
Регистрация: 28.05.2015
Сообщений: 149
20.12.2025, 16:50
Написал для себя небольшое решение по сохранению паролей. Никаких файлов, кроме самой программы не создаётся.
Алгоритм несложный. При первом запуске программа запрашивает пароль(можно сказать суперпароль) для её запуска и имя текущего пользователя Windows. После этого закрывается и сохраняет все данные. Далее заново запускаем и открываем таблицу, занося туда данные. Эти данные можно экспортировать в CSV-файл, а также импортировать из такого же файла(также реализован парсинг файла после Drag&Drop в таблицу) или же сохранять в программе. Данные считаю надёжно защищёнными. То есть здесь не поможет дизассеблирование. Сама защита устроена следующим образом. При первом запуске программа считывает серийный номер диска, с которого запущена программа и имя текущего пользователя. Привязывается к ним. Эти данные заносятся в специальную строку внутри программы. На последующих запусках программа считывает номер диска и берёт из него хеш SHA-256. Затем из хеша берёт первые 56 символов, которые являются ключом и этим ключом расшифровывается строка Converted, которая берётся из самого EXE-файла программы (из ресурсов). Расшифровка происходит алгоритмом Blowfish (в режиме ECB с набивкой (padding)). Смысл хеша - серийник может содержать разные символы и чтобы не было багов, было решено захешировать - там все символы предсказуемы (HEX). Суть в том, что расшифровка происходит с любым ключом, но только правильный ключ расшифрует строку правильно и она будет читаема. Если она не читаема, то программа не будет работать. То есть если вы запустили программу с другого компьютера - она не откроется. Кстати, я думаю, что отладчиком можно открыть программу, если забыл суперпароль, НО только если открыл на правильном компьютере. На неправильном - даже через отладчик получите только "крякозябры". После заполнения таблицы и её закрытии идёт всё в обратно порядке: считывается серийник, хешируется, 56-и символьным ключом шифруется и записывается в EXE-файл самой программы. Всё основано на криптостойкости алгоритма Blowfish Брюса Шнайера. В программе использован модуль самосохранения в EXE, считывание серийного номера от пользователя The trick и модули, реализовывающие сам алгоритм Blowfish, скаченные с иностранного ресурса, но верифицированные сообществом. Диалоговые окна взял из COMDLG32.DLL, а не COMDLG32.OCX, чтобы не было лишних файлов. А MsgBox-ы самописные.
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0   Готовые решения и полезные коды на Visual Basic 6.0   Готовые решения и полезные коды на Visual Basic 6.0  

Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: rar PassMan.rar (266.9 Кб, 11 просмотров)
4
 Аватар для Argus19
1450 / 467 / 78
Регистрация: 24.09.2017
Сообщений: 2,557
Записей в блоге: 24
18.03.2026, 10:37
Нашёл в интернете 3 прекрасных модуля:
Модуль класса открытия диалога открытия/сохранения файла на Win32 API;
Модуль класса быстрого перекодирования цветного изображения в оттенки серого;
Модуль класса записи изображения в форматах JPG с изменяемым качеством, PNG и GIF.
Написал программу, иллюстрирующую работу этих модулей:
https://www.cyberforum.ru/blogs/1083385/10814.html
2
Вернулся
 Аватар для HackerVlad
1751 / 647 / 45
Регистрация: 10.09.2021
Сообщений: 2,800
30.04.2026, 13:11
ClipboardPath версия 3.0

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

Код формы...
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
Option Explicit
 
Private Declare Function OpenClipboard Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function GetClipboardData Lib "user32.dll" (ByVal wFormat As Long) As Long
Private Declare Function SetClipboardData Lib "user32.dll" (ByVal wFormat As Long, ByVal hMem As Long) As Long
Private Declare Function CloseClipboard Lib "user32.dll" () As Long
Private Declare Function GlobalAlloc Lib "kernel32.dll" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function lstrcpyn Lib "kernel32.dll" Alias "lstrcpynW" (ByVal lpString1 As Long, ByVal lpString2 As Long, ByVal iMaxLength As Long) As Long
Private Declare Function GlobalLock Lib "kernel32.dll" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32.dll" (ByVal hMem As Long) As Long
Private Declare Function GlobalSize Lib "kernel32.dll" (ByVal hMem As Long) As Long
Private Declare Function GetMem4 Lib "msvbvm60.dll" (src As Any, dst As Any) As Long
Private Declare Sub ZeroMemory Lib "kernel32.dll" Alias "RtlZeroMemory" (Destination As Any, ByVal Length As Long)
Private Declare Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long
 
Private Const CF_UNICODETEXT    As Long = 13&
Private Const CF_LOCALE         As Long = 16
Private Const GMEM_MOVEABLE     As Long = &H2&
Private Const SND_ASYNC = &H1
Private Const SND_NODEFAULT = &H2
 
Dim LenClipboard As Long
 
Private Function wAppPath() As String
    If Right$(App.Path, 1) = "\" Then
        wAppPath = Mid(App.Path, 1, Len(App.Path) - 1)
    Else
        wAppPath = App.Path
    End If
End Function
 
Private Function GetClipboardSize() As Long
    On Error GoTo Handler
    
    Dim hMem As Long
    
    If OpenClipboard(0) Then
        hMem = GetClipboardData(CF_UNICODETEXT)
        
        If hMem Then
            GetClipboardSize = (GlobalSize(hMem) / 2)
        End If
        
        CloseClipboard
    End If
Handler:
End Function
 
' Получить буфер в уникоде
Private Function GetClipboardW() As String
    On Error GoTo ErrorHandler
    
    Dim hMem As Long
    Dim ptr  As Long
    Dim Size As Long
    Dim txt  As String
    
    If OpenClipboard(0) Then
        hMem = GetClipboardData(CF_UNICODETEXT)
        If hMem Then
            Size = GlobalSize(hMem)
            If Size Then
                txt = Space$(Size \ 2 - 1)
                ptr = GlobalLock(hMem)
                lstrcpyn ByVal StrPtr(txt), ByVal ptr, Size
                GlobalUnlock hMem
                GetClipboardW = txt
            End If
        End If
        CloseClipboard
    End If
    Exit Function
ErrorHandler:
    'Debug.Print "GetClipboardW" & " - #" & Err.Number & " " & Err.Description & ". LastDllError = " & Err.LastDllError
End Function
 
' Записать уникодную строку в буфер
Private Sub SetClipboardW(sText As String)
    On Error GoTo ErrorHandler
    Dim hMem As Long
    Dim ptr  As Long
    Dim Size As Long
    Dim txt  As String
    
    If OpenClipboard(0) Then
        hMem = GlobalAlloc(GMEM_MOVEABLE, 4)
        If hMem <> 0 Then
            ptr = GlobalLock(hMem)
            If ptr <> 0 Then
                GetMem4 &H419, ByVal ptr
                GlobalUnlock hMem
                SetClipboardData CF_LOCALE, hMem
            End If
            'GlobalFree hMem 'do not free!!!
        End If
        hMem = GlobalAlloc(GMEM_MOVEABLE, LenB(sText) + 2)
        If hMem <> 0 Then
            ptr = GlobalLock(hMem)
            If ptr <> 0 Then
                lstrcpyn ptr, StrPtr(sText), LenB(sText)
                ZeroMemory ByVal (StrPtr(sText) + LenB(sText)), 2&
                GlobalUnlock hMem
                SetClipboardData CF_UNICODETEXT, hMem
            End If
            'GlobalFree hMem 'do not free!!!
        End If
        CloseClipboard
    End If
    Exit Sub
ErrorHandler:
    'Debug.Print "SetClipboardW" & " - #" & Err.Number & " " & Err.Description & ". LastDllError = " & Err.LastDllError
End Sub
 
Private Function IsQuestionString(str As String) As Boolean
    If str = "?" Or str = "??" Or str = "???" Or str = "????" Or str = "?????" Or str = "??????" Then
        IsQuestionString = True
        Exit Function ' Для ускорения
    End If
    
    If str Like "*[?]*" Then ' Если найден знак вопроса
        If Len(str) < 32768 Then
            str = Replace(str, " ", "")
            str = Replace(str, ",", "")
            str = Replace(str, ".", "")
        End If
        
        If InStr(1, str, "?????") Then
            IsQuestionString = True
            Exit Function ' Для ускорения
        End If
        
        If InStr(1, str, "? ????") Then
            IsQuestionString = True
            Exit Function ' Для ускорения
        End If
        If InStr(1, str, "?? ???") Then
            IsQuestionString = True
            Exit Function ' Для ускорения
        End If
        If InStr(1, str, "??? ??") Then
            IsQuestionString = True
            Exit Function ' Для ускорения
        End If
        If InStr(1, str, "???? ?") Then
            IsQuestionString = True
        End If
    End If
End Function
 
Private Sub ClipboardPath()
    On Error Resume Next
    
    Dim ClipboardA As String
    Dim ClipboardW As String
    Dim ClipboardSize As Long
    
    ClipboardSize = GetClipboardSize ' Получить размер буфера обмена
    
    If ClipboardSize > 100000000 Then
        Beep
        Exit Sub
    End If
    
    If ClipboardSize <= 1000000 Then ' Если размер буфера меньше либо равняется миллион символов
        LenClipboard = ClipboardSize
        ClipboardA = Clipboard.GetText
        ClipboardW = GetClipboardW
        
        If Len(ClipboardW) > 0 Then
            If ClipboardW Like "*[" & ChrW(192) & "-" & ChrW(255) & ChrW(168) & ChrW(184) & "]*" Then ' Буфер содержит кракозяблики
                SetClipboardW ClipboardA ' Исправить буфер (засунуть в CF_UNICODETEXT правильную строку взятую из CF_TEXT)
                sndPlaySound wAppPath & "\FixingClipboard.wav", SND_ASYNC Or SND_NODEFAULT
                Exit Sub ' Для ускорения
            End If
        End If
        
        If Len(ClipboardA) > 0 Then
            If IsQuestionString(ClipboardA) = True Then
                ' Если ClipboardW содержит хотябы один русский символ
                If ClipboardW Like "*[А-Яа-яЁё]*" Then
                    Clipboard.SetText ClipboardW ' Исправить буфер (засунуть в CF_TEXT правильную строку взятую из CF_UNICODETEXT)
                    sndPlaySound wAppPath & "\FixingClipboard.wav", SND_ASYNC Or SND_NODEFAULT
                End If
            End If
        End If
    Else ' Большой буфер больше миллиона символов
        If LenClipboard <> ClipboardSize Then
            LenClipboard = ClipboardSize
            ClipboardA = Clipboard.GetText
            ClipboardW = GetClipboardW
            
            If Len(ClipboardW) > 0 Then
                If ClipboardW Like "*[" & ChrW(192) & "-" & ChrW(255) & ChrW(168) & ChrW(184) & "]*" Then ' Буфер содержит кракозяблики
                    SetClipboardW ClipboardA ' Исправить буфер (засунуть в CF_UNICODETEXT правильную строку взятую из CF_TEXT)
                    sndPlaySound wAppPath & "\FixingClipboard.wav", SND_ASYNC Or SND_NODEFAULT
                    Exit Sub ' Для ускорения
                End If
            End If
            
            If Len(ClipboardA) > 0 Then
                If IsQuestionString(ClipboardA) = True Then
                    ' Если ClipboardW содержит хотябы один русский символ
                    If ClipboardW Like "*[А-Яа-яЁё]*" Then
                        Clipboard.SetText ClipboardW ' Исправить буфер (засунуть в CF_TEXT правильную строку взятую из CF_UNICODETEXT)
                        sndPlaySound wAppPath & "\FixingClipboard.wav", SND_ASYNC Or SND_NODEFAULT
                    End If
                End If
            End If
        End If
    End If
End Sub
 
Private Sub Form_Load()
    Me.Hide
    App.TaskVisible = False
    
    If App.PrevInstance = True Then
        Unload Me
        End
    End If
    
    Call HookSet(Me.hwnd)
End Sub
 
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    Call HookClear
End Sub
 
Public Sub Callback_ClipboardChange()
    ClipboardPath
End Sub


Код модуля...
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
Option Explicit
 
Private Declare Function SetWindowSubclass Lib "comctl32" Alias "#410" (ByVal hwnd As Long, ByVal pfnSubclass As Long, ByVal uIdSubclass As Long, Optional ByVal dwRefData As Long) As Long
Private Declare Function GetWindowSubclass Lib "comctl32" Alias "#411" (ByVal hwnd As Long, ByVal pfnSubclass As Long, ByVal uIdSubclass As Long, pdwRefData As Long) As Long
Private Declare Function RemoveWindowSubclass Lib "comctl32" Alias "#412" (ByVal hwnd As Long, ByVal pfnSubclass As Long, ByVal uIdSubclass As Long) As Long
Private Declare Function DefSubclassProc Lib "comctl32" Alias "#413" (ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SetClipboardViewer Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ChangeClipboardChain Lib "user32" (ByVal hwnd As Long, ByVal hWndNext As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
 
Private m_hWnd As Long
Private h_NextClipBoardViewer As Long
Private m_iSubclassed As Long
 
Private Const WM_DRAWCLIPBOARD As Long = &H308&
Private Const WM_CHANGECBCHAIN As Long = &H30D&
Private Const WM_CLIPBOARDUPDATE As Long = &H31D&
Private Const WM_DESTROYCLIPBOARD As Long = &H307&
Private Const WM_NCDESTROY As Long = &H82
Private Const WM_UAHDESTROYWINDOW As Long = &H90&
 
Public Sub HookSet(hWindow As Long)
    If m_iSubclassed = 0 Then
        m_hWnd = hWindow
        m_iSubclassed = SetWindowSubclass(m_hWnd, AddressOf WndProc, 0&)
        h_NextClipBoardViewer = SetClipboardViewer(m_hWnd)
    End If
End Sub
 
Public Sub HookClear()
    If m_iSubclassed Then
        RemoveWindowSubclass m_hWnd, AddressOf WndProc, 0&: m_iSubclassed = 0
        ChangeClipboardChain m_hWnd, h_NextClipBoardViewer
        m_hWnd = 0
    End If
End Sub
 
Private Function WndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
    Dim bProcessed As Boolean
    
    Select Case uMsg
        Case WM_NCDESTROY, WM_UAHDESTROYWINDOW
            HookClear
            
        Case WM_DRAWCLIPBOARD
            SendMessage h_NextClipBoardViewer, uMsg, wParam, lParam
            Form1.Callback_ClipboardChange
            bProcessed = True
        
        Case WM_CLIPBOARDUPDATE
            SendMessage h_NextClipBoardViewer, uMsg, wParam, lParam
            Form1.Callback_ClipboardChange
            bProcessed = True
        
        Case WM_CHANGECBCHAIN
           If wParam = h_NextClipBoardViewer Then
                h_NextClipBoardViewer = lParam
           Else
               SendMessage h_NextClipBoardViewer, uMsg, wParam, lParam
           End If
           bProcessed = True
    End Select
    
    If Not bProcessed Then
        WndProc = DefSubclassProc(hwnd, uMsg, wParam, lParam)
    End If
End Function
Вложения
Тип файла: zip ClipboardPath 3.0.zip (18.7 Кб, 4 просмотров)
5
 Аватар для Argus19
1450 / 467 / 78
Регистрация: 24.09.2017
Сообщений: 2,557
Записей в блоге: 24
01.05.2026, 17:46
Асинхронный приём данных из COM-порта
https://www.cyberforum.ru/blogs/1083385/10884.html
4
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.05.2026, 17:46

Готовые решения и полезные коды на Visual Basic .NET (Часть-1)
Предлагаю в этой теме размещать ответы на часто задаваемые вопросы и просто делиться полезными кодами. Обращаю внимание на некоторые...

Готовые коды для решения лабораторных работ
Доброго времени суток всем! Очень срочно нужны готовые коды для решения лабораторных работ в С# по учебнику Павловской!!! Вариант 16, нужны...

Написать программу решения квадратного уравнения. В Office Visual Basic
Написать программу решения квадратного уравнения. В Office Visual Basic

Полезные коды и проекты на VBA
В этой теме предлагаю выкладывать различные коды и готовые проекты VBA, которые, на Ваш взгляд, могут помочь новичкам в разработке как...

Полезные коды для PascalABC.NET
В этой теме размещаются полезные исходники программ, различные процедуры и функции, а так же готовые решения на часто задаваемые вопросы,...


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

Или воспользуйтесь поиском по форуму:
360
Ответ Создать тему
Новые блоги и статьи
сукцессия 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