簡體   English   中英

我如何編寫使用C#鍵盤類的dll函數

[英]How can i write a dll function that uses the C# Keyboard Class

我想使用以下代碼在特定時間訪問鍵盤的狀態。

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Windows.Input;

namespace some.any
{

    public class ANY_CLASS
    {
    [STAThread] //seems to do nothing here
    public static short ThisIsCalledByAnExternalProgram()
    {
        try
        {
            if (Keyboard.IsKeyDown(Key.LeftAlt))
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }
        catch (Exception e)
        {
                MessageBox.Show(e.ToString());
                return 2;
         }
    }
}

此代碼需要一些dll進行編譯:WindowsBase.dll和PresentationCore.dll

鍵盤需要STA線程,通常我會寫的[STAThread]屬性的主要功能和它的工作,但是這個代碼將被用來作為一個dll,所以我不能做到這一點。 我的功能ThisIsCalledByAnExternalProgram()將不得不為STA運行,但它不。

我如何獲得此代碼以dll的形式工作?

編輯:什么,當你調用發生ThisIsCalledByAnExternalProgram()一個STAThread內標記的方法?

當我打電話的功能與我的外部程序我得到一個異常:System.InvalidOperationException:...調用線程必須為STA,因為許多UI組件都需要這個。 堆棧為:

System.Windows.Input.InputManager..ctor()
System.Windows.Input.InputManager.GetCurrentInputManagerImpl()
ThisIsCalledByAnExternalProgram()

EDIT#3:我誤解了問題-...在STAThread中標記為......我目前無法嘗試此問題。 假設它可以通過並且可以工作-由於我無法控制調用程序,因此這仍然無法解決問題。

編輯#2:使用Win32掛鈎:由於可移植性,我想留在.net內。 最終,所有全局鈎子變體都取決於虛擬機下方的計算機,我想使用准備好的c#鍵盤類。

它在不同的上下文中工作-這是一個簡短的演示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
//Requires WindowsBase.dll
//Requires PresentationCore.dll


namespace KeyBoardDemo
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            while (true)
            {
                if (Keyboard.IsKeyDown(Key.LeftAlt))
                {
                    Console.WriteLine("LEFT ALT IS PRESSED");
                }
                else
                {
                    Console.WriteLine("LEFT ALT IS NOT PRESSED");
                }
            }
        }
    }
}

考慮使用鈎子,而不是僅將winform類用於輸入。 本文很好地解釋了僅使用C#進行一些修改的情況。 它還提供了一個可能適合您需要的輸入庫(.dll)。 本文的范圍主要是全局掛鈎,但也討論了使用特定於應用程序的掛鈎。

http://www.codeproject.com/KB/cs/globalhook.aspx

我找到了解決問題的方法,但是感覺像是一種解決方法。

A)我必須避開靜態屬性,以便創建新的線程。 B)在使用Keayboard之前,我必須確保STA。

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Windows.Input;
using System.Threading;

namespace some.any
{

    public class ANY_CLASS
    {
    static STAKeyBoard mSTAKeyBoard = new STAKeyBoard();

    public static short ThisIsCalledByAnExternalProgram()
    {
        try
        {
            if (mSTAKeyBoard.IsKeyDown(Key.LeftAlt))
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }
        catch (Exception e)
        {
                MessageBox.Show(e.ToString());
                return 2;
         }
    }

    class STAKeyBoard
    {
        private Thread mKeyBoardReadThread = null;
        private Boolean mKeyState = false;
        private Key mKeyOfInterest;
        private string running = "ONLY ONE REQUEST";

        public Boolean IsKeyDown(Key KeyOfInterest)
        {
            lock (running)
            {
                mKeyOfInterest = KeyOfInterest;
                mKeyBoardReadThread = new Thread(new ThreadStart(GetKeyState));
                mKeyBoardReadThread.SetApartmentState(ApartmentState.STA);
                mKeyBoardReadThread.Start();
                mKeyBoardReadThread.Join(1000);
                mKeyBoardReadThread.Abort();
                mKeyBoardReadThread = null;
                return mKeyState;
            }
        }

        private void GetKeyState()
        {
            mKeyState = Keyboard.IsKeyDown(mKeyOfInterest);
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM