PDA

View Full Version : بدست آوردن كنترل فوكوس بوده ماقبل آخر



seyed_farid
جمعه 06 خرداد 1390, 16:17 عصر
من ميخواهم با فشردن كليدي بفهمم كه قبل از فشردن اين كليد چه كنترلي فوكوس بوده است.
كسي ميتونه كمك كنه؟:تشویق:

tdkhakpur
جمعه 06 خرداد 1390, 18:37 عصر
اگر منظورتان اینه که فوکاس جاری رو بدنید با GetFocus این کار رو میشه انجام داد ولی وقتی روی کلید دیگه کلیک بشه اطلاعات قبلی از بین میره مگه اینکه خودتون یک spy برای این کار بنویسید که هر لحظه به focus ها گوش بده.(با کنترل پیغامهای wm_focus)

Felony
جمعه 06 خرداد 1390, 19:36 عصر
راحت ترین کاری که به ذنم میرسه این هست که یک متغییر ( مثلا LastFocusHandle به صورت Private در کلاس فرم برنامتون تعریف کنید ) :

private
{ Private declarations }
LastFocusHandle: THandle;
public
{ Public declarations }
end;

و یک تایمر روی فرم بزارید و خصیصه Interval ش رو با 10 مقدار دهی کنید ، حالا در رویداد OnTimer کد زیر رو بنویسید :
if GetFocus <> Button1.Handle then
LastFocusHandle:= GetFocus;

حالا میتونید تو دکمتون به صورت زیر نام کنترل قبلی که فکوس رو در اختیار داشته رو به دست بیارید :
var
ControlName: Array [0..255] of Char;
begin
GetWindowText(LastFocusHandle, ControlName, 255);
ShowMessage(ControlName);
end;

tdkhakpur
جمعه 06 خرداد 1390, 23:47 عصر
و یک تایمر روی فرم بزارید و خصیصه Interval ش رو با 10 مقدار دهی کنید ، حالا در رویداد OnTimer کد زیر رو بنویسید :


if GetFocus <> Button1.Handle then
LastFocusHandle:= GetFocus;


این کار درسته اما جواب قطعی برای این کار نیست همانطور که خودتان هم اشاره فرمودید عدد 10 نشون میده که بین این چک کردنها توسط تایمر یک فاصله ای هست و ممکن هست کلیک خوردن خارج از این محدوده زمانی باشه یعنی focus جدید رخ داده باشه.
برای اینکه کارتون تضمین شده باشه برای پیغام WM_KILLFOCUS دو سه خط برنامه بنویسید تا بتونید هندل جاری رو برای استفاده بعدی داسته باشید.

Felony
شنبه 07 خرداد 1390, 12:55 عصر
برای اینکه کارتون تضمین شده باشه برای پیغام WM_KILLFOCUS دو سه خط برنامه بنویسید تا بتونید هندل جاری رو برای استفاده بعدی داسته باشید.
تقریبا راه حل ساده دیگه ای وجو نداره ، منظورتون از 2 ، 3 خط کد چیه ؟
پیغام های WM_SetFocus و WM_KillFocus مستقیما به کنترل مورد نظر ارسال میشن و نمیشه براشون یک Message Handler عمومی نوشت ، میشه برای اشیاء مورد نظر Message Handler شون رو تغییر داد ( فقط اشیائی که از TWinControl مشتق میشن ) ولی باز هم برای اشیائی که WNDProc اختصاصی ندارند ( از TWinControl مشتق نشدن ) به مشکل بر میخوریم ، راه حل مورد نظر شما غیر از این هاست ؟ لطفا نمونه کد قرار بدید .

tdkhakpur
شنبه 07 خرداد 1390, 14:19 عصر
ولی باز هم برای اشیائی که WNDProc اختصاصی ندارند ( از TWinControl مشتق نشدن ) به مشکل بر میخوریم

اونهایی که به این شکل هستن پنجره پدر دارن و خودشون فوکاس نمیشن البته کسی هم سراغ اینگونه اشیا نمی ره تا این گونه تشخیص ها رو انجام بده.


راه حل مورد نظر شما غیر از این هاست ؟ لطفا نمونه کد قرار بدید .

راه حل همانی هست که پست 2 ارسال شد و نمونه کد برای اینگونه کارها زیاده.
هوگ پیغامهای ویندوز رو جستجو کنید

vcldeveloper
یک شنبه 08 خرداد 1390, 04:37 صبح
ولی باز هم برای اشیائی که WNDProc اختصاصی ندارند ( از TWinControl مشتق نشدن ) به مشکل بر میخوریم
کنترلی که WndProc نداره، یعنی هندل نداره؛ همچین کنترل هایی نمی تونند Focus داشته باشند.

Felony
یک شنبه 08 خرداد 1390, 09:52 صبح
کنترلی که WndProc نداره، یعنی هندل نداره؛ همچین کنترل هایی نمی تونند Focus داشته باشند.
به این دقت نکرده بودم ، پس با این حساب میشه مشکل رو با یک حلقه و تغییر Default WndProc حل کرد ...

tdkhakpur
یک شنبه 08 خرداد 1390, 12:59 عصر
پس با این حساب میشه مشکل رو با یک حلقه و تغییر Default WndProc حل کرد

نخیر نمیشه حل کرد چون فوکاس نمیشن!!!

Felony
یک شنبه 08 خرداد 1390, 16:35 عصر
نخیر نمیشه حل کرد چون فوکاس نمیشن!!!
منظورتون رو نفهمیدم ، چی فوکوس نمیشه ؟ آقای کشاورز گفت کنترلی که WndProc نداشته باشه فوکوس نمیشه ، پس ما هم نیازی به Override کردن Default WndProc اون نداریم چون کاربر نمیتونه روش فوکوس کنه !

tdkhakpur
دوشنبه 09 خرداد 1390, 00:44 صبح
منظورتون رو نفهمیدم ، چی فوکوس نمیشه ؟ آقای کشاورز گفت کنترلی که WndProc نداشته باشه فوکوس نمیشه
نمیدانم شاید این شکلی گفتن ولی پست ایشون این مطلب رو میرسونه که فقط به focus نمیتوانند پاسخ بدهند..
در کل کنترلهای ویندوز به این شکل ساخته و عکس العمل نشون میدن
اول اینکه هر چیزی که داخل ویندوز ساخته میشه براش یک کد واحد اختصاص داده میشه تا توسط اون جستجو و پیدا بشه که بهش میگن هندل و این هندل میتونه آدرس یک ساختار باشه یا یک عدد به عنوان ایندکس که مرجع رو نشون میده.
وقتی از این مرحله میگذرید میرسید به تحلیل نوع کنترل که چطوری و به چه نحوی ساخته میشه.
از نظر ساخت بستگی به زیبایی و یا کاربر پسند بودن داره مثلا یک Button میتونه به هر شکلی عمل کنه و بالا و پایین رفتن رو نشون بده مثل تفاوت بین bitbtn و خود button. و یا تفاوت بین button نسخه های مختلف دلفی.
حالا میرسید به اصل قضیه که کنترل چه کاری رو باید انجام بده یعنی هر کنترل برای اینکه بتونه از نظر پاسخ و پرسش با کاربر ارتباط داشته باشه و کاربر بتونه از دور کنترلش کنه یه سری کد به اسم پیغام براش تعبیه شده که توسط یک دونه case نوع و مسیر این پیغام مشخص میشه و پروسه ای رو که باید این case داخل قرار بگیره همان wndproc هست تا پیغامهایی مانند wm_paint و .. رو که مربوط طراحی کنترل و ... هست اجرا بشه پس نتیجه میگیرم که اگر wnproc نباشه کنترلی هم نیست البته دیده نشدن کنترل دلیل بر نبودن wndproc نیست بعضی از کنترلها مانند timer وجود دارن اما دیده نمیشه و wndproc هم ندارن ولی بصورت استاندار رویدادهای خاصی دارن که مسیر پیغام رو بهش ارجا میدن تا توسط اون با کاربر ارتباط برقرار بشه مانند OnTimer.
و در نهایت نداشتن هندل هم دلیل بر نداشتن wndproc نیست یا اینکه به زعم اینکه کنترل فوکاش نمیشه پس wndproc نداره برای اینکه که کنترل احتیاج به paint و یا repaint داره پس حداقل این دو پیغام هست که باید کنترل مورد اجرا قرار بده تا بتونه دیده بشه.

vcldeveloper
دوشنبه 09 خرداد 1390, 00:54 صبح
پس نتیجه میگیرم که اگر wnproc نباشه کنترلی هم نیست البته دیده نشدن کنترل دلیل بر نبودن wndproc نیست
کنترل هایی که از TGraphicControl مشتق میشند، WindProc ندارند، کنترل هم هستند! نیازی نیست که کنترل خودش حتما WndProc داشته باشه، همچین کنترل هایی (مثل TLabel, TImage و غیره) توسط کنترل Parent خودشون رسم میشند.



بعضی از کنترلها مانند timer وجود دارن اما دیده نمیشه و wndproc هم ندارن ولی بصورت استاندار رویدادهای خاصی دارن که مسیر پیغام رو بهش ارجا میدن تا توسط اون با کاربر ارتباط برقرار بشه مانند OnTimer.
TTimer مثال خوبی برای این صحبت نیست، چون TTimer از یک پنجره مخفی برای دریافت پیام های WM_TIMER ویندوز استفاده میکنه.

tdkhakpur
دوشنبه 09 خرداد 1390, 01:12 صبح
همچین کنترل هایی (مثل TLabel, TImage و غیره) توسط کنترل Parent خودشون رسم میشند.


نمیدانم ولی Label1.WindowProc ادرسی برای پردازش کنترل اراءه داده حالا شاید این ادرس ماله parent باشه ولی دلیل نمیشه که بگید label از خودش هیچ اختیاری نداره.
برای label تست نکردم ببینیم وقتی کلیک میشه این محدوده رو پروسه فرم مشخص میکنه یا خود label تا بتونه به click پاسخ داده بشه.

چون TTimer از یک پنجره مخفی برای دریافت پیام های WM_TIMER ویندوز استفاده میکنه.

خب چه فرقی داره این رویداد (OnTimer)داخل اون پینجره مخفی درج شده که کاربر میتونه ازش کار بکشه.

vcldeveloper
دوشنبه 09 خرداد 1390, 01:24 صبح
خب چه فرقی داره این رویداد (OnTimer)داخل اون پینجره مخفی درج شده که کاربر میتونه ازش کار بکشه.
فرقش در این هست:


بعضی از کنترلها مانند timer وجود دارن اما دیده نمیشه و wndproc هم ندارن ولی بصورت استاندار رویدادهای خاصی دارن که مسیر پیغام رو بهش ارجا میدن تا توسط اون با کاربر ارتباط برقرار بشه مانند OnTimer.
در پست قبلی توضیح دادم که اتفاقا TTimer همچین تابعی داره، و در پشت صحنه یک پنجره مخفی میسازه تا بتونه از طریق اون پیام های ویندوز رو دریافت کنه.