View Full Version : مشکل با تابع SelectNext
drstrike
چهارشنبه 11 خرداد 1390, 17:57 عصر
سلام
روال زیر رو تو یه یونیت جدا می نویسم،موقع کامپایل SelectNext رو نمیشناسه
Procedure NextTab(Sender: TObject; Var Key: Char)
begin
If Key = #13 Then
Begin
If HiWord(GetKeyState(VK_SHIFT)) <> 0 then
SelectNext(Sender as TWinControl,False,True)
else
SelectNext(Sender as TWinControl,True,True);
Key := #0
end;
end;
یونیت Controls هم توی Usesها Add شده.
کسی میدونه مشکل کار کجاس؟
SAASTN
چهارشنبه 11 خرداد 1390, 19:14 عصر
ببینید تابع SelectNext یکی از روتین های کلاس TWinControl و فرزندان اونه. این که می بینید این تابع در روالهای یک فرم کار میکنه بخاطر اینه که فرم خودش از TWinControl مشتق شده. حالا شما در این روالی که نوشتید بدون ذکر نام شیئ SelectNext رو بکار بردید که باعث بروز خطا میشه. ضمنا توجه داشته باشید که این روال با سطح دسترسی protected پیاده سازی شده، یعنی شما نمی تونید خارج از متدهای یک TWinControl فراخونیش کنید.
drstrike
یک شنبه 15 خرداد 1390, 19:53 عصر
حالا شما در این روالی که نوشتید بدون ذکر نام شیئ SelectNext رو بکار بردید که باعث بروز خطا میشه.
با نام شی هم فراخوانی کردم ولی بازم خطل میده!
راهی وجود داره که بشه این تابع رو توی یه یونیت (pas.) دیگه فرخوانی کرد؟
SAASTN
دوشنبه 16 خرداد 1390, 20:10 عصر
با نام شی هم فراخوانی کردم ولی بازم خطل میده!
راهی وجود داره که بشه این تابع رو توی یه یونیت (pas.) دیگه فرخوانی کرد؟
فکر کنم به این بخش اصلا توجه نکردید:
ضمنا توجه داشته باشید که این روال با سطح دسترسی protected پیاده سازی شده، یعنی شما نمی تونید خارج از متدهای یک TWinControl فراخونیش کنید.
مسئله اصلا یونیت و use کردن و این صحبتا نیست. این روال یکی از متدهای TWinControl هست و شما تنها می تونید اون رو به ازای یک نمونه از TWinControl فراخونی کنید. وقتی نویسندگان TWinControl سطح دسترسی این روال رو protected تعیین کردند، معنیش اینه که لزومی به استفاده از این تابع در محلی خارج از روالهای خود TWinControl یا فرزندانش نیست. حالا اگه از نظر شما هست، باید TWinControl و تمام کنترلهای مشتق شده از اون رو باز نویسی کنید که عمر نوح می خواد و توجیحی هم نداره. متاسفانه این تابع هم به قدری با بقیه روالها و مشخصات دیگه ی TWinControl درگیره که نمیشه کشیدش بیرون.
حالا شما بگید دقیقا به چه منظوری می خواید این کار رو بکنید، شاید راه دیگه ای هم وجود داشته باشه.
drstrike
دوشنبه 16 خرداد 1390, 21:59 عصر
باید TWinControl و تمام کنترلهای مشتق شده از اون رو باز نویسی کنید که عمر نوح می خواد و توجیحی هم نداره.
اتفاقا داشتم همین کارو می کردم که همین اول کار حساب کار دستم اومدو بیخیال شدم :لبخندساده:
حالا شما بگید دقیقا به چه منظوری می خواید این کار رو بکنید، شاید راه دیگه ای هم وجود داشته باشه.
راستش یه سری تابع رو باید تو یه فایل پیاده کنم و تحویل بدم. اون روالی که تو پست اول نوشتم یکی از اوناست.
کارشم مشخصه، با زدن کلید Enter شی بعدی که بتونه Focus رو بگیره SetFoucs میشه و با Shift+Enter شی قبلی.
غیر از SelectNext هم با تابع دیگه ایی بلد نیستم این کارو انجام بدم :لبخند:
SAASTN
دوشنبه 16 خرداد 1390, 23:28 عصر
راستش یه سری تابع رو باید تو یه فایل پیاده کنم و تحویل بدم.
شاید من بد پرسیدم، ولی منظورم این بود که چرا می خواید توی یه یونیت دیگه بنویسید؟
چیزی که به نظر میاد اینه که می خواید از تکرار جلوگیری کنید، یعنی مثلا توی یه پروژه بزرگتر که چند فرم داره نمی خواید یه تابع رو برای تک تک فرما بنویسید. اگه منظور یه همچین کاری باشه خوب راه درست اینه که متد مد نظر رو برای یه فرم پایه بنویسید و همه فرمهای پروژه (یا اون فرماهیی که این رفتار رو دارن) رو بجای TForm از این فرم نوشته شده مشتق کنید.
برای این کار یه فرم جدید توی پروژتون ایجاد کنید و مثلا همون تابع رو براش بنویسید. بعد از اتمام کار روی فرم یا توی یونیتش راست کلیک کنید و Add To Repository رو کلیک کنید. یه عنوان مناسب براش انتخاب کنید و OK. حالا برای ایجاد یه فرم جدید که از این فرم مشتق شده باشه از منوی فایل و زیر منوی New گزینه Other... رو انتخاب کنید و از مسیر Delphi Projects\Delphi Files عنوان فرمتون رو انتخاب کنید، فقط توجه کنید که توی پنجره New Items توی اون رادیوی پائین Inherit رو انتخاب کنید.
اما اگه کلا می خواید هرجوری شده اون تابع رو توی یه یونیت دیگه پیاده کنید یه ایده اولیه اینه:
procedure SelectNext(CurControl: TWinControl);
var
Parent: TWinControl;
I: Integer;
Found: Boolean;
FirstControl: TWinControl;
begin
Parent := CurControl.Parent;
if Assigned(Parent) then
begin
Found := False;
FirstControl := nil;
for I := 0 to Parent.ControlCount - 1 do
if (Parent.Controls[I] is TWinControl) then
begin
if TWinControl(Parent.Controls[I]).TabOrder = CurControl.TabOrder + 1 then
begin
TWinControl(Parent.Controls[I]).SetFocus;
Found := True;
Break;
end
else if TWinControl(Parent.Controls[I]).TabOrder = 0 then
FirstControl := TWinControl(Parent.Controls[I]);
end;
if (not Found) and Assigned(FirstControl) then
FirstControl.SetFocus;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
unit1.SelectNext(TButton(Sender));
end;
دوتا Button روی فرم بذارید و OnClick جفتشون رو برابر Button1Click قرار بدید. البته به احتمال زیاد باید روی این روال تستای بیشتری انجام بشه و شاید همه حالات رو در بر نگیره.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.