PDA

View Full Version : حرفه ای: بدست آوردن هندل یک برنامه



omid-vbAuto
یک شنبه 05 دی 1389, 10:02 صبح
با سلام خدمت دوستان و اساتید گرامی

من توی سایت سرچ کردم ولی چیز به درد بخوری در مورد هندل پیدا نکردم . دوستان اطلاعاتی در مورد هندل کردن یک برنامه و یا هندل گرفتن از یک برنامه و کلا هر اطلاعات مفیدی که در زمینه هندل می دونن دریغ نکنن .

با تشکر

mehdi.mousavi
یک شنبه 05 دی 1389, 10:44 صبح
با سلام خدمت دوستان و اساتید گرامی من توی سایت سرچ کردم ولی چیز به درد بخوری در مورد هندل پیدا نکردم . دوستان اطلاعاتی در مورد هندل کردن یک برنامه و یا هندل گرفتن از یک برنامه و کلا هر اطلاعات مفیدی که در زمینه هندل می دونن دریغ نکنن . با تشکر

سلام.
شما چه مشخصه ای از اون برنامه دارید که Handle به اونو میخواهید؟ Win32 API های زیادی وجود دارن که میشه به کمک اونها Handle به یک Process، Window و ... رو بدست آورد.
دقیقا بفرمایید چی در ذهنتونه و قصد انجام چه کاری رو دارید.

موفق باشید.

omid-vbAuto
یک شنبه 05 دی 1389, 11:17 صبح
سلام.
شما چه مشخصه ای از اون برنامه دارید که Handle به اونو میخواهید؟ Win32 API های زیادی وجود دارن که میشه به کمک اونها Handle به یک Process، Window و ... رو بدست آورد.
دقیقا بفرمایید چی در ذهنتونه و قصد انجام چه کاری رو دارید.

موفق باشید.

از اینکه پاسخ دادین خیلی ممنونم.لطفا بنده رو تا آخر این تاپیک همراهی فرمائید.

اما چی تو ذهن منه؟ :افسرده:

من می خوام با خواص هندل (که نمی دونم چی هست) برنامه ی شماره 2 خودم رو توسط برنامه شماره 1 کنترل کنم.

بطور ساده عرض کنم:

فکر کنید در برنامه 2 من دو تا Textbox داریم و یه دکمه حالا قصد داریم توسط برنامه شماره 1 به برنامه شماره 2 پارامترهائی جهت پر کردن اون Textbox ها بفرستیم همچنین کدی رو از برنامه ی 1 به برنامه 2 مخابره کنم تا رخ داد کلیک دکمه برنامه 2 اتفاق بیفته.


نکات ضروری : من همین کار بالا رو با روش پارامتری و به کمک دوستان انجام دادم.حالا می خواهم همین کار رو مشخصا و حتما با API ها هم انجام بدم.

من و سایر دوستان که نیاز به راهنمائی شما داریم خوشحال می شیم.

Saman_12
یک شنبه 05 دی 1389, 13:49 عصر
Handle به معنای دستگیره هست و کاربردش هم تقریبا با اسمش هم خونی داره , Handle یک عدد چند رقمی هست و هر آبجکت یک Handle مخصوص به خودش رو داره یعنی Handle یک TextBox با Handle تکست باکس دیگه یکی نیست.ویندوز برای ارسال پیام های مورد نیاز خودش از Handle استفاده میکنه.(برای اطلاعات بیشتر میتونید جستجو.)

اینکه یک کنترل کامل روی یک برنامه داشته باشید کار زیاد آسونی نیست (شایدم باشه)!.
کاری که شما میخواید انجام بدید کار سختی نیست واحتیاج به API های زیر داره :
findwindow , findwindowex
sendmessage یا Postmessage
و . . .(میشه از روش های مختلفی رفت اما فکر کنم بالایی ها مشترک باشند.)
به چند تایی WM_Message هم احتیاجه :
WM_GETTEXT
WM_SETTEXT
این یدونه هم فکر کنم لازم باشه :
BM_CLICK

خوب حالا بستگی به شما و برنامه شما داره!.(اگه برنامه دیگه رو خودتون نوشتین که کار آسونتره.)
شما اون برنامه دومتون رو آپلود کنید تا یکمی اطلاعات درمورد برنامه دوم شما بالا بره بعد روش ها و کد های مربوطه رو شرح میدم.

mehdi.mousavi
یک شنبه 05 دی 1389, 14:01 عصر
من می خوام با خواص هندل (که نمی دونم چی هست) برنامه ی شماره 2 خودم رو توسط برنامه شماره 1 کنترل کنم. بطور ساده عرض کنم: فکر کنید در برنامه 2 من دو تا Textbox داریم و یه دکمه حالا قصد داریم توسط برنامه شماره 1 به برنامه شماره 2 پارامترهائی جهت پر کردن اون Textbox ها بفرستیم همچنین کدی رو از برنامه ی 1 به برنامه 2 مخابره کنم تا رخ داد کلیک دکمه برنامه 2 اتفاق بیفته. نکات ضروری : من همین کار بالا رو با روش پارامتری و به کمک دوستان انجام دادم.حالا می خواهم همین کار رو مشخصا و حتما با API ها هم انجام بدم. من و سایر دوستان که نیاز به راهنمائی شما داریم خوشحال می شیم.

سلام.
برای اینکار، فرض میکنم Title به پنجره مقصد رو دارید. بدین ترتیب میتونید با استفاده از FindWindow (http://www.pinvoke.net/default.aspx/user32.findwindow) هندل به پنجره مقصد رو پیدا کنید.
سپس، باید کلیه Child Window های اون پنجره رو Enumerate کنید. برای اینکار میتونید از GetWindow استفاده کنید:


HWND FindContainerWnd(HWND hWnd, LPCTSTR lpClassName)
{
HWND hChildWnd = ::GetWindow(hWnd, GW_CHILD | GW_HWNDFIRST);
while(hChildWnd)
{
TCHAR szClassName[255] = {NULL};
::GetClassName(hChildWnd, szClassName, 255);

if(_tcsnicmp(szClassName, lpClassName, 255) == 0)
return hChildWnd;

hChildWnd = ::GetWindow(hChildWnd, GW_HWNDNEXT);
}

return NULL;
}

(توضیح: کد فوق رو به زبان C قبلا برای یکی از دوستان در پیام خصوصی ارسال کرده بودم، که همونو برای شما اینجا قرار دادم. خودتون میتونید اونو به VB.NET تبدیل کنید).

دقت کنید، با استفاده از تابع فوق، من کلیه Child Window ها رو میگردم، اونهایی که Class Name اشون نام مورد نظر من بود رو انتخاب میکنم. بطور مثال شما فرمودید تو تا TextBox دارید توی اون پنجره. پس اینجا من باید دنبال Class Name ای تحت عنوان Edit بگردم که نشون دهنده TextBox ها هستش. در حقیقت، اینطوری میتونم به Handle اون 2 تا TextBox و اون Button برسم. وقتی handle به اونها رو پیدا کردم، حالا میتونم متن داخل اون TextBox ها رو با استفاده از SetWindowText ست کنم. میمونه Click کردن اون دکمه. برای اینکار هم به روشهای مختلفی میشه عمل کرد. یکی از اونها، بدست آوردن مختصات اون دکمه (با استفاده از Handle اون هستش که با تابع فوق بدست میاریم) با استفاده از تابع GetWindowRect (http://www.pinvoke.net/default.aspx/user32.getwindowrect) هستش. وقتی مختصات اون دکمه رو بدست آوردیم، میتونیم با استفاده از PostMessage، پیام WM_LBUTTONDOWN و سپس WM_LBUTTONUP رو برای Handle اون پنجره ارسال کنیم (که باید در اون WPARAM اش رو مختصات بدست آورده بذاریم). شما همچنین میتونید از mouse_event نیز استفاده کنید (یا نسخه جدید اون، SendInput، بدین ترتیب که یه structure از نوع INPUT ایجاد کرده، با مقادیر مناسب پر کنید و اونو به SendInput بدید)... روش دیگه این هستش که با SetFocus، فوکس رو روی Button مورد نظر قرار بدید، سپس پیام مربوطه به فشرده شدن کلید ENTER رو PostMessage کنید....

موفق باشید.

omid-vbAuto
یک شنبه 05 دی 1389, 15:04 عصر
Handle به معنای دستگیره هست و کاربردش هم تقریبا با اسمش هم خونی داره , Handle یک عدد چند رقمی هست و هر آبجکت یک Handle مخصوص به خودش رو داره یعنی Handle یک TextBox با Handle تکست باکس دیگه یکی نیست.ویندوز برای ارسال پیام های مورد نیاز خودش از Handle استفاده میکنه.(برای اطلاعات بیشتر میتونید جستجو.)

اینکه یک کنترل کامل روی یک برنامه داشته باشید کار زیاد آسونی نیست (شایدم باشه)!.
کاری که شما میخواید انجام بدید کار سختی نیست واحتیاج به API های زیر داره :
findwindow , findwindowex
sendmessage یا Postmessage
و . . .(میشه از روش های مختلفی رفت اما فکر کنم بالایی ها مشترک باشند.)
به چند تایی WM_Message هم احتیاجه :
WM_GETTEXT
WM_SETTEXT
این یدونه هم فکر کنم لازم باشه :
BM_CLICK

خوب حالا بستگی به شما و برنامه شما داره!.(اگه برنامه دیگه رو خودتون نوشتین که کار آسونتره.)
شما اون برنامه دومتون رو آپلود کنید تا یکمی اطلاعات درمورد برنامه دوم شما بالا بره بعد روش ها و کد های مربوطه رو شرح میدم.


با سلام مهندس این هم برنامه

این هم عکسی از برنامه:

64143


همان گونه که می بینید برنامه از دو Textbox مقادیر را می گیرد و با اعمال دکمه GO آن دو در هم ضرب کرده و نمایش می دهد.همین:چشمک:



حالا من می خوام با یه برنامه ی دیگه و با استفاده از API ها اعداد رو به Textbox ها روانه کنم و دکمه GO رو هم تحریک کنم.

omid-vbAuto
یک شنبه 05 دی 1389, 15:09 عصر
سلام.
برای اینکار، فرض میکنم Title به پنجره مقصد رو دارید. بدین ترتیب میتونید با استفاده از FindWindow (http://www.pinvoke.net/default.aspx/user32.findwindow) هندل به پنجره مقصد رو پیدا کنید.
سپس، باید کلیه Child Window های اون پنجره رو Enumerate کنید. برای اینکار میتونید از GetWindow استفاده کنید:


HWND FindContainerWnd(HWND hWnd, LPCTSTR lpClassName)
{
HWND hChildWnd = ::GetWindow(hWnd, GW_CHILD | GW_HWNDFIRST);
while(hChildWnd)
{
TCHAR szClassName[255] = {NULL};
::GetClassName(hChildWnd, szClassName, 255);

if(_tcsnicmp(szClassName, lpClassName, 255) == 0)
return hChildWnd;

hChildWnd = ::GetWindow(hChildWnd, GW_HWNDNEXT);
}

return NULL;
}

(توضیح: کد فوق رو به زبان C قبلا برای یکی از دوستان در پیام خصوصی ارسال کرده بودم، که همونو برای شما اینجا قرار دادم. خودتون میتونید اونو به VB.NET تبدیل کنید).

دقت کنید، با استفاده از تابع فوق، من کلیه Child Window ها رو میگردم، اونهایی که Class Name اشون نام مورد نظر من بود رو انتخاب میکنم. بطور مثال شما فرمودید تو تا TextBox دارید توی اون پنجره. پس اینجا من باید دنبال Class Name ای تحت عنوان Edit بگردم که نشون دهنده TextBox ها هستش. در حقیقت، اینطوری میتونم به Handle اون 2 تا TextBox و اون Button برسم. وقتی handle به اونها رو پیدا کردم، حالا میتونم متن داخل اون TextBox ها رو با استفاده از SetWindowText ست کنم. میمونه Click کردن اون دکمه. برای اینکار هم به روشهای مختلفی میشه عمل کرد. یکی از اونها، بدست آوردن مختصات اون دکمه (با استفاده از Handle اون هستش که با تابع فوق بدست میاریم) با استفاده از تابع GetWindowRect (http://www.pinvoke.net/default.aspx/user32.getwindowrect) هستش. وقتی مختصات اون دکمه رو بدست آوردیم، میتونیم با استفاده از PostMessage، پیام WM_LBUTTONDOWN و سپس WM_LBUTTONUP رو برای Handle اون پنجره ارسال کنیم (که باید در اون WPARAM اش رو مختصات بدست آورده بذاریم). شما همچنین میتونید از mouse_event نیز استفاده کنید (یا نسخه جدید اون، SendInput، بدین ترتیب که یه structure از نوع INPUT ایجاد کرده، با مقادیر مناسب پر کنید و اونو به SendInput بدید)... روش دیگه این هستش که با SetFocus، فوکس رو روی Button مورد نظر قرار بدید، سپس پیام مربوطه به فشرده شدن کلید ENTER رو PostMessage کنید....

موفق باشید.


با سلام مهندس من هم می دونم با SetWindowText میشه .ولی کد بدین شما می دونید که مباحث API خیلی مهم و سخت هستند و با راهنمائی نمیشه کاری از پیش برد.:ناراحت::افسرده:

بعدس هم اون کدی رو که دادین اگه #C بود یه سایت می دونستم که می شود به VB تبدیل کرد اما سایت مشابهی برای C نمی دونم.:گریه:

mehdi.mousavi
یک شنبه 05 دی 1389, 18:15 عصر
با سلام مهندس من هم می دونم با SetWindowText میشه .ولی کد بدین شما می دونید که مباحث API خیلی مهم و سخت هستند و با راهنمائی نمیشه کاری از پیش برد.:ناراحت::افسرده: بعدس هم اون کدی رو که دادین اگه #C بود یه سایت می دونستم که می شود به VB تبدیل کرد اما سایت مشابهی برای C نمی دونم.:گریه:

سلام.
به نظر من درستش این بود که شما اندکی تلاش میکردید، تا با مفاهیم مربوطه آشنا بشید، بعد پست بعدی رو میدادید و درخواست کد میکردید. :) من بهتون پاسخ سوال رو میدم، اما اینطوری خیلی از مفاهیم مربوطه رو از دست میدید.

به این کد دقت کنید:


private const int WM_SETTEXT = 0x0000000C;
private const int BN_CLICKED = 0x000000f5;

private const int GW_HWNDFIRST = 0;
private const int GW_HWNDLAST = 1;
private const int GW_HWNDNEXT = 2;
private const int GW_HWNDPREV = 3;
private const int GW_OWNER = 4;
private const int GW_CHILD = 5;
private const int GW_ENABLEDPOPUP = 6;

[DllImport("User32.dll")]
private static extern Int32 SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, StringBuilder lParam);

[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

[DllImport("user32.dll")]
static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);

private void ChangeInputs()
{
IntPtr hWnd = FindWindow(null, "Math");
if (hWnd != IntPtr.Zero)
SetAnotherAppInputs(hWnd, 3.5M, 7.5M);
}

private void SetAnotherAppInputs(IntPtr hWnd, decimal firstNum, decimal secondNum)
{
IntPtr hWndEditBoxFirst = IntPtr.Zero, hWndEditBoxSecond = IntPtr.Zero, hWndButtonGo = IntPtr.Zero;
IntPtr hChildWnd = GetWindow(hWnd, GW_CHILD | GW_HWNDFIRST);

int tabIndex = 0;
while (hChildWnd != IntPtr.Zero)
{
StringBuilder className = new StringBuilder(512);
GetClassName(hChildWnd, className, 512);

string windowClassName = className.ToString();
if (windowClassName.Contains(".EDIT."))
{
if (tabIndex == 4)
hWndEditBoxFirst = hChildWnd;
else if (tabIndex == 2)
hWndEditBoxSecond = hChildWnd;
}
else if (windowClassName.Contains(".BUTTON."))
hWndButtonGo = hChildWnd;

tabIndex++;
hChildWnd = GetWindow(hChildWnd, GW_HWNDNEXT);
}

Debug.Assert(hWndEditBoxFirst != null && hWndEditBoxSecond != null && hWndButtonGo != null);

SendMessage(hWndEditBoxFirst, WM_SETTEXT, IntPtr.Zero, new StringBuilder(firstNum.ToString()));
SendMessage(hWndEditBoxSecond, WM_SETTEXT, IntPtr.Zero, new StringBuilder(secondNum.ToString()));
SendMessage(hWndButtonGo, BN_CLICKED, IntPtr.Zero, null);
}
اینجا ابتدا من دو تا از Message های مورد نظرم رو که قراره استفاده کنم تعریف می کنم (WM_SETTEXT و BN_CLICKED). سپس مقادیر معتبر پارامتر دوم GetWindow که یه سری constant هستن رو تعریف کردم. (من این مقادیر رو از داخل یه برنامه C/C++ درآوردم). سپس Win32 API های مورد استفاده رو با DllImport به برنامه معرفی میکنم. سپس تابع ChangeInputs رو نوشتم، که میره، بر اساس عنوان پنجره شما (که Math هستش)، پنجره مربوطه رو پیدا میکنه، و تابع SetAnotherAppInputs رو فراخوانی میکنه. توی این تابع، در یک Loop و با استفاده از GetWindow، پنجره های درونی پنجره Math شما رو Enumerate میکنم و بر اساس جایگاه هر یک، Handle به هر کدوم رو در متغیرهای hWndEditBoxFirst، hWndEditBoxSecond و hWndButtonGo قرار میدم. در نهایت با استفاده از SendMessage، پیام WM_SETTEXT رو برای هر پنجره ارسال میکنم که منجر به قرارگرفتن عدد اول در TextBox سمت چپی، و عدد دوم در TextBox سمت راستی میشه. در نهایت، پیام BN_CLICKED رو به Button میفرستم، تا نتیجه توسط برنامه شما محاسبه و نمایش داده بشه.

اما اینجا چند نکته وجود داره. یکی اینکه استفاده از BN_CLICKED خیلی کار رو ساده میکنه و نیازی به شبیه سازی Cursor موس به شکلی که در پست قبلی توضیح دادم نیست (اگر چه، اونهم شدنیه اما خوب، روش صحیح ارسال BN_CLICKED بود که در پاسخ اول به ذهنم نرسیده بود). نکته دوم عدم استفاده از SetWindowText هستش. SetWindowText طبق گفته MSDN، نمیتونه Text یه Child Window رو در یک App دیگه Set کنه، در نتیجه، باید پیام WM_SETTEXT رو مستقیما براش ارسال میکردم. نکته سوم، تبدیل firstNum به string هنگام ایجاد StringBuilder هستش. StringBuilder بعنوان پارامتر، میتونه Capacity ی string رو بگیره و باید مراقب باشید اینجا اشتباهی رخ نده. نکته چهارم اینکه این برنامه رو به C# نوشتم، چون Syntax این VB.NET ... رو نمیدونم. خودتون میتونید با اون برنامه هایی که در پست قبلی فرمودید، اونو به VB.NET تبدیل کنید و ازش استفاده کنید. :لبخندساده:

در نهایت یادتون نره تابع ChangeInputs رو اونجاییکه می خواهید مقادیر مربوطه رو تغییر بدید، صدا بزنید.

موفق باشید.

omid-vbAuto
یک شنبه 05 دی 1389, 18:46 عصر
سلام.
به نظر من درستش این بود که شما اندکی تلاش میکردید، تا با مفاهیم مربوطه آشنا بشید، بعد پست بعدی رو میدادید و درخواست کد میکردید. :) من بهتون پاسخ سوال رو میدم، اما اینطوری خیلی از مفاهیم مربوطه رو از دست میدید.

به این کد دقت کنید:


private const int WM_SETTEXT = 0x0000000C;
private const int BN_CLICKED = 0x000000f5;

private const int GW_HWNDFIRST = 0;
private const int GW_HWNDLAST = 1;
private const int GW_HWNDNEXT = 2;
private const int GW_HWNDPREV = 3;
private const int GW_OWNER = 4;
private const int GW_CHILD = 5;
private const int GW_ENABLEDPOPUP = 6;

[DllImport("User32.dll")]
private static extern Int32 SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, StringBuilder lParam);

[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

[DllImport("user32.dll")]
static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);

private void ChangeInputs()
{
IntPtr hWnd = FindWindow(null, "Math");
if (hWnd != IntPtr.Zero)
SetAnotherAppInputs(hWnd, 3.5M, 7.5M);
}

private void SetAnotherAppInputs(IntPtr hWnd, decimal firstNum, decimal secondNum)
{
IntPtr hWndEditBoxFirst = IntPtr.Zero, hWndEditBoxSecond = IntPtr.Zero, hWndButtonGo = IntPtr.Zero;
IntPtr hChildWnd = GetWindow(hWnd, GW_CHILD | GW_HWNDFIRST);

int tabIndex = 0;
while (hChildWnd != IntPtr.Zero)
{
StringBuilder className = new StringBuilder(512);
GetClassName(hChildWnd, className, 512);

string windowClassName = className.ToString();
if (windowClassName.Contains(".EDIT."))
{
if (tabIndex == 4)
hWndEditBoxFirst = hChildWnd;
else if (tabIndex == 2)
hWndEditBoxSecond = hChildWnd;
}
else if (windowClassName.Contains(".BUTTON."))
hWndButtonGo = hChildWnd;

tabIndex++;
hChildWnd = GetWindow(hChildWnd, GW_HWNDNEXT);
}

Debug.Assert(hWndEditBoxFirst != null && hWndEditBoxSecond != null && hWndButtonGo != null);

SendMessage(hWndEditBoxFirst, WM_SETTEXT, IntPtr.Zero, new StringBuilder(firstNum.ToString()));
SendMessage(hWndEditBoxSecond, WM_SETTEXT, IntPtr.Zero, new StringBuilder(secondNum.ToString()));
SendMessage(hWndButtonGo, BN_CLICKED, IntPtr.Zero, null);
}
اینجا ابتدا من دو تا از Message های مورد نظرم رو که قراره استفاده کنم تعریف می کنم (WM_SETTEXT و BN_CLICKED). سپس مقادیر معتبر پارامتر دوم GetWindow که یه سری constant هستن رو تعریف کردم. (من این مقادیر رو از داخل یه برنامه C/C++ درآوردم). سپس Win32 API های مورد استفاده رو با DllImport به برنامه معرفی میکنم. سپس تابع ChangeInputs رو نوشتم، که میره، بر اساس عنوان پنجره شما (که Math هستش)، پنجره مربوطه رو پیدا میکنه، و تابع SetAnotherAppInputs رو فراخوانی میکنه. توی این تابع، در یک Loop و با استفاده از GetWindow، پنجره های درونی پنجره Math شما رو Enumerate میکنم و بر اساس جایگاه هر یک، Handle به هر کدوم رو در متغیرهای hWndEditBoxFirst، hWndEditBoxSecond و hWndButtonGo قرار میدم. در نهایت با استفاده از SendMessage، پیام WM_SETTEXT رو برای هر پنجره ارسال میکنم که منجر به قرارگرفتن عدد اول در TextBox سمت چپی، و عدد دوم در TextBox سمت راستی میشه. در نهایت، پیام BN_CLICKED رو به Button میفرستم، تا نتیجه توسط برنامه شما محاسبه و نمایش داده بشه.

اما اینجا چند نکته وجود داره. یکی اینکه استفاده از BN_CLICKED خیلی کار رو ساده میکنه و نیازی به شبیه سازی Cursor موس به شکلی که در پست قبلی توضیح دادم نیست (اگر چه، اونهم شدنیه اما خوب، روش صحیح ارسال BN_CLICKED بود که در پاسخ اول به ذهنم نرسیده بود). نکته دوم عدم استفاده از SetWindowText هستش. SetWindowText طبق گفته MSDN، نمیتونه Text یه Child Window رو در یک App دیگه Set کنه، در نتیجه، باید پیام WM_SETTEXT رو مستقیما براش ارسال میکردم. نکته سوم، تبدیل firstNum به string هنگام ایجاد StringBuilder هستش. StringBuilder بعنوان پارامتر، میتونه Capacity ی string رو بگیره و باید مراقب باشید اینجا اشتباهی رخ نده. نکته چهارم اینکه این برنامه رو به C# نوشتم، چون Syntax این VB.NET ... رو نمیدونم. خودتون میتونید با اون برنامه هایی که در پست قبلی فرمودید، اونو به VB.NET تبدیل کنید و ازش استفاده کنید. :لبخندساده:

در نهایت یادتون نره تابع ChangeInputs رو اونجاییکه می خواهید مقادیر مربوطه رو تغییر بدید، صدا بزنید.

موفق باشید.

مهندس راستشو بخواهین هیچی نفهمیدم:لبخند:

در ضمن این کدهائی که زحمتشو کشیدن #C بودن؟:لبخند:هر چی بود به غیر #C چون من با این وب سایت ترجمش می کنم و این سایتم نتونست کدهای #C شما رو به VB.NET برگرونه.
http://www.developerfusion.com/tools/convert/csharp-to-vb/

حالا اگه برنامه این کد ها دستتونه اونو بذارین.





به نظر من درستش این بود که شما اندکی تلاش میکردید، تا با مفاهیم مربوطه آشنا بشید، بعد پست بعدی رو میدادید و درخواست کد میکردید. :) من بهتون پاسخ سوال رو میدم، اما اینطوری خیلی از مفاهیم مربوطه رو از دست میدید.




مهندس من تلاش رو به این تعبیر می کنم که بیام از کسانی که در مورد API اطلاع دارن پرسو جو کنم و یاد بگیرم.قرار نیست که دوباره API ها رو اختراع کنم .در واقع کار با API ها مثل کار کردن با یه Textbox معمولی چون همه چیزشمون از قبل طراحی شده هست.و فقط باید بدونی که فلان کد چکار می کنه.که من هم این تاپیک رو زدم تا بدمون کد ApI برای هندل کردن چیه؟که الحمدالله همه در مورد API حرفه ای هستن.و چپ و راست هی نمونه برنامه و کد VB می دن.:عصبانی++:

mehdi.mousavi
یک شنبه 05 دی 1389, 18:55 عصر
سلام.
الان با همون ابزار این کد رو تولید کردم:



Imports System.Runtime.InteropServices
Imports System.Text

Public Class Form1
Private Const WM_SETTEXT As Integer = &HC
Private Const BN_CLICKED As Integer = &HF5

Private Const GW_HWNDFIRST As Integer = 0
Private Const GW_HWNDLAST As Integer = 1
Private Const GW_HWNDNEXT As Integer = 2
Private Const GW_HWNDPREV As Integer = 3
Private Const GW_OWNER As Integer = 4
Private Const GW_CHILD As Integer = 5
Private Const GW_ENABLEDPOPUP As Integer = 6

<DllImport("User32.dll")> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As StringBuilder) As Int32
End Function

<DllImport("user32.dll")> _
Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
End Function

<DllImport("user32.dll")> _
Private Shared Function GetClassName(ByVal hWnd As IntPtr, ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer
End Function

<DllImport("user32.dll")> _
Private Shared Function GetWindow(ByVal hWnd As IntPtr, ByVal uCmd As Integer) As IntPtr
End Function

Private Sub ChangeInputs()
Dim hWnd As IntPtr = FindWindow(Nothing, "Math")
If hWnd <> IntPtr.Zero Then
SetAnotherAppInputs(hWnd, 3.5D, 7.5D)
End If
End Sub

Private Sub SetAnotherAppInputs(ByVal hWnd As IntPtr, ByVal firstNum As Decimal, ByVal secondNum As Decimal)
Dim hWndEditBoxFirst As IntPtr = IntPtr.Zero, hWndEditBoxSecond As IntPtr = IntPtr.Zero, hWndButtonGo As IntPtr = IntPtr.Zero
Dim hChildWnd As IntPtr = GetWindow(hWnd, GW_CHILD Or GW_HWNDFIRST)

Dim tabIndex As Integer = 0
While hChildWnd <> IntPtr.Zero
Dim className As New StringBuilder(512)
GetClassName(hChildWnd, className, 512)

Dim windowClassName As String = className.ToString()
If windowClassName.Contains(".EDIT.") Then
If tabIndex = 4 Then
hWndEditBoxFirst = hChildWnd
ElseIf tabIndex = 2 Then
hWndEditBoxSecond = hChildWnd
End If
ElseIf windowClassName.Contains(".BUTTON.") Then
hWndButtonGo = hChildWnd
End If

tabIndex += 1
hChildWnd = GetWindow(hChildWnd, GW_HWNDNEXT)
End While

SendMessage(hWndEditBoxFirst, WM_SETTEXT, IntPtr.Zero, New StringBuilder(firstNum.ToString()))
SendMessage(hWndEditBoxSecond, WM_SETTEXT, IntPtr.Zero, New StringBuilder(secondNum.ToString()))
SendMessage(hWndButtonGo, BN_CLICKED, IntPtr.Zero, Nothing)
End Sub
End Class


از این استفاده کنید.

موفق باشید.

omid-vbAuto
یک شنبه 05 دی 1389, 19:36 عصر
خوب . مهندس این شد یه چیزی .حالا اگه می خواهین و حوصله شو دارین در مورد کدای که دادین بحث کنیم؟

و یا اگه تخصوصتون VB.net نیست که هیچ.

mehdi.mousavi
یک شنبه 05 دی 1389, 20:08 عصر
سلام.


مهندس من تلاش رو به این تعبیر می کنم که بیام از کسانی که در مورد API اطلاع دارن پرسو جو کنم و یاد بگیرم.قرار نیست که دوباره API ها رو اختراع کنم .در واقع کار با API ها مثل کار کردن با یه Textbox معمولی چون همه چیزشمون از قبل طراحی شده هست.و فقط باید بدونی که فلان کد چکار می کنه.که من هم این تاپیک رو زدم تا بدمون کد ApI برای هندل کردن چیه؟که الحمدالله همه در مورد API حرفه ای هستن.و چپ و راست هی نمونه برنامه و کد VB می دن.:عصبانی++:

ببینید. من عموما به بچه ها سعی میکنم سرنخ ها رو بدم، و این دیگه به "تلاش" خودشون (البته به تعبیر من ;)) بر میگرده که چطور از روی اون سرنخ ها، مشکل رو رفع کنن و به پاسخ سوالشون برسن. پاسخی هم که در پست اولم به شما دادم، می تونست باعث بشه که شما MSDN رو زیر و رو کنید، با لینکهایی که به سایت P/Invoke دادم، خودتون، از رو سایت مزبور، نسخه معادل Win32 API توابع مورد نیاز رو بر بردارید و سعی کنید برنامه رو بنویسید (درست همون کاری که من انجام دادم). اما خوب، شما روش ساده رو انتخاب کردید و گفتید من با Win32 API ها آشنا نیستم در حالیکه من براتون گفته بودم که از کدوم Win32 API ها باید استفاده کنید. توضیح هر یک از API ها هم در MSDN بود. بنابراین با کمال احترام، گمان نمیکنم تعبیر شما از "تلاش" درست بوده باشه. :لبخندساده:


خوب . مهندس این شد یه چیزی .حالا اگه می خواهین و حوصله شو دارین در مورد کدای که دادین بحث کنیم؟ و یا اگه تخصوصتون VB.net نیست که هیچ.
من اینجام که در مورد همین مسائل حرف بزنیم دیگه، مگه نه؟ :لبخندساده: درسته که من با VB.NET آشنا نیستم، اما یه چیزایی سرم میشه و در صورت نیاز میتونیم به این گفتگو ادامه بدیم.

موفق باشید.

omid-vbAuto
یک شنبه 05 دی 1389, 20:47 عصر
از توجه حضرتعالی بسیار ممنونم.اینکه نمی خوام خودم برم MSDN رو بخونم راستش رشته ی من کامپیوتر نیست تخصص من عمران هستش و از روی علاقه به برنامه نویسی روی آوردم.و اگه بخوام برم دنبال MSDN و نمی دونم مقاله ها برابر با شکست هست چون من اون تئوری های اولیه رشته کامپیوتر - نرم افزار رو بلد نیستم.تازه تازه دارم به کمک دوستانی مثل شما مثلا برنامه سازی می کنیم نه برنامه نویسی.در کل سطح ما پایین و اما می ریم در مورد کدهاتون بحث کنیم:

من اول کد شما رو اشاره می کنم و بعد سوالمو در موردش می پرسم:




Imports System.Runtime.InteropServices


منظور از InteropServices چیه؟ و آیا موقع استفاده از API ها باید کد بالا رو ذکر کنیم؟




Private Const WM_SETTEXT As Integer = &HC
Private Const BN_CLICKED As Integer = &HF5
Private Const GW_HWNDFIRST As Integer = 0
Private Const GW_HWNDLAST As Integer = 1
Private Const GW_HWNDNEXT As Integer = 2
Private Const GW_HWNDPREV As Integer = 3
Private Const GW_OWNER As Integer = 4
Private Const GW_CHILD As Integer = 5
Private Const GW_ENABLEDPOPUP As Integer = 6



شما مقادیر بالا رو بر چه اساسی مقدار دهی کردین؟ مخصوصا &HC یعنی چی و از کجا آوردین ؟ و یا 1 - 2-...





<DllImport("User32.dll")> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As StringBuilder) As Int32
$$$$$$$$$$$$

End Function




فکر کنم تو کد بالا شما یه DLL به نام User32.dll رو تو برنامه فراخوانی کردین.آره؟مسیر فراخوانیش کجاست؟

و مهمتر از همه اون جای که نوشتم $$$$$$$$$$$$ چرا کدی ننوشتین و خالیه!!!!






من قبلا در این مورد سوال کرده بودم ولی کسی جواب نداد. حالا از شما می پرسم:

بر فرض ما یه DLL داریم که مثلا یه Textbox پیشرفتس و کارائی زیادی داره ما آمدیم و از این DLL تو برناممون استفاده کردیم .حالا من می خوام که این DLL از کنار فایل EXE ام خونده نشه ، و من به برنامه دستور بدم که برو از فلان پوشه DLL رو لود کن.برا این کار باید از چه کدی استفاده کنم؟


شما بعد از فرا خوانی امدین از این عبارات استفاده کردین:



SendMessage
FindWindow
GetClassName
GetWindow

مجموعه ای از این دست توابع رو به صورت کامل با کاری که برا ما انجام می دن رو از کجا میشه گیر آورد؟



یک سوال مهم ، آقا این hWnd یعنی چی؟:عصبانی++:






tabIndex = 4

و یا

tabIndex = 2


شما اینها رو بر اساس سورس برنامه ی من نوشتین؟ یعنی برای نوشتنشون برنامه منو باز کردین و اینها رو کشیدین بیرون؟




While hChildWnd <> IntPtr.Zero



منظور از کد بالا چیه؟



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

mehdi.mousavi
دوشنبه 06 دی 1389, 00:16 صبح
سلام.


منظور از InteropServices چیه؟ و آیا موقع استفاده از API ها باید کد بالا رو ذکر کنیم؟

Interop Services به مجموعه سرویسهایی گفته میشه که دو هدف رو دنبال میکنن: تعامل با Component های COM (منظور Component Object Model هستش)، و سرویسهای P/Invoke. هنگام کار با این دو بخش، عموما از کلاسهایی که در این Namespace قرار گرفته اند استفاده میشه. از اونجاییکه من از DllImport استفاده کردم، مجبور بودم Namespace مزبور رو نیز Declare کنم.



شما مقادیر بالا رو بر چه اساسی مقدار دهی کردین؟ مخصوصا &HC یعنی چی و از کجا آوردین ؟ و یا 1 - 2-...
مقادیر بالا، تعاریفی هستش که در Platform SDK برای هر const توسط شرکت مایکروسافت تعیین شده. من یه پروژه C/C++ روی ماشینم ایجاد کردم، و با زدن کلید F12 رو یکی از اون تعاریف، به header file مربوطه رسیدم و مقادیر رو از اونجا Copy & Paste کردم. در مورد بخش دوم سوال نیز، &HC یعنی عدد 12 دسیمال. برای نشون دادن اعداد در VB.NET شما میتونید با استفاده از اون Syntax، اعداد رو بصورت Hex تعریف کنید. بطور مثال &HFF میشه 255 دسیمال، یا همون FF هگزادسیمال... جای &HFF هرجا بخوام میتونم 255 بنویسم، یا برعکس.



فکر کنم تو کد بالا شما یه DLL به نام User32.dll رو تو برنامه فراخوانی کردین.آره؟مسیر فراخوانیش کجاست؟
خیر. من چیزی رو فراخوانی نکردم. فقط به VB.NET گفتم که قصدا دارم توی برنامه، از تابع SendMessage استفاده کنم، تابعی که توسط مایکروسافت در فایل User32.dll پیاده سازی شده و مدخل ورودیش اونجاست. برای استفاده از Win32 API ها، شما باید همواره بدین شکل عمل کنید. در واقع Prototype تابع مورد نظر رو می نویسید، سپس با گذاشتن DllImportAttribute در بالای اون، به سیستم می فهمونید که تابع مورد نظر کجا پیاده سازی شده. سیستم هم، توی Environment Variable ها میگرده، میره از Path تعیین شده در سیستم، فایل User32.dll رو پیدا میکنه و Entry Point معرفی شده رو Invoke میکنه (هنگام فراخوانی تابع، نه Declare کردن اون).



و مهمتر از همه اون جای که نوشتم $$$$$$$$$$$$ چرا کدی ننوشتین و خالیه!!!!
چون پیاده سازیش در فایل User32.dll هستش.

من
قبلا در این مورد سوال کرده بودم ولی کسی جواب نداد. حالا از شما می پرسم. بر فرض ما یه DLL داریم که مثلا یه Textbox پیشرفتس و کارائی زیادی داره ما آمدیم و از این DLL تو برناممون استفاده کردیم .حالا من می خوام که این DLL از کنار فایل EXE ام خونده نشه ، و من به برنامه دستور بدم که برو از فلان پوشه DLL رو لود کن.برا این کار باید از چه کدی استفاده کنم؟

روش های انجام این کار در این آدرس (http://support.microsoft.com/kb/837908) ذکر شده. من از تکرار اونها صرف نظر میکنم.


مجموعه ای از این دست توابع رو به صورت کامل با کاری که برا ما انجام می دن رو از کجا میشه گیر آورد؟
در MSDN کلیه جزییات مربوط به تمامی Win32 API ها ذکر شده. این سایت (http://www.pinvoke.net/) نیز به شما کمک میکنه تا عمل تبدیل Prototype اون API ها رو به API های فایل فهم در CLR بسادگی انجام بدید.


یک سوال مهم ، آقا این hWnd یعنی چی؟
اون h اولش، نشوندهنده Handle هستش و Wnd مخفف Window. این اسم گذاری بین برنامه نویسهای C/C++ رایج هستش و بهش Hungarian Naming Convension میگن.



شما اینها رو بر اساس سورس برنامه ی من نوشتین؟ یعنی برای نوشتنشون برنامه منو باز کردین و اینها رو کشیدین بیرون؟
خیر. من حلقه اصلی رو که نوشتم، برنامه رو Trace کردم تا ببینم روی index چندم به اون TextBox/Button مورد نظرم میرسم، سپس اونو توی کدم Hard Code کردم. شما میتونید روشهای دیگه ای رو برای اینکار پیش بگیرید، این فقط یه مثال بود برای اینکه با روش انجام اینکار آشنا بشید.



While hChildWnd <> IntPtr.Zero
منظور از کد بالا چیه؟

یعنی "تا وقتی همه Control های موجود در پنجره Math رو بررسی نکرده ای، ادامه بده".


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

موفق باشید.

omid-vbAuto
دوشنبه 06 دی 1389, 09:08 صبح
با سلام مهندس از توضیحات کامل شما ممنونم. ولی بعضی از سوالاتم هنوز برام گنگ و نامفهوم که از تون می پرسم:



Interop Services به مجموعه سرویسهایی گفته میشه که دو هدف رو دنبال میکنن: تعامل با Component های COM (منظور Component Object Model هستش)، و سرویسهای P/Invoke. هنگام کار با این دو بخش، عموما از کلاسهایی که در این Namespace قرار گرفته اند استفاده میشه. از اونجاییکه من از DllImport استفاده کردم، مجبور بودم Namespace مزبور رو نیز Declare کنم.



مهندس شما کجا از DllImport استفاده کردین؟ و منظور از P/Invoke و Declare چیه؟




Private Const WM_SETTEXT As Integer = &HC
Private Const BN_CLICKED As Integer = &HF5
Private Const GW_HWNDFIRST As Integer = 0
Private Const GW_HWNDLAST As Integer = 1
Private Const GW_HWNDNEXT As Integer = 2
Private Const GW_HWNDPREV As Integer = 3
Private Const GW_OWNER As Integer = 4
Private Const GW_CHILD As Integer = 5
Private Const GW_ENABLEDPOPUP As Integer = 6

مقادیر بالا، تعاریفی هستش که در Platform SDK برای هر const توسط شرکت مایکروسافت تعیین شده.


آخه مهندس یعنی چی؟اگه من بخوام ه جای عدد 2 ، 19 بنویسم چی میشه؟کلا اعداد رو تغییر بدم؟:متفکر:



حالا اگه ما بیایم و برنامه ای مبتنی بر User32.dll بنویسیم ممکن هست در سیستم هدف به مشکل بر بخوریم؟مثلا سیستم هدف User32.dll رو نداشته باشه؟

آیا User32.dll در هر ویندوزی مثلا XP و Vista و Seven موجوده؟

در ضمن اکثر برنامه نویس ها از استفاده کردن از API کناره گیری میکنن.آیا دلیل خاصی داره؟




خیر. من حلقه اصلی رو که نوشتم، برنامه رو Trace کردم تا ببینم روی index چندم به اون TextBox/Button مورد نظرم میرسم، سپس اونو توی کدم Hard Code کردم. شما میتونید روشهای دیگه ای رو برای اینکار پیش بگیرید، این فقط یه مثال بود برای اینکه با روش انجام اینکار آشنا بشید.


شما می فرمائین حلقه هست قبول ، ولی این ها :



tabIndex = 4

و یا

tabIndex = 2



رو از کجا گیر آوردین.اینه سوال من:
فکر کنید ما 5 تا Textbox داریم و 3 تا دکمه من چطوری tabindex اونها رو بنویسم؟

با تشکر از زحمات شما.

Saman_12
دوشنبه 06 دی 1389, 17:47 عصر
آخه مهندس یعنی چی؟اگه من بخوام ه جای عدد 2 ، 19 بنویسم چی میشه؟کلا اعداد رو تغییر بدم؟
اتفاق خاصی نمیفته فقط مسیج مورد نظر که قراره فرستاده بشه ماهیتش عوض میشه یعنی مثلا اگر جای 2 بزارین 16 بجای اینکه هندل زیر پنجره بعدی رو بدست بیارین اون آبجکت رو دستور»»(Destor) کردین.(کاری شبیه Remove یا پاک کردن آبجکت و ... هست.)


حالا اگه ما بیایم و برنامه ای مبتنی بر User32.dll بنویسیم ممکن هست در سیستم هدف به مشکل بر بخوریم؟مثلا سیستم هدف User32.dll رو نداشته باشه؟
معمولا (حتمی) این اتفاق نمیفته چون این دی ال ال یکی از Dll های مود نیاز سیستم هست و توی نسخه های مختلف هم وجود داره از جمله ویندوز Xp , Se7en و ...


ی این ها :

کد PHP:
tabIndex = 4

و یا

tabIndex = 2

رو از کجا گیر آوردین.اینه سوال من:
فکر کنید ما 5 تا Textbox داریم و 3 تا دکمه من چطوری tabindex اونها رو بنویسم؟
این کار توسط یک پراپرتی به همین نام انجام میشه و هر کنترل این پراپرتی رو داره.

omid-vbAuto
دوشنبه 06 دی 1389, 19:21 عصر
سوال من اینه که این عدد 4 و یا 2 از کجا بدست آمده:


tabIndex = 4

و یا

tabIndex = 2






خیر. من حلقه اصلی رو که نوشتم، برنامه رو Trace کردم تا ببینم روی index چندم به اون TextBox/Button مورد نظرم میرسم، سپس اونو توی کدم Hard Code کردم. شما میتونید روشهای دیگه ای رو برای اینکار پیش بگیرید، این فقط یه مثال بود برای اینکه با روش انجام اینکار آشنا بشید.

و :


این کار توسط یک پراپرتی به همین نام انجام میشه و هر کنترل این پراپرتی رو داره.



شما می بینید که این دو جواب در تضاد هم قرار دارن و بالاخره ما نفهمیدم که چطوری اعداد 4 و 2 تو کدهامون سبز شدند؟:متفکر:

omid-vbAuto
دوشنبه 06 دی 1389, 19:41 عصر
خیر قربان. ادامه بدید...

موفق باشید.

کی این حرف و می زد؟:لبخند: پس چی شد؟ همش باید در مورد Textbox ازتون سوال بشه؟

البته ایشون تا همین جاشم در حق بنده لطف کردن.

ولی کمک کنید و الا 64184

Saman_12
دوشنبه 06 دی 1389, 20:00 عصر
سوال من اینه که این عدد 4 و یا 2 از کجا بدست آمده:
این اعداد چطور به وجود اومدن؟
این اعداد به طور پیش فرض به کنترل ها در زمان ایجاد نصبت داده میشن و اگر شما دست کاری شون نکنید به ترتیب اظافه کردن کنترل ها عدد بالا میره.
حالا جناب mehdi.mousavi چطور بدست آورده؟
کار ساده ای هست ایشون طبق همون توضیحشون tabIndex هر کدوم از آبجکت های برنامه شما رو به دست آورده حالا چجوری رو خدوشون میدونن مثلا عنوان تمام آبجکت های برنامه شما رو نصبت به tabIndex شون تنظیم کردن و نتیجه این شده.


خیر. من حلقه اصلی رو که نوشتم، برنامه رو Trace کردم تا ببینم روی index چندم به اون TextBox/Button مورد نظرم میرسم، سپس اونو توی کدم Hard Code کردم. شما میتونید روشهای دیگه ای رو برای اینکار پیش بگیرید، این فقط یه مثال بود برای اینکه با روش انجام اینکار آشنا بشید.
و :
این کار توسط یک پراپرتی به همین نام انجام میشه و هر کنترل این پراپرتی رو داره.

شما می بینید که این دو جواب در تضاد هم قرار دارن و بالاخره ما نفهمیدم که چطوری اعداد 4 و 2 تو کدهامون سبز شدند

بر عکس به نظر من هیچ تضادی در کار نیست جمله های اول میگند که tabindex رو به بدست آوردن(این tabindex در برنامه شما هم صدق میکنه یعنی همون پراپرتی که گفتم مقدارش با tabindex ها یکی هست.) و بر اساس اون ابجکت رو مشخص کردن و جمله من هم میگه که tabindex های آبجکت های موجود در برنامه شما توی یک پرارپتی با همین نام ذخیره میشه و مثلا tabindex ی که برنامه شما برای BtnGo در نظر گرفته 4 هست.

omid-vbAuto
دوشنبه 06 دی 1389, 20:18 عصر
سامان جان من هم مثل شما فکر می کردم یعنی:



این کار توسط یک پراپرتی به همین نام انجام میشه و هر کنترل این پراپرتی رو داره.


که دوستمون آقای mehdi.mousavi گفتن غلطه!

خوب من رفتم تو برنامه Math و tabIndex تکس باکس اول رو در اوردم و شد 1 دوباره رفتم tabIndex تکس باکس 2 رو در اوردم شد 3 من در مورد تکس باکس ها به اعداد 1 و 3 رسیدم و روش بدست آوردنشو گفتم.حالا شما بفرمائید اعداد 2 و 4 را از کجا بدست آوردین.

Saman_12
دوشنبه 06 دی 1389, 20:35 عصر
!

خوب من رفتم تو برنامه Math و tabIndex تکس باکس اول رو در اوردم و شد 1 دوباره رفتم tabIndex تکس باکس 2 رو در اوردم شد 3 من در مورد تکس باکس ها به اعداد 1 و 3 رسیدم و روش بدست آوردنشو گفتم.حالا شما بفرمائید اعداد 2 و 4 را از کجا بدست آوردین.

توی کد در اصل tabIndex باید -1 میشده که نشده.(البطه هیچ فرقی نداره ولی همینطوری جهت اطلاع گفتم.)در ضمن هیچ بایدی وجود نداره ولی برای به دست آوردن tabIndex اصلی این کار می بایست انجام بشه.


سامان جان من هم مثل شما فکر می کردم یعنی:

که دوستمون آقای mehdi.mousavi گفتن غلطه

اگه ایشون گفتن پس غلطه چون من هنوز آماتور هستم و چیز زیادی در برابر یک پیش کسوت نمیدونم.

omid-vbAuto
دوشنبه 06 دی 1389, 20:43 عصر
توی کد در اصل tabIndex باید -1 میشده که نشده.(البطه هیچ فرقی نداره ولی همینطوری جهت اطلاع گفتم.)در ضمن هیچ بایدی وجود نداره ولی برای به دست آوردن tabIndex اصلی این کار می بایست انجام بشه.



اگه ایشون گفتن پس غلطه چون من هنوز آماتور هستم و چیز زیادی در برابر یک پیش کسوت نمیدونم.






توی کد در اصل tabIndex باید -1 میشده که نشده.(البطه هیچ فرقی نداره ولی همینطوری جهت اطلاع گفتم.)در ضمن هیچ بایدی وجود نداره ولی برای به دست آوردن tabIndex اصلی این کار می بایست انجام بشه.



سامان نیازی به 1- کردن نیست چون من با کد های آقا مهدی که دادن کار کردم و جواب هم گرفتم و درست هم بود.ولی می خواستم بدونم از کجا به این اعداد 2 و 4 رسیدن.یه احتمال می دم و اونهم اینه که خود فرم tabIndex ای برابر 1 داره و در نتیجه اعداد به دست آورده من یعنی 1 و 3 تبدیل میشن به 2 و 4 ولی یه مسئله کوچیک این وسط میمونه سر tabIndex صفر چه بلائی می آد؟

Saman_12
دوشنبه 06 دی 1389, 20:50 عصر
سامان نیازی به 1- کردن نیست چون من با کد های آقا مهدی که دادن کار کردم و جواب هم گرفتم و درست هم بود.ولی می خواستم بدونم از کجا به این اعداد 2 و 4 رسیدن.یه احتمال می دم و اونهم اینه که خود فرم tabIndex ای برابر 1 داره و در نتیجه اعداد به دست آورده من یعنی 1 و 3 تبدیل میشن به 2 و 4 ولی یه مسئله کوچیک این وسط میمونه سر tabIndex صفر چه بلائی می آد؟

من هم که گفتم نیازی نیست و کد کار میکنه اما اگر -1 میشد اونوقت 2 و4 میشد 1 و3 .
نه خیر.فرم tabIndex نداره و tabIndex 0 هم به Btn شما اختصاص یافته!

mehdi.mousavi
سه شنبه 07 دی 1389, 10:38 صبح
مهندس شما کجا از DllImport استفاده کردین؟ و منظور از P/Invoke و Declare چیه؟
بالای اونجاییکه Win32 API ها رو تعریف کردم نگاه کنید. بالای هر خط... یه DllImport وجود داره.
Declare کردن یعنی تعریف کردن، اظهار کردن...
P/Invoke یعنی Platform Invoke، یکی از Interop Feature های CLR هستش که به شما امکان فراخوانی Win32 API ها رو میده. توضیحات کامل در این مورد رو میتونید در مقاله Jason Clark در مجله MSDN (http://msdn.microsoft.com/en-us/magazine/cc164123.aspx) بخونید.



آخه مهندس یعنی چی؟اگه من بخوام ه جای عدد 2 ، 19 بنویسم چی میشه؟کلا اعداد رو تغییر بدم؟:متفکر:
برنامه از کار می افته. ببینید. برای اینکه هر کسی نخواد این اعداد و ارقام رو حفظ کنه (چون عملا ممکن نیست)، اومدن تو C/C++ اونها رو جداگانه تعریف کردن و به هر یک اسمی دادن. مثلا گفتن وقتی میخواهیم از فلان Win32 API استفاده کنیم، و فلان پارامترش این 5 حالت رو میتونه داشته باشه، جای اینکه با اعداد اون حالات رو بشناسیم، به هر عدد یه اسم میدیم که اون اسامی تو ذهنمون باقی بمونه و از اون به بعد از این اسامی استفاده میکنیم. از طرف دیگه، متاسفانه مایکروسافت این تعاریف رو برای برنامه نویسهای محیط Managed خودش یکبار انجام نداد که ملت اینقدر به دردسر نیفتن. در نتیجه هر کسی باید اون تعاریف رو دوباره خودش تو برنامه خودش انجام بده و این، یعنی اینکه من باید اون تعاریف رو از برنامه C++ ی خودم کپی کنم و به همون شکل در C# استفاده کنم. (اجازه ندارم مقادیر رو تغییر بدم، اما اسامی رو چرا... طبیعتا اسامی رو هم تغییر نمیدیم، که فردا اگر کسی برنامه ما رو خوند، با اسامی جدید روبرو نشه و بدونه داره با چی کار میکنه).


حالا اگه ما بیایم و برنامه ای مبتنی بر User32.dll بنویسیم ممکن هست در سیستم هدف به مشکل بر بخوریم؟مثلا سیستم هدف User32.dll رو نداشته باشه؟
خیر. User32.dll (و بسیاری دیگه از این فایلها) بخش اعظمی از سرویسهای اصلی ویندوز رو تشکیل میدن. اگر User32.dll روی ویندوز نباشه، سیستم شما boot نمیشه که بخواهید نگران بود و نبود اون باشید.


آیا User32.dll در هر ویندوزی مثلا XP و Vista و Seven موجوده؟
بله.


در ضمن اکثر برنامه نویس ها از استفاده کردن از API کناره گیری میکنن.آیا دلیل خاصی داره؟
دلیلش، گذر از محیط Managed به Native و بالعکس هستش. این گذر باعث کاهش Performance برنامه میشه (البته اگر بسیار زیاد و نادرست تکرار بشه).


شما می فرمائین حلقه هست قبول ، ولی این ها tabIndex = 4 و یاtabIndex = 2 رو از کجا گیر آوردین. بالاخره ما نفهمیدم که چطوری اعداد 4 و 2 تو کدهامون سبز شدند؟
لوپ اصلی برنامه رو که نوشتم، برنامه رو Trace کردم ببینم چندمین Index میشه فلان TextBox یا Button. سپس از اون عدد برای شناسایی جایگاه اون Child Window استفاده کردم. ممکنه شما منطق دیگه ای برای شناسایی اون Child Window ها در ذهن داشته باشید، خوب، اونو پیاده سازی کنید. مجبور نیستید از رو Index اونها هنگام Enumerate کردن به این نتیجه برسید که hWnd ی فعلی، Handle به Calculate button هستش.


کی این حرف و می زد؟:لبخند: پس چی شد؟ همش باید در مورد Textbox ازتون سوال بشه؟
چی بگم آخه بهتون؟ من تو این دنیا کارهای دیگه ای نیز دارم که باید بهشون رسیدگی کنم. :(


این اعداد چطور به وجود اومدن؟ این اعداد به طور پیش فرض به کنترل ها در زمان ایجاد نصبت داده میشن و اگر شما دست کاری شون نکنید به ترتیب اظافه کردن کنترل ها عدد بالا میره. حالا جناب mehdi.mousavi چطور بدست آورده؟ کار ساده ای هست ایشون طبق همون توضیحشون tabIndex هر کدوم از آبجکت های برنامه شما رو به دست آورده حالا چجوری رو خدوشون میدونن مثلا عنوان تمام آبجکت های برنامه شما رو نصبت به tabIndex شون تنظیم کردن و نتیجه این شده.

نه نه. سوء تفاهم نشه، شاید اسم اون متغیر رو من باید index میذاشتم که اینهمه داستان درست نشه. :) من از روی TabIndex اون Child Window ها در مورد اونها قضاوت نکردم، از جایگاهشون هنگام Iterate کردن اونها پی به هویت هر یک میبرم. بالاخره باید از روی یه مشخصه ای میفهمیدم که hWnd ی فعلی، Handle به TextBox سمت چپی هست، یا TextBox سمت راستی. منم دیدم ساده ترین راه اینه که Enumerate کنم اونها رو، بر اساس Index ای که بدست میارم تصمیم میگیرم که کدوم Handle ماله کدوم TextBox هستش. حرف شما کاملا درسته، یعنی میشه بر اساس TabIndex واقعی هر Child Window اینکارو نیز انجام داد، اما خوب، من این کارو نکردم.

حالا اگر بازهم سوالی در این زمینه باقی مونده بفرمایید تا در اولین فرصت (و نه لزوما 5 دقیقه دیگه) بهش پاسخ بدم.

موفق باشید.

omid-vbAuto
سه شنبه 07 دی 1389, 15:11 عصر
بابا مهندس :عصبانی++:


ضمن تشکر فراون از زحمات آقا مهدی و آقا سامان
ولی

من فقط می خوام بدونم این 2 و 4 رو از کجا آوردین:گریه:.نمی دونم می گید Enumerate و ... خوب من دنبال این کارم دیگه.دنبال اسم روش که نیستم.این برنامه ای رو که گذاشتم براش هندل نوشتین Math یه برنامه نمونه ساده بود .برنامه اصلی من که این نیستش .من می خوام تو برنامه اصلیم بدونم اعدادی مثل 2 و 4 رو که بدست اوردین تو برنامه خودم چطوری بدست بیارم بعد شما می گید اون رو Enumerate کردم!!!!!!!!خوب روش این کارو بفرمائید.

بعدش هم شما گفتین هم از روش Enumerate بدست می آد و هم از روش سامان خوب یکیشو به من یاد بدین:گریه: