Показать полную графическую версию : Delphi | PChar into Cardinal
Чо-т голова совсем не варит... Как из PChar (или PAnsiChar) "сделать" тип Cardinal/Integer? Ну, к примеру, когда посылаешь сообщение WM_SETTEXT в lParam надо впихнуть указатель на строку, а в функции SendMessage lParam объявлен как Integer. Аналогично если действовать через TControl.Perform, то там lParam объявлен как Cardinal.
Netscaper
11-01-2005, 15:30
var A : Cardinal;
S : String;
begin
A := Cardinal(PChar(S));
end;
Netscaper
Ура! В Дельфи оказывается тоже есть преобразование типов как в Си. Ура, ура!
А почему я только щас об этом узнал?
Секундочку... Но если действовать так, то возникает Exception (в момент вызова Application.Run)
Form1.Controls[i*11].SetTextBuf(PChar(names[1,i+1]));
Form1.Controls[i*11].Perform(WM_SETTEXT,0,Cardinal(PChar(names[1,i+1])));
Эти 2 куска кода должны вести себя одинаково, так? Но если заменить первый вторым, то смотрим на скриншот.
Добавлено:
EListError is raised when an error is made in a list, TStrings, or TStringList object.
Так у меня на форме нет списков и переменных TStrings тоже нет :confused:
Добавлено:
Тут еще подумал. А такой массив случайно не рассматривается в Делфи как TStrings^
a: array[1..n] of string;
Нееее... Это уж действительно бред пошел. Пора вздремнуть хоть часок
Netscaper
11-01-2005, 16:46
На рисунке сказано, что указанный индекс в списке выходит за пределы допустимых границ. Например, если на форме есть TListBox с 10 строчками, при обращении к 11 «вылезет» это исключение. Массив строк - не объект! Он не может рассматриватся как TStrings и т.п. Проверьте программу :)
заснуть не удалось...
Netscaper, я знаю, когда "вылезает" это исключение, но вот не могу понять где (встроенный дебаггер даже строку с исключением найти не может, точнее может, но это строчка Application.Run; ). Повторюсь, что
у меня на форме нет списков и переменных TStrings тоже нет
, но зато есть КУЧА Static Text (по-дельфийски Labels), некоторым из которых в определенный момент времени надо поменять "жирность" шрифта (про SetText я тут просто для примера написал). Вот со сменой этой жирности я и мучаюсь :). Что удивительно, у Form1.Controls[i] нет свойства TFont, которое есть у TControl, которым и является Form1.Controls[i]. Вот! Приходится через WinAPI выкручиваться, а там надо знать хендл конкретного контрола, который не знаю как найти, кроме функций поиска. Выкручиваемся соответственно через Form1.Controls[i].Perform(), но у него проблема с истолкованием PChar'a. Вот такая фигня...
Netscaper
11-01-2005, 20:07
Если хочешь, зашли в оркестр, посмотрю, а то что-то с твоих слов не очень ясно...
Netscaper, спасибо за хелпу, но с той проблемой (EListError) я уже рассчитался. Она происходила при вызове Form1.Controls с несколько превышенным значением i. Соответственно заработали пребразования типов (я, кстати, нашел по ним наконец-то инфу в хелпе, в топике про округление дробных чисел :) ). Но никак не удается сменить жирность шрифта :(
Кстати, в чем я тут не прав?
procedure TForm1.EditxChange(Sender: TObject);
var
a,b: Integer; s: String;
begin
[I]// ShowMessage(IntToStr(Sizeof(s))); { !REMOVE! : debug info }
Form1.Controls[Form1.ActiveControl.ComponentIndex].GetTextBuf(PChar(s), SizeOf(s)); { <-- ошибка EAccessViolation in 'user32.dll' }
Val(s,a,b);
if b<>0 then Form1.Controls[Form1.ActiveControl.ComponentIndex].SetTextBuf(PChar('0')) else
if a>999999 then Form1.Controls[Form1.ActiveControl.ComponentIndex].SetTextBuf(PChar('999999'));
end;
В указанном месте возникает ошибка. Если эту строчку закомментировать и подставить какое-нибудь значение s, например s:='123', то все без проблем.
И еще: можно ли получить хендл контрола на форме, если известен его номер?
Netscaper
13-01-2005, 19:32
Savant
И еще: можно ли получить хендл контрола на форме, если известен его номер?
Можно. Если этот контрол есть твинконтрол :)
Помести на форму две кнопки:
procedure TForm1.Button2Click(Sender: TObject);
begin
if (Form1.Controls[0] is TWinControl) then
ShowMessage(IntToStr((Form1.Controls[0] as TWinControl).Handle));
ShowMessage(IntToStr((Button1 as TWinControl).Handle));
end;
Если ошибка, значит, это - ошибка.
GetTextLen, GetTextBuf, Text Example - пример из Delphi Help
Этот пример копирует текст из поля редактирования в строку, заканчивающуюся нулем, а также кладёт строку в другое поле, когда пользователь кликает на кнопке формы.
procedure TForm1.Button1Click(Sender: TObject);
var
Buffer: PChar;
Size: Byte;
begin
Size := Edit1.GetTextLen; {Получить длину строки Edit1}
Inc(Size); {Добавляем 1 для нуля}
GetMem(Buffer, Size); {Динамически создаем буфер}
Edit1.GetTextBuf(Buffer,Size); {Копируем в буфер}
Edit2.Text := StrPas(Buffer); {Конвертируем буфер в Паскалевскую строку Edit2}
FreeMem(Buffer, Size);{ Освобождаем занятую память}
end;
Заметим, что такой же результат может быть получен проще:
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit2.Text := Edit1.Text;
end;
Netscaper, огромное спасибо за хелпу с получением текста, все отлично проворачивается.
можно ли получить хендл контрола на форме, если известен его номер? Можно. Если этот контрол есть твинконтрол :)К величайшему сожалению TLabel оказался производным от TGraphicControl. Зато вчитавшись в справку нашел кое-что полезное для себя:
The TStaticText component functions like TLabel, except that it descends from TWinControl and therefore has a window handle. Use TStaticText instead of TLabel when the component’s accelerator key must belong to a windowed control — for example, on an ActiveX property page.Самое важное выделил.
Netscaper
Можешь еще помочь? Как изменить порядок элементов в Form1.Controls[k] ? А то у меня с 0 по 4 идут TLabel, с 5 по 14 TImage, а потом снова продолжаются TLabel, но уже и вперемешку с TStaticText :biggrin: . И так я уже замучался сотню TLabel в TStaticText "переделывать", так тут еще фигня появилась. Пытался редактировать файл *.dfm, но он по-видимому не является определяющим в этом вопросе.
Netscaper
13-01-2005, 23:27
Не очень понял смысл использования свойства Form.Controls... Почему нельзя написать Form.Label1 или Form.StaticText?
Пытался редактировать файл *.dfm, но он по-видимому не является определяющим в этом вопросе.
Да, ты прав... Действительно, создается «от балды»... Влияет только на невизуальные компоненты, а на визуальные - нет. Порядок создания невизуальных можно менять в «Edit - Creation Order». Что, собственно, возвращает к вопросу о том, почему нельзя обращаться напрямую к Label или StaticText.
Netscaper
Не очень понял смысл использования свойства Form.Controls
У меня на форме МНОГО однотипных элементов всего четырёх "видов" (Label, StaticText, Edit, Image). Поэтому обращаться к ним ТАК
.........
Form1.Label1.Caption:="...";
Form1.Label2.Caption:="...";
...
Form1.Label20.Caption:="..";
.........
было бы не очень удобно и приятно.
Гораздо эффективнее так:
const a: array[1..20] of String = (...);
...........
for i:=0 to 19 do
Form1.Controls[i].SetTextBuf(PChar(a[i+1]));
Аналогично мне надо одновременно сменить "жирность" шрифта у нескольких стоящий подряд StaticText. Так вот этого удобного порядка не получается, часть элементов у меня перемешались. А вот найти где этот порядок? Я по-моеему уже все перекопал, что в папке с моим проектом лежит... :(
Netscaper
14-01-2005, 00:00
Но ты можешь сделать так:
procedure TForm1.Button1Click(Sender: TObject);
var i : integer;
begin
for i:=1 to 20 do
(FindComponent('Label'+IntToStr(i)) as TLabel).Caption := IntToStr(i);
end;
Netscaper
Полностью согласен, я несколько ранее рассматривал различные варианты реализации нужного мне алгоритма, но по скорости выиграл Form1.Controls[k].SetTextBuf(PChar(a[k+1])); Не люблю перескакивать с одного на другое когда уже готово приличное кол-во кода, но видимо придется, раз нет возможности изменить порядок следования элементов в Form1.Controls[k].
Но вот для смены "жирности" шрифта он, кажется, мне подходит. Почему-то про него я забыл.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.