Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.53/140: Рейтинг темы: голосов - 140, средняя оценка - 4.53
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18035 / 7738 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16

Тестирование полезных кодов и примеров

15.10.2012, 00:56. Показов 30994. Ответов 301
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Если Ваш код из темы Готовые решения и полезные коды на Visual Basic 6.0

неправильно собран или неработоспособен, он будет перенесен сюда.

Для доведения кода в рабочее состояние в порядке обсуждения создайте новую тему
2
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.10.2012, 00:56
Ответы с готовыми решениями:

Тестирование полезных скриптов
В этой теме нужно писать: - о багах в выложенных полезных скриптах (закрепленная тема); - ошибках в кодах, на которые ведут ссылки...

Программное тестирование кодов
Доброго! Часто возникает потребность протестить некоторую программку, обычно небольшую. Т.к. в большинстве случаев это надо сделать быстро,...

Cумма кодов четных символов равна сумме кодов нечетных
Даны два поля edit1 и edit2. и кнопка button1. Нужно чтобы при нажатии на кнопку, проверялось: сумма кодов четных символов была равна сумме...

301
Модератор
Эксперт .NET
 Аватар для Yury Komar
4363 / 3433 / 512
Регистрация: 27.01.2014
Сообщений: 6,261
21.09.2014, 14:34
Студворк — интернет-сервис помощи студентам
The trick, руками получается, легко, но будет удобно для неопытных кодеров иметь такой мини инструмент под рукой
Да и самому мне очень пригодится в работе... много пишу для аанглийских систем. Абы сэкономить время - будет очень кстати.
Спасибо.
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18035 / 7738 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
13.10.2014, 10:54  [ТС]
Сохранение свойств объектов в файле ✰

Антихакер32, а как быть в том случае,
если я только что создал приложение с твоим модулем и у меня еще нет файла настроек,
а значит и загружать с помощью LoadSettings нечего ?

SaveSettings выдает ошибку, т.к. имя файла, задается процедурой LoadSettings.
Это ИМХО, как то неправильно.

А если я пытаюсь сначала загрузить настройки через LoadSetting,
выбивает ошибку:
Visual Basic
1
If Co.Count = 0 Then Err.Raise ErrNum, , prompt
Runtime Error 101.
Данные для применения настроек пусты. Может я что-то не так делаю.

+ у тебя в коде используются Split.
Боюсь как бы они не выдали ошибку, если значение свойства будет равно vbnullstring.

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

Мой тестовый проект ниже. Посмотри, пожалуйста.
Вложения
Тип файла: rar TestSettings.rar (2.4 Кб, 13 просмотров)
0
 Аватар для Антихакер32
1201 / 473 / 46
Регистрация: 06.01.2014
Сообщений: 1,797
Записей в блоге: 19
13.10.2014, 12:02
Цитата Сообщение от Dragokas Посмотреть сообщение
Антихакер32, а как быть в том случае,
если я только что создал приложение с твоим модулем и у меня еще нет файла настроек,
а значит и загружать с помощью LoadSettings нечего ?
при вызове этой комманды файл автоматически сконфигурирует
что надо, если отсутствует

Добавлено через 1 минуту
Должно идти все по порядку..
создание коллекции
загрузка.. по окончанию сохранение

Добавлено через 2 минуты
Пример

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Private Sub Form_Load()
    Me.Caption = App.EXEName & App.Major & "." & App.Minor
    
    SettingsAdd frmMain, "Left", "Top", "Width", "Height"
    SettingsAdd frmPairedWords, "Width", "Height"
    SettingsAdd frmViewSino, "Width", "Height"
    SettingsAdd frmSinoSettings.Controls("chSettings1"), "Value"
    SettingsAdd frmSinoSettings.Controls("chSettings2"), "Value"
    LoadSettingsINI
End Sub
Private Sub Form_Unload(Cancel As Integer)
    SaveSettingsINI
    End
End Sub
Добавлено через 4 минуты
Весь расчет на то, что не приходится писать километровый код..
для того чтобы внести в код настройку для сохранения..
достаточно дописать одну строчку

Добавлено через 6 минут
Странно что вы пытаетесь найти косяк.. ))

Добавлено через 1 минуту
Цитата Сообщение от Dragokas Посмотреть сообщение
Боюсь как бы они не выдали ошибку
это исключено

Добавлено через 1 минуту
вот я писал..
Цитата Сообщение от Антихакер32 Посмотреть сообщение
..очень компактно, решил полдня потратить на эту портянку,
все там продумал, и в дальнейшем можно этот модуль использовать для любых нужд
Добавлено через 5 минут
Цитата Сообщение от Dragokas Посмотреть сообщение
Мой тестовый проект ниже. Посмотри, пожалуйста.
ок, посмотрю и выскажусь

Добавлено через 5 минут
Ответ:
Вы не верно задали порядок выполнений..

порядок должен быть таким:
  • SettingsAdd
  • LoadSettingsINI
  • SaveSettingsINI

Не по теме:

The Trick, допиши в готовое решение порядок выполнений




Visual Basic
1
2
3
4
5
6
7
8
9
10
11
Private Sub Command1_Click()
    SettingsAdd Form1, "left", "top"
    SettingsAdd Text1, "text"
    SaveSettingsINI
End Sub
 
Private Sub Command2_Click()
    LoadSettingsINI
    ApplySettings Form1
    ApplySettings Text1
End Sub


Добавлено через 5 минут
Dragokas, вот как должно быть

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Option Explicit
 
Private Sub Command1_Click()
    SettingsAdd Form1, "left", "top"
    SettingsAdd Text1, "text"
End Sub
 
Private Sub Command2_Click()
    ApplySettings Form1
    ApplySettings Text1
End Sub
 
Private Sub Form_Unload(Cancel As Integer)
    SaveSettingsINI
End Sub
Добавлено через 4 минуты
Или так

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
Option Explicit
 
Private Sub Command1_Click()
    'Можно было этот же код написать в *Form_Load*
    SettingsAdd Form1, "left", "top"
    SettingsAdd Text1, "text"
    LoadSettingsINI
End Sub
 
Private Sub Form_Unload(Cancel As Integer)
    SaveSettingsINI
End Sub
Добавлено через 12 минут
...

Добавлено через 7 минут
Цитата Сообщение от Dragokas Посмотреть сообщение
SaveSettings выдает ошибку, т.к. имя файла, задается процедурой LoadSettings.
Это ИМХО, как то неправильно.
можно просто в процедуру SaveSettings добавить аргумент файлового имени
тогда это будет по Вашему ))

Добавлено через 2 минуты
но я этого делать не буду, так-как, моё имхо что первая должна выполняться
LoadSettingsINI, и она же дережирует и задаёт имя
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18035 / 7738 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
13.10.2014, 12:18  [ТС]
Цитата Сообщение от Антихакер32 Посмотреть сообщение
Dragokas, вот как должно быть
Заменил в тестовом проекте. Это не работает.

Цитата Сообщение от Антихакер32 Посмотреть сообщение
Или так
Так работает.
Я так понимаю, чтобы добавить новые объекты к сохранению нужно также
воспользоваться SettingsAdd ?

ИМХО, не достаточно документированно.
0
 Аватар для Антихакер32
1201 / 473 / 46
Регистрация: 06.01.2014
Сообщений: 1,797
Записей в блоге: 19
13.10.2014, 15:17
Цитата Сообщение от Dragokas Посмотреть сообщение
ИМХО, не достаточно документированно.
согласен, мой косяк.. даже не косяк а ахилесовая пята..
многие свои коды, нужно бы получше описать.. согласен

Добавлено через 26 минут
Цитата Сообщение от Dragokas Посмотреть сообщение
Я так понимаю, чтобы добавить новые объекты к сохранению нужно также
воспользоваться SettingsAdd ?
да, сохраняется то что в коллекции, так-как там вызываются значения по именам свойств

Добавлено через 1 минуту
вот..
Visual Basic
1
.WriteLine v(f) & rv & CStr(CallByName(v(u - 1), v(f), VbGet))
Добавлено через 1 час 8 минут
Вот, сделал еще лучше..
теперь если пользователь чтото напутает
то автоматика всё стерпит ))


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
Option Explicit
'
'Модуль для сохранения (или приминения) настроек в файле
'первая в программе должна выполнится SettingsAdd
'при загрузке и при сохранении настроек, будут обращения по именам из коллекции
'© Антихакер32 (CyberForum.ru).
'
Const q$ = "[", w$ = "]", rv$ = "=", t = ".", rm = "_"
Const prompt = _
"Данные для применения настроек пусты" & vbCrLf & _
"Необходимо указать с помощью SettingsAdd", ErrNum = 101
Const m_Def_FileName = "Settings.ini"
Dim m_FileName$, m_fso As Object
Dim f&, j$(), s$, u&, v, Key$, mApply As Boolean
Dim Co As New Collection, coDat As New Collection
 
Public Sub SettingsAdd(Obj As Object, ParamArray arg())
    'Необходимо указать форму или контрол, и имена свойств для сохранения
    'напимер: SettingsAdd Form1, "left","top"
    v = arg: ReDim Preserve v(UBound(v) + 2)
    If UBound(v) = 1 Then Exit Sub '>>Выход, если нет аргументов
    Key = GetKey(Obj): If KeyExists(Key) Then Co.Remove (Key)
    Set v(UBound(v) - 1) = Obj: v(UBound(v)) = Key: Co.Add v, Key
End Sub
 
Private Function KeyExists(Key$) As Boolean
    'Возвращает утверждение о наличии ключа
    On Error Resume Next
    KeyExists = Not IsError(Co(Key))
End Function
 
Private Function GetFso() As Object
    If m_fso Is Nothing Then Set m_fso = CreateObject("scripting.FileSystemObject")
    Set GetFso = m_fso
End Function
 
Private Function GetKey(Obj As Object)
    On Error Resume Next
    GetKey = Obj.Name: GetKey = Obj.Parent.Name & t & GetKey: GetKey = GetKey & rm & Obj.Index
End Function
 
 
 
Public Sub ApplySettings(Obj As Object)
    'Применение настроек для одного указанного объекта
    If coDat.Count = 0 Then mApply = True: LoadSettingsINI: mApply = False
    On Error GoTo ERRR
    v = Co(GetKey(Obj)): u = UBound(v)
    For f = 0 To u - 2: CallByName v(u - 1), v(f), VbLet, coDat(v(u) & t & v(f)): Next
ERRR:
End Sub
 
Public Sub LoadSettingsINI(Optional FileName$ = m_Def_FileName)
    'Загрузка и приминение всех настроек
    'Арг. имя файла (по умолчанию "Settings.ini")
    Dim f2&, j1$(), j2$(), j3$()
    If Co.Count = 0 Then Err.Raise ErrNum, , prompt
    On Error Resume Next
    m_FileName = App.Path & "\" & FileName
    If Not GetFso.FileExists(m_FileName) Then SaveSettingsINI
    s = GetFso.OpenTextFile(m_FileName).ReadAll
    j = Split(s, q)
    For f = 1 To UBound(j)
        j1 = Split(j(f), w)
        j2 = Split(j1(1), vbCrLf)
        For f2 = 1 To UBound(j2) - 1
            j3 = Split(j2(f2), rv)
            coDat.Add j3(1), j1(0) & t & j3(0)
    Next: Next
    If mApply Then Exit Sub '>>Если вызванно процедурой ApplySettings
    For Each v In Co: u = UBound(v) '---------Применение настроек
        For f = 0 To u - 2
            CallByName v(u - 1), v(f), VbLet, coDat(v(u) & t & v(f))
    Next: Next
End Sub
 
Public Sub SaveSettingsINI()
    'Сохранение настроек
    If Co.Count = 0 Then Err.Raise ErrNum, , prompt
    If Len(m_FileName) = 0 Then m_FileName = App.Path & "\" & m_Def_FileName
    With GetFso.CreateTextFile(m_FileName)
        On Error Resume Next
        For Each v In Co
            u = UBound(v)
            v(u - 1).WindowState = 0
            .WriteLine q & v(u) & w
            For f = 0 To u - 2
                 .WriteLine v(f) & rv & CStr(CallByName(v(u - 1), v(f), VbGet))
    Next: Next: End With
End Sub
0
Модератор
10060 / 3905 / 885
Регистрация: 22.02.2013
Сообщений: 5,854
Записей в блоге: 79
13.10.2014, 18:31
По-поводу замечания уважаемого Catstail'а. Так делать не стоит, т.к. код многократно разрастеться, принимая во внимание то что у свойств разные типы, в том числе и объектные. В Windows и в VB6 уже есть такой функционал. В COM - это интерфейс IPersist и его производные, для класса - это свойство Persistance с последующей обработкой событий ReadProperties, WriteProperties, InitProperties.
1
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38209 / 21142 / 4312
Регистрация: 12.02.2012
Сообщений: 34,755
Записей в блоге: 14
13.10.2014, 18:47
Да, согласен... Интерфейс IPersist - более правильный подход.
0
Модератор
10060 / 3905 / 885
Регистрация: 22.02.2013
Сообщений: 5,854
Записей в блоге: 79
13.10.2014, 19:45
Антихакер32, я тебе по секрету скажу что есть такой объект PropertyBag, который делает практически тоже самое что твой модуль. Позже скину пример.
0
 Аватар для Антихакер32
1201 / 473 / 46
Регистрация: 06.01.2014
Сообщений: 1,797
Записей в блоге: 19
13.10.2014, 19:57
Цитата Сообщение от The trick Посмотреть сообщение
Антихакер32, я тебе по секрету скажу что есть такой объект PropertyBag, который делает практически тоже самое что твой модуль. Позже скину пример.
я догадался, на середине своей разработки, что гдето такой подход уже видел
в частности при разработки компонентов
встроенный Add-ins *ActiveX Control Interface Wizard* автоматически создает похожие записи кода

Добавлено через 4 минуты
а хранятся эти данные в сопроводительном файле для компонента..
с одноименным названием, только расширение другое
ну тоесть там цвета, названия, размеры и тд
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18035 / 7738 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
04.01.2015, 03:01  [ТС]
Получение физического пути для виртуальных объектов ShellFolder, чей путь задан через индентификатор вида ::{GUID}

В примере на вход подается путь к виртуальной папке "Яндекс.Диск".
У меня это: "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\::{19170A69-A883-40D5-AF97-F6DC41495F15}"
Этот путь можно получить в свойствах ярлыка, если таковой создать для "Яндекс.Диск"-а,
который находится в папке "Мой компьютер" после установки соответствующего ПО от Яндекса.

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

- напрямую физ.путь ITEM ID List папки "Яндекс.Диск" не раскрывается.
Это и понятно. Папка виртуальная. На нее может быть спроецировано много других объектов
(как, например, вирт.папка "Корзина" - одна для всех папок корзин на всех дисках).
- поэтому я запустил перечисление дочерних объектов папки "Яндекс.Диск"
и по свойствам первого из них узнал физический путь к родителю.

Функция CombinePIDLs взята у Brad Martinez.
Для работы примера нужно подключить библиотеки типов (есть в проекте):
1. IShellFolder Extended Type Library v1.2
2. Edanmo's OLE interfaces for Implements
Вложения
Тип файла: zip VB6_ShellFolder.zip (215.2 Кб, 12 просмотров)
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18035 / 7738 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
04.01.2015, 03:02  [ТС]
Сам код:

Кликните здесь для просмотра всего текста
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
Option Explicit
 
Const MAX_PATH      As Long = 260&
 
Private Type ShellFolder_Info
    sIDL As String
    ObjName As String
    ObjPath As String
    isFolder As Boolean
End Type
 
Private Declare Function IIDFromString Lib "ole32.dll" (ByVal lpsz As Long, lpiid As Any) As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenW" (ByVal lpString As Long) As Long
Private Declare Function SHParseDisplayName Lib "shell32.dll" (ByVal pszName As Long, ByVal IBindCtx As Long, ppidl As Long, ByVal sfgaoIn As Long, psfgaoOut As Long) As Long
Private Declare Function SHGetDesktopFolder Lib "shell32.dll" (ISF As IShellFolder) As Long
Private Declare Function StrRetToStr Lib "shlwapi.dll" Alias "StrRetToStrA" (pstr As STRRET, ByVal pIDL As Long, ppsz As String) As Long
Private Declare Function SHBindToParent Lib "shell32.dll" (ByVal pIDL As Long, ByVal riid As Long, ppv As Any, ppidlLast As Any) As Long
Private Declare Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" (ByVal pIDL As Long, ByVal pszPath As Any) As Long
Private Declare Function SHGetMalloc Lib "shell32" (ppMalloc As IMalloc) As Long
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal dwLength As Long)
Private Declare Sub FillMemory Lib "kernel32" Alias "RtlFillMemory" (pDest As Any, ByVal dwLength As Long, ByVal bFill As Byte)
Private Declare Sub CoTaskMemFree Lib "ole32" (ByVal pv As Long)
Private Declare Function ILFree Lib "shell32" (ByVal pidlFree As Long) As Long
 
Dim SFInfo As ShellFolder_Info
 
Public Sub Test_PIDL()
 
    With SFInfo
        ' Яндекс.Диск
        .sIDL = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\::{19170A69-A883-40D5-AF97-F6DC41495F15}"
        
        GetShellFolderInfo SFInfo
        
        Debug.Print .ObjName; vbTab; .ObjPath; vbTab; "IsFolder="; .isFolder
    End With
      
End Sub
 
Public Sub GetShellFolderInfo(sfi As ShellFolder_Info)
    'in.  SFI.sIDL - путь к объекту пространства имен Shell, заданный как GUID
    'out. SFI.ObjName - имя объекта, как оно отображается для пользователя
    'out. SFI.folderPath - физический путь к объекту
    'out. SFI.isFolder - является ли объект каталогом ?
    Dim ISF        As IShellFolder
    Dim str        As STRRET
    Dim pIDL       As Long
    Dim pstr       As Long
    Dim lr         As Long
    Dim SFGAO_ret  As Long
 
    Const SFGAO_FOLDER As Long = &H20000000 ' является ли каталогом ?
 
    ' Создать Item ID List из строки и вернуть указатель на него
    ' SFGAO_ret -> возвращает сумму битов запрошенных для проверки атрибутов
    If SHParseDisplayName(StrPtr(sfi.sIDL), ByVal 0&, pIDL, SFGAO_FOLDER, SFGAO_ret) <> S_OK Then Exit Sub
    ' Получаем указатель на интерфейс IShellFolder корневого объекта - Desktop
    lr = SHGetDesktopFolder(ISF)
    ' Преобразуем IDL в имя, отображаемое по-умолчанию в Windows Explorer
    ISF.GetDisplayNameOf pIDL, ByVal 0&, str
    ' Структуру STRRET -> в строку
    sfi.ObjName = String$(MAX_PATH, Chr$(0))
    If StrRetToStr(str, pIDL, sfi.ObjName) = S_OK Then sfi.ObjName = Left$(sfi.ObjName, lstrlen(StrPtr(sfi.ObjName)))
    
    ' Проверяем, допускает ли объект перечисление (альтернативный вариант)
    'Dim attr As Long
    'attr = SFGAO_FOLDER
    'ISF.GetAttributesOf 1&, ppidl, attr
    'SFI.isFolder = (attr And SFGAO_FOLDER)
    
    sfi.isFolder = SFGAO_ret And SFGAO_FOLDER
    
    ' Пытаемся получить физический путь
    sfi.ObjPath = String$(MAX_PATH, Chr$(0&))
    If SHGetPathFromIDList(pIDL, sfi.ObjPath) <> 0 Then
        sfi.ObjPath = Left$(sfi.ObjPath, lstrlen(StrPtr(sfi.ObjPath)))
        ' Если получили нормальный путь -> на выход
        If StrComp(sfi.ObjPath, sfi.sIDL, 1) <> 0 Then
            Set ISF = Nothing
            ILFree pIDL
            Exit Sub
        Else    ' Если путь совпадает с переданным GUID (т.е. он не раскрылся)
            sfi.ObjPath = vbNullString
        End If
    End If
    
    ' Если ShellFolder виртуальная, она может не раскрыться в физический путь
    ' Попробуем получить путь через свойства одного из ее дочерних объектов
    If sfi.isFolder Then
        Dim IID_IShellFolder As GUID
    
        Dim ISFchild    As IShellFolder
        Dim IEnumIDL    As IEnumIDList
        Dim filePath    As String
        Dim pIDLcur     As Long
        Dim pIDLfull    As Long
        Dim pos         As Long
 
        IIDFromString StrPtr("{000214E6-0000-0000-C000-000000000046}"), IID_IShellFolder
        
        ' Подключимся интерфейсом IShellFolder к нашему каталогу
        If ISF.BindToObject(pIDL, 0&, IID_IShellFolder, ISFchild) = S_OK Then
        
            ' Получаем интерфейс IEnumIDList для перечисления дочерних объектов этого каталога
            If ISFchild.EnumObjects(0&, SHCONTF_FOLDERS Or SHCONTF_NONFOLDERS Or SHCONTF_INCLUDEHIDDEN, IEnumIDL) = S_OK Then
        
                ' получаем 1 любой дочерний объект
                If IEnumIDL.Next(1&, pIDLcur, 0&) = S_OK Then
                
                    ' строим полный путь к дочернему ID List
                    pIDLfull = CombinePIDLs(pIDL, pIDLcur)
                
                    If pIDLfull <> 0 Then
                
                        ' Получаем привычный путь файловой системы для дочернего объекта
                        filePath = String$(MAX_PATH, Chr$(0&))
                        
                        If SHGetPathFromIDList(pIDLfull, filePath) <> 0 Then
                            filePath = Left$(filePath, lstrlen(StrPtr(filePath)))
                        End If
                    
                        ' Урезаем до родительского каталога
                        If Len(filePath) <> 0 Then
                            pos = InStrRev(filePath, "\")
                            If pos <> 0 Then sfi.ObjPath = Left$(filePath, pos - 1)
                        End If
 
                        isMalloc.Free ByVal pIDLfull
                        ILFree pIDLcur
                    
                    End If
                
                End If
                
                Set IEnumIDL = Nothing
                
            End If
            
            Set ISFchild = Nothing
            
        End If
        
    End If
    
    Set ISF = Nothing
    ILFree pIDL
    
End Sub
 
' fFreePidl1, fFreePidl2 - очищать память, указанных IDL по завершению работы функции ?
Public Function CombinePIDLs(pidl1 As Long, _
                                                  pidl2 As Long, _
                                                  Optional fFreePidl1 As Boolean = False, _
                                                  Optional fFreePidl2 As Boolean = False) As Long
  Dim cb1 As Integer
  Dim cb2 As Integer
  Dim pidlNew As Long
 
  ' If pidl1 is non-zero...
  If pidl1 Then
    ' Get it's size
    cb1 = GetPIDLSize(pidl1)
    ' If pidl1 is valid (has a size), subtract the size of the zero terminator
    If cb1 Then cb1 = cb1 - 2
  End If
  
  ' If pidl2 is non-zero...
  If pidl2 Then
    ' Get it's size
    cb2 = GetPIDLSize(pidl2)
    ' If pidl2 is valid (has a size), subtract the size of the zero terminator
    If cb2 Then cb2 = cb2 - 2
  End If
 
  ' Create a new pidl sized to hold both pidl1, pidl2 and the zero terminator
  pidlNew = CreatePIDL(cb1 + cb2 + 2)
  If (pidlNew) Then
    
    ' If pidl1 is valid, put it's id list at the beginning of our new pidl
    If cb1 Then MoveMemory ByVal pidlNew, ByVal pidl1, cb1
    
    ' If pidl2 is valid, prepend it's id list to the end of the new pidl
    If cb2 Then MoveMemory ByVal pidlNew + cb1, ByVal pidl2, cb2
      
    ' Zero the terminating 2 bytes
    FillMemory ByVal pidlNew + cb1 + cb2, 2, 0
      
    ' Finally, free the pidls as specified
    If (pidl1 And fFreePidl1) Then isMalloc.Free ByVal pidl1
    If (pidl2 And fFreePidl2) Then isMalloc.Free ByVal pidl2
    
  End If
  
  CombinePIDLs = pidlNew
 
End Function
 
Public Function CreatePIDL(cb As Long) As Long
  Dim pIDL As Long
  pIDL = isMalloc.Alloc(cb)
  If pIDL Then
    FillMemory ByVal pIDL, cb, 0 ' initialize to zero, set by caller
    CreatePIDL = pIDL
  End If
End Function
 
Public Function isMalloc() As IMalloc
  Static im As IMalloc
  If (im Is Nothing) Then SHGetMalloc im
  Set isMalloc = im
End Function
 
Public Function GetPIDLSize(ByVal pIDL As Long) As Integer
  Dim cb As Integer
  ' Error handle in case we get a bad pidl and overflow cb.
  ' (most item IDs are roughly 20 bytes in size, and since an item ID represents
  ' a folder, a pidl can never exceed 260 folders, or 5200 bytes).
  On Error GoTo Out
  If pIDL Then
    Do While pIDL
      cb = cb + GetItemIDSize(pIDL)
      pIDL = GetNextItemID(pIDL)
    Loop
    ' Add 2 bytes for the zero terminating item ID
    GetPIDLSize = cb + 2
  End If
Out:
End Function
 
Public Function GetItemIDSize(ByVal pIDL As Long) As Integer
  ' If we try to access memory at address 0 (NULL), then it's bye-bye...
  If pIDL Then MoveMemory GetItemIDSize, ByVal pIDL, 2
End Function
 
Public Function GetNextItemID(ByVal pIDL As Long) As Long
  Dim cb As Integer   ' SHITEMID.cb, 2 bytes
  cb = GetItemIDSize(pIDL)
  ' Make sure it's not the zero value terminator.
  If cb Then GetNextItemID = pIDL + cb
End Function
1
Модератор
10060 / 3905 / 885
Регистрация: 22.02.2013
Сообщений: 5,854
Записей в блоге: 79
04.01.2015, 12:46
CombinePIDLs можно заменить на ILCombine, а вообще можно просто сделать так:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
Private Sub Form_Load()
    Dim shl As Object
    Dim fld As Object
    Dim itm As Variant
    
    Set shl = CreateObject("shell.application")
    Set fld = shl.namespace("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\::{19170A69-A883-40D5-AF97-F6DC41495F15}")
    
    For Each itm In fld.items
        Debug.Print itm.Path
    Next
    
End Sub
3
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18035 / 7738 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
04.01.2015, 14:32  [ТС]
Да, класс !
О большем и не мечтал.
0
Модератор
Эксперт .NET
 Аватар для Yury Komar
4363 / 3433 / 512
Регистрация: 27.01.2014
Сообщений: 6,261
09.01.2015, 12:32
Памирыч,
Потом опять значки с окошками расставлять пришлось.

Не по теме:

я на этот случай пользуюсь программкой "DESKTOP OK" очень выручает вернуть все на свои места... кстати хочктся написать что-то подобное но не пойму как она работает...

0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18035 / 7738 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
30.01.2015, 00:48  [ТС]
The trick,

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Private Sub Form_Load()
    Dim shl As Object
    Dim fld As Variant
    Dim itm As Variant
    Dim idl As Variant
    
    idl = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\::{19170A69-A883-40D5-AF97-F6DC41495F15}"
    
    Set shl = CreateObject("Shell.Application")
    Set fld = shl.NameSpace(idl)
    
    For Each itm In fld.Items
        Debug.Print itm.Path
    Next
    
    Stop
End Sub
при запуске с повышенными привилегиями почему-то выдает ошибку на строке shl.NameSpace
(ActiveX componnt can't create an object).

Мой код также не работает: функция ISF.BindToObject возвращает ошибку 0x80040154 (Class not registered.)
Можешь, пожалуйста, посмотреть по свободе в чем проблема?
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18035 / 7738 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
12.07.2015, 23:32  [ТС]
Обнаружилась еще одна ошибка в Классе StringBuilder от VolteFace

Если добавить строку, в которой будет присутствовать символ NUL,
то при возврате методом .ToString, строка урезается до первого NUL, хотя сама строка хранится полностью и верно возвращает размер через свойство .Length

Исходный метод:

Visual Basic
1
2
3
4
5
Public Property Get ToString() As String
    ' Create a buffer that is the size of the stored string and
    ' copy the string contents at the stored memory pointer into the buffer
    ToString = StrConv(SysAllocString(ByVal m_pMemoryPtr), vbFromUnicode)
End Property
Переделанный мною:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
Public Property Get ToString() As String
    ' Create a buffer that is the size of the stored string and
    ' copy the string contents at the stored memory pointer into the buffer
    Dim buf     As String
    Dim size    As Long
    
    size = Me.Length
    buf = String$(size, vbNullChar)
    RtlMoveMemory ByVal StrPtr(buf), ByVal m_pMemoryPtr, size * 2
    ToString = buf
End Property
Подскажите, пожалуйста, правильно ли сделал, не накосячил ли?

Добавлено через 1 минуту
Код для теста:

Кликните здесь для просмотра всего текста
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Option Explicit
 
Private Sub Form_Load()
    Dim cc As New clsStringBuilder
    
    cc.Append "1234"
    cc.Append "12" & vbNullChar & "34"
    cc.Append "12" & vbNullChar & vbNullChar & "34"
    
    Debug.Print cc.ToString
    Debug.Print Len(cc.ToString)
    
    Set cc = Nothing
    End
End Sub
0
Модератор
10060 / 3905 / 885
Регистрация: 22.02.2013
Сообщений: 5,854
Записей в блоге: 79
12.07.2015, 23:35
Цитата Сообщение от Dragokas Посмотреть сообщение
Подскажите, пожалуйста, правильно ли сделал, не накосячил ли?
Вроде правильно, только для избежания лищнего копирования можно сразу передать ToString вместо buf, а buf вообще исключить.
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18035 / 7738 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
12.07.2015, 23:39  [ТС]
Спасибо. Зная, что некоторые API не любят, когда им напрямую передают указатель на переменные из аргументов функций, уже страхуюсь ))
0
0 / 0 / 0
Регистрация: 12.08.2016
Сообщений: 4
12.08.2016, 15:36
блин там троян нафиг это скидывать ща жалобу на тебя напишу
0
Модератор
10060 / 3905 / 885
Регистрация: 22.02.2013
Сообщений: 5,854
Записей в блоге: 79
12.08.2016, 15:51
Цитата Сообщение от MonsterCroc Посмотреть сообщение
блин там троян нафиг это скидывать ща жалобу на тебя напишу
Где там?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
12.08.2016, 15:51

Парочка полезных видеоуроков по C++
323e1ffiYjw AEA7GmPli5Y OH7g2lfsYEU Может какой-нибудь следующий &quot;учитель&quot; посмотрит и передумает делать свои уроки :)

Удаленное тестирование приложение/Пересылка на тестирование
Если кто-то написал приложение под андроид и захочет показать другому человеку, то достаточно отослать apk. А как обстоит с этим дело в...

Unit -тестирование или автоматизированное тестирование
Доброго времени суток. Я программирую «для себя» второй год, на выходе получаются разного рода приложения от постоянно подающих с...

Не Большой Набор Полезных Функций
Функция проверки на наличие не запрещенных символов в поле, где ? - запрещенные символы Function Check_BadSymbols(sStr As String) As...

USBasp - пара возможно полезных плюшек.
Уважаемые коллеги! Возможно то, что я опишу - баян с бородищей. Готов принять справедливую критику. Но вдруг кому-то поможет. Держу...


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

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
Новые блоги и статьи
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru