GetWindowText the working way
בהמשך לפוסט על בדיקת שגיאות כתיב בכל מקום.
הבעיות שהתמודדתי איתן היו:
1. הפעלה של התוכנית ע"י צירוף מקשים כאשר האפליקציה שלי לא נמצאת בפוקוס.
2. קבלה של החלון שעכשיו המשתמש נמצא בתוכו ע"י שימוש בWin32 Api.
3. קבלת הטקסט מתוך החלון של המשתמש.
והפעם קריאה של הטקסט מתוך החלון.
לכאורה, עוד משימה פשוטה במיוחד, כיוון שקיימת פונקצית API בשם GetWindowText
השם מבטיח, אבל עם הבטחות לא הולכים למכולת.
ניסיתי לבצע את הקריאה ל GetWindowText, עבור רוב החלונות זה באמת עבד. כאשר עמדתי על כפתור, קיבלתי את הערך שלו, גם כאשר עמדתי בתוך חלון רגיל, אבל בתוך תיבת טקסט זה פשוט לא עבד.
לאחר חיפוש באינטרנט קראתי על המתודה GetDlgItemText אבל גם היא לא נתנה את הפתרון,לכן פניתי לפתרון הבסיסי ביותר, שימוש בשליחת הודעות ברמת מערכת הפעלה מקריאה בMSDN ידעתי שניתן לבצע שליחה של הודעה WM_GETTEXT לחלון ולקבל את תוכן החלון כתשובה.
בMSDN הופיעה החתימה הבא:
Syntax:
To send this message, call the SendMessage function as follows.
lResult = SendMessage(
// returns LRESULT in lResult
(HWND) hWndControl,
// handle to destination control
(UINT) WM_GETTEXT,
// message ID
(WPARAM) wParam,
// = (WPARAM) () wParam;
(LPARAM) lParam
// = (LPARAM) () lParam;
);
Parameters
wParam
Specifies the maximum number of TCHARs to be copied, including the terminating null character.
Windows NT/2000/XP:ANSI applications may have the string in the buffer reduced in size (to a minimum of half that of the wParam value) due to conversion from ANSI to Unicode.
lParam
Pointer to the buffer that is to receive the text.
Return Value
The return value is the number of TCHARs copied, not including the terminating null character.
זה נראה פשוט לבצע את הקריאה מתוך קוד ++C שזאת הדרך המקורית להשתמש בAPI אבל מתוך NET. זה לא כזה טריוויאלי.
לאחר חיפוש באינטרנט מצאתי שכל מה שצריך לעשות זה ליצור את החתימה הבאה:
[DllImport("user32.dll")]
public static extern
IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, StringBuilder sb);
ולאחר קריאה למתודה הStringBuiler יכיל את התוכן של החלון ומכן הכל פשוט.
נקודה יפה נוספת היא כאשר רוצים לקבל את הסימון של הטקסט בתוך חלון, ניתן לשלוח לו את הודעה EM_GETSEL ולקבל את StartIndex ואת הEndIndex של הסימון.