سؤال

لقد كنت أبحث حولي، ولم أجد كيف يمكنني القيام بذلك من C#.

كنت أرغب في القيام بذلك حتى أتمكن من إخبار Google Chrome بالتوقف إلى الأمام, خلف, افتح علامة تبويب جديدة, إغلاق علامة التبويب, فتح نافذة جديدة, ، و أغلق النافذة من تطبيقي C#.

لقد فعلت شيئًا مشابهًا باستخدام برنامج WinAmp

[DllImport("user32", EntryPoint = "SendMessageA")]
private static extern int SendMessage(int Hwnd, int wMsg, int wParam, int lParam);

وعدد قليل من الآخرين.لكنني لا أعرف ما هي الرسالة التي يجب إرسالها أو كيفية العثور على النافذة التي سأمررها إليها أو أي شيء.

فهل يمكن لأحد أن يوضح لي كيف يمكنني إرسال هذه الأوامر الستة إلى Chrome من C#؟شكرًا

يحرر:حسنًا، لقد تم التصويت ضدي، لذلك ربما لم أكن واضحًا بما فيه الكفاية، أو يفترض الناس أنني لم أحاول اكتشاف ذلك بنفسي.

أولاً، أنا لست جيدًا جدًا في التعامل مع عناصر DllImport بأكملها.ما زلت أتعلم كيف يعمل كل شيء.

لقد وجدت كيفية القيام بنفس الفكرة في برنامج Winamp منذ بضع سنوات، وكنت أنظر إلى الكود الخاص بي.لقد قمت بذلك حتى أتمكن من تخطي أغنية، والرجوع إليها، وتشغيلها، وإيقافها مؤقتًا، وإيقاف برنامج Winamp من كود C# الخاص بي.لقد بدأت باستيراد:

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr FindWindow([MarshalAs(UnmanagedType.LPTStr)] string lpClassName, [MarshalAs(UnmanagedType.LPTStr)] string lpWindowName);
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern int SendMessageA(IntPtr hwnd, int wMsg, int wParam, uint lParam);
    [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    public static extern int GetWindowText(IntPtr hwnd, string lpString, int cch);
    [DllImport("user32", EntryPoint = "FindWindowExA")]
    private static extern int FindWindowEx(int hWnd1, int hWnd2, string lpsz1, string lpsz2);
    [DllImport("user32", EntryPoint = "SendMessageA")]
    private static extern int SendMessage(int Hwnd, int wMsg, int wParam, int lParam);

ثم استخدم الكود الذي وجدته لاستخدام هذه الثوابت للرسائل التي أرسلها.

    const int WM_COMMAND = 0x111;
    const int WA_NOTHING = 0;
    const int WA_PREVTRACK = 40044;
    const int WA_PLAY = 40045;
    const int WA_PAUSE = 40046;
    const int WA_STOP = 40047;
    const int WA_NEXTTRACK = 40048;
    const int WA_VOLUMEUP = 40058;
    const int WA_VOLUMEDOWN = 40059;
    const int WINAMP_FFWD5S = 40060;
    const int WINAMP_REW5S = 40061;

سأحصل على hwnd (البرنامج المراد إرسال الرسالة إليه) عن طريق:

IntPtr hwnd = FindWindow(m_windowName, null);

ثم أود أن أرسل رسالة إلى هذا البرنامج:

SendMessageA(hwnd, WM_COMMAND, WA_STOP, WA_NOTHING);

أفترض أنني سأفعل شيئًا مشابهًا جدًا لهذا لمتصفح Google Chrome.لكنني لا أعرف ما ينبغي أن تكون عليه بعض هذه القيم، وقد بحثت في Google محاولًا العثور على الإجابة، لكنني لم أستطع، ولهذا سألت هنا.لذا سؤالي هو كيف أحصل على القيم لـ:

m_windowName و WM_COMMAND

ومن ثم، قيم الأوامر المختلفة، إلى الأمام, خلف, علامة تبويب جديدة, إغلاق علامة التبويب, نافذة جديدة, أغلق النافذة?

هل كانت مفيدة؟

المحلول

ابدأ بحثك في http://dev.chromium.org/developers


يحرر:إن إرسال رسالة إلى النافذة هو نصف العمل فقط.يجب أن تستجيب النافذة لتلك الرسالة وتتصرف وفقًا لذلك.إذا كانت تلك النافذة لا تعرف بوجود رسالة ما أو لا تهتم على الإطلاق، فليس لديك فرصة للتحكم بها عن طريق إرسال رسائل النافذة.

أنت تنظر إلى تفاصيل التنفيذ حول كيفية التحكم عن بعد في برنامج Winamp.يعد إرسال الرسائل إحدى الطرق للقيام بذلك وهي الطريقة التي اختارها مطورو برنامج Winamp.تلك الرسائل التي تستخدمها هي رسائل يحددها المستخدم ولها معنى محدد فقط لبرنامج وينامب.

ما عليك فعله في الخطوة الأولى هو معرفة ذلك لو يدعم Chromium نوعًا ما من التحكم عن بعد وما هي تلك الآليات.

نصائح أخرى

يمكنك الحصول على اسم النافذة بسهولة باستخدام Visual Studio’s Spy++ والضغط على CTRL+F، ثم العثور على chrome.لقد حاولت ذلك وحصلت

"Chrome_VistaFrame" للنافذة الخارجية.النافذة الفعلية التي تحتوي على صفحة الويب هي "Chrome_RenderWidgetHostHWND".

بقدر ما يذهب WM_COMMAND - ستحتاج إلى التجربة.من الواضح أنك تريد إرسال نقرات على الزر (WM_MOUSEDOWN من أعلى رأسي).نظرًا لأن الأزرار الخلفية والأمامية ليست نوافذ خاصة بها، فستحتاج إلى معرفة كيفية القيام بذلك من خلال محاكاة النقر بالماوس على موضع x وy معين حتى يعرف Chrome ما تفعله.أو يمكنك إرسال اختصار لوحة المفاتيح المكافئ للخلف/الأمام وما إلى ذلك.

مثال كتبته منذ فترة يفعل ذلك باستخدام Trillian و Winamp: إرسال الرسائل إلى Windows عبر C# وWinapi

هناك أيضًا أدوات متاحة لإنجاز هذا النوع من الأشياء بالفعل، باستخدام لغة البرمجة النصية - autoit هي إحدى اللغات التي استخدمتها: autoit.com

حسنًا ، إليك ما لدي حتى الآن ...أعلم نوعًا ما ما يجب أن أفعله، لكن الأمر يتعلق فقط بالقيام بذلك الآن...

هذه هي النافذة من Spy++، التي قمت بتأمينها على Chrome_RenderWidgetHostHWND وقمت بالنقر فوق الزر "رجوع" على لوحة المفاتيح.وهنا ما حصلت عليه:alt text

إذن هذه هي افتراضاتي، ولقد كنت ألعب بهذا الأمر منذ فترة طويلة الآن، ولا أستطيع معرفة ذلك قيم.

IntPtr hWnd = FindWindow("Chrome_RenderWidgetHostHWND", null);
SendMessage(hWnd, WM_KEYDOWN, VK_BROWSER_BACK, 0);
SendMessage(hWnd, WM_KEYUP,   VK_BROWSER_BACK, 0);

الآن، لا أعرف ما الذي يجب أن أقوم بإنشائه بقيم WM_KEYDOWN/UP أو قيم VK_BROWSER_BACK/FORWARD...حاولت هذا:

const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;
const int VK_BROWSER_BACK = 0x6A;
const int VK_BROWSER_FORWARD = 0x69;

القيمتان الأخيرتان اللتان حصلت عليهما من الصورة التي عرضتها للتو، هما ScanCodes لهذين المفتاحين.لا أعرف إذا كنت قد فعلت ذلك بشكل صحيح بالرغم من ذلك.القيمتان السابقتان اللتان حصلت عليهما بعد البحث في Google عن قيمة WM_KEYDOWN، واستخدم شخص ما &H100 و&H101 للقيمتين.لقد جربت العديد من الأفكار العشوائية الأخرى التي رأيتها تطفو على السطح.أنا فقط لا أستطيع معرفة هذا.

أوه، وهنا طريقة SendMessage

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, uint lParam);

هذا موقع رائع لثوابت التشغيل المتداخل:

com.pinvoca

هناك طريقة أخرى للعثور على القيم وهي البحث في koders.com، باستخدام C# كلغة، عن WM_KEYDOWN أو الثابت الذي تبحث عنه:

البحث في موقع كودرز.كوم

تبدو قيم &H وكأنها من VB(6).يقوم كل من pinvoc و koders بإرجاع نتائج لـ VK_BROWSER_FORWARD،

private const UInt32 WM_KEYDOWN        = 0x0100;
private const UInt32 WM_KEYUP          = 0x0101;

public const ushort VK_BROWSER_BACK = 0xA6;
public const ushort VK_BROWSER_FORWARD = 0xA7;
public const ushort VK_BROWSER_REFRESH = 0xA8;
public const ushort VK_BROWSER_STOP = 0xA9;
public const ushort VK_BROWSER_SEARCH = 0xAA;
public const ushort VK_BROWSER_FAVORITES = 0xAB;
public const ushort VK_BROWSER_HOME = 0xAC;

(من المضحك عدد التعريفات الخاطئة لثوابت VK التي تطفو على السطح، مع الأخذ في الاعتبار أن VK_* عبارة عن قيم 1 بايت 0-255، وقد جعلها الناس uints).

يبدو مختلفًا قليلاً عن ثوابتك.أعتقد أن الوظيفة التي تبحث عنها هي SendInput (لكنني لم أجرّبها) لأنها مفتاح افتراضي.

[DllImport("User32.dll")]
private static extern uint SendInput(uint numberOfInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] KEYBOARD_INPUT[] input, int structSize);

شرح عن المعلمات:

حدود

  • nInputs- عدد الهياكل في صفيف pInputs.
  • pInputs - مؤشر إلى مجموعة من بنيات INPUT.يمثل كل هيكل حدثًا سيتم إدراجه في تدفق إدخال لوحة المفاتيح أو الماوس.
  • cbSize - يحدد حجم بنية INPUT بالبايت.إذا لم يكن cbSize بحجم بنية INPUT، فستفشل الوظيفة.

يحتاج هذا إلى نوع KEYBOARD_INPUT:

[StructLayout(LayoutKind.Sequential)] 
public struct KEYBOARD_INPUT
{ 
    public uint type; 
    public ushort vk; 
    public ushort scanCode; 
    public uint flags; 
    public uint time; 
    public uint extrainfo; 
    public uint padding1; 
    public uint padding2; 
}

وأخيرًا عينة لم أختبرها إذا كانت تعمل:

/*
typedef struct tagKEYBDINPUT {
    WORD wVk;
    WORD wScan;
    DWORD dwFlags;
    DWORD time;
    ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT;
*/
public static void sendKey(int scanCode, bool press)
{
        KEYBOARD_INPUT[] input = new KEYBOARD_INPUT[1];
        input[0] = new KEYBOARD_INPUT();
        input[0].type = INPUT_KEYBOARD;
        input[0].vk = VK_BROWSER_BACK;

    uint result = SendInput(1, input, Marshal.SizeOf(input[0]));
}

ستحتاج أيضًا إلى التركيز على نافذة Chrome باستخدام SetForegroundWindow

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top