Write Your Own Windows Inspector

14 12 2008

سلام، امروز براتون یه نمونه برنامه ی توپ نوشتم که می خوام براتون توضیح بدم، معمولا هر برنامه ای که می نویسم هر کدومش داستانی برا خودش داره، چرا و از کجا شروع شد، هدف چی بود و چی از آب در اومد، همینقدر بدونین که ایده ی اینم از بحث Code injection به ذهنم رسید که اگه خدا بخواد و مطلب Code injection و تموم کنم براتون یک مقاله در این موردم می ذارم. اکثر دوستان برنامه نویس حتما با نرم افزار های Spy++, Winspector, HwndSpy آشنایی دارن، این نرم افزار ها ابزارهای بسیار نابی برای برنامه نویسان سیستم هستن. چرا که هر رخداد و رویدادی که در ویندوز میفته مانیتور می کنن و کمک زیادی در درک نحوه کار سیستم و نرم افزار به برنامه نویسان ارائه میدن. دیشب داشتم با یکی از این ابزار کار می کردم، با خودم گفتم من که این همه امکانات نیاز ندارم، بنابر این تصمیم گرفتم یک برنامه ی کوچولو برا خودم بنویسم که با حرکت ماوس بر روی Window ها و کنترل ها Handle , Control Id و Class name اون ها رو بر گردونه.

نحوه کار خیلی ساده ست، کلیات کار از این قراره که شما Handle ویندو رو بر اساس موقعیت ماوس بر روی Screen با استقاده از تابع WindowFromPoint بدست میارین و سپس به راحتی مشخصات Window مورد نظرتون رو با استفاده از Handle بدست اومده استخراج می کنید. قلب برنامه متد MouseMovementEvent هستش که وظیفش بدست آوردن Handle ویندو و مشخصات مربوط به ویندویی  رو داره که ماوس بر روی اونه.

تصویر زیر نمایش حالت اجرای نرم افزار رو نشون میده که مکان ماوس بر روی یکی از button های پنجره Run هستش و اطلاعات اون ویندو رو نشون میده :

SaberSoft.BitInspector

برای دانلود سورس کامل برنامه اینجا رو کلیک کنید
void MouseMovementEvent(HWND hwndDialog, POINT pt)
{
//----/ Get window handle from mouse location
HWND hwnd = WindowFromPoint(pt);
DWORD processID, threadID;
//----/ Get process id by handle of window that mouse now on it
threadID = GetWindowThreadProcessId(hwnd, &processID);
//----/ We don't want to inspect our process
if (::GetCurrentProcessId() == processID) return;
if (hwndOld == hwnd) return;
//------------------------------------------
//-----/ Clear border of last detected window
if (hwndOld)
HighLightWindow(hwndOld, false);
//-----/ Highlight selected window
HighLightWindow(hwnd, true);
//-----/ Set old window handle by new
hwndOld = hwnd;
TCHAR chr[128];
//-----/ Set handle EDIT
_stprintf(chr, __TEXT("0x%08X"), hwnd);
::SetDlgItemText(hwndDialog, IDC_HANDLEEDIT, chr);
//-----/ Set Control ID
DWORD id = GetWindowLong(hwnd, GWL_ID);
_stprintf (chr, __TEXT("%d"), id);
::SetDlgItemText (hwndDialog, IDC_CTRLIDEDIT, chr);
//-----/ Set Class name
::GetClassName (hwnd, chr, 128);
::SetDlgItemText (hwndDialog, IDC_CLASSEDIT, chr);
}