Посл.ответ |
Сообщение |
Ранг: 36.8 (посетитель) Активность: 0.02↘0 Статус: Участник
|
Создано: 25 ноября 2007 11:03 · Личное сообщение · #1
Всем привет... Есть API-функция SHBindToParent, однако в Windows 98 она отсутствует. В сети нашел исходник на С, вот он:
HRESULT SHBindToParent(
LPCITEMIDLIST pidl,
REFIID riid,
VOID** ppv,
LPCITEMIDLIST* ppidlLast)
{
if (!ppv)
return E_POINTER;
// There must be at least one item ID.
if (!pidl || !pidl->mkid.cb)
return E_INVALIDARG;
// Get the root folder.
IShellFolderPtr desktop;
HRESULT hr = SHGetDesktopFolder(&desktop);
if (FAILED(hr))
return hr;
// Walk to the penultimate item ID.
LPCITEMIDLIST marker = pidl;
for (;;)
{ !!!!!!!!!!!!!!!! Вот в этом месте я завис !!!!!!!!!!!!!!!!
LPCITEMIDLIST next = reinterpret_cast<LPCITEMIDLIST>(
marker->mkid.abID - sizeof(marker->mkid.cb) + marker->mkid.cb);
if (!next->mkid.cb)
break;
marker = next;
};
if (marker == pidl)
{
// There was only a single item ID, so bind to the root folder.
hr = desktop->QueryInterface(riid, ppv);
}
else
{
// Copy the ID list, truncating the last item.
int length = marker->mkid.abID - pidl->mkid.abID;
if (LPITEMIDLIST parent_id = reinterpret_cast<LPITEMIDLIST>(
malloc(length + sizeof(pidl->mkid.cb))))
{
LPBYTE raw_data = reinterpret_cast<LPBYTE>(parent_id);
memcpy(raw_data, pidl, length);
memset(raw_data + length, 0, sizeof(pidl->mkid.cb));
hr = desktop->BindToObject(parent_id, 0, riid, ppv);
free(parent_id);
}
else
return E_OUTOFMEMORY;
}
// Return a pointer to the last item ID.
if (ppidlLast)
*ppidlLast = marker;
return hr;
}
Помогите допортировать его в Pascal. Вот что я уже сделал:
function SHBindToParent(pidl: PItemIDList; const riid: TIID;
var ppv: Pointer; out ppidlLast): HResult;
var
desktop : IShellFolder;
hr : HRESULT;
marker, next : PITEMIDLIST;
length : integer;
parent_id : PITEMIDLIST;
raw_data : PBYTE;
begin
if ppv = nil then
Result := E_POINTER;
// There must be at least one item ID.
if (pidl = nil) or (pidl.mkid.cb = 0) then
Result := E_INVALIDARG;
// Get the root folder.
hr := SHGetDesktopFolder(desktop);
if hr <> S_OK then
Result := hr;
// Walk to the penultimate item ID.
marker := pidl;
(* while true do !!!!!!!!!!!!!!!! Вот в этом месте я завис !!!!!!!!!!!!!!!!
begin
length := marker.mkid.abID[0] - sizeof(marker.mkid.cb);
next := PITEMIDLIST(length + marker.mkid.cb);
try
if next.mkid.cb = 0 then
begin
break;
end;
except
break;
end;
marker := next;
end;*)
if marker = pidl then
begin
// There was only a single item ID, so bind to the root folder.
hr := desktop.QueryInterface(riid, ppv);
end
else
begin
// Copy the ID list, truncating the last item.
length := marker.mkid.abID[0] - pidl.mkid.abID[0];
parent_id := PITEMIDLIST(_malloc(length + sizeof(pidl.mkid.cb)));
if parent_id <> nil then
begin
raw_data := PBYTE(parent_id);
_memcmp(raw_data, pidl, length);
_memset(raw_data, 0, sizeof(pidl.mkid.cb) + length);
hr := desktop.BindToObject(parent_id, 0, riid, ppv);
_free(parent_id);
end
else
Result := E_OUTOFMEMORY;
end;
// Return a pointer to the last item ID.
if hr = S_OK then
ppidlLast := marker;
Result := hr;
end;
Все функции типа _malloc и прочие беру из заголовочного файла MSVCRT.PAS...
| Сообщение посчитали полезным: |
|
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 25 ноября 2007 12:09 · Личное сообщение · #2
NeoTall пишет:
marker, next : PITEMIDLIST;
NeoTall пишет:
if next.mkid.cb = 0 then
begin
break;
end;
брр, next это указатель, наверно надо так:
if next.mkid.cb^=0 then
break;
| Сообщение посчитали полезным: |
Ранг: 36.8 (посетитель) Активность: 0.02↘0 Статус: Участник
|
Создано: 25 ноября 2007 12:36 · Личное сообщение · #3
Ну, уж тогда: if next^.mkid.cb = 0 then . Только вопрос не в этом вообще-то... Я не могу next получить из marker...
| Сообщение посчитали полезным: |
Ранг: 54.0 (постоянный) Активность: 0.02↘0 Статус: Участник
|
Создано: 25 ноября 2007 12:58 · Личное сообщение · #4
Вроде так будет правильно:
while true do begin
next := PItemIDList(cardinal(addr(marker^.mkid.abID)) - sizeof(marker^.mkid.cb) + marker^.mkid.cb);
if next^.mkid.cb = 0 then break;
marker := next;
end;
Изврат конечно, хотя, вдруг проканает?
| Сообщение посчитали полезным: |
Ранг: 260.2 (наставник) Активность: 0.19↘0 Статус: Участник
|
Создано: 25 ноября 2007 13:25 · Личное сообщение · #5
NeoTall пишет:
Ну, уж тогда: if next^.mkid.cb = 0
ну да точно, ещё не проснулсо..
гы, так ты везде не туда обращаешься!
NeoTall пишет:
if (pidl = nil) or (pidl.mkid.cb = 0) then
и Pro100ya тебе показал ещё..
| Сообщение посчитали полезным: |
Ранг: 387.4 (мудрец) Активность: 0.17↘0 Статус: Участник системщик
|
Создано: 26 ноября 2007 03:06 · Личное сообщение · #6
NeoTall, слуш, а может просто скомпиль и прицкпи .obj? На худой конец попроси компилер вывести тебе listing и воткни asm.
| Сообщение посчитали полезным: |