View Full Version : مشکل در ساخت کامپوننت
MHajiSoft
جمعه 20 شهریور 1388, 19:35 عصر
من در حال طراحی یک کامپونت تقویم هستم. که پایه آن با محصولات Developer Express می باشد.
مشکل در کامپوننت cxListBox وحتی ListBox است. تابع OnDrawItem به هیچ عنوان فراخوانی نمیشود. یعنی میخواهم یک ایندکس مثلا به شماره 12 همیشه دورش قرمز باشد.
مشکل بعدی در مورد این دو کامپوننت این است که وقتی در یک Parent مانند TWinControl , TPanel قرار داده میشوند، نمیتوان سریعا آیتم های جدید به آنها اضافه کرد، منظورم پس از Create کلاس اصلی است.
یعنی با اجرای دستور TListBox.Items.Add پیغام خطایی مبنی براینکه این کنترل هیچ کنترل والدی ندارد داده میشود. اگر به صورت bpl استفاده شود که باید دلفی را دوباره اجرا کرد. در حالت برنامه نویسی معمولی هم که این کلاس ساخته نمیشود.
البته در شرایط وجود یک فرم، پس از قرار گرفتن کلاس اصلی روی فرم، میتوان با مراجعه به کلاس ساخته شده آیتم اضافه کرد. ولی همزمان با Construction نمیشود این کار را کرد. حتی از AfterConstruction نیز استفاده کردم ولی به نتیجه نرسیدم.
این مشکل را با کامپوننت cxHeader نیز دارم.
اگر دوستان راهنمایی به نظرشان میرسد، پیشاپیش از دکمه تشکر استفاده میکنم. :چشمک: :چشمک: :چشمک:
vcldeveloper
شنبه 21 شهریور 1388, 01:28 صبح
تابع OnDrawItem به هیچ عنوان فراخوانی نمیشود. باید خصوصیت OwnerDraw فعال باشه که اون رویداد فراخوانی بشه.
مشکل بعدی در مورد این دو کامپوننت این است که وقتی در یک Parent مانند TWinControl , TPanel قرار داده میشوند، نمیتوان سریعا آیتم های جدید به آنها اضافه کرد، منظورم پس از Create کلاس اصلی است.
یعنی با اجرای دستور TListBox.Items.Add پیغام خطایی مبنی براینکه این کنترل هیچ کنترل والدی ندارد داده میشود. اگر به صورت bpl استفاده شود که باید دلفی را دوباره اجرا کرد. در حالت برنامه نویسی معمولی هم که این کلاس ساخته نمیشود.کدی که برای constructor آن کامپوننت نوشتید رو اینجا بزارید.
MHajiSoft
شنبه 21 شهریور 1388, 08:54 صبح
با سلام و عرض تشکر از توجهتون :چشمک:
باید خصوصیت OwnerTrue فعال باشه که اون رویداد فراخوانی بشه.
متوجه منظورتون نشدم، این خصوصیت در کجا قرار داره. آخه در حالت عادی وقتی با Canvas مثلا FillRect را انجام میدهم باز تابع فراخوانی نمیشود.
کد مربوظ به Contruction هم به این صورت نوشتم.
قسمت مربوط به کلاس :
ThxCalendar = class(TcxControl)
private
FDayList : TcxListBox;
FCalHeader : TcxHeader;
{ Private declarations }
protected
{ Protected declarations }
public
constructor Create(AOwner : TComponent); override;
procedure AfterConstruction; override;
{ Public declarations }
published
{ Published declarations }
end;
قسمت Construction :
constructor ThxCalendar.Create(AOwner : TComponent);
var
i : integer;
begin
inherited Create(AOwner);
ParentColor := True;
Width := 143;
Height := 125;
FDayList := TcxListBox.Create(AOwner);
FCalHeader := TcxHeader.Create(AOwner);
FDayList.Parent := Self;
FDayList.Width := 120;
FDayList.Height := 92;
FDayList.Top := 33;
FDayList.Style.BorderStyle := cbsNone;
FDayList.StyleFocused.BorderStyle := cbsNone;
FDayList.StyleHot.BorderStyle := cbsNone;
FDayList.BiDiMode := bdRighttoLeft;
FDayList.Columns := 7; /// محل خطا
for I := 1 to 42 do
FDayList.Items.Add(inttostr(i));
FDayList.ItemIndex := 0;
FCalHeader.Parent := Self;
FCalHeader.Width := Width;
FCalHeader.Sections.Add; //// محل خطا
FCalHeader.Sections.Items[0].Width := Width - 2;
end;
vcldeveloper
شنبه 21 شهریور 1388, 19:30 عصر
متوجه منظورتون نشدم، این خصوصیت در کجا قرار داره. اشتباه تایپی بود، منظورم OwnerDraw بود. اشکال را اصلاح کردم.
روی خط 22 کد Break point بزارید و با F7 ببینید تغییر تعداد ستون ها در اون لیست باعث اجرای چه کدی میشه، و در کدام خط از اون کد شما خطا می گیرید. البته برای این کار نیاز دارید که سورس کامپوننت را داشته باشید.
MHajiSoft
یک شنبه 22 شهریور 1388, 14:03 عصر
با سلام وقتی از TListBox استفاده میکنم، خط 22 اجرا میشود ولی خظ 24 برای انجام تابع Add بدون اینکه روی سورس دیگری برودهمان پیغام خطا را میدهد.
Control '' has no parent window
اما وقتی از TcxListBox استفاده میکنم روی خظ 22 به فایل cxContainer رفته و پس از اجرای توابع در خط 5430 خطا میگیرد. تابع مورد استفاده cxGetScrollBarInfo میباشد. این فایل را ضمیمه کرده ام.
در ضمن خاصیت OwnerDraw در هیچ کدام از کنترل های TWinControl , TPanel, TListBox, TcxListBox وجود نداره که بتونم تو کلاس اصلی معرفیش کنم.
اگه لازمه بدونی از پکیج Developer Build 46 استفاده میکنم.
vcldeveloper
یک شنبه 22 شهریور 1388, 17:31 عصر
من با کامپوننت های DevExpress کار نمی کنم، و با مکانیزم داخلی آنها آشنا نیستم.
شما اگر کدهای خط 14 تا 32 را به AfterConstruction منتقل کنید، آیا باز همین پیغام خطا رو میده؟
MHajiSoft
یک شنبه 22 شهریور 1388, 21:32 عصر
سلام :لبخندساده:
کامپوننت های Developer Express مانند بقیه شرکت ها از ابتدا تمامی فایل های خود را ساخته است. یعنی برای تغییر کوچکی در یک کامپوننت ویژوال شاید مجبور به تغییر چند کلاس پایه آن باشید.
از AfterConstruction هم استفاده کردمم. جواب نمیده. . . . :ناراحت:
ممن کار با اشاره گر ها را بلد نیستم. فقط این سؤال برام پیش اومده، اگه در حال ساخت نمیتونه حافظه ای اختصاص بده میشه اونو با یک اشاره گر حل کرد. میگم در زمینه اشاره گر هیچ تجربه ای ندارم.
از اینکه به این موضوع توجه کردید ممنونم. :لبخندساده:
vcldeveloper
یک شنبه 22 شهریور 1388, 23:36 عصر
از AfterConstruction هم استفاده کردمم. جواب نمیده. . . . :ناراحت:
ممن کار با اشاره گر ها را بلد نیستم. فقط این سؤال برام پیش اومده، اگه در حال ساخت نمیتونه حافظه ای اختصاص بده میشه اونو با یک اشاره گر حل کرد. میگم در زمینه اشاره گر هیچ تجربه ای ندارم.
اونطور که از شواهد امر بر میاد، مشکل شما باید از Parent اون کنترل هایی که استفاده می کنید باشه. اینکه چرا میگه Parentایی وجود نداره، باید احتمالا به این دلیل باشه که شما Parent اون کامپوننت ها را در داخل constructor همان parent اختصاص میدید، یعنی تا زمانی که کار متد Create تمام نشده، شی مورد نظر شما آماده استفاده نیست، وقتی آن را به عنوان Parent به اون کنترل ها معرفی می کنید، و برخی از خصوصیات آن کنترل ها را تغییر می دهید، ظاهرا این تغییر خصوصیات باعث می شود که جایی در کد آن کنترل ها به Parent کنترل رجوع شود (مثلا برای رسم یک شکل خاص)، و چون Parent هنوز Create نشده، و در حال Create شدن هست، خطا دریافت می کنید. اگر مشکل این باشه، قاعدتا باید با انتقال کدها به AfterConstruction این مشکل بر طرف بشه.
برای بررسی این مشکل می تونید موقتا این کار را بکنید، کل کدهای مربوط به ساخت اون کنترل ها و تنظیم آنها را به یک متد دیگه (مثلا با نام Test) منتقل کنید، و سعی کنید در زمان اجرای برنامه، متد Test را فراخوانی کنید، و ببینید که آیا درست عمل میکنه یا نه.
اگه در حال ساخت نمیتونه حافظه ای اختصاص بده میشه اونو با یک اشاره گر حل کرد.
ربطی به اختصاص حافظه نداره، بلکه مسئله تنظیم Parent هست. وقتی شی خودتان Parent اون کنترل ها هست، و هنوز ساخته نشده، هر ارجاعی به Parent توسط اون کنترل ها موجب خطا میشه.
Parent در پنجره های ویندوز نقش مهمی ایفا میکنه، و خیلی از امور مربوط به یک کنترل یا بوسیله Parent انجام میشه، یا توسط Parent به اطلاع کنترل میرسه.
MHajiSoft
دوشنبه 23 شهریور 1388, 19:47 عصر
سلام
باز هم مشکل حل نشد. مثل اینکه AfterConstruction هم قبل از سوار شدن روی فرم اجرا میشود.
در هر صورت از راهنماییهاتون ممنونم. :لبخندساده:
vcldeveloper
دوشنبه 23 شهریور 1388, 22:12 عصر
باز هم مشکل حل نشد. مثل اینکه AfterConstruction هم قبل از سوار شدن روی فرم اجرا میشود.
فکر کنم مسئله شما این هست که کنترلی که Parent این کنترل ها محسوب میشه (یعنی همون شی ایی که از ThxCalendar ساخته میشه) در زمان اجرای Create و AfterConstruction هنوز خودش Parent نداره!
یعنی اول باید نمونه شی از ThxCalendar ساخته بشه، بعد Parent آن تعیین بشه، و بعد Parent مربوط به FDayList و FCalHeader تنظیم بشند. شما می تونید کدهای مرتبط با Parent را متد SetParent مربوط به ThxCalendar منتقل کنید. در اون متد ابتدا inherited را فراخوانی کنید تا شی شما صاحب parent شود، سپس چک کنید که Parent اختصاص داده شده Assigned شده باشه، و اگر بود، کدهای مورد نظرتان را اجرا کنید.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.