Динамический массив в функции CreatePolygonRgn

Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду

Ответить
Viktor Zull
Сообщения: 117
Зарегистрирован: 10 ноя 2005, 02:00

Функция CreatePolygonRgn позволяет создавать сложную область окна из массива вершин переданных во втором параметре. Мне нужно было сделать следующее: есть строка такой структуры: [0,0][100,50][200,0]. То есть в этой строке записаны координаты точек по которым нужно строить область.
На основании этой строки я создаю массив элементов типа TPoints, который передаю в функцию CreatePolygonRgn. Количество вершин в строке не фиксированное, поэтому и массив я делаю динамическим. А когда использую его,функция возвращает значение 0, область не получается.

Код функции приведен ниже:

function CreateCompositRgn_v2(MPoints:String; ErrorCode:Integer):HRGN;
const
ENoBeginPos = 1; //скобка не открыта
ENoEndPos = 2; //скобка не закрыта
ENoSeparator = 3; //нехватает запятой
ENoLongValue = 4; //нечисловое значение
var
ind:Integer;

separatorPos,
beginPos,
endPos:Integer;

MatrixPoints: array of array of Integer; //Хранит значения вершин полученных из текстовой строки
xValue, yValue:integer;
indM:integer;

v:array of TPoint; //массив вершин передаваемый в функцию
rgn:HRGN;

begin
separatorPos :=0;
beginPos := 0;
endPos := 0;

ErrorCode := 0;

//подсчет специальных символов
for ind := 0 to Length(MPoints) do
begin
if MPoints[ind] = '[' then
inc(beginPos)
else if Mpoints[ind] = ']' then
inc(endPos)
else if MPoints[ind] =',' then
inc(separatorPos);
end;

//проверка правильности строки:
if beginPos < endPos then ErrorCode := ENoBeginPos
else if endPos < beginPos then ErrorCode := ENoEndPos
else if beginPos = endPos then
begin
if separatorPos <> beginPos then ErrorCode := ENoSeparator
else
begin
//установка размеров массивов:
SetLength(MatrixPoints,beginPos,2);
SetLength(v,beginPos);

separatorPos :=0;
beginPos := 0;
endPos := 0;

//получение данных из строки:
indM :=0;
for ind := 0 to Length(MPoints) do
begin
if MPoints[ind] = '[' then
beginPos := ind
else if MPoints[ind] = ',' then
separatorPos := ind
else if MPoints[ind] =']' then
begin
endPos := ind;
try
xValue := StrToInt(Copy(MPoints,beginPos+1,separatorPos-beginPos-1));
yValue := StrToInt(Copy(MPoints,separatorPos+1,endPos-separatorPos-1));
MatrixPoints[indM,0] := xValue;
MatrixPoints[indM,1] := yValue;
inc(indM);
except
ErrorCode := ENoLongValue;
break;
end;
end;
end;
//создание массива вершин:
for ind := 1 to indM-1 do
begin
v[ind].X := MatrixPoints[ind,0];
v[ind].Y := MatrixPoints[ind,1];
end;

//вызов функции для построения сложной области:
Result := Windows.CreatePolygonRgn(v,indM,WINDING);

Finalize(MPoints);
Finalize(v);
end;
end;
end;

Я пробывал сделать массив не динамическим, а ограничить его [0..100000]. Тогда все получается. Но я думаю что и с динамическим должно получаться. Уважаемые участники форума, помогите разобраться, почему так происходит.
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Никак не взять адрес нулевого элемента с помощью семантики Дельфи? Возможно, придется делать Asm вставку.
2B OR NOT(2B) = FF
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Viktor Zull, все у тебя работает, только самый первый элемент всегда (0,0). Соответственно, если элемент 1, то функция возвращает 0. В моем случае:
h := CreateCompositRgn_v2('[0,0][110,50][200,0]', e); - работает ОК независимо от вида массива, а еще пробовал как ты ограничивать [0..1000] - тогда НЕ работает, т.к. в первом элементе массива V стоят громадные числа, что говорит о том, что элементы не были заполнены. Работает, когда [1..1000] - я не стал искать ошибки, думаю самому интересно будет. И еще - отключи Optimization - я с ней уже столько косяков в прошлом наловил, просто ужас...
Viktor Zull
Сообщения: 117
Зарегистрирован: 10 ноя 2005, 02:00

Я хотел привести код второй функции, но текст сообщения превысил максимальное количество строк. Она похожа на размещенную здесь. Но при использовании фиксированного массива я сначала заполнял все его элементы нулями, чтобы не было
"громандных чисел". Я использовал при этом только нужное количество элеменов сначала массива,а неиспользуемые оставались нулями и никакой роли не играли. Насчет того что первый элемент не заполняется, уж вижу свою опечатку - в цикле с 1 перебор начинается а нужно с 0. Но я пробывал и с 0 заполнять, много времени потратил думая в чем дело, неполучилось и поэтому обратился на форум. Если Вы считаете что все должно работать, я попробую еще раз. Спасбо Вам большое за внимание. Но если ж у меня не получится, я может еще продолжу тему.
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

&quot писал(а):Если Вы считаете что все должно работать
Я не считаю, я утверждаю - на моей семерке работает. Может в компиляции дело. Какая у тебя Delphi? Если есть возможность посмотри какой код генериться с разными массивами, поставь брякпоинт на v[ind].Y := MatrixPoints[ind,1] и нажми Ctrl+Alt+C
Аватара пользователя
Игорь Акопян
Сообщения: 1440
Зарегистрирован: 13 окт 2004, 17:11
Откуда: СПБ
Контактная информация:

&quot писал(а): превысил максимальное количество строк
думаю использование тэга

Код: Выделить всё

 должно решить проблему
Изображение
Ответить