Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Ansi to Unicode


Автор: Artem148 13.7.2011, 21:34
Здрасте!

Проблема: Ansi to Unicode...

Автор: kami 13.7.2011, 22:56
Цитата(Artem148 @  13.7.2011,  21:34 Найти цитируемый пост)
Проблема: Ansi to Unicode...

(была шутка, удалена)
Поконкретнее, пожалуйста, потому что из описания проблемы вообще ничего не понятно.

Автор: Snowy 14.7.2011, 10:36
Artem148, это очень хорошо, что у тебя проблемы.
Форум для этого и существует, чтобы поддержать морально.
Давай, мы с тобой!!!

Автор: Clasteruga 14.7.2011, 12:50
Код

function WideStringToString(const ws: WideString; codePage: Word): AnsiString;
var
  l: integer;
begin
  if ws = '' then
    Result := ''
else
  begin
    l := WideCharToMultiByte(codePage,
      WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
      @ws[1], -1, nil, 0, nil, nil);
    SetLength(Result, l - 1);
    if l > 1 then
      WideCharToMultiByte(codePage,
        WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
        @ws[1], -1, @Result[1], l - 1, nil, nil);
  end;
end;

Код


function StringToWideString(const s: AnsiString; codePage: Word): WideString;
var
  l: integer;
begin
  if s = '' then
    Result := ''
else
  begin
    l := MultiByteToWideChar(codePage, MB_PRECOMPOSED, PChar(@s[1]), -1, nil,
      0);
    SetLength(Result, l - 1);
    if l > 1 then
      MultiByteToWideChar(CodePage, MB_PRECOMPOSED, PChar(@s[1]),
        -1, PWideChar(@Result[1]), l - 1);
  end;
end;

Автор: Artem148 14.7.2011, 14:29
Подробнее: Функция  DeviceIOControl (моя любимая) с параметром IOCTL_STORAGE_QUERY_PROPERTY возврашает:

    1) VendorIdOffset        
    2) ProductIdOffset       
    3) ProductRevisionOffset 
    4) SerialNumberOffset   

смещение ASCII string(http://msdn.microsoft.com/en-us/library/ff800835(v=VS.85).aspx), а прога пишется в DELPHI XE(UnicodeString, как я понял) - следовательно отсюда:
Проблема: Ansi to Unicode...

P.S: Надеюсь я обьяснился, а не запутал сильнее

Автор: 14SatanA88 14.7.2011, 14:49
издалека ты зашел, Artem148 smile

Автор: Snowy 14.7.2011, 15:39
Так и в чём проблема-то?
Нужен AnsiString? Ну так его и используй.
Хочешь превратить его в юникодную строку? Дельфи это делает автоматически при использовании присваивания.

Автор: Artem148 14.7.2011, 17:05
Цитата

Хочешь превратить его в юникодную строку? Дельфи это делает автоматически при использовании присваивания...


Если б это было так (у меня или "китайскиие символы" или знаки "?")

Цитата

Так и в чём проблема-то?


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

Цитата

Нужен AnsiString? Ну так его и используй.


Используем. В 2007 дельфи нормальные надписи. В ХЕ - нет.

Перефразирую вопрос: как получить при запросе  IOCTL_STORAGE_QUERY_PROPERTY нормальную запись, а не иероглифы?


Автор: Artem148 14.7.2011, 18:24
to Clasteruga: Результат использования твоей функции - знаки вопроса...  
 
user posted image

Автор: kami 14.7.2011, 18:28
Цитата(Artem148 @  14.7.2011,  17:05 Найти цитируемый пост)
В 2007 дельфи нормальные надписи. В ХЕ - нет.

код получения одной строки из ее смещения - в студию

Автор: Artem148 14.7.2011, 20:22
Ок. Но Автора уже не помю...

Код

function getValue(buf: PSTORAGE_DEVICE_DESCRIPTOR; offs: dword): string;
var
 mas: array[0..255] of char;
begin
  if offs=0 then exit;
    asm
      push eax
      push ebx
      push edx
      push esi
      push edi
      xor edi,edi
      xor esi,esi
      mov esi,offs
      lea edx,buf
      lea ebx,mas
      @m1:
      mov al,[edx+esi]
      mov [ebx+edi],al
      inc edi
      inc esi
      cmp al,0
      jne @m1
      pop edi
      pop esi
      pop edx
      pop ebx
      pop eax
    end;

  result := string(mas);

end;


Автор: kami 14.7.2011, 22:11
Во всем приведенном коде заменить Char на AnsiChar и string на AnsiString (в asm не вникал)

Автор: CodeMonkey 15.7.2011, 07:36
Цитата(Artem148 @  14.7.2011,  21:22 Найти цитируемый пост)
Ок. Но Автора уже не помю...


Какое слово было здесь непонятно?

Цитата(Snowy @  14.7.2011,  16:39 Найти цитируемый пост)
Нужен AnsiString? Ну так его и используй.


Автор: Чучмек 16.7.2011, 16:19
Цитата(Artem148 @  14.7.2011,  20:22 Найти цитируемый пост)
Ок. Но Автора уже не помю...

А зачем такой гемор?

Код

...
var 
pc:pchar;
begin
pc:=pchar(buf)+offs;
rezult:=pc;
....

Это для 7

Для XE
Код

var s:string;

s:=pansichar(cardinal(buf)+offs);



Автор: Artem148 18.7.2011, 18:06
Чучмек, ошибка:

user posted image

Код:

Код

type
  PSTORAGE_PROPERTY_QUERY = ^_TSTORAGE_PROPERTY_QUERY;
  TSTORAGE_PROPERTY_QUERY = packed record
    PropertyId:              Integer;
    QueryType:               Integer;
    AdditionalParameters: array [0..1] of WORD;
  end;

  _TSTORAGE_PROPERTY_QUERY = TSTORAGE_PROPERTY_QUERY;


type
 Storage_Bus_Type = ( BusTypeUnknown,
                      BusTypeScsi,
                      BusTypeAtapi,
                      BusTypeAta,
                      BusType1394,
                      BusTypeSsa,
                      BusTypeFibre,
                      BusTypeUsb,
                      BusTypeRAID );

type
 PSTORAGE_DEVICE_DESCRIPTOR = ^_TSTORAGE_DEVICE_DESCRIPTOR;
 TSTORAGE_DEVICE_DESCRIPTOR = record
   Version :               dword;
   Size :                  dword;
   DeviceType :            UCHAR;
   DeviceTypeModifier :    UCHAR;
   RemovableMedia :        BOOLEAN;
   CommandQueueing :       BOOLEAN;
   VendorIdOffset :        dword;
   ProductIdOffset :       dword;
   ProductRevisionOffset : dword;
   SerialNumberOffset :    dword;
   BusType :               STORAGE_BUS_TYPE;
   RawPropertiesLength :   dword;
   RawDeviceProperties :   array[1..500]of CHAR;
 end;

 _TSTORAGE_DEVICE_DESCRIPTOR = TSTORAGE_DEVICE_DESCRIPTOR;


function GetProductId(Device: PChar): String;
var
 hDevice        : THandle;
 ReturnedLength : THandle;
 STORAGE_DEVICE_DESCRIPTOR        : PSTORAGE_DEVICE_DESCRIPTOR;
 STORAGE_PROPERTY_QUERY           : PSTORAGE_PROPERTY_QUERY;
begin
  hDevice := CreateFile(pchar('\\.\' + Device),
           GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ + FILE_SHARE_WRITE,
                                                 nil, OPEN_EXISTING, 0, 0);


  ZeroMemory(STORAGE_PROPERTY_QUERY, SizeOf(STORAGE_PROPERTY_QUERY));

  if hDevice <> INVALID_HANDLE_VALUE then

    if DeviceIoControl(hDevice,
                       IOCTL_STORAGE_QUERY_PROPERTY,
                       STORAGE_PROPERTY_QUERY,
                       sizeof(STORAGE_PROPERTY_QUERY),
                       STORAGE_DEVICE_DESCRIPTOR,
                       sizeof(STORAGE_DEVICE_DESCRIPTOR),
                       ReturnedLength,
                       nil  ) then

      begin
        Result := PAnsiChar(Сardinal(STORAGE_DEVICE_DESCRIPTOR) + STORAGE_DEVICE_DESCRIPTOR.ProductIdOffset);
      end;
end;

Автор: Чучмек 18.7.2011, 19:23
А где выделяется память под STORAGE_DEVICE_DESCRIPTOR ?

Автор: Artem148 18.7.2011, 21:26
А-а, даже если обнулять, то ошибка выскакивает...

P.S Функция "ZeroMemory" заполняет указанный фрагмент памяти нулями ("обнуляет"),
      а выделяется при чтении декларации (Слово "Var"  smile )   smile 

Автор: Чучмек 18.7.2011, 22:22
Цитата(Artem148 @  18.7.2011,  18:06 Найти цитируемый пост)
STORAGE_DEVICE_DESCRIPTOR        : PSTORAGE_DEVICE_DESCRIPTOR;



Цитата(Artem148 @  18.7.2011,  18:06 Найти цитируемый пост)
PSTORAGE_DEVICE_DESCRIPTOR = ^_TSTORAGE_DEVICE_DESCRIPTOR;


var выделит 4 байта под указатель

Автор: Чучмек 18.7.2011, 22:44
Код

type
  PSTORAGE_PROPERTY_QUERY = ^_TSTORAGE_PROPERTY_QUERY;
  TSTORAGE_PROPERTY_QUERY = packed record
    PropertyId:              Integer;
    QueryType:               Integer;
    AdditionalParameters: array [0..1] of WORD;
  end;
  _TSTORAGE_PROPERTY_QUERY = TSTORAGE_PROPERTY_QUERY;
type
 Storage_Bus_Type = ( BusTypeUnknown,
                      BusTypeScsi,
                      BusTypeAtapi,
                      BusTypeAta,
                      BusType1394,
                      BusTypeSsa,
                      BusTypeFibre,
                      BusTypeUsb,
                      BusTypeRAID );
type
 PSTORAGE_DEVICE_DESCRIPTOR = ^_TSTORAGE_DEVICE_DESCRIPTOR;
 TSTORAGE_DEVICE_DESCRIPTOR = record
   Version :               dword;
   Size :                  dword;
   DeviceType :            UCHAR;
   DeviceTypeModifier :    UCHAR;
   RemovableMedia :        BOOLEAN;
   CommandQueueing :       BOOLEAN;
   VendorIdOffset :        dword;
   ProductIdOffset :       dword;
   ProductRevisionOffset : dword;
   SerialNumberOffset :    dword;
   BusType :               STORAGE_BUS_TYPE;
   RawPropertiesLength :   dword;
   RawDeviceProperties :   array[1..500]of CHAR;
 end;
 _TSTORAGE_DEVICE_DESCRIPTOR = TSTORAGE_DEVICE_DESCRIPTOR;
function GetProductId(Device: PChar): String;
var
 hDevice        : THandle;
 ReturnedLength : THandle;
 STORAGE_DEVICE_DESCRIPTOR        : TSTORAGE_DEVICE_DESCRIPTOR;
 STORAGE_PROPERTY_QUERY           : TSTORAGE_PROPERTY_QUERY;
begin
  hDevice := CreateFile(pchar('\\.\' + Device),
           GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ + FILE_SHARE_WRITE,
                                                 nil, OPEN_EXISTING, 0, 0);
  ZeroMemory(@STORAGE_PROPERTY_QUERY, SizeOf(STORAGE_PROPERTY_QUERY));
  if hDevice <> INVALID_HANDLE_VALUE then
    if DeviceIoControl(hDevice,
                       IOCTL_STORAGE_QUERY_PROPERTY,
                       @STORAGE_PROPERTY_QUERY,
                       sizeof(STORAGE_PROPERTY_QUERY),
                       @STORAGE_DEVICE_DESCRIPTOR,
                       sizeof(STORAGE_DEVICE_DESCRIPTOR),
                       ReturnedLength,
                       nil  ) then
      begin
        Result := PAnsiChar(Сardinal(@STORAGE_DEVICE_DESCRIPTOR) + STORAGE_DEVICE_DESCRIPTOR.ProductIdOffset);
      end;
end;

Автор: Artem148 19.7.2011, 09:13
Чучмек - волшебник...  smile 

Если не затруднит: объясните в чём ошибка?

Спасибо всем за помощь!

Автор: Чучмек 19.7.2011, 21:43
Прежде чем передавать  в функцию указатель на структуру, нужно сначала выделить память под оную.(new(),getmem() и др.)
А указатель в var указывает в никуда.
 "Собака" возвращает указатель на память выделенную для переменной.
sizeof для любого указателя возвращает 4.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)