Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Работа с PChar средствами Windows (API) [D2005, XP]


Страницы:   1 2 3

Max_2006 ©   (2006-11-05 12:38:00) 

как работать с PChar в Delphi средствами Windows, т.е. API? Т.е. надо например воспользоваться API функцией GetSystemDirectory, что делать если после ее выполнения нужно выполнить что-то вроде SetLength(p, Length(p)); т.е. длина строки ранв MAX_PATH, после выполнения функции GetSystemDirectory, как обрезать строку?

var
 p: PChar
begin
 GetMem(p, MAX_PATH);
 GetSystemDirectory(p, MAX_PATH);

...
 FreeMem(p);

Работу со String и ShortString не предлагайте...


Anatoly Podgoretsky   (2006-11-05 15:50:00) [21]

> Max_2006  (05.11.2006 15:40:23)  [23]

Опять забыл приведение сделать, а ты сам не можешь догадаться? Тогда не
стоит программировать.


Ketmar   (2006-11-05 15:46:00) [22]

>[21] Anatoly Podgoretsky(c) 5-Nov-2006, 15:32
>не надо же полностью все писать, кое что надо
>оставить и автору
так это ж раздел "надмозги". тут неписаными правилами думать воспрещается. равно как и читать справку/книги. а ты издеваешься...


Max_2006   (2006-11-05 15:40:00) [23]

всеравно на строке N := GetSystemDirectory(S, MAX_PATH); ошибка: [Pascal Error] Unit1.pas(33): E2010 Incompatible types: 'string' and 'PAnsiChar'. А так все нормально работает:

SetLength(S, MAX_PATH);
N := GetSystemDirectory(@S[1], MAX_PATH);
SetLength(S, N);


sniknik   (2006-11-05 15:40:00) [24]

> а что быстрее будет работать S := PChar(S); или SetLength(S, N);?
спичка, раз...

> ошибка при компиляции: [Pascal Error] Unit1.pas(32): E2010 Incompatible types: 'string' and 'PAnsiChar'
он не учел, что функция виндовая с входным параметром PChar, и если использовать стринг то он тоже должен быть "наполненным" а не пустым (тогда можно сделать приведение типа после которого там быде во что писать функции)

вот пример "минимум"
procedure TForm1.Button1Click(Sender: TObject);
var
 a: array [0..MAX_PATH] of Char;
 s: string;
 n: Integer;
begin
 n:= GetSystemDirectory(a, MAX_PATH);
 //Win32Check(n <> 0); полезная функция но ексепты в модуле тоже SysUtils
 s:= a; //и "обрезание" и присваивание  
 //после этого можно
 Label1.Caption:= s;
 //впрочем можно и без этого, какая разница откуда копировать, разница где это предполагается использовать...
 Label1.Caption:= a;
end;
итого минимум
procedure TForm1.Button1Click(Sender: TObject);
var
 a: array [0..MAX_PATH] of Char;
begin
 GetSystemDirectory(a, MAX_PATH);
 Label1.Caption:= a;
end;

используя массив (говорилось ещё в [1])


Anatoly Podgoretsky   (2006-11-05 15:32:00) [25]

> Ketmar  (05.11.2006 15:24:18)  [18]

Смотри последний пример, ну не надо же полностью все писать, кое что надо
оставить и автору, у нас тут форум не по написанию программ, а для общения и
советов.


Anatoly Podgoretsky   (2006-11-05 15:31:00) [26]

> Max_2006  (05.11.2006 15:20:17)  [17]

Сделай придение к PChar - PChar(S) и выдели место для хранения результата
как SetLength(S, MAX_PATH)
Полный код будет выглядеть так


  SetLength(S, MAX_PATH);
  N := GetSystemDirectory(S, MAX_PATH);
  SetLength(S, N);


Добавить обработку ошибок


Anatoly Podgoretsky   (2006-11-05 15:27:00) [27]

> Max_2006  (05.11.2006 15:18:16)  [16]

> а что быстрее будет работать S := PChar(S); или SetLength(S, N);?
Естественно второе, поскольку не требуется сканировать строку на предмет
определения ее длины

> как же то что перед тем как строка string чтобы передалась в API ?
> функцию, она всеравно переводится в PChar?

Использовать функцию PChar, она проверяет не пустая ли строка и если не
пустая, то возращает указатель как есть, а если пустая, то возращает
указатель на предопределенную пустую строку, доступ к которой RO


Ketmar   (2006-11-05 15:24:00) [28]

>[14] Anatoly Podgoretsky(c) 5-Nov-2006, 14:56
>А тепеть тоже самое, но со String
э-э-э... скажи, что ты пошутил, а? не мог же ты серьёзно такой бред родить.


Max_2006   (2006-11-05 15:20:00) [29]

А еще в этом примере, Anatoly Podgoretsky ©   (05.11.06 14:56) [14] на строке N := GetSystemDirectory(S, MAX_PATH); ошибка при компиляции: [Pascal Error] Unit1.pas(32): E2010 Incompatible types: 'string' and 'PAnsiChar'


Max_2006   (2006-11-05 15:18:00) [30]

Anatoly Podgoretsky:

> // если есть желание обрезать то   S := PChar(S);// или
> воспользоваться результатом работы функции  SetLength(S,
>  N);

а что быстрее будет работать S := PChar(S); или SetLength(S, N);?

> А быстродействие с PChar хуже, функциям приходится искать
> конец строки методом сканирования. Кроме того как правило
> надо еще и выделять и освобождать память, при том в куче.

А как же то что перед тем как строка string чтобы передалась в API функцию, она всеравно переводится в PChar?


Anatoly Podgoretsky   (2006-11-05 14:57:00) [31]

> palva  (05.11.2006 14:22:07)  [7]

Мой код короче - одна или две строки, если с обрезанием.


Anatoly Podgoretsky   (2006-11-05 14:56:00) [32]

> Leonid Troyanovsky  (05.11.2006 14:03:05)  [5]

А тепеть тоже самое, но со String


var
  S: string;
  N: Integer;
begin
  N := GetSystemDirectory(S, MAX_PATH);
// если есть желание обрезать то
  S := PChar(S);
// или воспользоваться результатом работы функции
 SetLength(S, N);
end;


Anatoly Podgoretsky   (2006-11-05 14:52:00) [33]

> sniknik  (05.11.2006 14:02:04)  [4]

> ну ладно, пусть решили что оставить размер как есть эффективнее (не будем
> память экономить, переключимся на быстродействие),

А быстродействие с PChar хуже, функциям приходится искать конец строки
методом сканирования. Кроме того как правило надо еще и выделять и
освобождать память, при том в куче.


Anatoly Podgoretsky   (2006-11-05 14:49:00) [34]

> Dmitry_177  (05.11.2006 13:12:02)  [2]

> хотел бы сделать приложение максимально эффективное

А достигаешь совсем противоположного.


Anatoly Podgoretsky   (2006-11-05 14:49:00) [35]

> sniknik  (05.11.2006 13:05:01)  [1]

> интересно, а откуда берутся, в примерно в одно время, кучи однотипных
> вопросов, причём с примерно одинаковым незнанием тех же основ разными(???)
> авторами

А ты не знаешь? К сожалению в наших учебных заведения экзамены,
самостоятельные! работы проходят в одно и тоже время, а все предыдущее время
проводилось в других местах.


Anatoly Podgoretsky   (2006-11-05 14:47:00) [36]

> Max_2006  (05.11.2006 12:38:00)  [0]

Ее на надо образать, это лишнее, у нее есть естественный ограничитель.
А за что так ненавидишь тип String, вот там твое пожелание будет
естественным образом реализовано.

S := P;

Правда и P тут совсем лишнее. И заботиться об удалении не надо, и ошибок
будет на порядок меньше. В справке четко сказано, что тип String полностью
совместим с PCharи поэтому твое желание выглядит как то очень странно, если
не сказать больше.


KilkennyCat   (2006-11-05 14:37:00) [37]

> [4] sniknik ©   (05.11.06 14:02)
> и самое главное, все это, то что ты делаешь думая что оптимизация...,
>  на самом деле называется "экономия на спичках", за счет
> указателей, сдвигов, самостоятельных учетов блоков памяти,
> выиграть можно не более 5% скорости (испортить и сделать
> медленнее гораздо проще и вероятнее) чем если следовать
> стандартам (где уже все продумано), а вот на логике приложения
> можно выиграть на порядки (200%/1000%), если решать задачу
> а не проблемы выбранного пути решения... но почему то о
> ней не задумываются.


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


Leonid Troyanovsky   (2006-11-05 14:24:00) [38]


> Max_2006   (05.11.06 14:21) [6]

> Leonid Troyanovsky, Я имел ввиду на API, не используя модуль
> SysUtils. А функции StrAlloc и StrCopy какраз от туда...


GetMem, Move

--
Regards, LVT.


palva   (2006-11-05 14:22:00) [39]

Можно так:

{$APPTYPE CONSOLE}
uses Windows;
var
 s: String;
 len: Integer;
begin
 len := GetSystemDirectory(nil, 0);
 WriteLn(len);   // 18
 SetLength(s, len - 1);
 GetSystemDirectory(PChar(s), len);
 WriteLn(s);   // C:\WINNT\system32
end.


Max_2006   (2006-11-05 14:21:00) [40]

Leonid Troyanovsky, Я имел ввиду на API, не используя модуль SysUtils. А функции StrAlloc и StrCopy какраз от туда...


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо