Главная страница
    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.044 c
2-1178037815
Антон Шестаков
2007-05-01 20:43
2007.05.20
Меню как в Nero


15-1177350860
ProgRAMmer Dimonych
2007-04-23 21:54
2007.05.20
Поясните, пожалуйста, такую вещь


6-1163510799
DVM
2006-11-14 16:26
2007.05.20
Отправка письма через Winsock, искажается поле Subject


8-1157428625
Irinka
2006-09-05 07:57
2007.05.20
Как загрузить png в Image без дополнительных компонент?


2-1178206705
RomanLN
2007-05-03 19:38
2007.05.20
Возможно ли создать таблицу зарание незная сколько будет полей





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский