PDA

View Full Version : سوال: بدست آوردن کنترل فعال یک پنجره با داشتن فقط مکان اشاره گر ماوس



mbshareat
شنبه 18 آذر 1391, 09:31 صبح
سلام
من یه پنجره Hint طراحی کردم. تازگی متوجه شدم که وقتی این Hint نمایش داده میشه دیگه نمیشه روی فشار کلید حساب باز کرد چون پنجره فعال همین پنجره Hint هست.
به نظرم اگه بتونم کنترل فعال از پنجره ای که زیر ماوس هست بدست بیارم و کلیدها رو (به نحوی که فعلا نمی دونم.مثلا SendMessage!) بهش ارسال کنم، مشکل حل بشه. البته نمی دونم اینکار اصولیه یا نه؟
فعلا من خواستم از کد زیر استفاده کنم اما ایراد داره:

function GetFormHandle(ObjHandle: THandle): THandle;
begin
if GetParent(ObjHandle) = 0 then
Result := ObjHandle
else
Result := GetFormHandle(GetParent(ObjHandle));
end;
Function HintActiveCtrl(H:THandle):TControl;
begin
Result:=
TForm(WindowFromPoint(Mouse.CursorPos)).ActiveCont rol;
end;


تبدیل هندل به فرم چطور ممکنه؟

Felony
شنبه 18 آذر 1391, 09:44 صبح
مشکل کد بالا چیه ؟ من در برنامه Handle Viewer تقریبا از همین روش استفاده کردم و بدون هیچ مشکلی هم کار میکنه . ( پست شماره 4 (http://barnamenevis.org/showthread.php?288947-%D8%A8%D8%AF%D8%B3%D8%AA-%D8%A2%D9%88%D8%B1%D8%AF%D9%86-%D9%87%D9%86%D8%AF%D9%84&highlight=handle+viewer))

دلفی پیاده سازی خاص خودش از Form ها رو داره ( TForm ) ، پس تابع API ی برای این کار موجود نیست، در VCL هم تابعی در نظر گرفته نشده ، کاری که باید بکنید این هست که تو یک حلقه هندلی که دارید رو با هندل فرم های موجود تو برنامه مقایسه کنید تا به فرم مورد نظر برسید .

mbshareat
شنبه 18 آذر 1391, 10:51 صبح
سلام

مشکل کد بالا چیه ؟
می دونم شما بزرگوار از WindowFromPoint(Mouse.CursorPos) استفاده کردید اما من برای اینکه کنترل فعال رو بدست بیارم باید یه شیء از نوع TForm داشته باشم.

تو یک حلقه هندلی که دارید رو با هندل فرم های موجود تو برنامه مقایسه کنید
من Hint سفارشی خودم رو توی یه یونیت دیگه نوشتم.
من هنوز جواب این سوال رو میخوام:

تبدیل هندل به فرم چطور ممکنه؟
اما نمی دونم مجازم بحث رو از موضوع تاپیک منحرف کنم؟من یه نگاهی به Hint استاندارد کردم.
دیدم فشار کلید رو هم بررسی می کنه (وقتی Hint استاندارد توی صفحه نمایش داده میشه فشار کلید باعث نا پدید شدن هینت و بررسی کلید میشه!) .یه چنین کدی برای تعریف فرم Hint نوشتم:

TMyForm = Class(TForm)
Private
procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
End;
....
procedure TMyForm.WMNCHitTest(var Message: TWMNCHitTest);
begin
Message.Result := HTTRANSPARENT;
end;

اما هنگام ایجاد فرم:

Form := TMyForm.Create(Application);
پیغام میده Resource TMyForm not found !

دو سوال دارم:
این پیغام برای چی بود؟
HTTRANSPARENT چه کار می کنه؟

Felony
شنبه 18 آذر 1391, 11:09 صبح
من هنوز جواب این سوال رو میخوام:
تبدیل هندل به فرم چطور ممکنه؟
توضیحات مربوطه رو در پست قبل دادم ، این هم یک تابع :


function Handle2Form(const Handle: THandle): TForm;
var
FormsCount: Integer;
begin
for FormsCount := 0 to Screen.FormCount - 1 do
if (Screen.Forms[FormsCount].Handle= Handle) then
Exit(Screen.Forms[FormsCount]);
end;

استفاده :


var
A: TForm;
begin
A:= Handle2Form(456898);
ShowMessage(A.Caption);
end;


اما هنگام ایجاد فرم:
Form := TMyForm.Create(Application);
پیغام میده Resource TMyForm not found !
تو پست شماره 8 این تاپیک (http://barnamenevis.org/showthread.php?344359-%D9%85%D8%B4%DA%A9%D9%84-%D8%AF%D8%B1-%D8%B3%D8%A7%D8%AE%D8%AA-Unit&p=1521402&viewfull=1#post1521402) قبلا توضیح دادم .

mbshareat
شنبه 18 آذر 1391, 12:09 عصر
ممنونم.
متاسفانه مشکل پیچیده تر از اونی بود که فکر می کردم!
من دو جور Hint دارم: یک نوعش که با کد نویسی پنجرش رو ایجاد می کردم که بدون این تغییرات از همون اول مشکلی با فشار کلید نداشت و فرمی که Hint نیلز داشت بدون مشکل به کلیدها جواب میداد.
یه Hint دیگه هم داشتم که فرمش رو تو محیط طراحی درست کرده بودم و فقط به کلید های تابعی(مثل F1 و..) درست جواب میده.
جای عجیبش اینه که کلیدهای جهت نما(مثل کلید جهت چپ) رو نگه میداره بدون اینکه ظارا کاری کرده باشه دریافت می کنه و بعد که Hint رو مخفی می کنم و دوباره همون کلید رو میزنم(مثلا کلید جهت چپ) انگار دوبار فشار دادم.
و اگه کلید Esc رو بزنم این کلید فقط به فرم ارسال میشه در حالی که یه ادیت هم میتونم با F2 باز کنم که به Esc جواب نمیده ولی فرم به Esc جواب میده.
فقط خواستم بگم برام خیلی گیج کننده ست (چه از WMNCHitTest استفاده بکنم یا نکنم وضع همینه!) ولی انتظار ندارم با این توضیحات بشه جواب گرفت!
انشاء الله یه چیزایی رو تست می کنم بلکه درست شد!

Felony
شنبه 18 آذر 1391, 12:15 عصر
من که نفهمیدم چی نوشتی و مشکلت دقیقا چیه ، در هر صورت اگر درست نشد یک نمونه برنامه قرار بده .
کامپوننت نوشتن های شما هم داستانی شده تو این انجمن :چشمک:

mbshareat
شنبه 18 آذر 1391, 12:31 عصر
خودم فهمیدم مشکل چیه!
نمی دونم چرا با فشار کلید فقط KeyDown اجرا میشه و KeyUp اجرا نمیشه.
من با فرم معمولی که به عنوان هینت استفاده می کنم مشکل دارم که با Show نمایشش میدم!
بحث خیلی از موضوع تاپیک منحرف شد. این هم فرم و یونیتش:

مهرداد صفا
شنبه 18 آذر 1391, 13:10 عصر
سلام
من یه پنجره Hint طراحی کردم. تازگی متوجه شدم که وقتی این Hint نمایش داده میشه دیگه نمیشه روی فشار کلید حساب باز کرد چون پنجره فعال همین پنجره Hint هست.
به نظرم اگه بتونم کنترل فعال از پنجره ای که زیر ماوس هست بدست بیارم و کلیدها رو (به نحوی که فعلا نمی دونم.مثلا SendMessage!) بهش ارسال کنم، مشکل حل بشه. البته نمی دونم اینکار اصولیه یا نه؟
فعلا من خواستم از کد زیر استفاده کنم اما ایراد داره:

function GetFormHandle(ObjHandle: THandle): THandle;
begin
if GetParent(ObjHandle) = 0 then
Result := ObjHandle
else
Result := GetFormHandle(GetParent(ObjHandle));
end;
Function HintActiveCtrl(H:THandle):TControl;
begin
Result:=
TForm(WindowFromPoint(Mouse.CursorPos)).ActiveCont rol;
end;


تبدیل هندل به فرم چطور ممکنه؟


سلام
ببخشید همشهری!
تا حالا فکر میکردم با استفاده از WindowFromPoint میتوان کنترل را هم از یک نقطه به دست آورد، ولی به هر حال فکر میکنم با استفاده از GetFocus از توابع User32 میتوانید کنترل فعال را به دست بیاورید و در صورت لزوم با استفاده از GetWindowText متن آن را گرفته و چک کنید که کنترل مورد نظر شماست یا نه؟
موفق باشید.

mbshareat
شنبه 18 آذر 1391, 18:01 عصر
سلام
نمیخوام کشش بدم.
من از روش مورد استفاده از هینتم که با کد پنجرش رو درست می کنم استفاده کردم مشکل حل شد. برای نمایش پنجره از این کد به جای Show استفاده کردم:
SetWindowPos(Handle, HWND_TOP
,Left,Top,Width,Height,
SWP_SHOWWINDOW or SWP_NOACTIVATE or SWP_NOSIZE);

حالا مشکلش از جهت پاسخ دادن به کلید حل شد اما نمی فهمم چرا مخفی نمیشه!

mbshareat
شنبه 18 آذر 1391, 18:22 عصر
سلام
یه کاریش کردم ممنون.
جناب M.safa اگر میخواید بیشتر بدونید به لینک داخل پست شماره دو برید.