Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.11.2011, 01:39   #1
Pamparam
Форумчанин
 
Регистрация: 08.11.2009
Сообщений: 225
По умолчанию Странные исключения

Есть таймер который вызывает следующую процедуру раз в 100мс
Код:
procedure showa3();
var foo: TPoint; foo2: TPoint;xz:string;  h:hwnd;h2:hwnd;r:       TRect;  pt:TPOINT;   ColorValue: integer; image1:Timage;
begin
      GetCursorPos(pt);
      ColorValue := GetPixel(GetDC(0), pt.X-2, pt.Y-2);
           ColorValue := GetPixel(GetDC(0), pt.X-2, pt.Y-2);
                ColorValue := GetPixel(GetDC(0), pt.X-2, pt.Y-2);
                     ColorValue := GetPixel(GetDC(0), pt.X-2, pt.Y-2);
      ColorValue := GetPixel(GetDC(0), pt.X-2, pt.Y-2);
           ColorValue := GetPixel(GetDC(0), pt.X-2, pt.Y-2);
                ColorValue := GetPixel(GetDC(0), pt.X-2, pt.Y-2);
                     ColorValue := GetPixel(GetDC(0), pt.X-2, pt.Y-2);
end;
Не спрашивайте в чем смысл функции... выдернуто из другой, более большой функции (В общем, нужно рисовать несколько десятков значений на канвасе, в зависимости от значения пикселя на экране).

При работе около минуты, иногда раньше, вылезают исключения (рандомно) двух типов:
Project Project2.exe raised exception class EOutOfResources with message 'Неверный дескриптор.
'. Process stopped. Use Step or Run to continue.

Project Project2.exe raised exception class EInvalidOperation with message 'Canvas does not allow drawing'. Process stopped. Use Step or Run to continue.
На строчку не указывают.
Пробовал добавлять проверку в таймер по переменной (в функцию showa3 добавлял в старт и в конец изменения переменной, а при тике таймера проверял ее значение, т.е. выполнилось ли предыдущее действие). Пробовал потоки юзать, хотя они здесь, по сути не нужны, и ошибок стало еще больше =\

Читаем правила раздела.
Там подробно написано, как следует оформлять код и что получается, если этого не делать.

Последний раз редактировалось Pamparam; 09.11.2011 в 02:08.
Pamparam вне форума Ответить с цитированием
Старый 09.11.2011, 01:57   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Код:
procedure showa3();
 var foo: TPoint; foo2: TPoint;xz:string; h:hwnd;h2:hwnd;r: TRect; pt:TPOINT; ColorValue: integer; image1:Timage;DC:HDC
 begin
 GetCursorPos(pt);
 DC:=GetDC(0);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ReleaseDC(0,dc);
 end;
а если так попробовать?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 09.11.2011, 02:03   #3
Pamparam
Форумчанин
 
Регистрация: 08.11.2009
Сообщений: 225
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
Код:
procedure showa3();
 var foo: TPoint; foo2: TPoint;xz:string; h:hwnd;h2:hwnd;r: TRect; pt:TPOINT; ColorValue: integer; image1:Timage;DC:HDC
 begin
 GetCursorPos(pt);
 DC:=GetDC(0);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ColorValue := GetPixel(DC, pt.X-2, pt.Y-2);
 ReleaseDC(0,dc);
 end;
а если так попробовать?
все равно вылазят...

Цитата:
Зачем вы отвечаете с цитированием всего предыдущего поста ?
Чтоб "простыня" подлиннее получилась ?
Чтоб ваш "драгоценнейший" пост занимал весь экран ?
Вы не видите кнопку справа от кнопки "Цитата" ?
Или вам почему-то не видно пустое окно редактора под последним сообщением, куда можно просто ввести ответ ?
За оверквотинг у нас штрафуют, имейте это ввиду.
Дабы не нарушать правила раздела, внимательно их почитайте...
за тем, что перед этим постом был еще один от другого пользователя, который позже был удален. Если вам делать нечего и нравится угадывать кто на какой пост ответил, то в след раз отвечу без квота

Последний раз редактировалось Pamparam; 09.11.2011 в 14:51.
Pamparam вне форума Ответить с цитированием
Старый 09.11.2011, 02:12   #4
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

походу, таймер у вас через потоки реализован
либо где-то ещё другой поток работает с GetDC(0)
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 09.11.2011, 08:55   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

veniside, +1

либо процедура в обработке таймера НЕ УСПЕВАЕТ завершиться до того, как опять происходит вызов процедуры таймера.
от этого очень легко защититься с помощью дополнительной глобальной переменной.
например.
Код:
..
  isTimerInside : boolean;
..
  на OnCreate формы
  isTimerInside ;= false;
...
procedure showa3();
 var foo: TPoint; foo2: TPoint;xz:string; h:hwnd;h2:hwnd;r: TRect; pt:TPOINT; ColorValue: integer; image1:Timage;DC:HDC
 begin
    if isTimerInside then Exit;
    isTimerInside := true;
    GetCursorPos(pt);
    DC:=GetDC(0);
 .....
    ReleaseDC(0,dc);
    isTimerInside ;= false;
 end;
Serge_Bliznykov вне форума Ответить с цитированием
Старый 09.11.2011, 14:47   #6
Pamparam
Форумчанин
 
Регистрация: 08.11.2009
Сообщений: 225
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
либо процедура в обработке таймера НЕ УСПЕВАЕТ завершиться до того, как опять происходит вызов процедуры таймера.
от этого очень легко защититься с помощью дополнительной глобальной переменной.
Цитата:
Сообщение от Parampampam
(в функцию showa3 добавлял в старт и в конец изменения переменной, а при тике таймера проверял ее значение, т.е. выполнилось ли предыдущее действие
Цитата:
походу, таймер у вас через потоки реализован
либо где-то ещё другой поток работает с GetDC(0)
в этой форме с getdc больше ничего не работает 100%

Последний раз редактировалось mihali4; 09.11.2011 в 17:22.
Pamparam вне форума Ответить с цитированием
Старый 09.11.2011, 18:38   #7
Pamparam
Форумчанин
 
Регистрация: 08.11.2009
Сообщений: 225
По умолчанию

Попробуем немного по-другому
Код:
procedure showa2();
var foo: TPoint; foo2: TPoint;xz:string;  h:hwnd;h2:hwnd;r:       TRect;  pt:TPOINT;   ColorValue: integer; ColorValue2: integer;image1:Timage; DC:HDC;
begin
    che:=1;
  GetCursorPos(pt);
    DC:=GetDC(0);
     ColorValue := GetPixel(GetDC(0), pt.X-2, pt.Y-2);
Form1.Image1.canvas.Pixels[5,5]:=random(1000000);
Form1.Image1.canvas.Rectangle(10, 5, 15, 10);
      ReleaseDC(0,dc);
   che:=0;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if che<>1 then showa2();
end;
Project Project2.exe raised exception class EInvalidOperation with message 'Canvas does not allow drawing'. Process stopped. Use Step or Run to continue.
Опять же упростил, но исключение вылазит. Работает несколько минут или меньше и прерывается именно на строке, которая выделена. Будь там
Код:
 ColorValue2 := GetPixel(GetDC(0), pt.X-1, pt.Y-2);
или
 Form1.Image1.canvas.Pixels[5,5]:=random(1000000);
т.е. после первой прорисовки в процедуре чего-то на канве - exception. Почему именно после первой и через длительное время работы программы? Что не так с канвой ? Мб отображение проги иногда подвисает и нельзя рисовать на канве? Можно ли как-то проверить готова ли канва?

Вообщем у меня почему-то кушало память, т.е., как будто, ReleaseDC(0,dc); не работал. Полазил по нету и нашел аналогичную проблему, где была та же ошибка и ело память (поэтому проверил свою прогу на утечку), там все решилось правильными значениями в ReleaseDC.
Но т.к. у меня releaseDC должно работать правильно пересмотрел подробнее пример. Там ТС использовал не глобальную переменную (для проверки выполнения в таймере), а остановку и запуск таймера в самом таймере, т.е.:
Код:
procedure TForm5.Timer2Timer(Sender: TObject);
begin
   Timer2.Enabled:=false;
showa3();
   Timer2.Enabled:=true;
end;
И, опа, заработало! Память теперь не увеличивается при работе этой процедуры!
Хз почему с переменной возникали проблемы, т.к. использовал данную процедуру в чистой форме (наверное значения неправильно синхронизировались в потоках таймера или т.п.).
такие вот пироги.

Последний раз редактировалось mihali4; 10.11.2011 в 19:50.
Pamparam вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
странные таблички Пепел Феникса Свободное общение 5 22.09.2010 14:13
странные проблемы с с++ Plastilin Общие вопросы C/C++ 9 21.02.2010 03:50
Странные ошибки. Rio309 Общие вопросы Delphi 2 19.10.2009 19:22
Странные окна в ХР. Танатис Windows 3 03.07.2009 14:13