ورود

View Full Version : سوال: مشکل در بدست آوردن هندل پنجره!



mbshareat
شنبه 23 بهمن 1389, 19:29 عصر
با سلام
یه برنامه دلفی دارم که برای ویرایش فایلها وابسته به یه برنامه تحت داسه(به زبان C)
من با Winexec برنامه داسی ویرایشگر رو به همراه نام فایل برای ویرایش رو اجرا می کنم و مشکلی نیست.
ولی مشل من اینه که نمی تونم بفهمم کار ویرایش فایل کی تموم می شه و پنجره برنامه داسی کی بسته میشه چون هر کار کنم چیزی که توسط WinExec برگشت داده میشه همیشه عدد 33 هست وقتی از ShellExecute استفاده میکنم هم همیشه مقدار 2 برمیگردونه.
من فعلا یه پنجره ویژه گذاشتم که کاربر خودش وقتی کارش با برنامه داسی تموم شد دکمه ادامه عملیات توی پنجره رو فشار بده و برنامه از اول فایل رو بخونه و خودش رو هماهنگ کنه.
یه جا تو همین سایت یه نفر یه کد گذاشته بود که چطور برنامه دیگه ای رو از برناممون اجرا کنیم و تا پایان اجراش منتظر بمونیم
چند روز پیش کد رو نگاه کردم و نفهمیدم چطور ازش استفاده کنم( البته در صحت کد هم شک دارم و چون برنامه مورد نظر من داسیه هم نمی دونم کارایی داره یا نه؟)
کسی راهی داره که بتونم چیزی مثل این فرمان داس رو باهاش اجرا کنم و برنامم تا خاتمه اجرای این برنامه داسی منتظر بمونه؟
'FED2.exe a.t'

fire.angle
شنبه 23 بهمن 1389, 22:37 عصر
اگه میخوای بدونی برنامه تون هنوز در حال اجراست یا نه (یعنی هندلش رو بدست بیاری ) میتونید از دستور Findwindow استفاده کنید

اگر خروجی تابع صفر بود یعنی اینکه برنامه شما تمام شده و پنجرش بسته شده ( البته باید Class name و window caption رو درست وارد کنید که خروجی تون معتبر باشه ) اما اگه هندل پنجره مورد نظرتون به عنوان به عنوان خروجی برگشت داده بشه یعنی اینکه پنجره هنوز بازه و بسته نشده

راه دیگه استفاده از تابع WaitforsingleObject هست

Felony
یک شنبه 24 بهمن 1389, 06:36 صبح
اگه میخوای بدونی برنامه تون هنوز در حال اجراست یا نه (یعنی هندلش رو بدست بیاری ) میتونید از دستور Findwindow استفاده کنید

اگر خروجی تابع صفر بود یعنی اینکه برنامه شما تمام شده و پنجرش بسته شده ( البته باید Class name و window caption رو درست وارد کنید که خروجی تون معتبر باشه ) اما اگه هندل پنجره مورد نظرتون به عنوان به عنوان خروجی برگشت داده بشه یعنی اینکه پنجره هنوز بازه و بسته نشده

راه دیگه استفاده از تابع WaitforsingleObject هست
FindWindow برای پنجره هایی جواب میده که از کلاس های استاندارد Win32 مشتق شده باشند ، پنجره برنامه Dos هندلی نداره که به دستش بیارید چون در حقیقت اون یک Shell هست که برنامه شما با کمک اون اجرا شده .

1- اگر برنامه داس رو خودتون نوشتید میتونید با AllocateWindow براش یک فرم بسازید و پیغام رو به اون فرم مخفی بدید .
2- در غیر این صورت از راه دوم میشه استفاده کرد .

lord_viper
یک شنبه 24 بهمن 1389, 17:25 عصر
وقتی یک فایل exe اجرا میشه معمولا یک پروسه با نام فایل اجرایی ساخته میشه میتونین هندل پروسه رو بگیرید
و چک کنین ایا اون پروسه در حال اجرا هست یا بسته شده

mbshareat
یک شنبه 24 بهمن 1389, 18:15 عصر
سلام خدمت بزرگان
اون برنامه داسی رو من ننوشتم من فقط با کدی که آقای شاهین عشایری برای تغییر عنوان پنجره My Computer گذاشته بودند تونستم عنوان پنجره رو تغییر بدم اما فکر نکنم بتونم هندل پنجره رو گیر بیارم.
اگه ممکنه درمورد AllocateWindow و WaitforsingleObject برام توضیح بدین تنها کاری که برنامه من می کنه اینه که با Winexec برنامه داسی از پیش ساخته شده FED2.exe رو با پارامتر نام فایل فرا خوانی میکنه.
حالا لطفا راهنماییم کنین چه کاری میتونم تو برنامم بکنم؟

mehdi.mousavi
یک شنبه 24 بهمن 1389, 18:34 عصر
سلام.
جای استفاده از WinExec (که برای Compatibility با برنامه های 16 بیتی هنوز حفظ شده)، از CreateProcess استفاده کنید. بدین ترتیب که با استفاده از CreateProcess، برنامه Console خودتون رو Launch کنید، سپس با استفاده از متود WaitForSingleObject منتظر Signal شدن Handle به Process ایجاد شده، بشید. هر وقت Handle مزبور Signal شد، متوجه خواهید شد که اجرای برنامه Console ای نیز پایان پذیرفته. من Pascal بلد نیستم اما کد مزبور رو براتون به C می نویسم تا متوجه منظورم بشید (و احیانا کسی پیدا بشه معادلش رو براتون در پاسکال بنویسه):


STARTUPINFO si = {NULL};
PROCESS_INFORMATION pi = {NULL};

si.cb = sizeof(si);
si.wShowWindow = SW_SHOWNORMAL;

TCHAR path[MAX_PATH] = _T("\"d:\\myconsolefile.exe\" param1");
if(!CreateProcess(NULL, path, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
return -1;

WaitForSingleObject(pi.hProcess, INFINITE);

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
در کد فوق، من فایل مورد نظر رو با پارامتر های مورد نیازم اجرا میکنم، سپس در WaitForSingleObject منتظر اتمام Process (و Signal شدن pi.hProcess) خواهم موند. دقت کنید که این کار باعث میشه Thread فعلی به وضعیت Wait بره، بنابراین شاید مجبور باشید اینکارو در Thread دیگه ای انجام بدید. در هر حال، بدین روش شما می تونید از اتمام اون برنامه console ای اطمینان حاصل کنید و روند مورد نظرتون رو پی بگیرید.

موفق باشید.

mbshareat
یک شنبه 24 بهمن 1389, 18:42 عصر
سلام علیکم و خدا قوت
آقا من خیلی مبتدیم در مورد console و thread تقریبا هیچی نمی دونم قبلا هم تو help مربوط به WinApi بهcreateprocess برخورد کردم.فکر کنم گفته بود برای برنامه های Win32 طراحی شده.

mehdi.mousavi
یک شنبه 24 بهمن 1389, 18:48 عصر
سلام علیکم و خدا قوت
آقا من خیلی مبتدیم در مورد console و thread تقریبا هیچی نمی دونم قبلا هم تو help مربوط به WinApi بهcreateprocess برخورد کردم.فکر کنم گفته بود برای برنامه های Win32 طراحی شده.

سلام.
مگه شما نمیخواهید برنامه تحت DOS اتون رو، از طریق برنامه ای که در ویندوز (با دلفی) نوشته اید اجرا کنید؟ مگه الان از WinExec برای اینکار استفاده نمی کنید؟ (نکنه من صورت مساله رو بد فهمیدم؟) در هر حال، هر جا نوشتم Console، فکر کنید نوشته ام "برنامه تحت DOS"... اگر برنامه شما، قرار نیست تو اون مدتی که Editor تحت DOS بازه کاری انجام بده، دیگه نیازی به یک Thread دیگه هم نخواهید داشت و کد فوق جوابگوی نیاز شما هستش. (بازم میگم، مگر اینکه من صورت مساله رو اشتباه متوجه شده باشم).

موفق باشید.

Felony
یک شنبه 24 بهمن 1389, 20:08 عصر
سلام خدمت بزرگان
اون برنامه داسی رو من ننوشتم من فقط با کدی که آقای شاهین عشایری برای تغییر عنوان پنجره My Computer گذاشته بودند تونستم عنوان پنجره رو تغییر بدم اما فکر نکنم بتونم هندل پنجره رو گیر بیارم.
اگه ممکنه درمورد AllocateWindow و WaitforsingleObject برام توضیح بدین تنها کاری که برنامه من می کنه اینه که با Winexec برنامه داسی از پیش ساخته شده FED2.exe رو با پارامتر نام فایل فرا خوانی میکنه.
حالا لطفا راهنماییم کنین چه کاری میتونم تو برنامم بکنم؟

AllocateWindow یک پنجره مخفی میسازه و هندلش رو بهتون تحویل میده ، میتونید با PeekMessage پیغام ها رو ازش بخونید و براش یک MessageHandler بنویسید ، تایمر دلفی دقیقا از همین شیوه استفاده میکنه ، البته وقتی برنامه Dos رو خودتون ننوشتید کارایی براتون نداره ، باقی توضیحات رو هم که آقای موسوی گفت .

lord_viper
دوشنبه 25 بهمن 1389, 09:05 صبح
شما میتونین از کد زیر استفاده کنین



var
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
NotepadExe: String;
begin
SetLength(NotepadExe, MAX_PATH);
GetWindowsDirectory(Pchar(NotepadExe), MAX_PATH);
StrCat(Pchar(NotepadExe),'\notepad.exe');

ZeroMemory(@StartupInfo,SizeOf(TStartupInfo));
StartupInfo.cb := SizeOf(TStartupInfo);

if(CreateProcess(Pchar(NotepadExe), Nil, Nil, Nil,
False, NORMAL_PRIORITY_CLASS,
Nil, Nil, StartupInfo,ProcessInfo))
then
begin
WaitForSingleObject(pi.hProcess,INFINITE);
ShowMessage('Hi there');
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end
end;


این لینک هم خوبه



http://delphi.about.com/od/windowsshellapi/a/executeprogram.htm


اینو هم میتونین تو گوگل جستجو کنین



execute wait until finish delphi

mbshareat
دوشنبه 25 بهمن 1389, 16:56 عصر
با سلام
آقا کد بالا رو اجرا کردم به این خط گیر میده:

WaitForSingleObject(pi.hProcess,INFINITE);
در ضمن آیا برای اجرای برنامه داسی FED2.exe با پارامتر نام یک فایل چطور عمل کنم آیا این روش جواب میده.
اونطور که من فهمیدم سه خط اول بهد از Begin رو باید نادیده بگیرم و باید

if(CreateProcess(Pchar(NotepadExe)
رو به

if(CreateProcess(Pchar('FED2.Exe a.t')
تبدیل کنم.
اگه اشکالی دارم لطفا بفرمایین.