Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.60/2086: Рейтинг темы: голосов - 2086, средняя оценка - 4.60
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
07.07.2023, 20:04
Студворк — интернет-сервис помощи студентам
Программа RegEditJumpHacking версия 2.2

В отличии от программы RegJump от Марка Руссиновича, программа не эмулирует нажатие клавиш
в дереве regedit'а, а посылает напрямую запросы дереву процесса regedit, через SendMessage.
Поэтому скорость доступа к нужному разделу реестра значительно увеличивается.
Это в своём роде единственная программа RegJump, которая не эмулирует нажатие клавиш,
а написана совсем по другому алгоритму, более правильно.
Идея создания программы родилась благодаря testuser2. Данная программа полноценно отвечает на вопрос
как управлять деревом другого процесса, не своего. А так же бонусом добавлена фишка встраивания
адресной строки внуть редактора реестра, точно так же как это реализовано в десятке.
Если программа запущена в скрытом режиме, то программа автоматически завершается,
при закрытии редактора реестра (лезть в диспетчер задач и снимать задачу не надо).

Команды запуска: любой путь к реестру, например HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Wi ndows\CurrentVersion\Run
Просто выполните команду запуска: RegEditJumpHacking.exe HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Wi ndows\CurrentVersion\Run

Ключи:
/hide - запустить программу в скрытом режиме
/32 - запустить 32-битный regedit (для 32-битных операционных систем не используется)
/no_address_bar - не встраивать адресную строку в редактор реестра (например для Windows 10 так как там уже есть адресная строка)
/no_focus_in_tree_view - не переводить фокус на дерево редактора реестра, после нажатия клавиши Enter в адресной строке (этот ключ не применяется вместе с /no_address_bar)

07.07.2023 by HackerVlad
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: zip RegEditJumpHacking2.zip (94.6 Кб, 36 просмотров)
4
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.07.2023, 20:04
Ответы с готовыми решениями:

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

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

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

354
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
02.08.2023, 00:02
Модуль для изменения обоев на рабочем столе

Представляю Вашему вниманию новый модуль для изменения обоев на рабочем столе. Здесь три функции SetWallpaper, ActiveDesktopSetWallpaper и вишенка на торте - SetWallpaperUniversal. Советую пользоваться именно SetWallpaperUniversal так как она будет выигрывать по времени, для jpg картинок будет очень быстро устанавливать обои, плюс поддерживает все графические форматы. Теперь нет необходимости самому конвертировать картинку в BMP а потом её устанавливать!!! Функция SetWallpaper просто устанавливает обои, для XP эта функция поддерживает только BMP, в семёрке как BMP так и JPG, но не поддерживает PNG. Функция ActiveDesktopSetWallpaper устанавливает обои через интерфейс IActiveDesktop с помощью ассемблерной вставки, но код может иногда не работать если у вас другой линкёр (компилятор) но в большинстве случае должен работать, если у вас родной компилятор стандартного Vb6. Думаю проблем никаких не возникнет.

Пользуйтесь на здоровье!

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
Option Explicit
'/////////////////////////////////////////////////
'// Модуль для изменения обоев на рабочем столе //
'// Copyright (c) 01.08.2023 by HackerVlad      //
'// e-mail: vladislavpeshkov@yandex.ru          //
'// Версия 3.0                                  //
'/////////////////////////////////////////////////
 
' Декларации API...
Private Declare Function SystemParametersInfoW Lib "user32" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Long, ByVal fuWinIni As Long) As Long
Private Declare Function IIDFromString Lib "ole32" (ByVal lpszIID As Long, iid As Any) As Long
Private Declare Function CoCreateInstance Lib "ole32" (rclsid As Any, ByVal pUnkOuter As Long, ByVal dwClsContext As Long, riid As Any, ByVal ppv As Long) As Long
Private Declare Function CallWindowProcA Lib "user32" (ByVal addr As Long, ByVal p1 As Long, ByVal p2 As Long, ByVal p3 As Long, ByVal p4 As Long) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32" (pDst As Any, pSrc As Any, ByVal dlen As Long)
Private Declare Function GetMem4 Lib "msvbvm60" (srcAddr As Any, dstValue As Long) As Long
Private Declare Function GetMem1 Lib "msvbvm60" (srcAddr As Any, dstValue As Long) As Long
Private Declare Function IsFileAPI Lib "shlwapi" Alias "PathFileExistsW" (ByVal pszPath As Long) As Long
 
' Константы
Private Const SETDESKWALLPAPER = &H14
Private Const UPDATEINIFILE = &H1
Private Const CLSCTX_INPROC_SERVER  As Long = 1
Private Const CLSID_ActiveDesktop   As String = "{75048700-EF1F-11D0-9888-006097DEACF9}"
Private Const IID_ActiveDesktop     As String = "{F490EB00-1240-11D1-9888-006097DEACF9}"
 
Private Type GUID
    data1                   As Long
    data2                   As Integer
    data3                   As Integer
    data4(7)                As Byte
End Type
 
Private Type IActiveDesktop
    ' IUnknown
    QueryInterface          As Long
    AddRef                  As Long
    Release                 As Long
    ' IActiveDesktop
    ApplyChanges            As Long
    GetWallpaper            As Long
    SetWallpaper            As Long
    GetWallpaperOptions     As Long
    SetWallpaperOptions     As Long
    GetPattern              As Long
    SetPattern              As Long
    GetDesktopItemOptions   As Long
    SetDesktopItemOptions   As Long
    AddDesktopItem          As Long
    AddDesktopItemWithUI    As Long
    ModifyDesktopItem       As Long
    RemoveDesktopItem       As Long
    GetDesktopItemCount     As Long
    GetDesktopItem          As Long
    GetDesktopItemByID      As Long
    GenerateDesktopItemHtml As Long
    AddUrl                  As Long
    GetDesktopItemBySource  As Long
End Type
 
Private Enum AD_APPLY
    AD_APPLY_SAVE = &H1
    AD_APPLY_HTMLGEN = &H2
    AD_APPLY_REFRESH = &H4
    AD_APPLY_ALL = &H7
    AD_APPLY_FORCE = &H8
    AD_APPLY_BUFFERED_REFRESH = &H10
    AD_APPLY_DYNAMICREFRESH = &H20
End Enum
 
' Универсальная функция изменения обоев на рабочем столе
Public Function SetWallpaperUniversal(ByVal FileName As String) As Boolean
    If IsFileAPI(StrPtr(FileName)) = 0 Then ' Файл не существует, с вероятностью 99%
        Exit Function
    End If
    
    If SetWallpaper(FileName) = False Then
        If ActiveDesktopSetWallpaper(FileName) = True Then
            SetWallpaperUniversal = True
        End If
    Else
        SetWallpaperUniversal = True
    End If
End Function
 
' Изменение обоев на рабочем столе
Public Function SetWallpaper(ByVal FileName As String) As Boolean
    Dim RetVal As Long
    
    RetVal = SystemParametersInfoW(SETDESKWALLPAPER, 0, StrPtr(FileName), UPDATEINIFILE)
    If RetVal = 1 Then SetWallpaper = True
End Function
 
' Изменение обоев на рабочем столе с помощью интерфейса IActiveDesktop
Public Function ActiveDesktopSetWallpaper(ByVal strFile As String) As Boolean
    Dim vtbl            As IActiveDesktop
    Dim vtblptr         As Long
    Dim classid         As GUID
    Dim iid             As GUID
    Dim obj             As Long
    Dim hRes            As Long
    
    If IsFileAPI(StrPtr(strFile)) = 0 Then ' Файл не существует, с вероятностью 99%
        Exit Function
    End If
    
    ' CLSID (BSTR) to CLSID (GUID)
    hRes = IIDFromString(StrPtr(CLSID_ActiveDesktop), classid)
    If hRes <> 0 Then
        Exit Function
    End If
    
    ' IID (BSTR) to IID (GUID)
    hRes = IIDFromString(StrPtr(IID_ActiveDesktop), iid)
    If hRes <> 0 Then
        Exit Function
    End If
    
    ' Создать экземпляр IActiveDesktop
    ' (Set IActiveDesktop = New IActiveDesktop)
    hRes = CoCreateInstance(classid, 0, CLSCTX_INPROC_SERVER, iid, VarPtr(obj))
    If hRes <> 0 Then
        Exit Function
    End If
    
    GetMem4 ByVal obj, vtblptr
    RtlMoveMemory vtbl, ByVal vtblptr, Len(vtbl)
    
    ' IActiveDesktop::SetWallpaper
    ' Первым параметром всегда является указатель на объект
    ' Возвращаемое значение всегда должно быть HRESULT (0 = S_OK)
    hRes = CallPointer(vtbl.SetWallpaper, obj, StrPtr(strFile), 0)
    If hRes = 0 Then
        ActiveDesktopSetWallpaper = True
    End If
    
    ' IActiveDesktop::ApplyChanges
    hRes = CallPointer(vtbl.ApplyChanges, obj, AD_APPLY_ALL Or AD_APPLY_FORCE)
    
    ' Освободить память
    ' (Set IActiveDesktop = Nothing)
    CallPointer vtbl.Release, obj
End Function
 
Private Function CallPointer(ByVal fnc As Long, ParamArray params()) As Long
    Dim btASM(&HEC00& - 1)  As Byte
    Dim pASM                As Long
    Dim i                   As Integer
    
    pASM = VarPtr(btASM(0))
    
    AddByte pASM, &H58                  ' POP EAX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H50                  ' PUSH EAX
    
    For i = UBound(params) To 0 Step -1
        AddPush pASM, CLng(params(i))   ' PUSH dword
    Next
    
    AddCall pASM, fnc                   ' CALL rel addr
    AddByte pASM, &HC3                  ' RET
    
    CallPointer = CallWindowProcA(VarPtr(btASM(0)), 0, 0, 0, 0)
End Function
 
Private Sub AddPush(pASM As Long, lng As Long)
    AddByte pASM, &H68
    AddLong pASM, lng
End Sub
 
Private Sub AddCall(pASM As Long, addr As Long)
    AddByte pASM, &HE8
    AddLong pASM, addr - pASM - 4
End Sub
 
Private Sub AddLong(pASM As Long, lng As Long)
    GetMem4 lng, ByVal pASM
    pASM = pASM + 4
End Sub
 
Private Sub AddByte(pASM As Long, bt As Byte)
    GetMem1 bt, ByVal pASM
    pASM = pASM + 1
End Sub
Вложения
Тип файла: zip Изменение обоев на рабочем столе 3.0.zip (8.4 Кб, 42 просмотров)
4
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
26.09.2023, 15:57
PixelingNT - программа для считывания пикселей с экрана (своеобразная экранная лупа)

Я давно ещё придумал и написал для себя эту программку, которая позволяет увеличивать область экрана вокруг курсора мыши в квадрате 16х16 пикселей, увеличивая в 16 раз один пиксель. Это очень удобная утилитка для программистов и веб-дизайнеров. Она позволяет очень легко определить цвет пикселя с экрана. Для программирования для Windows и для программирования для WEB, что для меня тоже очень часто нужно было и экран увеличивать, пиксели смотреть, и получать номер цвета пикселя. Это бывает очень важно при работе с цветами и пикселями. Давным-давно, в 2011 году, я написал для себя эту программу, и она была основана на функции GetPixel, во времена Windows XP, она работала спокойно, но вот сейчас настали другие времена, и в семёрке, для правильной работы, понадобился новый механизм считывания пикселей с экрана, с этим мне помог The trick, спасибо ему. Поэтому недавно я полностью переписал эту программу и решил поделиться со всем миром. Думаю, много кому нужно узнавать цвета пикселей с экрана, это очень-очень удобно. Идеальная утилитка для программистов и веб-дизайнеров.

Теперь подгонять пикселя будет очень легко))) Итак возможности программы:

1. Нажатие комбинации клавиш Ctrl+Win позволяет останавливать слежение за экраном, чтобы как бы застопорить картинку в этой экранной лупе, чтобы потом на неё можно было навести мышку и спокойно выковырять нужный цвет.

2. Нажатие левой кнопки мыши копирует в буфер обмена номер цвета в API и в Html-формате.

3. Удержание курсора мыши в нижней области экрана позволяет перетаскивать саму программу, можно тягать её за низ.

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

5. Нажатие комбинации клавиш Ctrl+Win снимает также программу с заморозки с остоновленного режима и программа продолжает дальше следить за экраном вокруг курсора мыши. Но нажимать эту комбинацию клавиш, можно только, если курсор мыши не находится над самой программой (этой лупой такой своеобразной)

Стандартная лупа 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
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
Option Explicit
' *----------------------------------------*
' | Программа PixelingNT                   |
' | Версия 1.0                             |
' | Copyright (c) 26.09.2023 by HackerVlad |
' | e-mail: vladislavpeshkov@ya.ru         |
' *----------------------------------------*
 
Private Declare Function GetDC Lib "user32" (ByVal hwnd As OLE_HANDLE) As OLE_HANDLE
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As OLE_HANDLE, ByVal hDC As OLE_HANDLE) As Long
Private Declare Function StretchBlt Lib "gdi32" (ByVal hDC As OLE_HANDLE, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As OLE_HANDLE, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
Private Declare Function GetCursorPos Lib "user32" (ByRef Point As POINTAPI) As Long
Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Private Declare Function GetMem1 Lib "msvbvm60" (ByVal Src As Long, Dst As Any) As Long
 
Private Const WM_NCLBUTTONDOWN = &HA1
Private Const HTCAPTION = 2
 
Private Type POINTAPI
  x As Long
  y As Long
End Type
 
Dim ScreenX As Long
Dim ScreenY As Long
Dim Stopped As Boolean
Dim MouseXY As POINTAPI
 
Private Function APIColor2HtmlColor(APIColor As Long) As String
    Dim colorR As Byte
    Dim colorG As Byte
    Dim colorB As Byte
    
    GetMem1 VarPtr(APIColor), colorR
    GetMem1 VarPtr(APIColor) + 1, colorG
    GetMem1 VarPtr(APIColor) + 2, colorB
    
    APIColor2HtmlColor = "#" & IIf(Len(Hex(colorR)) = 2, Hex(colorR), "0" & Hex(colorR)) & IIf(Len(Hex(colorG)) = 2, Hex(colorG), "0" & Hex(colorG)) & IIf(Len(Hex(colorB)) = 2, Hex(colorB), "0" & Hex(colorB))
End Function
 
Private Sub Form_Click()
    With GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
       .SetText Label1.Caption
       .PutInClipboard
    End With
End Sub
 
Private Sub Form_Load()
    WindowTopMost hwnd, True
    PositionWindow hwnd, mRightBottom
    
    ScreenX = (Screen.Width / Screen.TwipsPerPixelX)
    ScreenY = (Screen.Height / Screen.TwipsPerPixelY)
End Sub
 
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
    Dim GetColor As Long
    Dim LabelString As String
    
    GetColor = Me.Point(x, y)
    
    If x <> 255 And y <> 255 And (x Mod 16) <> 0 And (y Mod 16) <> 0 Then
        LabelString = "VB: (&&H" & Hex(GetColor) & "), Html: (" & APIColor2HtmlColor(GetColor) & ")"
        
        If Label1.Caption <> LabelString Then
            Label1.Caption = LabelString
        End If
    End If
End Sub
 
Private Sub Form_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Button = 2 Then
        Unload Me
    End If
End Sub
 
Private Sub Label1_Click()
    If Stopped = True Then
        Label1.Caption = "Stopped (" & MouseXY.x & " x " & MouseXY.y & ")"
    End If
End Sub
 
Private Sub Label1_DblClick()
    PositionWindow hwnd, mRightBottom
End Sub
 
Private Sub Label1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    Call ReleaseCapture
    Call SendMessage(Me.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&)
End Sub
 
Private Sub Label1_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Stopped = True Then
        Label1.Caption = "Stopped (" & MouseXY.x & " x " & MouseXY.y & ")"
    End If
End Sub
 
Private Sub Timer1_Timer()
    Dim hDC As OLE_HANDLE
    Dim tPT As POINTAPI
    Dim mouseX As Long
    Dim mouseY As Long
    Dim lN As Long
    
    If Stopped = False Then
        GetCursorPos tPT
        
        If WindowFromPoint(tPT.x, tPT.y) <> Me.hwnd Then ' Если под курсором мыши не моё окно
            Label1.Caption = tPT.x & " x " & tPT.y
            hDC = GetDC(0)
            
            If hDC Then
                If (tPT.x - 8) >= 0 Then
                    If tPT.x >= ScreenX - 8 Then
                        Me.Cls
                        mouseX = ScreenX - 8
                    Else
                        mouseX = tPT.x - 8
                    End If
                End If
                If (tPT.y - 8) >= 0 Then
                    If tPT.y > ScreenY - 8 Then
                        Me.Cls
                        mouseY = ScreenY - 8
                    Else
                        mouseY = tPT.y - 8
                    End If
                End If
                
                StretchBlt Me.hDC, 0, 0, 256, 256, hDC, mouseX, mouseY, 16, 16, vbSrcCopy
                
                ReleaseDC 0, hDC
                Me.Refresh
            End If
        End If
    End If
End Sub
 
Private Sub Timer2_Timer()
    Dim tPT As POINTAPI
    Dim lN  As Long
    
    GetCursorPos tPT
    
    If GetAsyncKeyState(17) And GetAsyncKeyState(91) Or GetAsyncKeyState(17) And GetAsyncKeyState(92) Then
        If WindowFromPoint(tPT.x, tPT.y) <> Me.hwnd Then ' Если под курсором мыши не моё окно
            Timer3.Enabled = True
            Timer2.Enabled = False
            
            Stopped = Not (Stopped)
            Timer1.Enabled = Not (Timer1.Enabled)
            
            If Stopped = True Then
                MouseXY = tPT
                Label1.Caption = "Stopped (" & MouseXY.x & " x " & MouseXY.y & ")"
                
                For lN = 0 To 15
                    Me.Line (0, lN * 16)-Step(256, 0), vbBlack
                    Me.Line (lN * 16, 0)-Step(0, 256), vbBlack
                Next
                
                Me.Line (255, 0)-(255, 255), vbBlack
                Me.Line (0, 255)-(256, 255), vbBlack
            End If
            
            Exit Sub
        End If
    End If
    
    If WindowFromPoint(tPT.x, tPT.y) <> Me.hwnd Then ' Если под курсором мыши не моё окно
        If Stopped = True Then
            Label1.Caption = "Stopped (" & MouseXY.x & " x " & MouseXY.y & ")"
        End If
    End If
End Sub
 
Private Sub Timer3_Timer()
    Timer3.Enabled = False
    Timer2.Enabled = True
End Sub
Изображения
 
Вложения
Тип файла: zip PixelingNT2.zip (20.6 Кб, 46 просмотров)
4
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
02.10.2023, 13:05
Список процессов с помощью функции WTSEnumerateProcesses

Давно помню искал в Интернете как пользоваться функцией WTSEnumerateProcesses, ещё пару лет назад, интересовался этой темой, так помню ничего толком не нашёл. Я тогда ещё плохо понимал в API и помню для меня было важно найти готовое решение, но так и не нашёл. Нашёл тогда один код, но он был глючный и постоянно были вылеты из среды IDE VB6, там что-то с CopyMemory намудрили не так. Написал свой код, который не глючит. В Интернете этого кода нигде нет для VB6 поэтому выкладываю. Эта функция кстати раньше была недокументированная вообще, теперь уже есть в MSDN полное описание, поэтому стало легче работать с этой функцией. Функция хороша тем, что сразу высвечивает весь список процессов со всеми PID, со всеми именами EXE, а так же со всеми SID, для лёгкого определения пользователя процесса.

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
Option Explicit
Private Declare Function WTSEnumerateProcesses Lib "wtsapi32.dll" Alias "WTSEnumerateProcessesW" (ByVal hServer As Long, ByVal Reserved As Long, ByVal Version As Long, ppProcessInfo As Long, pCount As Long) As Long
Private Declare Function WTSFreeMemory Lib "wtsapi32.dll" (ByVal pMemory As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, ByVal Source As Long, ByVal Length As Long)
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenW" (ByVal lpString As Long) As Long
Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyW" (ByVal lpString1 As Long, ByVal lpString2 As Long) As Long
Private Declare Function SysAllocStringLen Lib "oleaut32" (ByVal olestr As Long, ByVal BLen As Long) As Long
Private Declare Sub PutMem4 Lib "msvbvm60" (ByVal ptr As Long, ByVal Value As Long)
Private Declare Function ConvertSidToStringSid Lib "advapi32.dll" Alias "ConvertSidToStringSidW" (ByVal lpSid As Long, lpString As Long) As Long
Private Declare Function LookupAccountSid Lib "advapi32.dll" Alias "LookupAccountSidW" (ByVal lpSystemName As Long, ByVal sid As Long, ByVal name As Long, cbName As Long, ByVal ReferencedDomainName As Long, cbReferencedDomainName As Long, peUse As Long) As Long
Private Declare Function LocalFree Lib "kernel32" (ByVal hMem As Long) As Long
 
Private Const WTS_CURRENT_SERVER_HANDLE = 0
Private Const MAX_PATH As Long = 260
 
Private Type WTS_PROCESS_INFO
    SessionId As Long
    ProcessId As Long
    pProcessName As Long
    pUserSid As Long
End Type
 
Private Sub Command1_Click()
    Dim ppProcessInfo As Long
    Dim pCount As Long
    Dim WTS As WTS_PROCESS_INFO
    Dim ProcessName As String
    Dim pVoid As Long
    Dim i As Long
    Dim lpString As Long
    Dim StringSid As String
    Dim lpszDomain As String, lpszUsername As String
    Dim cbDomain As Long, cbUsername As Long
    Dim peUse As Long
    Dim AddLookupAccountSid As Boolean
    
    If List1.ListCount > 0 Then List1.Clear
    If List2.ListCount > 0 Then List2.Clear
    If List3.ListCount > 0 Then List3.Clear
    If List4.ListCount > 0 Then List4.Clear
    
    If WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1, ppProcessInfo, pCount) > 0 Then
        pVoid = ppProcessInfo
        
        For i = 0 To pCount - 1
            CopyMemory WTS, pVoid, LenB(WTS)
            StringSid = ""
            
            If WTS.ProcessId > 0 Then
                PutMem4 VarPtr(ProcessName), SysAllocStringLen(0, lstrlen(WTS.pProcessName))
                lstrcpy StrPtr(ProcessName), WTS.pProcessName
                AddLookupAccountSid = False
                
                If ConvertSidToStringSid(WTS.pUserSid, lpString) > 0 Then
                    PutMem4 VarPtr(StringSid), SysAllocStringLen(0, lstrlen(lpString))
                    lstrcpy StrPtr(StringSid), lpString
                    LocalFree lpString
                    
                    cbDomain = MAX_PATH
                    cbUsername = MAX_PATH
                    PutMem4 VarPtr(lpszDomain), SysAllocStringLen(0, MAX_PATH)
                    PutMem4 VarPtr(lpszUsername), SysAllocStringLen(0, MAX_PATH)
                    
                    If LookupAccountSid(ByVal 0&, WTS.pUserSid, StrPtr(lpszUsername), cbUsername, StrPtr(lpszDomain), cbDomain, peUse) > 0 Then
                        lpszDomain = Left$(lpszDomain, cbDomain)
                        lpszUsername = Left$(lpszUsername, cbUsername)
                        AddLookupAccountSid = True
                    End If
                End If
                
                List1.AddItem WTS.ProcessId & "    " & WTS.SessionId
                List2.AddItem ProcessName
                List3.AddItem StringSid
                If AddLookupAccountSid = True Then
                    List4.AddItem lpszDomain & "\" & lpszUsername
                Else
                    List4.AddItem "<Unknown>\<Unknown>"
                End If
            End If
            
            pVoid = pVoid + LenB(WTS)
        Next
        
        WTSFreeMemory ppProcessInfo
    End If
    
    List1.Selected(0) = True
    List1.SetFocus
End Sub
 
Private Sub List1_Click()
    List2.Selected(List1.ListIndex) = True
    List3.Selected(List1.ListIndex) = True
    List4.Selected(List1.ListIndex) = True
End Sub
 
Private Sub List2_Click()
    List1.Selected(List2.ListIndex) = True
    List3.Selected(List2.ListIndex) = True
    List4.Selected(List2.ListIndex) = True
End Sub
 
Private Sub List3_Click()
    List1.Selected(List3.ListIndex) = True
    List2.Selected(List3.ListIndex) = True
    List4.Selected(List3.ListIndex) = True
End Sub
 
Private Sub List4_Click()
    List1.Selected(List4.ListIndex) = True
    List2.Selected(List4.ListIndex) = True
    List3.Selected(List4.ListIndex) = True
End Sub
Вложения
Тип файла: zip WTSEnumerateProcessesW.zip (7.9 Кб, 45 просмотров)
5
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
10.10.2023, 11:53
PixelingNT версия 1.1

Новая версия программы PixelingNT. По просьбе иностранца xxdoc осуществил нормальное отображение окна программы в других DPI экрана. При 125% увеличения экрана и при 150% даже теперь работает нормально. Файл манифеста прилагается.

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
Option Explicit
' *----------------------------------------*
' | Программа PixelingNT                   |
' | Версия 1.1                             |
' | Copyright (c) 10.10.2023 by HackerVlad |
' | e-mail: vladislavpeshkov@ya.ru         |
' *----------------------------------------*
 
Private Declare Function GetDC Lib "user32" (ByVal hwnd As OLE_HANDLE) As OLE_HANDLE
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As OLE_HANDLE, ByVal hDC As OLE_HANDLE) As Long
Private Declare Function StretchBlt Lib "gdi32" (ByVal hDC As OLE_HANDLE, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As OLE_HANDLE, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
Private Declare Function GetCursorPos Lib "user32" (ByRef Point As POINTAPI) As Long
Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Private Declare Function GetMem1 Lib "msvbvm60" (ByVal Src As Long, Dst As Any) As Long
Private Declare Function SHAppBarMessage Lib "shell32.dll" (ByVal dwMessage As Long, pData As APPBARDATA) As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
 
Private Const WM_NCLBUTTONDOWN = &HA1
Private Const HTCAPTION = 2
Private Const ABS_AUTOHIDE = &H1
Private Const ABS_ONTOP = &H2
Private Const ABM_GETSTATE = &H4
Private Const ABM_GETTASKBARPOS = &H5
Private Const HWND_TOPMOST = -1
Private Const SWP_NOACTIVATE = &H10
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOSIZE = &H1
 
Private Type POINTAPI
  x As Long
  y As Long
End Type
 
Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
 
Private Type APPBARDATA
    cbSize As Long
    hwnd As Long
    uCallbackMessage As Long
    uEdge As Long
    rc As RECT
    lParam As Long
End Type
 
Dim ScreenX As Long
Dim ScreenY As Long
Dim Stopped As Boolean
Dim MouseXY As POINTAPI
 
Private Function APIColor2HtmlColor(APIColor As Long) As String
    Dim colorR As Byte
    Dim colorG As Byte
    Dim colorB As Byte
    
    GetMem1 VarPtr(APIColor), colorR
    GetMem1 VarPtr(APIColor) + 1, colorG
    GetMem1 VarPtr(APIColor) + 2, colorB
    
    APIColor2HtmlColor = "#" & IIf(Len(Hex(colorR)) = 2, Hex(colorR), "0" & Hex(colorR)) & IIf(Len(Hex(colorG)) = 2, Hex(colorG), "0" & Hex(colorG)) & IIf(Len(Hex(colorB)) = 2, Hex(colorB), "0" & Hex(colorB))
End Function
 
Private Sub Form_Click()
    Dim PutSetText As String
    
    PutSetText = Label1.Caption
    
    If Len(PutSetText) > 0 Then
        PutSetText = Replace(PutSetText, "&&H", "&H")
        
        With GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
           .SetText PutSetText
           .PutInClipboard
        End With
    End If
End Sub
 
Private Sub Form_Load()
    Dim ABD As APPBARDATA, Ret As Long
    Dim hPanel As Integer
    Dim gPanel As Integer
    
    ScreenX = (Screen.Width / Screen.TwipsPerPixelX)
    ScreenY = (Screen.Height / Screen.TwipsPerPixelY)
    
    ' Предотвратить растягивание формы в других DPI
    If IsScreenZoom > 100 Then
        Me.Width = 256 * Screen.TwipsPerPixelX
        Me.Height = 273 * Screen.TwipsPerPixelY
        Label1.Top = 256
        Label1.Left = 0
        Label1.Width = 256
        Label1.Height = Me.Height - Label1.Top
        Label1.Font = GetSystemFontName(MessageFont)
        
        If IsScreenZoom > 120 Then
            Label1.FontSize = 7
        Else
            Label1.FontSize = 9
        End If
    End If
    
    SetWindowPos hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_NOSIZE Or SWP_NOMOVE
    
    ' Математические расчёты для центрирования формы в правом нижнем углу экрана, в соответствии с таскбаром
    SHAppBarMessage ABM_GETTASKBARPOS, ABD
    Ret = SHAppBarMessage(ABM_GETSTATE, ABD)
    If Trim(Str(ABD.rc.Top)) > 0 Then hPanel = (Trim(Str(ABD.rc.Bottom)) - Trim(Str(ABD.rc.Top))) * Screen.TwipsPerPixelX
    If Trim(Str(ABD.rc.Left)) > 0 Then gPanel = (Trim(Str(ABD.rc.Right)) - Trim(Str(ABD.rc.Left))) * Screen.TwipsPerPixelX
    
    Me.Left = Screen.Width - Me.Width - gPanel
    Me.Top = Screen.Height - Me.Height - hPanel
End Sub
 
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
    Dim GetColor As Long
    Dim LabelString As String
    
    GetColor = Me.Point(x, y)
    
    If Stopped = True Then
        If x <> 255 And y <> 255 And (x Mod 16) <> 0 And (y Mod 16) <> 0 Then
            LabelString = "VB: (&&H" & Hex(GetColor) & "), Html: (" & APIColor2HtmlColor(GetColor) & ")"
            
            If Label1.Caption <> LabelString Then
                Label1.Caption = LabelString
            End If
        End If
    Else
        LabelString = "VB: (&&H" & Hex(GetColor) & "), Html: (" & APIColor2HtmlColor(GetColor) & ")"
        
        If Label1.Caption <> LabelString Then
            Label1.Caption = LabelString
        End If
    End If
End Sub
 
Private Sub Form_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Button = 2 Then
        Unload Me
    End If
End Sub
 
Private Sub Label1_Click()
    If Stopped = True Then
        Label1.Caption = "Stopped (" & MouseXY.x & " x " & MouseXY.y & ")"
    End If
End Sub
 
Private Sub Label1_DblClick()
    Dim ABD As APPBARDATA, Ret As Long
    Dim hPanel As Integer
    Dim gPanel As Integer
    
    ' Математические расчёты для центрирования формы в правом нижнем углу экрана, в соответствии с таскбаром
    SHAppBarMessage ABM_GETTASKBARPOS, ABD
    Ret = SHAppBarMessage(ABM_GETSTATE, ABD)
    If Trim(Str(ABD.rc.Top)) > 0 Then hPanel = (Trim(Str(ABD.rc.Bottom)) - Trim(Str(ABD.rc.Top))) * Screen.TwipsPerPixelX
    If Trim(Str(ABD.rc.Left)) > 0 Then gPanel = (Trim(Str(ABD.rc.Right)) - Trim(Str(ABD.rc.Left))) * Screen.TwipsPerPixelX
    
    Me.Left = Screen.Width - Me.Width - gPanel
    Me.Top = Screen.Height - Me.Height - hPanel
End Sub
 
Private Sub Label1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    Call ReleaseCapture
    Call SendMessage(Me.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&)
End Sub
 
Private Sub Label1_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Stopped = True Then
        Label1.Caption = "Stopped (" & MouseXY.x & " x " & MouseXY.y & ")"
    End If
End Sub
 
Private Sub Timer1_Timer()
    Dim hDC As OLE_HANDLE
    Dim tPT As POINTAPI
    Dim mouseX As Long
    Dim mouseY As Long
    Dim lN As Long
    
    If Stopped = False Then
        GetCursorPos tPT
        
        If WindowFromPoint(tPT.x, tPT.y) <> Me.hwnd Then ' Если под курсором мыши не моё окно
            Label1.Caption = tPT.x & " x " & tPT.y
            hDC = GetDC(0)
            
            If hDC Then
                If (tPT.x - 8) >= 0 Then
                    If tPT.x >= ScreenX - 8 Then
                        Me.Cls
                        mouseX = ScreenX - 8
                    Else
                        mouseX = tPT.x - 8
                    End If
                End If
                If (tPT.y - 8) >= 0 Then
                    If tPT.y > ScreenY - 8 Then
                        Me.Cls
                        mouseY = ScreenY - 8
                    Else
                        mouseY = tPT.y - 8
                    End If
                End If
                
                StretchBlt Me.hDC, 0, 0, 256, 256, hDC, mouseX, mouseY, 16, 16, vbSrcCopy
                
                ReleaseDC 0, hDC
                Me.Refresh
            End If
        End If
    End If
End Sub
 
Private Sub Timer2_Timer()
    Dim tPT As POINTAPI
    Dim lN  As Long
    
    GetCursorPos tPT
    
    If GetAsyncKeyState(17) And GetAsyncKeyState(91) Or GetAsyncKeyState(17) And GetAsyncKeyState(92) Then
        If WindowFromPoint(tPT.x, tPT.y) <> Me.hwnd Then ' Если под курсором мыши не моё окно
            Timer3.Enabled = True
            Timer2.Enabled = False
            
            Stopped = Not (Stopped)
            Timer1.Enabled = Not (Timer1.Enabled)
            
            If Stopped = True Then
                MouseXY = tPT
                Label1.Caption = "Stopped (" & MouseXY.x & " x " & MouseXY.y & ")"
                
                For lN = 0 To 15
                    Me.Line (0, lN * 16)-Step(256, 0), vbBlack
                    Me.Line (lN * 16, 0)-Step(0, 256), vbBlack
                Next
                
                Me.Line (255, 0)-(255, 255), vbBlack
                Me.Line (0, 255)-(256, 255), vbBlack
            End If
            
            Exit Sub
        End If
    End If
    
    If WindowFromPoint(tPT.x, tPT.y) <> Me.hwnd Then ' Если под курсором мыши не моё окно
        If Stopped = True Then
            Label1.Caption = "Stopped (" & MouseXY.x & " x " & MouseXY.y & ")"
        End If
    End If
End Sub
 
Private Sub Timer3_Timer()
    Timer3.Enabled = False
    Timer2.Enabled = True
End Sub
Вложения
Тип файла: zip PixelingNT2 (3).zip (17.2 Кб, 34 просмотров)
4
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
22.10.2023, 20:53
Своя собственная подсказка на VB6

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

Форма...
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
Option Explicit
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal CX As Long, ByVal CY As Long, ByVal wFlags As Long) As Long
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
 
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOACTIVATE = &H10
Private Const SWP_NOZORDER = &H4
Private Const HWND_TOPMOST = -1
 
Private Type POINTAPI
    x As Long
    y As Long
End Type
 
Private Sub Command1_Click()
    Dim CursorSizeHeight As Integer
    Dim HotY As Integer
    
    GetMouseCursorHeight CursorSizeHeight, HotY
    
    Me.Cls
    Print "Height: " & CursorSizeHeight
    Print "HotY: " & HotY
End Sub
 
Private Sub Form_Load()
    Form2.Show
End Sub
 
Private Sub Form_Unload(Cancel As Integer)
    Unload Form2
End Sub
 
Private Sub Timer1_Timer()
    Dim pt As POINTAPI
    Dim CursorSizeHeight As Integer
    Dim HotY As Integer
    
    GetCursorPos pt
    GetMouseCursorHeight CursorSizeHeight, HotY ' Супер-мега-идеальная функция, которую я писал целую неделю
    
    ' Поверх всех окон
    SetWindowPos Form2.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_NOSIZE Or SWP_NOMOVE
    
    ' Прибавим плюс один пиксель от высоты непрозрачной области курсора мыши (отодвинуть на один писель вниз)
    SetWindowPos Form2.hwnd, 0, pt.x, pt.y + ((CursorSizeHeight - HotY) + 1), 0, 0, SWP_NOSIZE Or SWP_NOZORDER Or SWP_NOACTIVATE
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
111
112
113
114
115
116
117
118
119
120
Option Explicit
Private Declare Function GetCursorInfo Lib "user32" (ByRef pci As CURSORINFO) As Long
Private Declare Function GetIconInfo Lib "user32" (ByVal hIcon As Long, ByRef piconinfo As ICONINFO) As Long
Private Declare Function GetObjectW Lib "gdi32" (ByVal hObject As Long, ByVal nCount As Long, ByRef lpObject As Any) As Long
Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
 
Private Type CURSORINFO
    cbSize          As Long
    Flags           As Long
    hCursor         As Long
    ptPosX          As Long
    ptPosY          As Long
End Type
 
Private Type ICONINFO
    fIcon           As Long
    xHotspot        As Long
    yHotspot        As Long
    hbmMask         As Long
    hbmColor        As Long
End Type
 
Private Type BITMAP
    bmType          As Long
    bmWidth         As Long
    bmHeight        As Long
    bmWidthBytes    As Long
    bmPlanes        As Integer
    bmBitsPixel     As Integer
    bmBits          As Long
End Type
 
Public Sub GetMouseCursorHeight(SizeHeight As Integer, HotY As Integer)
    Dim tCurInfo As CURSORINFO
    
    ' If there is no mouse cursor, these should be 0
    SizeHeight = 0
    HotY = 0
    
    tCurInfo.cbSize = Len(tCurInfo)
    GetCursorInfo tCurInfo
    
    If tCurInfo.Flags = 1 And CBool(tCurInfo.hCursor) Then
        ' In case we can't figure out the dimensions, this is a best guess
        SizeHeight = 19
        
        Dim tICONINFO As ICONINFO
        
        If GetIconInfo(tCurInfo.hCursor, tICONINFO) Then
            Dim bm As BITMAP
            
            If GetObjectW(tICONINFO.hbmMask, Len(bm), bm) <> 0 Then
                ' Extract the bitmap bits
                Dim max As Long
                Dim curMask() As Byte
                
                max = bm.bmWidth * bm.bmHeight / 8
                ReDim curMask(max * 2 - 1) ' Enough space for the mask and the xor mask
                
                ' bm.bmWidthBytes = UBound(curMask)
                If GetBitmapBits(tICONINFO.hbmMask, UBound(curMask), curMask(0)) <> 0 Then
                    Dim hasXORMask As Byte
                    Dim Empt As Boolean
                    Dim bottom As Long
                    
                    If tICONINFO.hbmColor Then
                    
                    Else
                        ' if no color bitmap, then the hbmMask is a double height bitmap
                        ' with the cursor and the mask stacked.
                        hasXORMask = 1
                        max = max / 2
                    End If
                    
                    ' Go through the bitmap looking for the bottom of the image and/or mask
                    Empt = True
                    bottom = max
                    bottom = bottom - 1
                    
                    Do While bottom >= 0
                        If curMask(bottom) <> &HFF Or (hasXORMask And (curMask(bottom + max) <> 0)) Then
                            Empt = False
                            Exit Do
                        End If
                        
                        bottom = bottom - 1
                    Loop
                    
                    If Empt = False Then
                        ' Go through the bitmap looking for the top of the image and/or mask
                        Dim top As Long
                        Dim byteWidth As Long
                        
                        For top = 0 To max - 1
                            If curMask(top) <> &HFF Or (hasXORMask And (curMask(top + max) <> 0)) Then Exit For
                        Next
                        
                        ' byteWidth = bytes per row AND bytes per vertical pixel
                        byteWidth = bm.bmWidth / 8
                        bottom = bottom / byteWidth
                        top = top / byteWidth
                        
                        SizeHeight = bottom - top + 1
                        HotY = tICONINFO.yHotspot - top
                    Else
                        ' (Final value) We didn't find anything in the bitmap.
                        ' So, we'll make a guess with the information that we have.
                        ' Note: This seems to happen on I-Beams and Cross-hairs -- cursors that
                        ' are all inverted. Strangely, their hbmColor is non-null.
                        SizeHeight = bm.bmHeight
                        HotY = tICONINFO.yHotspot
                    End If
                End If
                
                DeleteObject tICONINFO.hbmMask
            End If
        End If
    End If
End Sub
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: zip GetMouseCursorHeight.zip (9.7 Кб, 58 просмотров)
4
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
16.11.2023, 00:01
Уникодный InputBox

Уникодный InputBox с полной поддержкой уникода и китайских символов для ввода. Написал за пару часов буквально этот модуль, так как понадобилось вводить в текстовое поле InputBox уникодные символы иногда. Например для того чтобы создать папку с уникодным именем. Так же можно менять заголовок диалога InputBox на уникодное имя тоже. И текст сообщение тоже уникодное. Радуйтесь)

Единственное что не написал это смену стандартного шрифта на какой-нибудь другой. Но это можно тоже осуществить, если захотеть. Но китайский итак работает.

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
Option Explicit
'////////////////////////////////////////////
'// Модуль создания уникодного InputBox'а  //
'// Copyright (c) 15.11.2023 by HackerVlad //
'// e-mail: vladislavpeshkov@yandex.ru     //
'// Версия 1.0                             //
'////////////////////////////////////////////
 
Private Declare Function SetWinEventHook Lib "user32" (ByVal eventMin As Long, ByVal eventMax As Long, ByVal hmodWinEventProc As Long, ByVal pfnWinEventProc As Long, ByVal idProcess As Long, ByVal idThread As Long, ByVal dwFlags As Long) As Long
Private Declare Function UnhookWinEvent Lib "user32" (ByVal hWinEventHook As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameW" (ByVal hwnd As Long, ByVal lpClassName As Long, ByVal nMaxCount As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
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 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 DefWindowProcW Lib "user32" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWndParent As Long, ByVal hWndChildAfter As Long, ByVal lpClassName As String, ByVal lpWindowName As String) As Long
 
Private Const EVENT_OBJECT_SHOW As Long = &H8002&
Private Const WM_COMMAND = &H111
Private Const IDOK = 1
Private Const WM_GETTEXT As Long = &HD
Private Const WM_GETTEXTLENGTH As Long = &HE
Private Const WM_SETTEXT = &HC
Private Const EM_SETSEL = &HB1
 
Dim hEvent As Long
Dim HandleDialogWindow As Long
Dim HandleEdit As Long
Dim Subclassed As Long
Dim InputText As String
Dim TitleCaption As String
Dim DialogPrompt As String
Dim TextDefault As String
Dim once As Boolean
 
Public Function InputBoxW(ByVal strPrompt As String, Optional ByVal strTitle As String, Optional ByVal strDefault As String) As String
    InputText = vbNullString
    HandleDialogWindow = 0
    Subclassed = 0
    HandleEdit = 0
    hEvent = 0
    once = False
    
    DialogPrompt = strPrompt
    TitleCaption = strTitle
    TextDefault = strDefault
    
    hEvent = SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_SHOW, 0, AddressOf WinEventProc, 0, App.ThreadID, 0) ' Устанавливаем хук на создание окон в системе
    InputBox strPrompt, vbNullString ' Вызвать классический InputBox
    
    RemoveWindowSubclass Subclassed, AddressOf WndProc, 0 ' Снять субклассирование
    If hEvent > 0 Then UnhookWinEvent hEvent
    
    InputBoxW = InputText
End Function
 
' Функция вызывается при создании окна
Private Sub WinEventProc(ByVal hWinEventHook As Long, ByVal dwEvent As Long, ByVal hwnd As Long, ByVal idObject As Long, ByVal idChild As Long, ByVal dwEventThread As Long, ByVal dwmsEventTime As Long)
    Dim cls As String
    Dim sLn As Long
    Dim hwndStatic As Long
    
    cls = Space(256)
    
    ' Получаем имя класса окна
    sLn = GetClassName(hwnd, StrPtr(cls), Len(cls))
    
    If sLn Then
        cls = Left(cls, sLn)
        
        If StrComp(cls, "Edit", vbTextCompare) = 0 Then
            HandleEdit = hwnd ' Запомнить hwnd текстового поля
        End If
        
        If cls = "#32770" Then ' Если класс этого окна это диалоговое окно
            HandleDialogWindow = hwnd ' Запомнить hwnd диалогового окна
            
            If once = False Then ' На всякий случай, чтобы код выполнялся только один раз
                hwndStatic = FindWindowEx(hwnd, ByVal 0&, "Static", vbNullString) ' Найти Static
                If Len(TitleCaption) = 0 Then TitleCaption = App.Title
                
                ' Установить заголовок окна с поддержкой уникода (SendMessage не работает в этом случае)
                DefWindowProcW hwnd, WM_SETTEXT, 0, StrPtr(TitleCaption)
                
                ' Установить заголовок окна с поддержкой уникода (а вот здесь SendMessage уже работает почему-то)
                SendMessage hwndStatic, WM_SETTEXT, 0, StrPtr(DialogPrompt)
                
                If Len(TextDefault) > 0 Then
                    SendMessage HandleEdit, WM_SETTEXT, 0, StrPtr(TextDefault) ' Установить текст по умолчанию в текстовом поле
                    SendMessage HandleEdit, EM_SETSEL, 0, -1 ' Выделить всё в текстовом поле
                End If
                
                once = True
            End If
            
            If HandleEdit > 0 And HandleDialogWindow > 0 Then
                ' Снять хук, если мы получили оба значения и HandleDialogWindow и HandleEdit
                If hEvent > 0 Then ' Только единожды
                    UnhookWinEvent hEvent
                    hEvent = 0
                End If
            End If
            
            If Subclassed = 0 Then
                Subclassed = SetWindowSubclass(HandleDialogWindow, AddressOf WndProc, 0&)
            End If
        End If
    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
    Dim TextLen As Long
    
    Select Case uMsg
        Case WM_COMMAND
            If wParam = IDOK Then ' Событие которое обрабатывается при нажатии ОК
                InputText = Space$(256)
                TextLen = SendMessage(HandleEdit, WM_GETTEXTLENGTH, 0, 0)
                SendMessage HandleEdit, WM_GETTEXT, TextLen + 1, StrPtr(InputText)
                InputText = Left$(InputText, TextLen)
            End If
    End Select
    
    If Not bProcessed Then
        WndProc = DefSubclassProc(hwnd, uMsg, wParam, lParam)
    End If
End Function
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: zip Уникодный InputBox.zip (10.5 Кб, 28 просмотров)
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
16.11.2023, 15:18
Уникодный InputBox версия 1.1

В новой версии модуля произведены некоторые улучшения и исправления. Теперь события отлавливаются в самом начале создания окон через EVENT_OBJECT_CREATE, таким образом, стало возможно изначально отловить все окна, и кнопки, и надпись статик в том числе, чтобы потом не искать через FindWindowEx. Изменение текста окон на уникодное теперь находится в WM_SHOWWINDOW самого диалогового окна, это перестановка позволила теперь отображать правильно уникодный заголовок диалогового окна с китайскими иероглифами, даже в классическом стиле окна, не прибегая к DefWindowProcW.

Новый код модуля:

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
Option Explicit
'////////////////////////////////////////////
'// Модуль создания уникодного InputBox'а  //
'// Copyright (c) 16.11.2023 by HackerVlad //
'// e-mail: vladislavpeshkov@yandex.ru     //
'// Версия 1.1                             //
'////////////////////////////////////////////
 
Private Declare Function SetWinEventHook Lib "user32" (ByVal eventMin As Long, ByVal eventMax As Long, ByVal hmodWinEventProc As Long, ByVal pfnWinEventProc As Long, ByVal idProcess As Long, ByVal idThread As Long, ByVal dwFlags As Long) As Long
Private Declare Function UnhookWinEvent Lib "user32" (ByVal hWinEventHook As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameW" (ByVal hwnd As Long, ByVal lpClassName As Long, ByVal nMaxCount As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextW" (ByVal hwnd As Long, ByVal lpString As Long) As Long
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 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 Const EVENT_OBJECT_CREATE As Long = &H8000&
Private Const WM_COMMAND = &H111
Private Const IDOK = 1
Private Const WM_GETTEXT As Long = &HD
Private Const WM_GETTEXTLENGTH As Long = &HE
Private Const WM_SETTEXT = &HC
Private Const EM_SETSEL = &HB1
Private Const WM_SHOWWINDOW As Long = &H18
 
Dim hEvent As Long
Dim HandleDialogWindow As Long
Dim HandleStatic As Long
Dim HandleEdit As Long
Dim Subclassed As Long
Dim InputText As String
Dim TitleCaption As String
Dim DialogPrompt As String
Dim TextDefault As String
 
Public Function InputBoxW(ByVal strPrompt As String, Optional ByVal strTitle As String, Optional ByVal strDefault As String) As String
    InputText = vbNullString
    HandleDialogWindow = 0
    HandleStatic = 0
    Subclassed = 0
    HandleEdit = 0
    hEvent = 0
    
    DialogPrompt = strPrompt
    TitleCaption = strTitle
    TextDefault = strDefault
    
    hEvent = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, 0, AddressOf WinEventProc, 0, App.ThreadID, 0) ' Устанавливаем хук на создание окон в системе
    InputBox strPrompt, vbNullString ' Вызвать классический InputBox
    
    RemoveWindowSubclass Subclassed, AddressOf WndProc, 0 ' Снять субклассирование
    If hEvent > 0 Then UnhookWinEvent hEvent
    
    InputBoxW = InputText
End Function
 
' Функция вызывается при создании окна
Private Sub WinEventProc(ByVal hWinEventHook As Long, ByVal dwEvent As Long, ByVal hwnd As Long, ByVal idObject As Long, ByVal idChild As Long, ByVal dwEventThread As Long, ByVal dwmsEventTime As Long)
    Dim cls As String
    Dim sLn As Long
    
    cls = Space(256)
    
    ' Получаем имя класса окна
    sLn = GetClassName(hwnd, StrPtr(cls), Len(cls))
    
    If sLn Then
        cls = Left(cls, sLn)
        
        If HandleDialogWindow = 0 Then
            If cls = "#32770" Then ' Если класс это диалоговое окно
                HandleDialogWindow = hwnd ' Запомнить hwnd диалогового окна
                
                If Subclassed = 0 Then
                    Subclassed = SetWindowSubclass(HandleDialogWindow, AddressOf WndProc, 0&)
                End If
            End If
        End If
        
        If HandleStatic = 0 Then
            If StrComp(cls, "Static", vbTextCompare) = 0 Then
                HandleStatic = hwnd
            End If
        End If
        
        If HandleEdit = 0 Then
            If StrComp(cls, "Edit", vbTextCompare) = 0 Then
                HandleEdit = hwnd ' Запомнить hwnd текстового поля
            End If
        End If
        
        If HandleDialogWindow > 0 And HandleStatic > 0 And HandleEdit > 0 Then
            If hEvent > 0 Then ' Только единожды
                UnhookWinEvent hEvent ' Снять хук
                hEvent = 0
            End If
        End If
    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
    Dim TextLen As Long
    
    Select Case uMsg
        Case WM_SHOWWINDOW
            If Len(TitleCaption) = 0 Then TitleCaption = App.Title
            SetWindowText HandleDialogWindow, StrPtr(TitleCaption)
            
            SendMessage HandleStatic, WM_SETTEXT, 0, StrPtr(DialogPrompt)
            
            If Len(TextDefault) > 0 Then
                SendMessage HandleEdit, WM_SETTEXT, 0, StrPtr(TextDefault) ' Установить текст по умолчанию в текстовом поле
                SendMessage HandleEdit, EM_SETSEL, 0, -1 ' Выделить всё в текстовом поле
            End If
        
        Case WM_COMMAND
            If wParam = IDOK Then ' Событие которое обрабатывается при нажатии ОК
                InputText = Space$(256)
                TextLen = SendMessage(HandleEdit, WM_GETTEXTLENGTH, 0, 0)
                SendMessage HandleEdit, WM_GETTEXT, TextLen + 1, StrPtr(InputText)
                InputText = Left$(InputText, TextLen)
            End If
    End Select
    
    If Not bProcessed Then
        WndProc = DefSubclassProc(hwnd, uMsg, wParam, lParam)
    End If
End Function
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0  
2
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
16.11.2023, 18:26
Лучший ответ Сообщение было отмечено Catstail как решение

Решение

Модуль для вызова диалога выбора папки версия 2.5

Подходит как для VB6 так и для VBA. Данный модуль имеет широкие возможности. Можно самому указывать во сколько раз увеличивать окно диалога выбора папки. Можно устанавливать начальную папку обзора, не боясь что произойдёт глюк и не сработает прокрутка дерева. Диалог можно центрировать на экране!!!! А это очень удобно!!! Можно в адресной строке вводить папки, при этом если ввести файл, то файл выбираться не будет. Самая главная фишка: своя собственная кнопка "Создать папку". Полная поддержка уникода. Можно скрывать в обзоре папок всё кроме логических разделов жёсткого диска компьютера, всё кроме винчестера. Все остальные папки, такие как сетевое окружение, корзина, которые нам не нужны. Можно задавать файловые маски для папок, чтобы можно было выбирать только те папки которые содержат определённые типы файлов. Можно менять заголовок окна, в том числе с уникодным именем. Можно устанавливать поверх всех окон даже. Полностью прописан ресайз окна идеально-правильно, как надо. Убраны все неровности пикселей майкрософта. Каждый пиксель подогнан идеально-точно, используя правильные математические формулы расчётов расположения окон. Функция BrowseForFolder имеет множество параметров. Приведу здесь только код функции, так как весь модуль не помещается в сообщении. Чтобы увидеть весь модуль, вам придётся скачать ZIP-архив.

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
' ***  Модифицированная функция BrowseForFolder. Получает на вход следующие аргументы:
' ***
' ***  hWnd_Owner        - hWnd вызывающего объекта
' ***  sPrompt           - текст подсказки
' ***  InitDir           - начальная папка обзора (если не задана, то "Мой компьютер")
' ***  ChangeSize        - увеличивать ли размер диалога; если "да", то надо указать RatioX и RatioY
' ***  RatioX            - во сколько раз увеличивать ширину диалога (принимается во внимание, если ChangeSize = True)
' ***  RatioY            - во сколько раз увеличивать высоту диалога (принимается во внимание, если ChangeSize = True)
' ***  CenterOnScreen    - центрировать ли диалог на экране
' ***  ShowEditBox       - показывать ли адресную строку
' ***  ShowNewFoldButton - показывать ли кнопку создания новой папки
' ***  OnlyDisks         - показывать только диски моего компьютера
' ***  fileMasks         - файловые маски, разделённые символом ";" (*.doc; *.txt и т.п.)
' ***                      если эта строка задана, то папку можно выбрать только если она
' ***                      содержит файлы, удовлетворяющие заданным маскам)
' ***  DialogTitle       - пользовательский заголовок диалога
' ***  TopMost           - если = True, то диалог будет поверх всех открытых окон
' ***  SetFocusTreeView  - если = True, то фокус по умолчанию переходит на дерево каталогов
Public Function BrowseForFolder(ByVal hWnd_Owner As Long, ByVal sPrompt As String, Optional ByVal InitDir As String, Optional ByVal ChangeSize As Boolean, Optional ByVal RatioX As Double = 1, Optional ByVal RatioY As Double = 1, Optional ByVal CenterOnScreen As Boolean, Optional ByVal ShowEditBox As Boolean, Optional ByVal ShowNewFoldButton As Boolean, Optional ByVal OnlyDisks As Boolean, Optional ByRef fileMasks As String, Optional ByVal DialogTitle As String, Optional ByVal TopMost As Boolean, Optional ByVal SetFocusTreeView As Boolean) As String
    Dim lpIDList As Long
    Dim lResult As Long
    Dim sPath As String
    Dim udtBI As BROWSEINFO
    Dim WhatBr As Long
    Dim lItemIDList As ItemIDList
    
    bff_DialogTitle = DialogTitle
    bff_ChangeSize = ChangeSize
    bff_RatioX = RatioX
    bff_RatioY = RatioY
    bff_CenterOnScreen = CenterOnScreen
    bff_TopMost = TopMost
    bff_NewBoy = False
    
    If ShowEditBox = True Then
        WhatBr = BIF_RETURNONLYFSDIRS Or BIF_STATUSTEXT Or BIF_EDITBOX Or BIF_VALIDATE
    Else
        WhatBr = BIF_RETURNONLYFSDIRS Or BIF_STATUSTEXT Or BIF_VALIDATE
    End If
    
    bff_CreatedDirictory = ""
    bff_ShowNewFoldButton = ShowNewFoldButton
    bff_ShowEditTextBox = ShowEditBox
    bff_SetFocusTreeView = SetFocusTreeView
    
RestartDialog:
    bff_hwndSysTreeView32 = 0
    bff_WidthStatic = 0
    bff_HwndStatic = 0
    bff_Subclassed = 0
    
    If Len(InitDir) > 0 Then
        bff_CurrentDirectory = InitDir & vbNullChar
    Else
        bff_CurrentDirectory = vbNullString
    End If
    
    If Len(fileMasks) > 0 Then
        bff_FileMasks = Split(fileMasks, ";")
    Else
        ReDim bff_FileMasks(0 To 0)
        bff_FileMasks(0) = vbNullString
    End If
    
    With udtBI
        If OnlyDisks = True Then
            SHGetSpecialFolderLocation hWnd_Owner, CSIDL_DRIVES, lItemIDList
            .pidlRoot = lItemIDList.mkid.cb
        End If
        
        .hwndOwner = hWnd_Owner
        .lpszTitle = sPrompt
        .ulFlags = WhatBr
        .lpfnCallback = FarProc(AddressOf BrowseCallbackProc)
    End With
    
    lpIDList = SHBrowseForFolder(VarPtr(udtBI))
    
    If lpIDList Then
        sPath = Space$(MAX_PATH)
        lResult = SHGetPathFromIDList(lpIDList, StrPtr(sPath))
        
        CoTaskMemFree lpIDList
    End If
    
    If bff_Subclassed Then
        RemoveWindowSubclass bff_hwndDialog, AddressOf WndProc, 0
    End If
    
    If bff_NewBoy = True Then
        GoTo RestartDialog
    End If
    
    BrowseForFolder = APIStrToVBStr(sPath)
End Function
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: zip Диалог выбора папки 2.5.zip (25.8 Кб, 66 просмотров)
5
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
19.11.2023, 01:51
Модуль для вызова юникодного InputBox'а версия 2.0

Наконец-таки, я создал новый модуль для вызова юникодного InputBox'а. Теперь InputBox вызывается по совершенно новой технологии, минуя саму функцию InputBox, вызывается всего одной строкой кода, с помощью функции DialogBoxParam. Оказывается можно вызывать диалоговое окно напрямую из ресурсов msvbvm60.dll! Спасибо конечно The Trick'у за подсказки как двигаться в правильном направлении. Мой юникодный InputBox работает даже без манифестов!

Код нового модуля:

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
Option Explicit
'/////////////////////////////////////////////
'// Модуль для вызова юникодного InputBox'а //
'// Copyright (c) 19.11.2023 by HackerVlad  //
'// e-mail: vladislavpeshkov@yandex.ru      //
'// Версия 2.0                              //
'/////////////////////////////////////////////
 
Private Declare Function DialogBoxParam Lib "user32" Alias "DialogBoxParamW" (ByVal hInstance As Long, ByVal lpTemplate As Long, ByVal hWndParent As Long, ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryW" (ByVal lpLibFileName As Long) As Long
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Private Declare Function EndDialog Lib "user32" (ByVal hDlg As Long, ByVal nResult As Long) As Long
Private Declare Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageW" (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SetDlgItemText Lib "user32" Alias "SetDlgItemTextW" (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal lpString As Long) As Long
Private Declare Function GetDlgItemText Lib "user32" Alias "GetDlgItemTextW" (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal lpString As Long, ByVal nMaxCount As Long) As Long
Private Declare Function GetDlgItem Lib "user32" (ByVal hDlg As Long, ByVal nIDDlgItem As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextW" (ByVal hwnd As Long, ByVal lpString As Long) As Long
Private Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal CX As Long, ByVal CY As Long, ByVal wFlags As Long) As Long
Private Declare Function GetMonitorInfo Lib "user32.dll" Alias "GetMonitorInfoA" (ByVal hMonitor As Long, ByRef lpmi As MONITORINFO) As Long
Private Declare Function MonitorFromWindow Lib "user32.dll" (ByVal hwnd As Long, ByVal dwFlags As Long) As Long
 
Private Const IDOK = 1
Private Const IDCANCEL = 2
Private Const ID_EDIT = 4900
Private Const ID_STATIC = 4901
Private Const ID_HELP = 4902
Private Const WM_COMMAND = &H111
Private Const WM_INITDIALOG = &H110
Private Const SW_HIDE = 0
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOZORDER = &H4
Private Const MONITOR_DEFAULTTONEAREST = &H2
Private Const WM_GETTEXTLENGTH As Long = &HE
Private Const EM_SETSEL = &HB1
 
Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
 
Public Type MONITORINFO
    cbSize As Long
    rcMonitor As RECT
    rcWork As RECT
    dwFlags As Long
End Type
 
Dim InputText As String
Dim TitleText As String
Dim DefaultText As String
Dim CenterOnWorkspace As Boolean ' Аналог DS_CENTER
 
' Вызвать InputBox из msvbvm60.dll с поддеркой юникода
Public Function InputBoxW(ByVal hParent As Long, ByVal strPrompt As String, Optional ByVal strTitle As String, Optional CenterOnMonitorWorkspace As Boolean, Optional ByVal strDefault As String) As String
    Dim msvbvm60 As Long
    
    msvbvm60 = LoadLibrary(StrPtr("msvbvm60.dll"))
    
    If msvbvm60 <> 0 Then
        TitleText = strTitle
        DefaultText = strDefault
        CenterOnWorkspace = CenterOnMonitorWorkspace
        DialogBoxParam msvbvm60, 4031, hParent, AddressOf DlgProc, StrPtr(strPrompt) ' Тот самый заветный код, который вызывает InputBox
    End If
    
    InputBoxW = InputText
    InputText = vbNullString
    TitleText = vbNullString
    DefaultText = vbNullString
End Function
 
' Функция обработки сообщений диалогового окна
Private Function DlgProc(ByVal hwndDlg As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim NotidyCode As Long
    Dim ItemID As Long
    Dim rct As RECT
    Dim hMonitor As Long
    Dim MI As MONITORINFO
    Dim TextLen As Long
    
    Select Case uMsg
        Case WM_INITDIALOG
            If Len(TitleText) = 0 Then TitleText = App.Title
            SetWindowText hwndDlg, StrPtr(TitleText)
            
            ShowWindow GetDlgItem(hwndDlg, ID_HELP), SW_HIDE
            SetDlgItemText hwndDlg, ID_STATIC, lParam
            
            ' Определяем размеры окна
            GetWindowRect hwndDlg, rct
            
            If CenterOnWorkspace = False Then ' Стандартная центровка
                SetWindowPos hwndDlg, 0, ((Screen.Width / Screen.TwipsPerPixelX) - (rct.Right - rct.Left)) / 2, (((Screen.Height / Screen.TwipsPerPixelY) - (rct.Bottom - rct.Top)) / 2) - (rct.Bottom - rct.Top), 0, 0, SWP_NOSIZE Or SWP_NOZORDER
            Else ' Центровка по рабочей области экрана (аналог стиля DS_CENTER)
                hMonitor = MonitorFromWindow(hwndDlg, MONITOR_DEFAULTTONEAREST)
                MI.cbSize = LenB(MI)
                
                If GetMonitorInfo(hMonitor, MI) <> 0 Then
                    SetWindowPos hwndDlg, 0, ((MI.rcWork.Right - MI.rcWork.Left) - (rct.Right - rct.Left)) / 2, ((MI.rcWork.Bottom - MI.rcWork.Top) - (rct.Bottom - rct.Top)) / 2, 0, 0, SWP_NOSIZE Or SWP_NOZORDER
                End If
            End If
            
            If Len(DefaultText) > 0 Then
                SetDlgItemText hwndDlg, ID_EDIT, StrPtr(DefaultText)
                SendDlgItemMessage hwndDlg, ID_EDIT, EM_SETSEL, 0, -1
            End If
            
            DlgProc = 1
            Exit Function
        
        Case WM_COMMAND
            NotidyCode = wParam \ 65536
            ItemID = wParam And 65535
            
            If ItemID = IDOK Then
                TextLen = SendDlgItemMessage(hwndDlg, ID_EDIT, WM_GETTEXTLENGTH, 0, 0)
                InputText = Space$(TextLen)
                GetDlgItemText hwndDlg, ID_EDIT, StrPtr(InputText), TextLen + 1
                
                EndDialog hwndDlg, 0
                DlgProc = 1
                Exit Function
            End If
            
            If ItemID = IDCANCEL Then
                EndDialog hwndDlg, 0
                DlgProc = 1
                Exit Function
            End If
    End Select
    
    DlgProc = 0
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
Option Explicit
Private Declare Function DefWindowProcW Lib "user32" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Const WM_SETTEXT = &HC
 
Private Sub Command1_Click()
    Dim str As String
    
    str = InputBoxW(0, "Китайский язык приветствуется. " & vbNewLine & "Введите китайщину (например " & ChrW(&H4EBA) & "):", "Дружба народов " & ChrW(-29686), True, "Это китайский символ дружбы - " & ChrW(-29686))
    
    If Len(str) > 0 Then
        DefWindowProcW Me.hwnd, WM_SETTEXT, 0, ByVal StrPtr(Chr(34) & str & Chr(34))
    Else
        Me.Caption = "Canceled."
    End If
End Sub
 
Private Sub Command2_Click()
    Dim str As String
    
    str = InputBoxW(hwnd, "Китайский язык приветствуется. " & vbNewLine & "Введите китайщину (например " & ChrW(-29686) & "):")
    
    If Len(str) > 0 Then
        DefWindowProcW Me.hwnd, WM_SETTEXT, 0, ByVal StrPtr(Chr(34) & str & Chr(34))
    Else
        Me.Caption = "Canceled."
    End If
End Sub
 
Private Sub Command3_Click()
    Dim str As String
    
    str = InputBoxW(hwnd, "Китайский язык приветствуется. " & vbNewLine & "Введите китайщину (например " & ChrW(&H4EBA) & "):", "Дружба народов " & ChrW(-29686), True, "Это китайский символ дружбы - " & ChrW(-29686))
    
    If Len(str) > 0 Then
        DefWindowProcW Me.hwnd, WM_SETTEXT, 0, ByVal StrPtr(Chr(34) & str & Chr(34))
    Else
        Me.Caption = "Canceled."
    End If
End Sub
 
Private Sub Command4_Click()
    Dim str As String
    
    str = InputBoxW(hwnd, "Китайский язык приветствуется. " & vbNewLine & "Введите китайщину (например " & ChrW(&H4EBA) & "):", "Дружба народов " & ChrW(-29686), False, "Это китайский символ дружбы - " & ChrW(-29686))
    
    If Len(str) > 0 Then
        DefWindowProcW Me.hwnd, WM_SETTEXT, 0, ByVal StrPtr(Chr(34) & str & Chr(34))
    Else
        Me.Caption = "Canceled."
    End If
End Sub
И сам проект прилагается в ZIP-архиве конечно же :-)
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: zip Юникодный InputBox 2.0.zip (9.8 Кб, 30 просмотров)
3
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
01.02.2024, 02:42
Модуль для вызова юникодного InputBox'а версия 2.5

Новая, усовершенствованная версия модуля. Теперь диалоговое окно InputBoxW вызывается по в точности таким же координатам, как и оригинальная функция InputBox, пиксель-в-пиксель одинаково. Так как была разгадана формула выравнивания диалогового окна инпутбокса, за что большое спасибо The Trick'у. Так же я добавил возможность позиционировать окно по координатам, так же как и в оригинальной функции, плюс добавил возможность подключения файлов справок и кнопки Help, в диалоговом окне. Новый код модуля:

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
Option Explicit
'/////////////////////////////////////////////
'// Модуль для вызова юникодного InputBox'а //
'// Copyright (c) 01.02.2024 by HackerVlad  //
'// e-mail: vladislavpeshkov@yandex.ru      //
'// Версия 2.5                              //
'/////////////////////////////////////////////
 
Private Declare Function DialogBoxParam Lib "user32" Alias "DialogBoxParamW" (ByVal hInstance As Long, ByVal lpTemplate As Long, ByVal hWndParent As Long, ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryW" (ByVal lpLibFileName As Long) As Long
Private Declare Function EndDialog Lib "user32" (ByVal hDlg As Long, ByVal nResult As Long) As Long
Private Declare Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageW" (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SetDlgItemText Lib "user32" Alias "SetDlgItemTextW" (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal lpString As Long) As Long
Private Declare Function GetDlgItemText Lib "user32" Alias "GetDlgItemTextW" (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal lpString As Long, ByVal nMaxCount As Long) As Long
Private Declare Function GetDlgItem Lib "user32" (ByVal hDlg As Long, ByVal nIDDlgItem As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextW" (ByVal hwnd As Long, ByVal lpString As Long) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal CX As Long, ByVal CY As Long, ByVal wFlags As Long) As Long
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, lpvParam As Any, ByVal fuWinIni As Long) As Long
Private Declare Function WinHelp Lib "user32" Alias "WinHelpW" (ByVal hwnd As Long, ByVal lpHelpFile As Long, ByVal wCommand As Long, ByVal dwData As Long) As Long
Private Declare Function HtmlHelp Lib "hhctrl.ocx" Alias "HtmlHelpW" (ByVal hwndCaller As Long, ByVal pszFile As Long, ByVal uCommand As Long, ByVal dwData As Long) As Long
 
Private Const IDOK = 1
Private Const IDCANCEL = 2
Private Const ID_EDIT = 4900
Private Const ID_STATIC = 4901
Private Const ID_HELP = 4902
Private Const WM_COMMAND = &H111
Private Const WM_INITDIALOG = &H110
Private Const WM_HELP = &H53
Private Const WM_DESTROY = &H2
 
Private Const SW_HIDE = 0
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOZORDER = &H4
Private Const WM_GETTEXTLENGTH As Long = &HE
Private Const EM_SETSEL = &HB1
Private Const SPI_GETWORKAREA = 48
Private Const HH_DISPLAY_TOPIC = &H0
Private Const HH_HELP_CONTEXT = &HF
Private Const HELP_CONTEXT = &H1
Private Const HELP_INDEX = &H3
Private Const HELP_QUIT = &H2
 
Private Type RECT
    iLeft As Long
    iTop As Long
    iRight As Long
    iBottom As Long
End Type
 
Dim sInputText As String
Dim sTitleText As String
Dim sDefaultText As String
Dim CenterOnWorkspace As Boolean ' Аналог DS_CENTER
Dim iXPos As Integer
Dim iYPos As Integer
Dim sHelpFile As String
Dim lContext As Long
Dim IsWinHelpRunning As Boolean
 
' Вызвать InputBox из msvbvm60.dll с поддеркой юникода
Public Function InputBoxW(ByVal hParent As Long, ByVal strPrompt As String, Optional ByVal strTitle As String, Optional ByVal strDefault As String, Optional intXPos As Integer, Optional intYPos As Integer, Optional strHelpFile As String, Optional intContext As Long, Optional CenterOnMonitorWorkspace As Boolean) As String
    Dim msvbvm60 As Long
    
    msvbvm60 = LoadLibrary(StrPtr("msvbvm60.dll"))
    
    If msvbvm60 <> 0 Then
        sTitleText = strTitle
        sDefaultText = strDefault
        CenterOnWorkspace = CenterOnMonitorWorkspace
        iXPos = intXPos
        iYPos = intYPos
        sHelpFile = strHelpFile
        lContext = intContext
        IsWinHelpRunning = False
        
        DialogBoxParam msvbvm60, 4031, hParent, AddressOf DlgProc, StrPtr(strPrompt) ' Тот самый заветный код, который вызывает InputBox
    End If
    
    InputBoxW = sInputText
    sInputText = vbNullString
    sTitleText = vbNullString
    sDefaultText = vbNullString
    sHelpFile = vbNullString
End Function
 
' Функция обработки сообщений диалогового окна
Private Function DlgProc(ByVal hwndDlg As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim NotifyCode As Long
    Dim ItemID As Long
    Dim wndRect As RECT
    Dim rcWork As RECT
    Dim TextLen As Long
    Dim lLeft As Long
    Dim lTop As Long
    
    Select Case uMsg
        Case WM_INITDIALOG
            If Len(sTitleText) = 0 Then sTitleText = App.Title
            SetWindowText hwndDlg, StrPtr(sTitleText)
            
            If Len(sHelpFile) = 0 Then
                ShowWindow GetDlgItem(hwndDlg, ID_HELP), SW_HIDE
            End If
            
            SetDlgItemText hwndDlg, ID_STATIC, lParam
            
            ' Определяем размеры окна
            GetWindowRect hwndDlg, wndRect
            
            ' Определяем размеры рабочей области экрана
            SystemParametersInfo SPI_GETWORKAREA, 0, rcWork, 0
            
            If CenterOnWorkspace = False Then ' Стандартная центровка
                If (iXPos Or iYPos) = 0 Then
                    ' Абсолютно идеальный код выравнивания диалогового окна, в точности так же, как это делает оригинальный InputBox
                    lLeft = rcWork.iLeft + (rcWork.iRight - rcWork.iLeft - (wndRect.iRight - wndRect.iLeft)) \ 2
                    lTop = rcWork.iTop + (rcWork.iBottom - rcWork.iTop - (wndRect.iBottom - wndRect.iTop)) \ 3
                Else
                    lLeft = iXPos
                    lTop = iYPos
                End If
            Else ' Центровка по рабочей области экрана (аналог стиля DS_CENTER)
                lLeft = ((rcWork.iRight - rcWork.iLeft) - (wndRect.iRight - wndRect.iLeft)) / 2
                lTop = ((rcWork.iBottom - rcWork.iTop) - (wndRect.iBottom - wndRect.iTop)) / 2
            End If
            
            SetWindowPos hwndDlg, 0, lLeft, lTop, 0, 0, SWP_NOSIZE Or SWP_NOZORDER ' Выравнивание диалогового окна
            
            If Len(sDefaultText) > 0 Then
                SetDlgItemText hwndDlg, ID_EDIT, StrPtr(sDefaultText)
                SendDlgItemMessage hwndDlg, ID_EDIT, EM_SETSEL, 0, -1
            End If
            
            DlgProc = 1
            Exit Function
        
        Case WM_COMMAND
            NotifyCode = wParam \ 65536
            ItemID = wParam And 65535
            
            If ItemID = IDOK Then
                TextLen = SendDlgItemMessage(hwndDlg, ID_EDIT, WM_GETTEXTLENGTH, 0, 0)
                sInputText = Space$(TextLen)
                GetDlgItemText hwndDlg, ID_EDIT, StrPtr(sInputText), TextLen + 1
                
                EndDialog hwndDlg, 0
                DlgProc = 1
                Exit Function
            End If
            
            If ItemID = IDCANCEL Then
                EndDialog hwndDlg, 0
                DlgProc = 1
                Exit Function
            End If
            
            If ItemID = ID_HELP Then
                RunHelp hwndDlg
                DlgProc = 1
                Exit Function
            End If
        
        Case WM_HELP
            RunHelp hwndDlg
            DlgProc = 1
            Exit Function
        
        Case WM_DESTROY
            If IsWinHelpRunning = True Then
                WinHelp hwndDlg, 0, HELP_QUIT, 0 ' Закрыть окно HLP справки
            End If
            
            DlgProc = 1
            Exit Function
    End Select
    
    DlgProc = 0
End Function
 
Private Sub RunHelp(ByVal hwnd As Long)
    If Len(sHelpFile) > 0 Then
        If Right$(sHelpFile, 4) = ".hlp" Then
            If lContext = 0 Then
                WinHelp hwnd, StrPtr(sHelpFile), HELP_INDEX, 0
            Else
                WinHelp hwnd, StrPtr(sHelpFile), HELP_CONTEXT, lContext
            End If
            IsWinHelpRunning = True
        Else ' CHM
            If lContext = 0 Then
                HtmlHelp hwnd, StrPtr(sHelpFile), HH_DISPLAY_TOPIC, 0
            Else
                HtmlHelp hwnd, StrPtr(sHelpFile), HH_HELP_CONTEXT, lContext
            End If
        End If
    End If
End Sub
Вложения
Тип файла: zip Юникодный InputBox 2.5.zip (654.1 Кб, 25 просмотров)
3
 Аватар для Mikle Quits
758 / 277 / 14
Регистрация: 21.01.2023
Сообщений: 385
29.02.2024, 14:51
Синтез звука струны. Эмуляция физики процесса.

Представим, что струна - это цепочка массивных звеньев, связанных пружинками и закреплённых за два конца. Попробуем вносить в равновесную позицию струны некоторые возмущения и вычислять дальнейшие состояния струны с помощью численного интегрирования. Зададим самые простые законы упругости, когда сила, действующая на звено, пропорциональна смещению этого звена относительно среднеарифметической позиции двух соседей. Так же она пропорциональна силе натяжения струны. При интегрировании скорость - это интеграл ускорения, а ускорение пропорционально силе и обратно пропорционально массе звена. Для оптимизации силу натяжения можно заранее разделить на массу, эти величины постоянны.
Зададим массивы для хранения состояний звеньев:
Visual Basic
1
2
3
Dim FdM()  As Single  'сила натяжения, делённая на массу
Dim P()    As Single  'позиция
Dim S()    As Single  'скорость
Исходя из вышесказанного, скорость будет рассчитываться так:
Visual Basic
1
2
3
4
  For i = 1 To stLen - 1
    d = (P(i - 1) + P(i + 1)) * 0.5 - P(i)
    S(i) = S(i) + d * FdM(i)
  Next i
Здесь stLen - длина струны (кол-во звеньев)
А позиция - это интеграл скорости, считаем так:
Visual Basic
1
2
3
  For i = 1 To stLen - 1
    P(i) = P(i) + S(i)
  Next i
Теперь нам нужно ввести потери энергии колебаний, иначе струна будет колебаться вечно, назовём их "вязкость":
Visual Basic
1
2
3
  For i = 1 To stLen - 1
    S(i) = S(i) * k1 + (S(i - 1) + S(i + 1)) * k2
  Next i
Здесь два коэффициента, k1 и k2.
k1 совсем немного меньше единицы, скорость звена в каждом тике немного уменьшается. При таком расчёте струна, как и положено, затухает по экспоненте, но её тембр не меняется. Реальная же струна после удара звучит звонко, а дольше, по мере затихания, всё глуше, это от того, что струна, даже не натянутая, обладает упругостью, то есть стремится выпрямиться, и делает это тоже с потерей энергии. Это имитирует коэффициент k2, который немного больше нуля.

Во вложении реализация этого алгоритма с небольшими добавлениями:
- в массы звеньев вносится рэндомная погрешность, это придаёт звуку неидеальность, живость. Но, если слишком задрать эту поправку, звук станет "колокольным" и может немного фальшивить.
- введена вероятность дребезга струны (о лады в случае гитары), как будто струну слишком сильно дёрнули. В небольших кол-вах это тоже придаёт живости.

Если мы хотим задавать не силу натяжения и длину струны, а непосредственно ноты, вычислить параметры для конкретной ноты можно так (этой функции нет во вложении):

Кликните здесь для просмотра всего текста
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
Public Sub StSetNote(ByVal n As Long, Optional ByVal kDemp As Single = 0.005, Optional ByVal kHard As Single = 0.7, Optional ByVal kRattle As Single = 0)
  Dim s As Single, L As Long, Exp As Single, Frc As Single
 
  Exp = 2 ^ (n / 12)
  Frc = 0.375 * ((n / 20) + 1)
  s = 378.3 * Sqr(Frc) / Exp
  stLen = Int(s) + 1
  Frc = Frc * ((stLen - 1) / s) * ((stLen - 1) / s)
  k1 = 1 - 0.05 * Frc / (n + 12)
  k2 = (1 - k1) * 0.5
  StStart stLen, Frc, kDemp, stLen * 0.001, kHard, kRattle
End Sub

Нота "n" задаётся от 0 до 60 (от "ми" контроктавы до "ми" 3-й октавы)
Значения по умолчанию kDemp, kHard и kSlap примерно соответствуют обычной гитаре-басгитаре. Меняя kDemp можно добиться звука от жёстких стальных струн через нейлон до "muted" или "pizzicato".

Приложенный архив содержит код на VB6 и готовый EXE. Тестовая программа формирует четырёхсекундный фрагмент звука струны по заданным параметрам, воспроизводит этот звук и сохраняет его в WAV файл в текущей папке.
Вложения
Тип файла: zip String.zip (11.8 Кб, 37 просмотров)
7
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
29.04.2024, 23:05
Модуль для вызова диалога выбора файлов

Написал модуль для вызова стандартного диалога выбора файлов для отображения окошка Открыть или Сохранить. Примечательно, что при открытии файлов можно выбирать сразу несколько файлов. А так же диалоговое окошко отображается в новом красивом стиле и при этом полностью совместима со старым 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
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
Option Explicit
'/////////////////////////////////////////////
'// Модуль для вызова диалога выбора файлов //
'// Copyright (c) 29.04.2024 by HackerVlad  //
'// e-mail: vladislavpeshkov@yandex.ru      //
'// Версия 1.0                              //
'/////////////////////////////////////////////
 
Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameW" (ByVal pOpenfilename As Long) As Long
Private Declare Function GetSaveFileName Lib "comdlg32.dll" Alias "GetSaveFileNameW" (ByVal pOpenfilename As Long) As Long
 
Private Const OFN_ALLOWMULTISELECT = &H200
Private Const OFN_EXPLORER = &H80000
Private Const OFN_FILEMUSTEXIST = &H1000
Private Const OFN_EXTENSIONDIFFERENT = &H400
Private Const OFN_LONGNAMES = &H200000
Private Const OFN_NOCHANGEDIR = &H8
Private Const OFN_NODEREFERENCELINKS = &H100000
Private Const OFN_OVERWRITEPROMPT = &H2
Private Const OFN_SHAREAWARE = &H4000
 
Private Type OPENFILENAME
    lStructSize As Long
    hwndOwner As Long
    hInstance As Long
    lpstrFilter As String
    lpstrCustomFilter As String
    nMaxCustFilter As Long
    nFilterIndex As Long
    lpstrFile As String
    nMaxFile As Long
    lpstrFileTitle As String
    nMaxFileTitle As Long
    lpstrInitialDir As String
    lpstrTitle As String
    flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    lpstrDefExt As String
    lCustData As Long
    lpfnHook As Long
    lpTemplateName As String
End Type
 
Public Enum OpenFileEnum
    OFEOpenForLoad = 1
    OFEOpenForSave = 2
End Enum
 
' Диалог выбора файлов (открыть или сохранить)
Public Function MyGetFileName(OpenMode As OpenFileEnum, DirStr As String, FileNameStr() As String, FilterMass() As String, Optional FileExt As String = "", Optional hwndOwnerArg As Long = 0, Optional ByVal DialogTitle As String) As Boolean
    Dim pOpenfilename As OPENFILENAME
    Dim N As Integer
    Dim i As Integer
    Dim x As Long
    Dim St1 As String
    Dim St2 As String
    Dim St3 As String
    
    pOpenfilename.lStructSize = Len(pOpenfilename)
    pOpenfilename.hwndOwner = hwndOwnerArg
    
    If Len(DialogTitle) > 0 Then
        pOpenfilename.lpstrTitle = DialogTitle
    End If
    
    If UBound(FilterMass, 1) = 1 Then
        N = UBound(FilterMass, 2)
        
        If N >= 0 Then
            For i = 0 To N
                If Len(FilterMass(1, i)) > 1 Then
                    If Len(FilterMass(0, i)) > 1 Then
                        St1 = St1 & (FilterMass(0, i) + vbNullChar)
                    Else
                        St1 = St1 & ("Разные файлы" + vbNullChar)
                    End If
                    
                    St1 = St1 & (FilterMass(1, i) + vbNullChar)
                End If
            Next
            
            St1 = St1 & vbNullChar & vbNullChar
        Else
            St1 = "Все файлы" & vbNullChar & "*.*" & vbNullChar & vbNullChar
        End If
    End If
    
    If FileExt <> "" Then
        pOpenfilename.lpstrDefExt = FileExt
    End If
    
    pOpenfilename.lpstrInitialDir = DirStr
    pOpenfilename.lpstrFilter = St1
    pOpenfilename.lpstrFile = LPBuff(512)
    pOpenfilename.nMaxFile = 511
    pOpenfilename.lpstrFileTitle = LPBuff(512)
    pOpenfilename.nMaxFileTitle = 511
    pOpenfilename.flags = OFN_SHAREAWARE Or OFN_LONGNAMES Or OFN_NODEREFERENCELINKS Or OFN_EXPLORER
    
    If OpenMode = OFEOpenForLoad Then
        pOpenfilename.flags = pOpenfilename.flags Or OFN_ALLOWMULTISELECT
        x = GetOpenFileName(VarPtr(pOpenfilename))
    Else
        pOpenfilename.flags = pOpenfilename.flags Or OFN_OVERWRITEPROMPT
        x = GetSaveFileName(VarPtr(pOpenfilename))
    End If
    
    If x = 1 Then
        MyGetFileName = True
        St1 = LP2VB2(pOpenfilename.lpstrFile)
        DirStr = Left(St1, pOpenfilename.nFileOffset - 1)
        N = -1
        St2 = St1
        
        Do
            St3 = MyGetLpStr(St2)
            N = N + 1
        Loop Until St2 = ""
        
        If N >= 1 Then
            ReDim FileNameStr(N - 1)
            St2 = St1
            St3 = MyGetLpStr(St2)
            
            For i = 1 To N
                FileNameStr(i - 1) = MyGetLpStr(St2)
            Next
        Else
            ReDim FileNameStr(0)
            FileNameStr(0) = Right$(St1, Len(St1) - pOpenfilename.nFileOffset)
        End If
    Else
        MyGetFileName = False
        DirStr = ""
        ReDim FileNameStr(0)
        FileNameStr(0) = ""
        '  ResErr = CommDlgExtendedError
        '  Debug.Print ResErr
    End If
End Function
 
Private Function LPBuff(N As Integer) As String
    LPBuff = String(N, vbNullChar)
End Function
 
Private Function LP2VB2(St1) As String
    LP2VB2 = Left$(St1, InStr(1, St1, vbNullChar & vbNullChar) - 1)
End Function
 
Private Function MyGetLpStr(St1 As String) As String
Dim i As Variant
i = InStr(1, St1, vbNullChar)
If IsNull(i) Then
  MyGetLpStr = ""
  St1 = ""
  Exit Function
ElseIf i = 0 Then
  MyGetLpStr = St1
  St1 = ""
  Exit Function
Else
  MyGetLpStr = Left$(St1, i - 1)
  St1 = Right$(St1, Len(St1) - i)
  Exit Function
End If
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
Option Explicit
Private Declare Function DrawText Lib "user32" Alias "DrawTextW" (ByVal hdc As Long, ByVal lpStr As Long, ByVal nCount As Long, lpRect As RECT, ByVal wFormat As Long) As Long
 
Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
 
Private Const DT_WORDBREAK = &H10
 
Private Sub Command1_Click()
    Dim BrowseFilePath As String
    Dim Flname() As String
    Dim Flt1() As String
    Dim i As Long
    
    ReDim Flname(0) As String
    ReDim Flt(1, 1) As String
    
    Flt(0, 0) = "Файлы картинок"
    Flt(1, 0) = "*.jpg; *.png"
    
    Flt(0, 1) = "Файлы видео"
    Flt(1, 1) = "*.avi; *.mkv"
    
    If MyGetFileName(OFEOpenForLoad, BrowseFilePath, Flname(), Flt(), , hWnd, "Открыть файл(ы)") = True Then
        Dim PrintText As String
        Dim myRect As RECT
        
        myRect.Left = 0
        myRect.Top = 0
        myRect.Right = Me.Width
        myRect.Bottom = Me.Height
        
        Me.Cls
        
        For i = 0 To UBound(Flname)
            PrintText = i + 1 & ". " & Chr(34) & BrowseFilePath + "\" & Flname(i) & Chr(34)
            DrawText Me.hdc, StrPtr(PrintText), Len(PrintText), myRect, DT_WORDBREAK
            
            myRect.Top = myRect.Top + 16
        Next
        
        Me.Refresh
    End If
End Sub
 
Private Sub Command2_Click()
    Dim BrowseFilePath As String
    Dim Flname() As String
    Dim Flt1() As String
    Dim i As Long
    
    ReDim Flname(0) As String
    ReDim Flt(0, 0) As String
    
    BrowseFilePath = App.Path
    
    If MyGetFileName(OFEOpenForLoad, BrowseFilePath, Flname(), Flt(), , hWnd) = True Then
        Dim PrintText As String
        Dim myRect As RECT
        
        myRect.Left = 0
        myRect.Top = 0
        myRect.Right = Me.Width
        myRect.Bottom = Me.Height
        
        Me.Cls
        
        For i = 0 To UBound(Flname)
            PrintText = i + 1 & ". " & BrowseFilePath + "\" & Flname(i)
            DrawText Me.hdc, StrPtr(PrintText), Len(PrintText), myRect, DT_WORDBREAK
            
            myRect.Top = myRect.Top + 16
        Next
        
        Me.Refresh
    End If
End Sub
 
Private Sub Command3_Click()
    Dim BrowseFilePath As String
    Dim Flname() As String
    Dim Flt1() As String
    Dim i As Long
    
    ReDim Flname(0) As String
    ReDim Flt(1, 0) As String
    
    Flt(0, 0) = "Файлы картинок"
    Flt(1, 0) = "*.jpg"
    
    If MyGetFileName(OFEOpenForSave, BrowseFilePath, Flname(), Flt(), , hWnd) = True Then
        Dim PrintText As String
        Dim myRect As RECT
        
        myRect.Left = 0
        myRect.Top = 0
        myRect.Right = Me.Width
        myRect.Bottom = Me.Height
        
        Me.Cls
        
        For i = 0 To UBound(Flname)
            PrintText = i + 1 & ". " & BrowseFilePath + "\" & Flname(i)
            DrawText Me.hdc, StrPtr(PrintText), Len(PrintText), myRect, DT_WORDBREAK
            
            myRect.Top = myRect.Top + 16
        Next
        
        Me.Refresh
    End If
End Sub
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0   Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: zip Диалог выбора файлов.zip (10.7 Кб, 39 просмотров)
5
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
02.05.2024, 21:31
Модуль для вызова диалога выбора файлов версия 2.0

Представляю Вашему вниманию новую, усовершенствованную версию модуля для вызова диалога выбора файлов. Версия 2.0 - это значительно улучшенная версия модуля. Этот модуль весь целиком и полностью написал я сам. Строк кода стало значительно меньше.

Новые возможности модуля:

1. Теперь стало можно в функции выбирать включать или не включать множественный выбор файлов (AllowMultiSelect)
2. Массив, который наполняется именами файлов, arrFiles теперь для удобства стал необязательным параметром
3. Увеличен буфер nMaxFile до 65535 по максимуму, чтобы можно было выбирать сразу несколько тысяч файлов, но к сожалению сам по себе диалог, имеет внутреннее ограничение на количество выделенных файлов, и прям очень много, тысяч 10 файлов, выделить не получится, но тысячи 2-3 осилит...
4. InitDir теперь необязательный параметр, это папка старта по умолчанию
5. Фильтр масок файлов теперь задаётся через строку (так гораздо удобнее!), в которой идут разделители vbNullChar, а не через массивы как раньше

Код модуля (теперь строк стало меньше!!!):

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
Option Explicit
'/////////////////////////////////////////////
'// Модуль для вызова диалога выбора файлов //
'// Copyright (c) 02.05.2024 by HackerVlad  //
'// e-mail: vladislavpeshkov@yandex.ru      //
'// Версия 2.0                              //
'/////////////////////////////////////////////
 
Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameW" (ByVal pOpenfilename As Long) As Long
Private Declare Function GetSaveFileName Lib "comdlg32.dll" Alias "GetSaveFileNameW" (ByVal pOpenfilename As Long) As Long
 
Private Const OFN_ALLOWMULTISELECT = &H200
Private Const OFN_EXPLORER = &H80000
Private Const OFN_LONGNAMES = &H200000
Private Const OFN_NODEREFERENCELINKS = &H100000
Private Const OFN_OVERWRITEPROMPT = &H2
Private Const OFN_SHAREAWARE = &H4000
 
Private Type OPENFILENAME
    lStructSize As Long
    hwndOwner As Long
    hInstance As Long
    lpstrFilter As String
    lpstrCustomFilter As String
    nMaxCustFilter As Long
    nFilterIndex As Long
    lpstrFile As String
    nMaxFile As Long
    lpstrFileTitle As String
    nMaxFileTitle As Long
    lpstrInitialDir As String
    lpstrTitle As String
    flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    lpstrDefExt As String
    lCustData As Long
    lpfnHook As Long
    lpTemplateName As String
End Type
 
Public Enum OpenFileEnum
    OFEOpenForLoad = 1
    OFEOpenForSave = 2
End Enum
 
' Функция диалога выбора файлов (открыть или сохранить) возвращает путь ВСЕГДА без косой черты на конце
' Массив arrFiles является необязательным параметром и используется только при выборе множества файлов
Public Function GetDialogFileName(OpenMode As OpenFileEnum, ByVal strFilter As String, Optional ByVal hwndOwner As Long, Optional ByVal InitDir As String, Optional ByVal DialogTitle As String, Optional ByVal AllowMultiSelect As Boolean, Optional arrFiles As Variant) As String
    Dim ofn As OPENFILENAME
    Dim str As String
    Dim ret As Long
    Dim i As Long
    
    ofn.nMaxFile = 65535 ' Размер буфера, на который указывает lpstrFile, в символах. Буфер должен быть достаточно большим, чтобы хранить строку или строки пути и имени файла, включая завершающий символ NULL.
    ofn.hwndOwner = hwndOwner
    If Len(DialogTitle) > 0 Then ofn.lpstrTitle = DialogTitle
    ofn.lpstrFile = Space$(65535)
    ofn.lStructSize = LenB(ofn)
    ofn.lpstrFilter = strFilter
    If Len(InitDir) > 0 Then ofn.lpstrInitialDir = InitDir
    ofn.flags = OFN_SHAREAWARE Or OFN_LONGNAMES Or OFN_NODEREFERENCELINKS Or OFN_EXPLORER
    
    If OpenMode = OFEOpenForLoad Then
        If AllowMultiSelect = True Then ofn.flags = ofn.flags Or OFN_ALLOWMULTISELECT
        ret = GetOpenFileName(VarPtr(ofn))
    Else
        ofn.flags = ofn.flags Or OFN_OVERWRITEPROMPT
        ret = GetSaveFileName(VarPtr(ofn))
    End If
    
    If ret <> 0 Then
        If AllowMultiSelect = True And OpenMode = OFEOpenForLoad Then
            i = InStr(1, ofn.lpstrFile, vbNullChar & vbNullChar)
            If i Then ofn.lpstrFile = Left$(ofn.lpstrFile, i - 1)
            
            str = Left$(ofn.lpstrFile, ofn.nFileOffset - 1)
            
            ofn.lpstrFile = Right$(ofn.lpstrFile, Len(ofn.lpstrFile) - ofn.nFileOffset)
            arrFiles = Split(ofn.lpstrFile, vbNullChar)
            
            If Right$(str, 1) <> "\" Then
                GetDialogFileName = str
            Else
                GetDialogFileName = Left$(str, Len(str) - 1)
            End If
        Else
            i = InStr(1, ofn.lpstrFile, vbNullChar)
            If i Then GetDialogFileName = Left$(ofn.lpstrFile, i - 1)
        End If
    End If
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
Option Explicit
Private Declare Function DrawText Lib "user32" Alias "DrawTextW" (ByVal hdc As Long, ByVal lpStr As Long, ByVal nCount As Long, lpRect As RECT, ByVal wFormat As Long) As Long
 
Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
 
Private Const DT_WORDBREAK = &H10
 
Private Sub Command1_Click()
    Dim ArrayFiles() As String
    Dim strFileName As String
    
    strFileName = GetDialogFileName(OFEOpenForLoad, "Все файлы" & vbNullChar & "*.*" & vbNullChar & vbNullChar, hWnd, , "Открыть любой файл(ы)", True, ArrayFiles)
    
    If Len(strFileName) > 0 Then
        MsgBox Chr(34) & strFileName & Chr(34), vbInformation
        
        Dim PrintText As String
        Dim myRect As RECT
        Dim i As Long
        
        myRect.Left = 0
        myRect.Top = 0
        myRect.Right = Me.Width
        myRect.Bottom = Me.Height
        
        Me.Cls
        
        For i = 0 To UBound(ArrayFiles)
            PrintText = i + 1 & ". " & Chr(34) & strFileName + "\" & ArrayFiles(i) & Chr(34)
            DrawText Me.hdc, StrPtr(PrintText), Len(PrintText), myRect, DT_WORDBREAK
            
            myRect.Top = myRect.Top + 16
        Next
        
        Me.Refresh
    End If
End Sub
 
Private Sub Command2_Click()
    Dim strFileName As String
    
    strFileName = GetDialogFileName(OFEOpenForLoad, "Музыкальные файлы" & vbNullChar & "*.mp3;.wav;*.ac3;*.flac" & vbNullChar & _
    "Все файлы" & vbNullChar & "*.*" & vbNullChar & vbNullChar, hWnd, App.Path)
    
    If Len(strFileName) > 0 Then
        MsgBox Chr(34) & strFileName & Chr(34), vbInformation
    End If
End Sub
 
Private Sub Command3_Click()
    Dim strFileName As String
    
    strFileName = GetDialogFileName(OFEOpenForSave, "Все файлы" & vbNullChar & "*.*" & vbNullChar & vbNullChar, hWnd)
    
    If Len(strFileName) > 0 Then
        MsgBox Chr(34) & strFileName & Chr(34), vbInformation
    End If
End Sub
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0   Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: zip Диалог выбора файлов 2.0.zip (9.2 Кб, 44 просмотров)
3
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
14.05.2024, 18:43
Модуль вывода текста на форме в юникоде

Я недавно узнал, что есть такая API-функция TextOutW которая позволяет с лёгкостью выводить юникодные надписи на форму. Мне эта функция понравилась больше, чем привычная мне DrawTextW так как она легче в исполнении и не нужно прописывать все координаты региона. Этой функцией можно написать текст всего в одну строку кода вообще, без предварительного заполнения структуры региона. Так вот я решил использовать эту функцию, чтобы сделать замену привычного Print для рисования текста на форме. Я сделал функцию PrintW чтобы теперь ещё и поддерживался юникод! Это очень полезно и часто бывает нужно (в основном в качестве отладки) выводить текст на форме, с поддержкой юникода.

Каждый новый вызов функции PrintW переводит строчку на следующею позицию на форме, в зависимости от размера шрифта, тут мне помогает функция GetTextExtentPoint32.

Итак вот код модуля с функцией PrintW:

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
Option Explicit
'/////////////////////////////////////////////
'// Модуль вывода текста на форме в юникоде //
'// Copyright (c) 14.05.2024 by HackerVlad  //
'// e-mail: vladislavpeshkov@yandex.ru      //
'// Версия 2.0                              //
'/////////////////////////////////////////////
 
' Декларации API...
Private Declare Function TextOut Lib "gdi32" Alias "TextOutW" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As Long, ByVal nCount As Long) As Long
Private Declare Function GetTextExtentPoint32 Lib "gdi32" Alias "GetTextExtentPoint32W" (ByVal hDC As Long, ByVal lpsz As Long, ByVal cbString As Long, lpSize As POINTAPI) As Long
Private Declare Function SafeArrayGetDim Lib "oleaut32.dll" (arr() As Any) As Long
 
' Типы...
Private Type POINTAPI
   x As Long
   y As Long
End Type
 
Dim PlusY() As Long
Dim PlusHwnds() As Long
 
' Напечатать на форме текст
Public Function PrintW(PrintText As String, Optional PrintForm As Object) As Boolean
    Dim Frms As Form
    Dim hDC As Long
    Dim hwnd As Long
    Dim pt As POINTAPI
    Dim Redraw As Boolean
    Dim i As Long
    Dim Founded As Boolean
    Dim plus As Long
    
    If PrintForm Is Nothing Then
        For Each Frms In Forms
            hDC = Frms.hDC
            hwnd = Frms.hwnd
            Redraw = Frms.AutoRedraw
            Frms.AutoRedraw = True
            Exit For ' Выбирать всегда первую форму
        Next
    Else
        hDC = PrintForm.hDC
        hwnd = PrintForm.hwnd
        Redraw = PrintForm.AutoRedraw
        PrintForm.AutoRedraw = True
    End If
    
    GetTextExtentPoint32 hDC, StrPtr(PrintText), Len(PrintText), pt
    
    If SafeArrayGetDim(PlusY) > 0 Then ' Если наполнен массив
        For i = 0 To UBound(PlusHwnds)
            If PlusHwnds(i) = hwnd Then
                plus = PlusY(i)
                PlusY(i) = PlusY(i) + pt.y
                
                Founded = True
                Exit For
            End If
        Next
        
        If Founded = False Then
            ReDim Preserve PlusHwnds(UBound(PlusHwnds) + 1)
            ReDim Preserve PlusY(UBound(PlusY) + 1)
            
            PlusHwnds(UBound(PlusHwnds)) = hwnd
            PlusY(UBound(PlusY)) = pt.y
        End If
    Else
        ReDim Preserve PlusY(0)
        ReDim Preserve PlusHwnds(0)
        
        PlusY(0) = pt.y
        PlusHwnds(0) = hwnd
    End If
    
    TextOut hDC, 0, plus, StrPtr(PrintText), Len(PrintText)
    
    If PrintForm Is Nothing Then
        If Redraw = True Then Frms.Refresh
        Frms.AutoRedraw = Redraw
    Else
        If Redraw = True Then PrintForm.Refresh
        PrintForm.AutoRedraw = Redraw
    End If
    
    PrintW = True
End Function
 
' Очистить форму
Public Sub ClsW(Optional PrintForm As Object)
    Dim Frms As Form
    Dim hwnd As Long
    Dim i As Long
    
    If PrintForm Is Nothing Then
        For Each Frms In Forms
            Frms.Cls
            hwnd = Frms.hwnd
            Exit For ' Выбирать всегда первую форму
        Next
    Else
        PrintForm.Cls
        hwnd = PrintForm.hwnd
    End If
    
    If SafeArrayGetDim(PlusHwnds) > 0 Then ' Если наполнен массив
        For i = 0 To UBound(PlusHwnds)
            If PlusHwnds(i) = hwnd Then
                PlusY(i) = 0
                Exit For
            End If
        Next
    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
Option Explicit
 
Private Sub Command1_Click()
    PrintW ChrW(&H88E7) & "1234567890 1234567890 1234567890 1234567890"
End Sub
 
Private Sub Command2_Click()
    Print ChrW(&H88E7) & "1234567890 1234567890 1234567890 1234567890"
End Sub
 
Private Sub Command3_Click()
    Cls
End Sub
 
Private Sub Command4_Click()
    Refresh
End Sub
 
Private Sub Command5_Click()
    ClsW
End Sub
 
Private Sub Command6_Click()
    Form2.Show
End Sub


Развернуть код второй формы...
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Option Explicit
 
Private Sub Command1_Click()
    PrintW "1234567890" & ChrW(&H88E7), Me
End Sub
 
Private Sub Command2_Click()
    ClsW
End Sub
 
Private Sub Command3_Click()
    ClsW Form2
End Sub
 
Private Sub Command4_Click()
    PrintW "123", Form1
End Sub
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: zip Вывод текста на форме 2.0.zip (9.6 Кб, 35 просмотров)
4
 Аватар для Mikle Quits
758 / 277 / 14
Регистрация: 21.01.2023
Сообщений: 385
29.05.2024, 11:51
Быстрый поиск простых чисел.

Используя одно ядро среднестатистического современного процессора, программа находит все простые числа до 2 000 000 000 менее, чем за 2 секунды, решения быстрее я пока не встречал.
Программа использует модернизированный вариант метода "Решето Эратосфена".
В программе создаётся маска на 15015 чисел. 15015 - это 3*5*7*11*13. Здесь нет множителя "2", почему? Потому, что мы ищем числа только среди нечётных. Таким образом мы проходим по натуральным числам шагами по 30030, но сразу с пропуском чётных чисел.
Байтовый массив Mask() содержит нули на месте простых чисел и единицы на месте остальных.
На каждом следующем шаге мы задаём в переменной Base базу, от которой отмечаем простые числа в массиве Out(). Сначала Base = 1, потом 30031 и т. д. В массив Out() копируется массив Mask(), таким образом мы сразу отмечаем заведомо НЕ простые числа, потом оставшиеся числа проверяются на делимость на простые числа от 17 до Sqr(Base + 30030). Все не прошедшие проверку считаем простыми.

Приложенная программа может сохранять найденные числа в виде бинарного файла, это уже немного дольше.
Вложения
Тип файла: zip Simple.zip (7.8 Кб, 26 просмотров)
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
01.06.2024, 18:21
Функция которая подсчитывает количество определённых символов либо подстрок в одной большой строке:

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
' Количество найденных символов (либо подстрок) в строке
Public Function CountSymbolFromString(ByVal str As String, ByVal SearchSymbol As String) As Long
    Dim FirstSearch As Long
    Dim SearchFromTheSymbol As Long
    Dim cnt As Long
    Dim LenSearchSymbol As Long
    
    LenSearchSymbol = Len(SearchSymbol)
    SearchFromTheSymbol = 1
    
    If Len(str) > 0 And Len(SearchSymbol) > 0 Then
        ' Очень быстрый поиск подстрок в строке
        Do
            FirstSearch = InStr(SearchFromTheSymbol, str, SearchSymbol) ' Искать нужную нам подстроку
            If FirstSearch > 0 Then
                cnt = cnt + 1
                SearchFromTheSymbol = FirstSearch + LenSearchSymbol
            End If
        Loop While FirstSearch > 0 ' Выполнять цикл до тех пор, пока будет найдена искомая подстрока
    End If
    
    CountSymbolFromString = cnt
End Function
1
Модератор
10046 / 3892 / 883
Регистрация: 22.02.2013
Сообщений: 5,844
Записей в блоге: 79
27.06.2024, 23:00
Патчинг кодогенерации __vbaSetSystemError

Как известно любая API функция объявленная через Declare генерирует вызов функции __vbaSetSystemError которая задает свойство Err.LastDllError. Иногда может быть полезно избежать генерацию этого кода для производительности либо других целей. Для того чтобы сделать это необходимо пропатчить функцию кодогенератора EXMGR::ProcessSystemError:



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
Option Explicit
 
Private Enum PTR
    [_]
End Enum
 
Private Const PAGE_EXECUTE_READWRITE  As Long = &H40&
 
Private Declare Function GetModuleHandle Lib "kernel32" _
                         Alias "GetModuleHandleW" ( _
                         ByVal lpModuleName As PTR) As PTR
Private Declare Function VirtualProtect Lib "kernel32" ( _
                         ByVal lpAddress As Long, _
                         ByVal dwSize As Long, _
                         ByVal flNewProtect As Long, _
                         ByRef lpflOldProtect As Long) As Long
Private Declare Sub GetMem4 Lib "msvbvm60" ( _
                    ByRef pAddr As Any, _
                    ByRef pDst As Any)
Private Declare Sub GetMemPtr Lib "msvbvm60" _
                    Alias "GetMem4" ( _
                    ByRef pAddr As Any, _
                    ByRef pDst As Any)
Private Declare Sub GetMem8 Lib "msvbvm60" ( _
                    ByRef pAddr As Any, _
                    ByRef pDst As Any)
Private Declare Sub PutMemPtr Lib "msvbvm60" _
                    Alias "PutMem4" ( _
                    ByRef pDst As Any, _
                    ByVal pVal As PTR)
Private Declare Sub PutMem2 Lib "msvbvm60" ( _
                    ByRef pDst As Any, _
                    ByVal iVal As Integer)
 
Private Function RemoveSystemError() As Boolean
    Dim hVB6    As PTR
    Dim pNTHdr  As PTR
    Dim pStart  As PTR
    Dim pEnd    As PTR
    Dim cSign   As Currency
    Dim lLength As Long
    Dim lProt   As Long
   
    hVB6 = GetModuleHandle(StrPtr("vba6.dll"))
    If hVB6 = 0 Then Exit Function
 
    GetMem4 ByVal hVB6 + &H3C, pNTHdr
    pNTHdr = pNTHdr + hVB6
   
    GetMem4 ByVal pNTHdr + &H104, pStart
    pStart = pStart + hVB6
   
    GetMem4 ByVal pNTHdr + &H100, lLength
    pEnd = pStart + lLength - 8
       
    Do While pStart <= pEnd
       
        GetMem8 ByVal pStart, cSign
       
        If cSign = -356375250902713.1008@ Then
 
            If VirtualProtect(pStart + &H10, 2, PAGE_EXECUTE_READWRITE, lProt) Then
           
                PutMem2 ByVal pStart + &H10, &H9090
                VirtualProtect pStart + &H10, 2, lProt, lProt
                RemoveSystemError = True
               
            End If
           
            Exit Do
           
        End If
       
        pStart = pStart + 1
       
    Loop
 
End Function
4
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
15.07.2024, 10:26
Модуль для изменения обоев на рабочем столе версия 3.5

Новый модуль для изменения обоев на рабочем столе. Добавлена функция GetWallpaper для получения пути и имени файла к обоям на рабочем столе, а так же самое главное волшебство - плавное красивое появление картинки на рабочем столе, при её изменении, с fade-эффектом! Ну это только для семёрки, скорее всего. Так как в десятке нет красивостей... Главное это один раз вызвать функцию EnableActiveDesktop и обои на рабочем столе после этого всегда будут появляться с плавным красивым переходом с fade-эффектом! Но для того чтобы этот эффект был виден придётся использовать функцию ActiveDesktopSetWallpaper которая, к сожалению, по времени работает чуть медленнее... Но всё же! Главное - это красота

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
Option Explicit
'/////////////////////////////////////////////////
'// Модуль для изменения обоев на рабочем столе //
'// Copyright (c) 15.07.2024 by HackerVlad      //
'// e-mail: vladislavpeshkov@yandex.ru          //
'// Версия 3.5                                  //
'/////////////////////////////////////////////////
 
' Декларации API...
Private Declare Function SystemParametersInfoW Lib "user32" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Long, ByVal fuWinIni As Long) As Long
Private Declare Function IIDFromString Lib "ole32" (ByVal lpszIID As Long, iid As Any) As Long
Private Declare Function CoCreateInstance Lib "ole32" (rclsid As Any, ByVal pUnkOuter As Long, ByVal dwClsContext As Long, riid As Any, ByVal ppv As Long) As Long
Private Declare Function CallWindowProcA Lib "user32" (ByVal addr As Long, ByVal p1 As Long, ByVal p2 As Long, ByVal p3 As Long, ByVal p4 As Long) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32" (pDst As Any, pSrc As Any, ByVal dlen As Long)
Private Declare Function GetMem4 Lib "msvbvm60" (srcAddr As Any, dstValue As Long) As Long
Private Declare Function GetMem1 Lib "msvbvm60" (srcAddr As Any, dstValue As Long) As Long
Private Declare Function IsFileAPI Lib "shlwapi" Alias "PathFileExistsW" (ByVal pszPath As Long) As Long
Private Declare Function SendMessageTimeout Lib "user32" Alias "SendMessageTimeoutA" (ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal fuFlags As Long, ByVal uTimeout As Long, lpdwResult As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
 
' Константы
Private Const SETDESKWALLPAPER = &H14
Private Const SPI_GETDESKWALLPAPER = 115
Private Const MAX_PATH As Long = 260
Private Const UPDATEINIFILE = &H1
Private Const CLSCTX_INPROC_SERVER  As Long = 1
Private Const CLSID_ActiveDesktop   As String = "{75048700-EF1F-11D0-9888-006097DEACF9}"
Private Const IID_ActiveDesktop     As String = "{F490EB00-1240-11D1-9888-006097DEACF9}"
 
Private Type GUID
    data1                   As Long
    data2                   As Integer
    data3                   As Integer
    data4(7)                As Byte
End Type
 
Private Type IActiveDesktop
    ' IUnknown
    QueryInterface          As Long
    AddRef                  As Long
    Release                 As Long
    ' IActiveDesktop
    ApplyChanges            As Long
    GetWallpaper            As Long
    SetWallpaper            As Long
    GetWallpaperOptions     As Long
    SetWallpaperOptions     As Long
    GetPattern              As Long
    SetPattern              As Long
    GetDesktopItemOptions   As Long
    SetDesktopItemOptions   As Long
    AddDesktopItem          As Long
    AddDesktopItemWithUI    As Long
    ModifyDesktopItem       As Long
    RemoveDesktopItem       As Long
    GetDesktopItemCount     As Long
    GetDesktopItem          As Long
    GetDesktopItemByID      As Long
    GenerateDesktopItemHtml As Long
    AddUrl                  As Long
    GetDesktopItemBySource  As Long
End Type
 
Private Enum AD_APPLY
    AD_APPLY_SAVE = &H1
    AD_APPLY_HTMLGEN = &H2
    AD_APPLY_REFRESH = &H4
    AD_APPLY_ALL = &H7
    AD_APPLY_FORCE = &H8
    AD_APPLY_BUFFERED_REFRESH = &H10
    AD_APPLY_DYNAMICREFRESH = &H20
End Enum
 
' Универсальная функция изменения обоев на рабочем столе
Public Function SetWallpaperUniversal(ByVal FileName As String) As Boolean
    If IsFileAPI(StrPtr(FileName)) = 0 Then ' Файл не существует, с вероятностью 99%
        Exit Function
    End If
    
    If SetWallpaper(FileName) = False Then
        If ActiveDesktopSetWallpaper(FileName) = True Then
            SetWallpaperUniversal = True
        End If
    Else
        SetWallpaperUniversal = True
    End If
End Function
 
' Изменение обоев на рабочем столе
Public Function SetWallpaper(ByVal FileName As String) As Boolean
    Dim RetVal As Long
    
    RetVal = SystemParametersInfoW(SETDESKWALLPAPER, 0, StrPtr(FileName), UPDATEINIFILE)
    If RetVal = 1 Then SetWallpaper = True
End Function
 
' Получение пути и имени файла к обоям на рабочем столе
Public Function GetWallpaper() As String
    Dim RetVal As Long
    Dim str As String
    Dim lNullPos As Long
    
    str = Space$(MAX_PATH)
    
    RetVal = SystemParametersInfoW(SPI_GETDESKWALLPAPER, MAX_PATH, StrPtr(str), 0)
    
    If RetVal Then
        lNullPos = InStr(1, str, vbNullChar)
        If lNullPos Then
            str = Left$(str, lNullPos - 1)
        End If
        GetWallpaper = str
    End If
End Function
 
' Включить ActiveDesktop для того чтобы картинка на рабочем столе появлялась с красивым fade эффектом
Public Sub EnableActiveDesktop()
    Dim result As Long
    
    SendMessageTimeout FindWindow("Progman", vbNullString), &H52C, ByVal 0&, ByVal 0&, ByVal 0&, 500, result
End Sub
 
' Изменение обоев на рабочем столе с помощью интерфейса IActiveDesktop
Public Function ActiveDesktopSetWallpaper(ByVal strFile As String) As Boolean
    Dim vtbl            As IActiveDesktop
    Dim vtblptr         As Long
    Dim classid         As GUID
    Dim iid             As GUID
    Dim obj             As Long
    Dim hRes            As Long
    
    If IsFileAPI(StrPtr(strFile)) = 0 Then ' Файл не существует, с вероятностью 99%
        Exit Function
    End If
    
    ' CLSID (BSTR) to CLSID (GUID)
    hRes = IIDFromString(StrPtr(CLSID_ActiveDesktop), classid)
    If hRes <> 0 Then
        Exit Function
    End If
    
    ' IID (BSTR) to IID (GUID)
    hRes = IIDFromString(StrPtr(IID_ActiveDesktop), iid)
    If hRes <> 0 Then
        Exit Function
    End If
    
    ' Создать экземпляр IActiveDesktop
    ' (Set IActiveDesktop = New IActiveDesktop)
    hRes = CoCreateInstance(classid, 0, CLSCTX_INPROC_SERVER, iid, VarPtr(obj))
    If hRes <> 0 Then
        Exit Function
    End If
    
    GetMem4 ByVal obj, vtblptr
    RtlMoveMemory vtbl, ByVal vtblptr, Len(vtbl)
    
    ' IActiveDesktop::SetWallpaper
    ' Первым параметром всегда является указатель на объект
    ' Возвращаемое значение всегда должно быть HRESULT (0 = S_OK)
    hRes = CallPointer(vtbl.SetWallpaper, obj, StrPtr(strFile), 0)
    If hRes = 0 Then
        ActiveDesktopSetWallpaper = True
    End If
    
    ' IActiveDesktop::ApplyChanges
    hRes = CallPointer(vtbl.ApplyChanges, obj, AD_APPLY_ALL Or AD_APPLY_FORCE Or AD_APPLY_BUFFERED_REFRESH)
    
    ' Освободить память
    ' (Set IActiveDesktop = Nothing)
    CallPointer vtbl.Release, obj
End Function
 
Private Function CallPointer(ByVal fnc As Long, ParamArray params()) As Long
    Dim btASM(&HEC00& - 1)  As Byte
    Dim pASM                As Long
    Dim i                   As Integer
    
    pASM = VarPtr(btASM(0))
    
    AddByte pASM, &H58                  ' POP EAX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H50                  ' PUSH EAX
    
    For i = UBound(params) To 0 Step -1
        AddPush pASM, CLng(params(i))   ' PUSH dword
    Next
    
    AddCall pASM, fnc                   ' CALL rel addr
    AddByte pASM, &HC3                  ' RET
    
    CallPointer = CallWindowProcA(VarPtr(btASM(0)), 0, 0, 0, 0)
End Function
 
Private Sub AddPush(pASM As Long, lng As Long)
    AddByte pASM, &H68
    AddLong pASM, lng
End Sub
 
Private Sub AddCall(pASM As Long, addr As Long)
    AddByte pASM, &HE8
    AddLong pASM, addr - pASM - 4
End Sub
 
Private Sub AddLong(pASM As Long, lng As Long)
    GetMem4 lng, ByVal pASM
    pASM = pASM + 4
End Sub
 
Private Sub AddByte(pASM As Long, bt As Byte)
    GetMem1 bt, ByVal pASM
    pASM = pASM + 1
End Sub
Вложения
Тип файла: zip Изменение обоев на рабочем столе 3.5.zip (12.0 Кб, 24 просмотров)
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
30.10.2024, 17:09
Модуль для проигрывания WAV-файла из ресурсов

Имеется возможность проигрывать WAV-файлы из ресурсов своего EXE с помощью стандартных средств VB6, для этого спользуется функция LoadResWaveVB. А так же имеется возможность проигрывать WAV-файлы из ресурсов абсолютно любых файлов, где бы они не находились, с помощью функции LoadResWaveAPI. Полностью поддерживает юникодные имена файлов. Дописал сегодня этот модуль благодаря подсказки Argus19.
Миниатюры
Готовые решения и полезные коды на Visual Basic 6.0  
Вложения
Тип файла: zip Проигрывание WAV-файла из ресурсов 2.5.zip (293.0 Кб, 38 просмотров)
4
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
30.10.2024, 17:09
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
340
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru