View Full Version : Event فشاردن کلید روی یک Form دیگر
searcher_man
چهارشنبه 08 مهر 1388, 08:40 صبح
سلام
می خوام برنامه ای بنویسم که بتونه روی یک Form یک نرم افزار دیگر یک سری Eventها را اجرا کنه بدین صورت که :
Formی از یک نرم افزار دیگر باز می شه ، حالا زمانی که من برنامه ای که نوشتم را اجرا کنم . بتونه روی Formی که از نرم افزار قبل بازشده Event فشاردادن کلید را به صورت F8 بعد از یک ثانیه F2 دوباره بعد از یک ثانیه F8 دوباره بعد از یک ثانیه F2 و ... تا زمانی که خودم Stop کنم را انجام بده .
لازم به ذکر است که از نرم افزار قبلی Sourceی نداریم.
سیکل اجرای نرم افزار
F8=>1Sec.=>F2=>1Sec.=>F8=>1Sec.=>F2 .... STOP
Mahmood_M
چهارشنبه 08 مهر 1388, 13:10 عصر
باید به پنجره ی مورد نظر پیغام بفرستید ... !
ابتدا میتونید با تابع FindWindow هندل پنجره مورد نظر رو بدست بیارید و بعد با استفاده از تابع PostMessage به هندل بدست اومده پیغام مربوط به کلید رو بفرستید ...
مثال :
procedure TForm1.BitBtn1Click(Sender: TObject);
var
H : THandle;
begin
H := FindWindow('AppClass', 'AppCaption');
PostMessage(H, WM_KEYDOWN, VK_RETURN, 0);
end;
به جای AppCaption باید عنوان پنجره ی مربوط به برنامه رو بنویسید و به جای AppClass هم باید نام Class فرم برنامه مقصد رو بنویسید ( مثلا TForm1 ) ، اما با دادن یکی از مقادیر عنوان یا نام کلاس ، هندل پیدا خواهد شد ، هر کدوم از این 2 مورد رو نداشتید به جاش Nil بزارید ! ...
اما برای رسیدن به هدفتون می تونید از یک تایمر استفاده کنید ، نکته ی مهم برای رسیدن به هدف والا ! کنترل کلیدها هست ، من یک نمونه براتون می زارم ، سورس رو نگاه کنید اگه مشکلی داشتید بگید تا توضیح بدم ...
از اینجا میتونید دانلود کنید : http://nabegheh.parsaspace.com/Examples/Post_Message.rar
در مثال بالا یک نمونه برنامه برای دریافت کلیدهای فشرده شده هم گذاشتم که میتونید با اون برنامه اصلی رو آزمایش کنید ...
موفق باشید ...
Batman
یک شنبه 02 اسفند 1388, 11:23 صبح
با سلام
من میخوام به edit یه برنامه دیگه مقدار بفرستم.من اسم فرم برنامه رو دارم اما با کد بالا فقط اسم برنامه تغییر میکنه.برای اینکه یه مقدار به edit داخل فرمی که اسمش رو میدونم بفرستم مراحل کار چطوریه؟در ضمن من اسم edit رو ندارم.
ممنونم
Batman
یک شنبه 02 اسفند 1388, 11:33 صبح
من میخوام دقیقا به همون قسمتی که با رنگ زرد مشخص شده داده بفرستم یا بگیرم.در ضمن دقت کنید که همونطوری که گفتم من اسم form رو میدونم ولی اسم اون edit رو نمیدونم و اینکه توی برنامه از pagecontrol استفاده شده.
ممنونم
Felony
یک شنبه 02 اسفند 1388, 11:53 صبح
شما باید هندل اون ادیت رو به وسیله ی تابع FindWindowEX به دست بیارید و بهش متن مورد نظرتون رو ارسال کنید .
یه نمونه کد براتون نوشتم که متن Test رو به Edit پنجره Run ارسال میکنه :
var
Hand: THandle;
begin
Hand:= FindWindow('#32770','Run');
Hand:= FindWindowEX(Hand,0,'ComboBox','');
SendMessage(Hand,WM_SetText,0,Integer(PChar('Test' )));
end;
Batman
یک شنبه 02 اسفند 1388, 12:30 عصر
شما باید هندل اون ادیت رو به وسیله ی تابع FindWindowEX به دست بیارید و بهش متن مورد نظرتون رو ارسال کنید .
میشه بگید چطوری؟من که اسم edit رو ندارم.
Mahmood_M
یک شنبه 02 اسفند 1388, 15:14 عصر
میشه بگید چطوری؟من که اسم edit رو ندارم.
نیازی به اسم Edit نیست ، با بدست آوردن هندل فرم می تونید به عناصر داخل اون هم دسترسی داشته باشید ، فقط باید نوع ( یا کلاس ) اونها رو بدونید ، اگر برنامه ی مقصد با دلفی نوشته شده باشه ، Edit داخلش از نوع TEdit هست ، اگر مثلا با VB نوشته شده باشه از نوع Text هست و ...
در کد بالا که آقا مجتبی قرار دادن ، Combobox مربوط به کلاس شی ای هست که در پنجره ی Run ویندوز می تونید دستورتون رو توش بنویسید ...
موفق باشید ...
Modernidea
یک شنبه 02 اسفند 1388, 15:42 عصر
نیازی به اسم Edit نیست ، با بدست آوردن هندل فرم می تونید به عناصر داخل اون هم دسترسی داشته باشید ، فقط باید نوع ( یا کلاس ) اونها رو بدونید
اگر چندین شی از یک کلاس بود یعنی چندین Edit در یک فرم وجود داشت!؟
چطوری باید اون شی مورد نظر را انتخاب کنیم؟
Batman
یک شنبه 02 اسفند 1388, 16:12 عصر
نیازی به اسم Edit نیست ، با بدست آوردن هندل فرم می تونید به عناصر داخل اون هم دسترسی داشته باشید ، فقط باید نوع ( یا کلاس ) اونها رو بدونید ، اگر برنامه ی مقصد با دلفی نوشته شده باشه ، Edit داخلش از نوع TEdit هست ، اگر مثلا با VB نوشته شده باشه از نوع Text هست و ...
در کد بالا که آقا مجتبی قرار دادن ، Combobox مربوط به کلاس شی ای هست که در پنجره ی Run ویندوز می تونید دستورتون رو توش بنویسید ...
موفق باشید ...
خوب میشه محبت کنید و کدش رو بذارید؟
ممنونم
Mahmood_M
یک شنبه 02 اسفند 1388, 17:55 عصر
اگر چندین شی از یک کلاس بود یعنی چندین Edit در یک فرم وجود داشت!؟
چطوری باید اون شی مورد نظر را انتخاب کنیم؟
اگر نام Edit رو نداشته باشید ، باید از نام کلاس استفاده کنید که در این صورت برنامه اولین کلاس هم نام با نام وارد شده رو که پیدا میکنه پیغام رو به همون می فرسته و یا اینکه می تونید به همه اونها پیغام بفرستید ( یا توابعی مثل EnumWindows اگر اشتباه نکرده باشم ! ) ، به هر حال باید مشخصه ای از کنترل مورد نظر پیدا کنید و به برنامه بدید تا برنامه بتونه اون کنترل رو از سایر کنترلها متمایز کنه ، اون مشخصه می تونه یک متن هم باشه ، مثلا فرض کنید در یک Edit در یک نرم افزار دیگه یک متنی نوشته شده ، اگر نام Edit رو ندونید و فقط متن درون اون رو هم بدونید باز میشه پیداش کرد ، با توابعی مثل GetWindowText یا ...
توابع EnumWindows و GetWindowText رو جستجو کنید ، فکر کنم در سایت مقاله و مثال باشه ، اگر نبود بگید تا یک نمونه قرار بدم ...
خوب میشه محبت کنید و کدش رو بذارید؟
ممنونم
کدش رو جناب SilverSoft گذاشتن
توضیح کد :
Hand:= FindWindow('#32770','Run');
مقدار متغیر Hand رو برابر با هندل پنجره ای که عنوانش Run هست قرار میده ، می تونید به جای مقدار 32770# مقدار Nil رو قرار بدید و نام کلاس رو برای پنجره نا دیده بگیرید در این صورت فقط عنوان پنجره رای پیدا کردن اون ملاک خواهد بود :
Hand:= FindWindow(nil,'Run');
...
Hand:= FindWindowEX(Hand,0,'ComboBox','');
تابع FindWindowEx نسخه ی کاملتری از تابع FinWindow هست که می تونید با اون عناصر داخل یک پنجره که Handle اون رو دارید رو پیدا کنید ، در کد بالا Hand همون Handle پنجره هست که در خط بالایی کد اون رو پیدا کردیم و در نهایت برابر مقدار Handle کلاس ComboBox درون پنجره ی Run قرار می گیره ، در کد بالا ComboBox نام کلاس شی ComboBox درون پنجره ی Run ویندوز هست که با کد بالا اون رو پیدا می کنیم ...
SendMessage(Hand, WM_SetText, 0, Integer(PChar('Test')));
کد بالا هم متن " Test " رو به هندل نهایی پیدا شده که همون ComboBox درون پنجره ی Run هست می فرسته ...
اگر مشکلتون جای دیگه ای هست بگید ...
موفق باشید ...
Felony
یک شنبه 02 اسفند 1388, 18:35 عصر
اگر چندین شی از یک کلاس بود یعنی چندین Edit در یک فرم وجود داشت!؟
چطوری باید اون شی مورد نظر را انتخاب کنیم؟
میتونید با تابع GetWindow هندل شئ مورد نظر رو پیدا کنید ، نمونه کدی که در زیر نوشتم هندل Edit ها UserName و Password پنجره Dial-up Connection رو برمیگردونه :
var
Hand, UserName, Password: THandle;
begin
Hand:= FindWindow('#32770','Connect Dial-up Connection');
UserName:= FindWindowEX(Hand,0,'Edit',nil); // دریافت هندل ادیت نام کاربری
Password:= GetWindow(UserName,GW_HwndNext);
Password:= GetWindow(Password,GW_HwndNext); // دریافت هندل ادیت کلمه عبور
end;
این کد رو قبلا یکی از کاربران ( Damavand ) قرار داده بود .
Batman
یک شنبه 02 اسفند 1388, 20:13 عصر
ببینید توی صفحه قبلی یه تصویر گذاشتم.
اسم فرم TForm1 هستش.داخل یکی از اون سه tab مربوط به pagecontrol یه edit با مقدار عددی 30 وجود داره.حالا میخوام بدونم که چجوری میتونم این مقدار رو مثلا 50 بکنم.
امیدوارم که دیگه این دفعه تونسته باشم منظورم رو برسونم.
Felony
دوشنبه 03 اسفند 1388, 05:11 صبح
ببینید توی صفحه قبلی یه تصویر گذاشتم.
اسم فرم TForm1 هستش.داخل یکی از اون سه tab مربوط به pagecontrol یه edit با مقدار عددی 30 وجود داره.حالا میخوام بدونم که چجوری میتونم این مقدار رو مثلا 50 بکنم.
امیدوارم که دیگه این دفعه تونسته باشم منظورم رو برسونم.
ما که همه نوع مثالی زدیم ، دیگه دنبال چی هستید ، فقط باید یکم کد رو دستکاری کنید .
اگر میتونید اون برنامه مورد نظرتون رو قرار بدید تا کد رو بر اساس اون تغییر بدم .
Batman
دوشنبه 03 اسفند 1388, 08:31 صبح
ما که همه نوع مثالی زدیم ، دیگه دنبال چی هستید ، فقط باید یکم کد رو دستکاری کنید .
اگر میتونید اون برنامه مورد نظرتون رو قرار بدید تا کد رو بر اساس اون تغییر بدم .
این هم لینک
http://rapidshare.com/files/354080336/DLL.rar
Felony
دوشنبه 03 اسفند 1388, 10:15 صبح
فایلی که قرار دادید یکسری dll و ... هست ، قایل اجرایی وجود نداره که بررسی کنم و کد رو براتون تغییر بدم .
Batman
دوشنبه 03 اسفند 1388, 12:31 عصر
http://rapidshare.com/files/354145714/New_folder__5_.rar.html
Felony
دوشنبه 03 اسفند 1388, 14:05 عصر
این کد هندل Edit مورد نظرتون رو به دست میاره و متنش رو به Test تغییر میده :
var
Hand: THandle;
begin
Hand:= FindWindow('TForm1','WBE RFDemo V2.0');
Hand:= FindWindowEX(Hand,0,'TGroupBox','');
Hand:= FindWindowEX(Hand,0,'TPageControl','');
Hand:= FindWindowEX(Hand,0,'TTabSheet','Mifare R/W');
Hand:= FindWindowEX(Hand,0,'TGroupBox','Mifare1 Fuction');
Hand:= FindWindowEX(Hand,0,'TEdit',nil);
Hand:= GetWindow(Hand,GW_HwndNext); // Get next object handle to find own edit
Hand:= GetWindow(Hand,GW_HwndNext); // Get next object handle to find own edit
Hand:= GetWindow(Hand,GW_HwndNext); // Get next object handle to find own edit
Hand:= GetWindow(Hand,GW_HwndNext); // Get next object handle to find own edit
Hand:= GetWindow(Hand,GW_HwndNext); // Here i find handle of my own edit
SendMessage(Hand,WM_SetText,0,Integer(PChar('Test' )));
end;
البته یکم ساده تر از این هم میشد ولی من حوصله نداشتم .
Batman
دوشنبه 03 اسفند 1388, 14:43 عصر
مشکل حل شد.ممنونم.خوب حالا چجوری میشه مقدار همون edit رو توی edit برنامه خودم بریزم؟
pezhvakco
دوشنبه 03 اسفند 1388, 17:09 عصر
درود :
استادان با حوصله :
اگه خواسته باشی با مرور گرهای اینترنت همین کار رو انجام بدی (ارسال و دریافت مقادیر)، چه طوری هاست .
تشکر...
Felony
دوشنبه 03 اسفند 1388, 18:15 عصر
درود :
استادان با حوصله :
اگه خواسته باشی با مرور گرهای اینترنت همین کار رو انجام بدی (ارسال و دریافت مقادیر)، چه طوری هاست .
تشکر...
طبق قوانین سایت هر سوال در تاپیک جداگانه ، و مثل پاسخ ها قبلی ، کافی هست هندل پنجره مرورگر و هندل Edit شئ AddressBar رو به دست بیارید و بهش پیغام ارسال کنید .
Felony
دوشنبه 03 اسفند 1388, 18:20 عصر
مشکل حل شد.ممنونم.خوب حالا چجوری میشه مقدار همون edit رو توی edit برنامه خودم بریزم؟
GetWndText(Handle);
Batman
دوشنبه 03 اسفند 1388, 20:26 عصر
چنین چیزی ظاهرا وجود نداره.اشتباه ننوشتید؟
اگه منظورتون GetWindowText هستش که علاوه بر پارامتر نوع handle دو تا پارامتر دیگه داره.
GetWindowText(hwnd: HWND,IpString: PWideChar,nMaxCount: Integer)
میشه درباره دو تا پارامتر آخری توضیح بدید؟
ممنونم.
Felony
دوشنبه 03 اسفند 1388, 20:41 عصر
شرمنده ، این تابع رو قبلا برای یکی از برنامه هام استفاده کرده بودم ، این تابع رو از سورس اون برنامه قدیمی که نوشته بودم دراوردم و یادم رفت کد خود تابع رو بزارم :
function GetWndText(hWnd: THandle): String;
var
I: Integer;
begin
if (SendMessageTimeout(hWnd,WM_GETTEXTLENGTH,0,0,SMTO _ABORTIFHUNG,2000,dword(I))<>0) then begin
SetLength(Result,I+1);
if SendMessageTimeout(hWnd,WM_GETTEXT,I+1,integer(Res ult),SMTO_ABORTIFHUNG,2000,dword(I))<>0 then
SetLength(Result,I)
else Result:='';
end else
Result:='';
end;
Batman
دوشنبه 03 اسفند 1388, 22:35 عصر
با تشکر حل شد.
میشه درباره عملکرد تابع یکمی توضیح بدید؟
در ضمن چجوری میشه همون برنامه رو پس از اجرا Hide کرد؟
ممنونم.
Felony
سه شنبه 04 اسفند 1388, 05:42 صبح
میشه درباره عملکرد تابع یکمی توضیح بدید؟
کجاشو توضیح بدم ، واضحه ، تابع GetWindowText 3 تا پارامتر داره :
1.هندل برنامه مورد نظر - 2. متغیر برای ذخیره متن یافت شده - 3. طول رشته
از اونجا که ویندوز با C نوشته شده و نوع داده ای با نام رشته ( String ) نداره و تابع GetWindowText یکی از توابع API ویندوز هست پس باید نوع متغیرمون رو با زبان C سازگار کنیم برای همین متغیر رو به شکل آرایه ای از کارکتر ها در نظر میگیریم که زبان C هم ازش پشتیبانی میکنه ، مثلا :
Text: Array [0..255] of Char;
حالا تابع GetWindowText متن پیدا کرده رو به صورت کارکتر به کارکتر داخل آرایه ما جا میده و در آخر ما میتونیم ازش استفاده کنیم ، این روش زمانی خوب هست که ما طول رشته ای که میخوایم پیدا کنیم رو دقیق یا تقریبی بدونیم ، ولی در زمان هایی که طول رو نمیدونیم و متغیر هست با مشکل مواجه میشیم ( ممکنه آرایه رو از 0 تا 255 تعریف کنیم و متنمون که میخوایم دریافت کنیم 300 کارکتر باشه که دراین صورت فقط 255 کارکتر اول رو دریافت میکنیم و 45 کارکتر باقی مانده تو آرایمون جا نمیشه و ازش صرف نظر میشه ) ، اگر هم آرایه رو بزرگ بگیریم ( مثلا 1024 ) اون وقت اگه متنمون طولش کم باشه مقداری از آرایه خالی میمونه که این استفاده نادرست از حافظه هست ...
برای اینکه این مشکل حل بشه اول یه پیغام ( WM_GETTEXTLENGTH ) به شئ مورد نظر فرستادم و طول متنش رو ازش درخواست کردم و بعد هم مقدار بازگشتی تابع رو بر حسب اون تغییر دادم .
البته متن داخل ادیت مورد نظر شما فکر نمیکنم بیشتر از 500 کارکتر باشه ، پس تخصیص حافظه زیاد براش مهم نیست و اگه مستقیم از تابع GetWindowText استفاده کنید مشکلی پیش نمیاد ، تابعی که من نوشته بودم و براتون گزاشتم برای دریافت متن یک Memo بود که گاهی به چند صد هزار کلمه میرسید ...
اگر بخواید از همون GetWindowText استفاده کنید که برای کار شما ساده تر هم هست کد به صورت زیر باید تغییر پیدا کنه :
var
Hand: THandle;
Text: Array [0..500] of Char;
begin
Hand:= FindWindow('TForm1','WBE RFDemo V2.0');
ShowWindow(Hand,SW_Hide);
Hand:= FindWindowEX(Hand,0,'TGroupBox','');
Hand:= FindWindowEX(Hand,0,'TPageControl','');
Hand:= FindWindowEX(Hand,0,'TTabSheet','Mifare R/W');
Hand:= FindWindowEX(Hand,0,'TGroupBox','Mifare1 Fuction');
Hand:= FindWindowEX(Hand,0,'TEdit',nil);
Hand:= GetWindow(Hand,GW_HwndNext); // Get next object handle to find own edit
Hand:= GetWindow(Hand,GW_HwndNext); // Get next object handle to find own edit
Hand:= GetWindow(Hand,GW_HwndNext); // Get next object handle to find own edit
Hand:= GetWindow(Hand,GW_HwndNext); // Get next object handle to find own edit
Hand:= GetWindow(Hand,GW_HwndNext); // Here i find handle of my own edit
GetWindowText(Hand, Text, Length(Text));
ShowMessage(Text);
end;
در ضمن چجوری میشه همون برنامه رو پس از اجرا Hide کرد؟
var
Hand: THandle;
begin
Hand:= FindWindow('TForm1','WBE RFDemo V2.0');
ShowWindow(Hand,SW_Hide);
end;
Batman
سه شنبه 04 اسفند 1388, 19:51 عصر
دوست عزیز میشه بگید چطوری میشه اون برنامه رو کلا terminate کرد؟
ممنونم.
Felony
سه شنبه 04 اسفند 1388, 20:13 عصر
var
Hand: THandle;
begin
Hand:= FindWindow('TForm1','WBE RFDemo V2.0');
PostMessage(Hand, WM_Close,0 ,0);
end;
Batman
سه شنبه 04 اسفند 1388, 20:18 عصر
برنامه رو نمیبنده.
Felony
چهارشنبه 05 اسفند 1388, 08:16 صبح
من تست کردم درست کار کرد ، شاید برنامه تو حلقه افتاده و نمیتونه به پیغام های ارسالی توسط شما پاسخ بده .
Batman
چهارشنبه 05 اسفند 1388, 21:47 عصر
احتمالا یه همچین چیزی باید باشه.چون من از کد زیر برای محبوس کردن برنامه تو برنامه خودم استفاده کردم:
procedure TFTagReading.FormCreate(Sender: TObject);
Var
T:Cardinal;
begin
ShellExecute(Handle,'Open',PChar(ExtractFilePath(A pplication.ExeName) + 'MFDemo'),'','',SW_SHOWNORMAL);
Hand:=0;
T:=GetTickCount;
While Hand = 0 do
begin
Hand:=FindWindow(nil,PChar('WBE RFDemo V2.0'));
if GetTickCount - T > 5000 then
Break;
end;
if Hand <> 0 then
Windows.SetParent(Hand,Handle);
end;
DAMAVAND
پنج شنبه 06 اسفند 1388, 04:43 صبح
اين کد رو امتحان کنيد :
var
h:hwnd;
begin
h:=FindWindowEx(Handle,0,nil,'WBE RFDemo V2.0');
PostMessage(h,WM_CLOSE,0,0);
end;
Batman
پنج شنبه 06 اسفند 1388, 09:41 صبح
من مطمئن شدم مشکل از کدی هستش که جناب damavand گذاشته بودن.کد مربوط به محبوس کردن یک برنامه در برنامه خودم توی یه تاپیک دیگه بود.
procedure TFTagReading.FormCreate(Sender: TObject);
Var
T:Cardinal;
begin
ShellExecute(Handle,'Open',PChar(ExtractFilePath(A pplication.ExeName) + 'MFDemo'),'','',SW_SHOWNORMAL);
Hand:=0;
T:=GetTickCount;
While Hand = 0 do
begin
Hand:=FindWindow(nil,PChar('WBE RFDemo V2.0'));
if GetTickCount - T > 5000 then
Break;
end;
if Hand <> 0 then
Windows.SetParent(Hand,Handle);
end;
کد بالا توی حلقه قرار میگیره و دیگه handle فرم درگیره و هیچکدوم از توابع دیگه مثل findwindow و findwindowex نموتونن handle رو پیدا کنن.لطفا راهنماییم کنید.
دو تا سوال دیگه:
1-چجوری میتونم برنامه دلخواه رو مثلا توی notebook1.pageindex[0] باز کنم.
2-چجوری میشه left و right و top و height اون رو تنظیم کرد؟
در ضمن مشکلم با بستن برنامه حل شد.از KillProcess استفاده کردم.
ممنونم
Batman
جمعه 07 اسفند 1388, 12:50 عصر
آقا یکی نیست که به ما کمک کنه؟
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.