PDA

View Full Version : چطور مشخص میشه که یک کنترل فوکوس بشه یا نه؟



SAASTN
دوشنبه 23 آبان 1390, 00:58 صبح
میشه کاری کرد که کنترلی مثل TPanel هم فوکوس بشه؟
در واقع چه تفاوتی بین مثلا TButton با TPanel هست که یکی Message های مربوط به کیبورد رو دریافت می کنه و یکی نمی کنه؟

MohsenB
دوشنبه 23 آبان 1390, 02:38 صبح
سلام


هر دوی این کاپوننت ها از TWinControl ارث برده شدن ولی تنها تفاوتشون اینه که کنترلی مثل TButton پیامهای ویندوز رو دریافت میکنه و از اونا استفاده میکنه .

برای مثال همین کنترل TButton یه روال داره به این صورت :


procedure WndProc(var Message: TMessage); override;


بعد درون کد این روال اینطور نوشته شده :


procedure TButtonControl.WndProc(var Message: TMessage);
begin
case Message.Msg of
WM_LBUTTONDOWN, WM_LBUTTONDBLCLK:
if not (csDesigning in ComponentState) and not Focused then
begin
FClicksDisabled := True;
Winapi.Windows.SetFocus(Handle);
FClicksDisabled := False;
if not Focused then Exit;
end;
CN_COMMAND:
if FClicksDisabled then Exit;
end;
inherited WndProc(Message);
end;


که کار بردن فوکوس رو به کنترل انجام میده .


و یا برای کلیک کردن با کلید اینتر یا اسپیس :


procedure CMDialogKey(var Message: TCMDialogKey); message CM_DIALOGKEY;


procedure TCustomButton.CMDialogKey(var Message: TCMDialogKey);
begin
with Message do
if (((CharCode = VK_RETURN) and FActive) or
((CharCode = VK_ESCAPE) and FCancel)) and
(KeyDataToShiftState(Message.KeyData) = []) and CanFocus then
begin
Click;
Result := 1;
end else
inherited;
end;



موفق باشید .

SAASTN
دوشنبه 23 آبان 1390, 18:33 عصر
ممنون، من دقت نکرده بودم که حتی TButton هم خودش خودش رو فوکوس می کنه. اما مثلا شما همچین کدی رو توی TCutomEdit نمی بینید. به نظر می رسه که در مورد Edit پیام SET_FOCUS مستقیما توسط Windows به کنترل ارسال میشه.
من یکم بررسی کردم و به فراخونی متد CreateSubClass توی متد CreateParams مربوط به کنترل های فوکوس پذیر رسیدم، مثل:
// TCustomComboBox
CreateSubClass(Params, 'COMBOBOX');
// TCustomCheckBox, TButton
CreateSubClass(Params, 'BUTTON');
// TCustomEdit
CreateSubClass(Params, 'EDIT');

جالب اینجاس که اگه متد CreateParams یه کنترل مشتق شده از TWinControl مثل TPanel رو هم بازنویسی کنید و توش CreateSubClass رو با هر کدوم از پارامترهای بالا فراخونی کنید، اون کنترل هم فوکوس رو نگه میداره. اما مشکل اینجاس که بعضی تغییرات ظاهری به کنترل ما تحمیل میشه، مثلا اگه 'EDIT' رو ارسال کنید میبینید که Caret نمایش پیدا می کنه و شروع میکنه وسط کنترل چشمک زدن، حتی با زدن کلید ها متن Panel هم تغییر می کنه! یا زمانی که اون متد با 'BUTTON' فراخونی میشه زمانی که کنترل چندین بار پشت سر هم Repaint میشه می بینید که قبل از ترسیم به شکل Panel یه دکمه در جای کنترل ترسیم میشه و ...
حالا سوال اینجاس که CreateSubClass چه تغییراتی روی Params اعمال میکنه که منجر به این مسائل میشه و آیا میشه تنها بخش مربوط به ارسال فوکوس توسط Windows رو جدا و به کنترل (و در واقع Params) اعمال کرد؟

MohsenB
دوشنبه 23 آبان 1390, 20:19 عصر
سلام


با بررسیی که انجام دادم به این نتیجه رسیدم که برا مثال تابع CreateSubClass(Params, 'EDIT'); تنها میاد مشخصات پیش فرضی که ویندوز دوست داره رو تو Params قرار میده و ویندوز اون رفتاری رو برای این کنترل انجام میده که طبق الگوی مشخص شده باشد . مثلا برا این کنترل مشخص شده که طبق الگوی کادر متن با این کنترل رفتار کن . شما میتوانید اگر میخواهید کنترلی غیر از اشیاء استاندارد ویندوز ایجاد کنید این کد را در کنترل مورد نظر ننویسید و خودتون موقع گرفتن فوکوس کنترل را به دلخواه تغییر دهید .


موفق باشید .