בהמשך לפוסט על בדיקת שגיאות כתיב בכל מקום.
הבעיות שהתמודדתי איתן היו:
1. הפעלה של התוכנית ע"י צירוף מקשים כאשר האפליקציה שלי לא נמצאת בפוקוס.
2. קבלה של החלון שעכשיו המשתמש נמצא בתוכו ע"י שימוש בWin32 Api.
3. קבלת הטקסט מתוך החלון של המשתמש.
והפעם קבלה של חלון שעכשיו המשתמש נמצא בתוכו.
הבעיה השניה נראתה לי פשוטה. מנסיוני, ידעתי שWindows API מכיל את המתודה GetFocus
בגלל זה ניסיתי את הקוד הפשוט הבא:
[DllImport("user32.dll")]
public static extern IntPtr GetFocus();
public void TryGetFoucsWindow()
{
MessageBox.Show(GetFocus().ToString());
}
אבל בכל פעם שבדקתי תמיד חזר לי הערך 0.
לאחר מחקר קצר בMSDN הבנתי שGetFocus וGetActiveWindow עבודות כאשר החלון נמצא בתוך הThread שלי, ואז מצאתי את המודה בAttachThreadInput. מקריאה בMSDN ראיתי שבכדי להפעיל את המתודה צריך להעביר לה את הThread Id.
Thread Id ? מאיפה זה הגיע?! ואז מצאתי את המתודות הבאות:
1. GetWindowThreadProcessId - מחזירה את הThreadId של חלון.
2. GetCurrentThreadId - מחזירה את הThreadId של האפליקציה שלי.
לסיום כתבתי את הקוד הבא:
[DllImport("user32.dll")]
public static extern
IntPtr GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
[DllImport("user32.dll")]
public static extern
IntPtr AttachThreadInput(IntPtr idAttach, IntPtr idAttachTo, int fAttach);
[DllImport("user32.dll")]
public static extern
IntPtr GetFocus();
[DllImport("user32.dll")]
public static extern
IntPtr GetActiveWindow();
[DllImport("user32.dll")]
public static extern
IntPtr GetForegroundWindow();
[DllImport("Kernel32.dll")]
public static extern
IntPtr GetCurrentThreadId();
public void TryGetFoucsWindow()
{
IntPtr activeWindow = GetForegroundWindow();
IntPtr threadID1 = GetCurrentThreadId();
IntPtr threadID2 = GetWindowThreadProcessId(activeWindow, IntPtr.Zero);
if (threadID1 != threadID2
{
AttachThreadInput(threadID1, threadID2, 1);
IntPtr focusWindow = GetFocus();
AttachThreadInput(threadID1, threadID2, 0);
MessageBox.Show(focusWindow);
}
}
החתימות הnet. לכל המתודות מתוך הWin32 Api הגיעו מתוך Pinvoke.net