C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

стр.: (2) < [1] 2 >
TGraphicControl?, Написание собственного компонента?
Александр
Отправлено: 22.10.2006, 13:28


Ученик-кочегар

Группа: Участник
Сообщений: 18



Здравствуйте!
Где (в каком заголовочном файле) находится TGraphicControl и как к нему обратиться, если я хочу написать на его базе свой компонент?
Заранее благодарен ответившим smile.gif
olegenty
Отправлено: 23.10.2006, 07:30


Ветеран

Группа: Модератор
Сообщений: 2412



Controls.hpp
Александр
Отправлено: 29.10.2006, 14:58


Ученик-кочегар

Группа: Участник
Сообщений: 18



Спасибо, работает biggrin.gif ,
Меня долго не было, так как закончился интернет sad.gif
Но тут я уже столкнулся с такой трудностью:
Где-то почитал, что TGraphicControl поддерживает канву. Но увы в списке функций я её не нашёл
Александр
Отправлено: 29.10.2006, 15:03


Ученик-кочегар

Группа: Участник
Сообщений: 18



Ой,... ohmy.gif Гуру, поздравлюя с прошедшим днем рождения. smile.gif
olegenty
Отправлено: 30.10.2006, 07:48


Ветеран

Группа: Модератор
Сообщений: 2412



TCustomControl имеет такое СВОЙСТВО, но не ФУНКЦИЮ
Александр
Отправлено: 30.10.2006, 13:13


Ученик-кочегар

Группа: Участник
Сообщений: 18



Хм, причем тут TCustomControl? У меня базовый класс — TGraphicControl. У него нет такого свойства. wizard.gif
Doga
Отправлено: 30.10.2006, 14:20


Мастер участка

Группа: Участник
Сообщений: 575



Привет!

Тем не менее, TGraphicControl имеет свойство Canvas. Правда, объявлено оно не в Public-секции, а в секции Protected. Но это не мешает всем наследникам класса TGraphicControl иметь доступк к вышеозначенному свойству Canvas.
olegenty
Отправлено: 30.10.2006, 14:45


Ветеран

Группа: Модератор
Сообщений: 2412



Если уж писать контрол, то наследоваться надо от TCustomControl. А дальше  — сам, сам...
Александр
  Отправлено: 30.10.2006, 20:07


Ученик-кочегар

Группа: Участник
Сообщений: 18



Привет, Doga!
QUOTE
Но это не мешает всем наследникам класса TGraphicControl иметь доступк к вышеозначенному свойству Canvas.

И как же к нему добраться? sad.gif

Гуру:
Хм, а ведь идея! Спасибо ...

Отредактировано Александр — 30.10.2006, 21:28
Doga
Отправлено: 31.10.2006, 16:30


Мастер участка

Группа: Участник
Сообщений: 575



Все общедоступные (Public) и закрытые (Protected) свойства и методы одинаково доступны в наследниках класса TGraphicControl, в отличие от частных (Private). Здесь имеется ввиду непосредственно код класса-наследника. т.е. Canvas->...

Если же Canvas Вас интерисует как общедоступное свойство в Вашем классе-наследнике, можно просто переобьявить его в Public-секции:
CODE

public:
TCanvas *Canvas;


Вообще, состав классов TGraphicControl и TCustomControl различен — просмотрите их свойства, методы и иерархию предков. Например, TGraphicControl не имеет такого полезного иногда свойства как DoubleBuffered. К тому же он не имеет фокуса ввода — т.е. у Вас будут некоторые ( biggrin.gif ) трудности при реализации в его наследнике простого текстового редактора.

Из стандартных компонентов, например, TGraphicControl является предком для TSpeedButton, TPie ...
TCustomControl является предком для TEdit, TStringGrid...
А TChart в конечном счёте вообще основан на классе TPersistent.

Короче, что б правильно выбрать предка Вам надо хорошо подумать biggrin.gif


P.S. Кстати, у TCustomControl Canvas то же закрытое (защищённое) свойство...

Отредактировано Doga — 31.10.2006, 21:38
Александр
Отправлено: 31.10.2006, 17:32


Ученик-кочегар

Группа: Участник
Сообщений: 18



Doga, спасибо большое!
Вы мне разъяснили картину.
Собственно TCustomControl будет наследовать много ненужных мне свойств
QUOTE
Вообще, состав классов TGraphicControl и TCustomControl различен — просмотрите их свойства, методы и иерархию предков. Например, TGraphicControl не имеет такого полезного иногда свойства как DoubleBuffered. К тому же он не имеет фокуса ввода — т.е. у Вас будут некоторые (  ) трудности при реализации в его наследнике простого текстового редактора.

Я хочу реализовать простую линию, без текста и т. п.

Поэтому — TCanvas — для меня единственное условие. И ещё одно, очень главное, чтобы контрол принимал форму нарисованной на нем Canvas'ом фигуры. Такое вообще возможно (с АПИ или без АПИ)???
Doga
Отправлено: 31.10.2006, 17:59


Мастер участка

Группа: Участник
Сообщений: 575



QUOTE

чтобы контрол принимал форму нарисованной на нем Canvas'ом фигуры


???
Александр
Отправлено: 31.10.2006, 19:23


Ученик-кочегар

Группа: Участник
Сообщений: 18



Я раньше программировал на Visual Basic. Там это реализовывалось через определнные АПИ, но весь процесс тормозила среда.
В то же время на Visual Basic 6 есть один нестандартный контрол Line. Который имеет именно форму линии. (не прозрачного прямоугольника с нарисованной на нем линией, а именно линии!!) Больше не в одной среде я такого чуда не видел.
Сейчас я хочу его написать на C++. На VB6 же написали как-то, но там нет возмодности сделать контрол, подобный линии. А сам бейсиковский меня не устраивает, потому что не распознает события мыши...
Эх... это если кратко
Александр
Отправлено: 31.10.2006, 20:01


Ученик-кочегар

Группа: Участник
Сообщений: 18



Ну ладно, пока ещё рано об этом говорить.
Еще дожить надо:
QUOTE
Все общедоступные (Public) и закрытые (Protected) свойства и методы одинаково доступны в наследниках класса TGraphicControl, в отличие от частных (Private). Здесь имеется ввиду непосредственно код класса-наследника. т.е. Canvas->...

Если же Canvas Вас интерисует как общедоступное свойство в Вашем классе-наследнике, можно просто переобьявить его в Public-секции:...
Что-то у мня в обоих случаях ошибка выскакивает:

Привожу полный текст
QUOTE
Project <название проекта> raised exception class EAccessViolation with 'Mesage violation at address 400B6DCB in module 'vcl60.bpl''. Read of address 00000000'. Process stopped. Use step or run to continue. ?
Doga
Отправлено: 31.10.2006, 20:22


Мастер участка

Группа: Участник
Сообщений: 575



Ну, это явно ваша ошибка smile.gif , Canvas тут не причём. Скорее всего Вы пытаетесь либо обратиться к неинициализированному объекту, либо очистить такой объект, либо что то подобное... Подключите к проэкту Host Application и смотрите в отладчике что там у Вас происходит.


А вообще, если Вам нужен контрол типа линии, советую обратить внимание на компонент TShape, предком которого является TGraphicControl. Может, всё таки, не стоит изобретать велосипед? biggrin.gif

Отредактировано Doga — 31.10.2006, 21:34
Александр
Отправлено: 31.10.2006, 21:17


Ученик-кочегар

Группа: Участник
Сообщений: 18



А что такое Host Application?

Да, скажите пожалуйста, сильно ли отличаются выражения:
:public TGraphicControl
и
:public Controls::TGraphicControl
?
Doga
Отправлено: 31.10.2006, 22:11


Мастер участка

Группа: Участник
Сообщений: 575



Host Application — это приложение, в которм будет тестироваться Ваш компонент в режиме отладки. Создаёте новое приложение, кидаете на форму компонент, компилируете и получаете EXEшник. Т.е. тот самый Host Application. Затем открываете BPK-проэкт Вашего компонента и в меню Run->Parameters... в качестве Host Application устанавливаете только что созданный Вами EXEшник. После этого становится доступной кнопка Run. Тыкайте в неё и наслаждайтесь biggrin.gif


:public TGraphicControl и :public Controls::TGraphicControl обычно равнозначны и редко кто пользуется уточнением Controls::, поскольку компилятор и так знает о чем речь, а программистам достаточно и одного TGraphicControl smile.gif . Но если Вы, в пику Борланду, решите написать свой TGraphicControl ohmy.gif , то тут могут начаться проблемы. И ругань компилятора по поводу его непонимания какой же из этих TGraphicControl'ов надо использовать, будет абсолютно правомерной angry2.gif . Именно для таких случаев, в качестве страховки и применяется уточнение (в данном случае Controls:: ) . Controls.pas — модуль, в котором объявлен TGraphicControl и уточнение Controls:: явным образом указывает компилятору откуда брать TGraphicControl.

Почитайте про Области Видимости (Name Space) . Все вышесказанное касается не только Controls, но и всех других областей видимости . cool.gif

Отредактировано Doga — 31.10.2006, 23:30
Александр
Отправлено: 31.10.2006, 23:59


Ученик-кочегар

Группа: Участник
Сообщений: 18



Что-то я никак свою ошибку не могу инициализировать
QUOTE
Скорее всего Вы пытаетесь либо обратиться к неинициализированному объекту, либо очистить такой объект, либо что то подобное...
меня все время выбрасывает в главный файл проекта в строчку
Application->Run();
Но эта ошибка как бы то ни было связана с канвой. Как только я что-то хочу нарисовать — выскакивает оона angry2.gif
cool.gif
Doga
Отправлено: 01.11.2006, 00:31


Мастер участка

Группа: Участник
Сообщений: 575



Поставьте точки останова там где Вы пытаетесь рисовать и по шагам смотрите значения переменных в инспекторе объектов
Александр
Отправлено: 01.11.2006, 15:04


Ученик-кочегар

Группа: Участник
Сообщений: 18



Да я так и сделал.
Сражу зе после строчки Canvas, меня выкидывает окошко с сообщением, вышепомянутым, и далее, как я сказал в главный файл...
sad.gif

По-видимому я что-то упустил из вида...

Пытаюсь сделать по аналогии:
в объявлении класса TImage есть такая срочка:
Graphics::TCanvas* __fastcall GetCanvas(void);
Я не пойму, где её объявили, эту функцию?

poland
Отправлено: 02.11.2006, 13:13


Ученик-кочегар

Группа: Участник
Сообщений: 16



QUOTE (Александр @ 31.10.2006, 20:23)
В то же время на Visual Basic 6 есть один нестандартный контрол Line. Который имеет именно форму линии. (не прозрачного прямоугольника с нарисованной на нем линией, а именно линии!!) Больше не в одной среде я такого чуда не видел.

А чем TShape плох — по крайней мере его можно использовать как образец кода.
В Raize (www.raise.com) есть компонент TRzLine.
В ABC (www.obsof.com/index.html) TabcLine
Это из того что у меня на компе есть.

У всех мышка отлично обрабатывается.
Александр
Отправлено: 02.11.2006, 16:35


Ученик-кочегар

Группа: Участник
Сообщений: 18




QUOTE
В Raize (www.raise.com) есть компонент TRzLine.
В ABC (www.obsof.com/index.html) TabcLine
Это из того что у меня на компе есть.
Что-то я не нашел, где их скачать. sad.gif может скинешь на мыло? smile.gif

Tshape — прислушаюсь, но там нет св-ва Canvas,
В лб, спасибо

poland
Отправлено: 02.11.2006, 17:55


Ученик-кочегар

Группа: Участник
Сообщений: 16



QUOTE (Александр @ 02.11.2006, 17:35)
Что-то я не нашел, где их скачать.

Мегабайт шибко много. Поспрашивай у китайцев. Они есть почти на любом CD с компонентами для BCB.
QUOTE
Tshape — прислушаюсь, но там нет св-ва Canvas.
А зачем компоненту линия Канва?
TShape наследуется от TGraphicControl. Я имел ввиду: посмотри его код и напиши по образцу свою линию, если очень хочется.
Александр
Отправлено: 02.11.2006, 18:30


Ученик-кочегар

Группа: Участник
Сообщений: 18



Хм, да у меня всё одно:
Та же самая ошибка выскакивает: может вы знаете
Напрмер в модуле заголовка компонента:
class PACKAGE TGraphControl1 : public Controls::TGraphicControl
{
private:
void __fastcall SetPen(Graphics::TPen* Value);
Graphics::TPen* FPen;
protected:
public:
int __fastcall drw();
__fastcall TGraphControl1(TComponent* Owner);
__property Graphics::TPen* Pen = {read=FPen, write=SetPen};
__published:

};
А далее в Form1.cpp
void __fastcall TForm1::Button1Click(TObject *Sender)
{
GraphicControl1->Pen->Color = 0;//на этой строчке выскакивает вышеупомянутая ошибка
}
По точкам стопа проходить не имеет смысла: до этой строчки все нормально, а дальше — выскакивает знакомое окно с сообщением
Admin
Отправлено: 03.11.2006, 08:09


Владимир

Группа: Администратор
Сообщений: 1190



А сам объект GraphicControl1 вы где-то создаете ?
Согласен c: "Скорее всего Вы пытаетесь либо обратиться к неинициализированному объекту, либо очистить такой объект, либо что то подобное... ".
Александр
Отправлено: 03.11.2006, 15:49


Ученик-кочегар

Группа: Участник
Сообщений: 18



QUOTE
А сам объект GraphicControl1 вы где-то создаете ?

Да вроде бы здесь:
CODE
#include <vcl.h>
#pragma hdrstop
#include "TGraphComponent.cpp"
#include "Test1Line.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TGraphControl1 *GraphicControl1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
{
GraphicControl1 = new TGraphControl1(Form1);
GraphicControl1->Parent = Form1;
GraphicControl1->Top = 100;
GraphicControl1->Left = 100;
GraphicControl1->Visible = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
       //GraphicControl1->Canvas->LineTo(100,100);
}
Doga
Отправлено: 03.11.2006, 19:27


Мастер участка

Группа: Участник
Сообщений: 575



Очевидно что Вы пытаетесь бороться со следствием а не с причиной ошибки. wink.gif

Если Вы не желаете следовать советам участников Форума, так хотя бы приведите здесь ВЕСЬ код своего компонента.
Александр
Отправлено: 03.11.2006, 19:49


Ученик-кочегар

Группа: Участник
Сообщений: 18



QUOTE
Очевидно что Вы пытаетесь бороться со следствием а не с причиной ошибки.
Как правило, когда мы не знаем настоящей причины, то так и происходит wink.gif

QUOTE
Если Вы не желаете следовать советам участников Форума, так хотя бы приведите здесь ВЕСЬ код своего компонента.
Я желаю, но... не получается sad.gif
Файл реализации компонента
CODE
//---------------------------------------------------------------------------

#include <basepch.h>

#pragma hdrstop

#include "TGraphComponent.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(TGraphControl1 *)
{
       new TGraphControl1(NULL);
}
//---------------------------------------------------------------------------
__fastcall TGraphControl1::TGraphControl1(TComponent* Owner)
       :TGraphicControl (Owner)
{

}
//---------------------------------------------------------------------------
namespace TGraphComponent
{
       void __fastcall PACKAGE Register()
       {
                TComponentClass classes[1] = {__classid(TGraphControl1)};
                RegisterComponents("Samples", classes, 0);
       }
}
//---------------------------------------------------------------------------
int __fastcall TGraphControl1::drw()
{
      //Canvas->LineTo(100,200);
}
Файл заголовка компонента:
CODE
//---------------------------------------------------------------------------

#ifndef TGraphComponentH
#define TGraphComponentH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <Graphics.hpp>
#include <sysmac.h>
//---------------------------------------------------------------------------
class PACKAGE TGraphControl1 : public Controls::TGraphicControl
{
private:
protected:
public:
       int __fastcall drw();
       Graphics::TCanvas* Canvas;
       __fastcall TGraphControl1 (TComponent* Owner);
__published:

};

//---------------------------------------------------------------------------
#endif
Файл реализации программы/формы (не знаю, как павльно):Test1Line.cpp

CODE
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include "TGraphComponent.cpp"
#include "Test1Line.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TGraphControl1 *GraphicControl1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
{
GraphicControl1 = new TGraphControl1(Form1);
GraphicControl1->Parent = Form1;
GraphicControl1->Top = 100;
GraphicControl1->Left = 100;
GraphicControl1->Visible = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
       //GraphicControl1->Canvas->LineTo(100,100);
}
//---------------------------------------------------------------------------

Ну и заголовка Test1Line.h
CODE
//---------------------------------------------------------------------------

#ifndef Test1LineH
#define Test1LineH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
       TButton *Button1;
       void __fastcall Button1Click(TObject *Sender);
private: // User declarations
public:  // User declarations
       __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

На форме лежит кнопка
Вроде все
Doga
Отправлено: 03.11.2006, 20:46


Мастер участка

Группа: Участник
Сообщений: 575



Ну вот, теперь всё ясно biggrin.gif

QUOTE

Скорее всего Вы пытаетесь либо обратиться к неинициализированному объекту, либо очистить такой объект, либо что то подобное...


Так и есть. А именно — первое.

Вместо того что бы использовать уже имеющееся свойство компонента Canvas, Вы объявляете новый Canvas, не предринимая никаких мер к его инициализации:
CODE

public:
      Graphics::TCanvas* Canvas;


т.е. теперь у Вас в компоненте есть FCanvas и Canvas!!! Зачем Вам 2 канваса?!!! Изучите код TGraphicControl ! Ведь говорили уже про это...
И уберите это объявление нафиг! angry2.gif

А в методе drw() исползуйте следующий код:
CODE

Canvas->MoveTo(0,0/*Или ещё где- нибудь*/); // Это кто будет за Вас делать?
Canvas->LineTo(100,200);

Вместо Вашего канваса будет использоваться уже имеющийся, инициализируемый в конструкторе класса TGraphicControl:
CODE

constructor TGraphicControl.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 FCanvas := TControlCanvas.Create;
 TControlCanvas(FCanvas).Control := Self;
end;


А вообще, это (т.е. рисовать) по хорошему надо делать в методе Paint.
И разберитесь в коде класса TShape — это поможет Вам продолжить работу над компонентом самостоятельно.

А теперь о том, что Вы должны были сделать ДО создания этой темы:
возьмите хороший учебник по C++, и изучите наконец, что такое КЛАССЫ!



cool.gif
Александр
Отправлено: 04.11.2006, 13:08


Ученик-кочегар

Группа: Участник
Сообщений: 18



Спасибо, Doga , всё работает!

И разберитесь в коде класса TShape — это поможет Вам продолжить работу над компонентом самостоятельно.

Спасибо! Так и сделаю

Учебник по С++?
Вообще у меня есть несколько, но куда я не смотрую на классы делается минимальный упор. Вот и приходится . . .

В следующий раз буду внимательней
wink.gif
стр.: (2) < [1] 2 >
Вернуться в Вопросы программирования в C++Builder