Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Правильно получить информацию о дисках, не получается 
:(
    Опции темы
Router
Дата 29.3.2009, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 67
Регистрация: 23.11.2007

Репутация: нет
Всего: нет



Нужно получить список дисков и их метки, так как они показаны в проводнике.

Получить доступные диски не проблема.
Код

function get_system_drives() : shortstring;
var Drives : set of 0..25;
    i : byte;
begin
  result := '';
  integer(Drives) := GetLogicalDrives;
  for i := 0 to 25 do
    if i in Drives then
      result := result + chr(i + 65) + ' ';
end;

а вот метку у меня не получается получить. Использую функцию GetVolumeInformation.
Код

function GetVolumeLable(Drive : char) : shortstring;
var
  VolName, FileSysName: array [0..255] of char;
  MaxCompLength, FileSysFlags : cardinal;
  VolSerial : dword;
begin
  GetVolumeInformation(PChar(Drive + ':\'), VolName, 255, @VolSerial,
      MaxCompLength, FileSysFlags, FileSysName, 255);
  if (not (VolName[0] in [#1, #0])) then
  begin result := string(VolName); exit; end;
  result := '';
end;

Получается следующее:
Если метка тома задана то все нормально, я ее получаю.
Но если ее нет - то я получаю, пустую строку.
А мне надо получить метки, так как они отображении в проводнике, как мне быть?
user posted image

PM MAIL   Вверх
Rrader
  Дата 29.3.2009, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 29
Всего: 191



Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ShlObj, ShellAPI, ActiveX;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

function StrRetToStrW(pstr: PStrRet; const pidl: PItemIdList;
  out ppszName: PWideChar): HRESULT; stdcall; external 'shlwapi.dll';

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
const
  SHCONTF_STORAGE = $800;
var
  ID: PItemIDList;
  Malloc: IMalloc;
  Desktop: IShellFolder;
  MyComp: IShellFolder2;
  Enum: IEnumIDList;
  MCDrive: PItemIDList;
  FName: TStrRet;
  StringName: WideString;
  Buffer: PWideChar;
begin
  { Поправил }
  if Succeeded(CoGetMalloc(1, Malloc)) then
  try
    if Succeeded(SHGetSpecialFolderLocation(Handle, CSIDL_DRIVES, ID)) then
    try
      if Succeeded(SHGetDesktopFolder(Desktop)) then
      try
        if Succeeded(Desktop.BindToObject(ID, nil,
          IID_IShellFolder2, MyComp)) then
        try
          if Succeeded(MyComp.EnumObjects(Handle, SHCONTF_STORAGE, Enum)) then
          try
            while Enum.Next(1, MCDrive, PULONG(nil)^) = S_OK do
            try
              if Succeeded(MyComp.GetDisplayNameOf(MCDrive, SHGDN_NORMAL,
                FName)) then
              begin
                SetLength(StringName, MAX_PATH);
                if Succeeded(StrRetToStrW(@FName, MCDrive, Buffer)) then
                try
                  StringName := Buffer;
                finally
                  CoTaskMemFree(Buffer);
                end;
              end;
              ShowMessage(StringName);
            finally
              Malloc.Free(MCDrive);
            end;
          finally
            Enum := nil;
          end;
        finally
          MyComp := nil;
        end;
      finally
        Desktop := nil;
      end;
    finally
      Malloc.Free(ID);
    end;  
  finally
    Malloc := nil;
  end;
end;

end.


Это сообщение отредактировал(а) Rrader - 2.4.2009, 18:08


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
Router
Дата 29.3.2009, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 67
Регистрация: 23.11.2007

Репутация: нет
Всего: нет



А можно пояснить, что здесь происходит!
PM MAIL   Вверх
Rrader
  Дата 29.3.2009, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 29
Всего: 191



Работа с моим компьютером средствами оболочки smile 


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
Alix
Дата 31.3.2009, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


L45
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 4.5.2005
Где: Pskov/Spb

Репутация: 3
Всего: 23



Если explorer.exe не запущен, все будет нормально?

Добавлено через 7 минут и 7 секунд
Вначале возникла идея воспользоваться National Language Support API, но сходу функция типа GetText(localeid, stringid) найдена не была. Да и скорее всего этот текст - в ресурсах explorer'a. Кстати, тоже вариант, даже если само приложение не запущено.

Добавлено через 8 минут и 51 секунду
Под текстом имею в виду строку "Локальный диск" и т.п.


--------------------
Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois
PM MAIL ICQ Skype   Вверх
Rrader
  Дата 31.3.2009, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 29
Всего: 191



Цитата(Alix @  31.3.2009,  22:37 Найти цитируемый пост)
Если explorer.exe не запущен, все будет нормально?

Да


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
bems
Дата 31.3.2009, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 21
Всего: 88



Rrader, я в подобной задаче вместо вызова Malloc.Free делал CoTaskMemFree.
Про SHGetMalloc сказано 
Цитата
 This function is available through Microsoft Windows XP Service Pack 2 (SP2) and Windows Server 2003. It might be altered or unavailable in subsequent versions of Windows. Use the CoTaskMemFree and CoTaskMemAlloc functions in its place.


Еще для этой цели можно использовать ILFree, хотя и вместо нее говорят надо CoTaskMemFree
Цитата
Note  When using Microsoft Windows 2000 or later, use CoTaskMemFree rather than ILFree. ITEMIDLIST structures are always allocated with the Component Object Model (COM) task allocator on those platforms.


Короче что-то многовато тут способов. Почему ты делаешь именно так?

Это сообщение отредактировал(а) bems - 31.3.2009, 18:43


--------------------
Обижено школьников: 8
PM MAIL   Вверх
bems
Дата 31.3.2009, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 21
Всего: 88



Кстати с SHGetFileInfo с флажком SHGFI_DISPLAYNAME это будет короче


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Rrader
  Дата 1.4.2009, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 29
Всего: 191



Цитата(bems @  1.4.2009,  00:42 Найти цитируемый пост)
Про SHGetMalloc сказано

Цитата(bems @  1.4.2009,  00:42 Найти цитируемый пост)
Еще для этой цели можно использовать ILFree

Описание этих функций в разных редакциях MSDN было разным и двусмысленным. Сейчас, соглашусь, надо вносить исправления в коды. SHGetMalloc менять на CoGetMalloc. CoTaskMemXXX функции аналогичны методам интерфейса IMalloc, который для меня более удобен по возможностям, поэтому использую его.

Цитата(bems @  1.4.2009,  01:22 Найти цитируемый пост)
Кстати с SHGetFileInfo с флажком SHGFI_DISPLAYNAME это будет короче

Это реализовано через IShellFolder. Когда у нас на руках уже есть (как в этом примере) этот интерфейс, лучше использовать именно его smile


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
bems
Дата 1.4.2009, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 21
Всего: 88



Цитата(Rrader @  1.4.2009,  13:05 Найти цитируемый пост)
CoTaskMemXXX функции аналогичны методам интерфейса IMalloc, который для меня более удобен по возможностям, поэтому использую его
ну если бы только его, было бы понятно. Но в твоем примере есть и CoTaskMemFree. Может лучше однообразно? ну и явное присваивание nil интерфейсам имхо лишнее



Цитата(Rrader @  1.4.2009,  13:05 Найти цитируемый пост)
Это реализовано через IShellFolder. Когда у нас на руках уже есть (как в этом примере) этот интерфейс, лучше использовать именно его 
Дык в примере ты его сам получаешь, чтобы перечислить и узнать имена. Не феншуй.



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Rrader
  Дата 2.4.2009, 08:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 29
Всего: 191



Цитата(bems @  2.4.2009,  01:14 Найти цитируемый пост)
Может лучше однообразно? 

Можно!
Цитата(bems @  2.4.2009,  01:14 Найти цитируемый пост)
ну и явное присваивание nil интерфейсам имхо лишнее

В связи с тем, что интерфейс является сложным автообъектом и тесно связан с COM, я всегда и везде самостоятельно дереференсирую ссылки. Для локального кода это забота Delphi, но ссылки могут быть и глобальными, на что новички и попадаются.
Цитата(bems @  2.4.2009,  01:14 Найти цитируемый пост)
Дык в примере ты его сам получаешь, чтобы перечислить и узнать имена. Не феншуй.

Не совсем понял. Я использую IShellFolder в примере и только его, все однообразно.


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
bems
Дата 2.4.2009, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 21
Всего: 88



Цитата(Rrader @  2.4.2009,  08:48 Найти цитируемый пост)
Не совсем понял. Я использую IShellFolder в примере и только его, все однообразно. 

ну ты выше говорил "Когда у нас на руках уже есть (как в этом примере) этот интерфейс, лучше использовать именно его "
А я в примере вижу, что "уже есть" на практике означает "я его получаю только чтобы добраться до имени". Я понимаю была бы "сопутствующая" задача, для которой нужен этот интерфейс, тогда можно заодгл им же воспользоваться и для получения имён. А тут только ради имен все это. 

Да  я в общем не против этого примера, я просто дусал вдруго есть какие-то высшие причины. По ходу похоже что ты просто так привык когда-то, и пишеш на автомате. Ну оно работает и ладно.


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Rrader
  Дата 2.4.2009, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 29
Всего: 191



Цитата(bems @  2.4.2009,  23:47 Найти цитируемый пост)
на практике означает "я его получаю только чтобы добраться до имени"

Я его получаю только исходя из удобства перечисления объектов. smile 

И мне нравится функционал IShellFolder(2), тем более, когда все рядом


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0556 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.