Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2007.05.20;
Скачать: [xml.tar.bz2];

Вниз

Знаю, что решение совсем простое, но...   Найти похожие ветки 

 
ProgRAMmer Dimonych ©   (2007-04-22 16:39) [0]

найти чего-то не могу.

Стоит задача: написание компонента-наследника TCustomPanel. Контрол сам на себе рисует с помощью OpenGL. Когда происходит инициализация OpenGL, то переменной типа HDC присваивается значение, возвращаемое функцией GetDC. А при деинициализации вызывается ReleaseDC. Т.е. всё по учебнику.

Проблема в том, что при завершении приложения сначала удаляется форма, а затем происходит вызов деструктора моего контрола. В результате при вызове ReleaseDC программа вылетает с ошибкой о том, что контрол не имеет родительского окна.

Как устранить эту проблему?

Заранее спс.


 
ferr ©   (2007-04-22 16:47) [1]

> Проблема в том, что при завершении приложения сначала удаляется
> форма, а затем происходит вызов деструктора моего контрола.

сомнительно.


 
Gero ©   (2007-04-22 16:50) [2]

> Как устранить эту проблему?

Найти ошибку в своем коде.


 
ProgRAMmer Dimonych ©   (2007-04-22 16:54) [3]

> ferr ©   (22.04.07 16:47) [1]
> сомнительно.
Я тоже думал, что должно быть по-другому, но...

Я создал обработчик OnDestroy главной формы, на которой находится мой контрол, написал туда Form1.Hint:=""; (чтобы было на что поставить брякпоинт). После выполнения процедуры TForm1.Form1Destroy() происходит вызов деструктора...

destructor TOGLPanel.Destroy;
begin
DeInitOpenGL;
{Ещё всякие мелочи}
inherited Destroy;
end;

А DeInitOpenGL, вот он...

procedure TOGLPanel.DeInitOpenGL;
begin
wglMakeCurrent(0,0);
wglDeleteContext(hrc);
ReleaseDC(Self.Handle,DC);
end;

И вот этот-то ReleaseDC вылетает с EInvalidOp, хотя ещё в OnDestroy-процедуре Watch показывал Form1.OGLPanel1.Handle=<Некоторому числу>.

:(


 
ProgRAMmer Dimonych ©   (2007-04-22 17:35) [4]

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

Подскажите, пожалуйста, хотя бы в каком направлении искать?


 
_Аноним   (2007-04-22 17:38) [5]

Делай инийиализацию\деинициализацию не в конструктор \ деструкторе
а в CreateWnd \ DestroyWnd


 
ProgRAMmer Dimonych ©   (2007-04-22 17:40) [6]

> _Аноним   (22.04.07 17:38) [5]
> Делай инийиализацию\деинициализацию не в конструктор \ деструкторе
> а в CreateWnd \ DestroyWnd
Прошу прощения, за отсутствием достаточного опыта работы со вскими хэндлами окон и т.п. не понял Вашего совета. Объясните, пожалуйста, подробнее.


 
_Аноним   (2007-04-22 17:41) [7]

Что кстати правильно и по другой причине
Борланд любит время от времени пересоздать окно,
после того, как это случится, ты будешь иметь невалидный  хендл


 
ProgRAMmer Dimonych ©   (2007-04-22 18:08) [8]

Прямо не знаю, что делать.

Выкидываю исходник, пусть каждый укажет, что может быть причиной ошибки. Это то, что я наэкспериментировал. В оригинале был именно TPanel и override"нный метод Paint.

unit DSChart;

interface

uses
 SysUtils, Classes, Controls, OpenGL, Windows, ExtCtrls, Messages;

type
 TDSChart = class(TWinControl)
 private
   FData:array of Extended;
   //
   DC:HDC;
   hrc:HGLRC;
   { Private declarations }
 protected
   procedure PixelFormat;
   procedure InitOpenGL;
   procedure DeInitOpenGL;
   procedure Paint(var Message:TWMPaint); message WM_PAINT;
   { Protected declarations }
 public
   constructor Create(AOwner:TComponent); override;
   destructor Destroy; override;
   //
   procedure ClearData;
   procedure Add(Value:Extended);
   procedure AddEx0(Value:Extended; Position:Integer);
   procedure AddEx1(Value:Extended; Position:Integer);
   { Public declarations }
 published
   { Published declarations }
 end;

procedure Register;

implementation

procedure Register;
begin
 RegisterComponents("DimonSoft", [TDSChart]);
end;

//
//
//

procedure TDSChart.PixelFormat;
var
nPixelFormat:Integer;
pfd:TPixelFormatDescriptor;
begin
ZeroMemory(@pfd,SizeOf(pfd));
pfd.nSize:=SizeOf(pfd);
pfd.nVersion:=1;
pfd.dwFlags:=PFD_DOUBLEBUFFER or PFD_SUPPORT_OPENGL or PFD_DRAW_TO_WINDOW;
pfd.iPixelType:=PFD_TYPE_RGBA;
pfd.cColorBits:=24;
pfd.cAlphaBits:=64;
pfd.cAccumBits:=64;
pfd.cDepthBits:=32;
pfd.cStencilBits:=64;
pfd.iLayerType:=PFD_MAIN_PLANE;
nPixelFormat:=ChoosePixelFormat(DC,@pfd);
if nPixelFormat=0 then Exception.Create("Unable to set pixel format!!!");
SetPixelFormat(DC,nPixelFormat,@pfd);
end;

procedure TDSChart.InitOpenGL;
var
W,H:Integer;
begin
DC:=GetDC(Self.Handle);
PixelFormat;
hrc:=wglCreateContext(DC);
wglMakeCurrent(DC,hrc);
//
W:=Self.Width; H:=Self.Height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
if W<=H then
 glOrtho(-2,2,-2*H/W,2*H/W,-10,10)
else
 glOrtho(-2*W/H,2*W/H,-2,2,-10,10);
glViewPort(0,0,W,H);
end;

procedure TDSChart.DeInitOpenGL;
begin
wglMakeCurrent(0,0);
wglDeleteContext(hrc);
ReleaseDC(Self.Handle,DC);
end;

procedure TDSChart.Paint;
var
ps:TPaintStruct;
begin
BeginPaint(Self.Handle,ps);
glClearColor(1,0.5,0.5,1);
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(10);
glColor3f(0,1,0);
glBegin(GL_POINTS);
 glVertex3f(1.25,1.25,0);
 glVertex3f(-1.25,-1.25,0);
glEnd;
glEnable(GL_POINT_SMOOTH);
glColor3f(1,0,0);
glBegin(GL_POINTS);
 glVertex3f(1.25,-1.25,0);
 glVertex3f(-1.25,1.25,0);
glEnd;
glDisable(GL_POINT_SMOOTH);
glColor3f(0,0,1);
glBegin(GL_LINES);
 glVertex3f(1,-1,0);
 glVertex3f(-1,1,0);
 glVertex3f(1,1,0);
 glVertex3f(-1,-1,0);
glEnd;
glFlush;
SwapBuffers(DC);
EndPaint(Self.Handle,ps);
end;

//
//
//

constructor TDSChart.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
MessageBox(0,PChar(IntToStr(Self.Handle)),"",64);
SetLength(FData,0);
InitOpenGL;
end;

destructor TDSChart.Destroy;
begin
DeInitOpenGL;
SetLength(FData,0);
inherited Destroy;
end;

procedure TDSChart.ClearData;
begin
SetLength(FData,0);
end;

procedure TDSChart.Add(Value:Extended);
var
L:Integer;
begin
L:=Length(FData); SetLength(FData,L+1); FData[L]:=Value;
end;

procedure TDSChart.AddEx0(Value:Extended; Position:Integer);
var
L:Integer;
begin
L:=Length(FData);
if Position>=L then
 SetLength(FData,Position+1);
FData[Position]:=Value;
end;

procedure TDSChart.AddEx1(Value:Extended; Position:Integer);
begin
AddEx0(Value,Position-1);
end;

end.



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2007.05.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.041 c
15-1176851446
Германн
2007-04-18 03:10
2007.05.20
Вот интересно, это очепятка где-нить или совпадение?


15-1177056559
infom
2007-04-20 12:09
2007.05.20
Механизм отображения "красивого" графа


15-1177164438
Raqw
2007-04-21 18:07
2007.05.20
Подключается к интернету, но не загружаются страницы!


1-1174565452
thecat
2007-03-22 15:10
2007.05.20
Где взять mmx.dcu?


15-1177269761
ferr
2007-04-22 23:22
2007.05.20
Префикс vs суффикс.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский