Форум: "Основная";
Текущий архив: 2003.12.19;
Скачать: [xml.tar.bz2];
ВнизCanvas не позволяет рисовать - через 30 минут работы :-(( Найти похожие ветки
← →
Донской (2003-12-05 19:54) [0]Приветствую всех!
SNoCanvasHandle = "Canvas не позволяет рисовать"; - это ошибка которая появляется на win98 после почти часа работы осциллографа.
Судя по имени строки "Нет хендла канваса" - нету Хендла. А как же она до этого столько отработала??
Я уже два дня бьюсь, понять не могу. Пишет пишет осциллограмы и вдруг бац...
Куда Хендл может деться?
← →
Юрий Зотов (2003-12-05 21:06) [1]> Куда Хендл может деться?
Навскидку - две причины (первая, IMHO, более вероятна).
1. Идет утечка ресурсов GDI и они заканчиваются.
2. Уничтожается какое-то окно, на котором должна идти отрисовка.
Чтобы сказать точнее, нужно видеть код отрисовки. Еще можно включить Use debug DCUs, поставить условный BreakPoint в TCanvas.RequiredState на строке
raise EInvalidOperation.CreateRes(@SNoCanvasHandle);
и по приходу туда раскрутить стек вызовов.
← →
Nikolay M. (2003-12-05 21:09) [2]Делаешь GetDC/BeginPaint, но не делаешь ReleaseDC/EndPaint?
← →
Донской (2003-12-06 11:46) [3]Да, по поводу утечки ресурсов - есть такое. по крайней мере другие приложения под win98 начинают ругаться что им не хватает.
Но я-то делаю по-простому, доверил все VCL.
Moveto, Lineto и больше ничего.
> Nikolay M. ©
Я API не использую, в смысле напрямую. Если указанных действий не делает компонент TPAintBox - может быть такое разве? Вроде умные люди писали VCL.
← →
VICTOR_ (2003-12-06 12:18) [4]По возможности поставь WIN NT/2000/XP
← →
nikkie (2003-12-06 12:32) [5]>По возможности поставь WIN NT/2000/XP
и ошибка будет вылетать не через час, а через месяц работы.
ошибку исправлять надо. а без кода ничего сказать нельзя.
← →
Донской (2003-12-06 12:57) [6]Я кажется нашел, по совету Nilkolay M. - при каждой прорисовке делаю сначала GetDC, потом прорисовываю, а потом ReleaseDC.
procedure TFrameTechGraphics.paintelementsofgraf(erase:boolean; index:longint);
var Myhdc:hdc;
begin
if GrafInDraw then
exit;
Myhdc:=GetDC(handle);
if MyHDC=null then
raise exception.create("MyHDC = NULL");
//try
GrafInDraw:=true;
graffieldresize(nil);
//defineconstscale;
paintcorners;
GrafFieldclearcanvas;
paintgrids(erase);
paintgraf(erase,index);
paintscales(erase);
LFPaint;
HFpaint;
paintcursors(erase,-1);
ReDrawGraf;
reDrawScales;
setscrollparameters;
setscrollparametersVErt;
//except
//end;
GrafinDraw:=false;
releaseDC(handle,Myhdc);
end;
← →
VICTOR_ (2003-12-06 13:01) [7]>nikkie © (06.12.03 12:32) [5]
Согласен.
← →
Nikolay M. (2003-12-06 13:01) [8]А тебе компилятор не выдает предупреждение на строчку
var Myhdc:hdc;
что
Myhdc is declared but never used
?
Эта переменная у тебя в коде нигде не фигурирует - какой смысл в том, что-бы просто получать девайс контекст, а потом освобождать его?
← →
Донской (2003-12-06 13:47) [9]Уау а как вам это??
Зашел в файл Graphics? чтобы посмотреть что там вообще делается, дошел по ссылкам до процедуры CreateHandle, которая всегда вызывается классом TCanvas при попытке прорисовать (например, LineTo).
procedure TCanvas.CreateHandle;
begin
end;
Она же совсем пустая, неужели она что-то делает??
← →
Донской (2003-12-06 13:50) [10]> Nikolay M. ©
Нет, предупреждения не видно.
← →
Androw (2003-12-06 14:00) [11]Попробуй каждые 5 секунд загражать хэндл канваса в какую-то переменную, а при вознекновение исключения присваевай его обратно:
Unit Main;
Interface
...
Type
TMainForm = class (TForm)
...
Timer : TTimer;
AppEvent : TApplicationEvents;
PaintBox : TPaintBox;
...
Procedure TimerOnTimer(Sender : TObject);
Procedure AppEventOnException(Sender : TObject; E : Exception);
...
end;
Var
MainForm : TMainForm;
Canvas_Handle : THandle;
...
Implementation
...
Procedure MainForm.TimerOnTimer(Sender : TObject);
begin
Canvas_Handle := PaintBox.Canvas.Handle;
end;
Procedure AppEventOnException(Sender : TObject; E : Exception);
begin
If E = EInvalidOperation Then
PaintBox.Canvas.Handle := Canvas.Handle;
end;
...
end.
Эту операцию, если она мешает, можно вынестии в поток.
Желаю успехов!!!
← →
Донской (2003-12-06 14:16) [12]Ух, сильно!
Попробую, спасибо.
В любом случае здесь сообщу о результатах!
← →
Anatoly Podgoretsky (2003-12-06 14:26) [13]Nikolay M. © (06.12.03 13:01) [8]
Она используется
Донской © (06.12.03 13:47) [9]
Это виртуальный метод, сделано так, что бы не иметь проблемы с абстрактным методом.
← →
Nikolay M. (2003-12-06 14:32) [14]
> Донской © (06.12.03 13:47) [9]
> Уау а как вам это??
> Зашел в файл Graphics? чтобы посмотреть что там вообще делается,
> дошел по ссылкам до процедуры CreateHandle, которая всегда
> вызывается классом TCanvas при попытке прорисовать (например,
> LineTo).
>
> procedure TCanvas.CreateHandle;
> begin
> end;
>
>
> Она же совсем пустая, неужели она что-то делает??
Если посмотришь на объявление этой функции, то увидишь, что она объявлена как виртуальная. Логично, что эта процедура используется в классах-наследниках (например, TBitmapCanvas).
← →
Донской (2003-12-06 14:35) [15]Ну я запустил,
посмотрю минут через 20 не слетела ли.
Но вот какой вопрос.
Хорошо, произошла ошибка, Хендл восстановили. А как в этом случае ресурсы? Они-то в лучае такой ошибки восстанавливаются только после закрытия программы (по крайней мере у меня так было - пока проглючившую прогу не закроешь, остальные приложения прлохо прорисовываются и ругаются на недостаток ресурсов)
← →
Донской (2003-12-06 14:41) [16]По поводу виртуального метода я понял. Заглянул в аналогичный файл в Delphi 6 и там в комментариях сказано про это.
← →
Донской (2003-12-06 15:35) [17]Не, стало еще хуже. Это получилось слишком грубо.
В общем, я сделаю пока наверное на стандартном TChart? а там посмотрю...
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.12.19;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.009 c