У меня есть требование, когда мне нужно создать библиотеку классов, чтобы уведомлять вызывающую сторону, когда пользователь делает cntrl + c. Я создал windows форму (отключение пользовательского интерфейса формы, даже процесс скрыт от панели задач) внутри этой библиотеки классов !, так что будет иметь обработчик для SetClipboardViewer
метода WinApi32. Ниже приведен фрагмент кода.
Инициализатор формы,
private void InitializeComponent()
{
this.SuspendLayout();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.ClientSize = new System.Drawing.Size(326, 90);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Name = "ClipboardHandle";
this.Text = "ClipboardHandler";
this.Opacity = 0D;
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.WindowState = System.Windows.Forms.FormWindowState.Minimized;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnFormClosing);
this.Load += new System.EventHandler(this.OnLoad);
this.ResumeLayout(false);
}
И в моем классе формы (т.е. ClipboardHandle) OnLoad
событие, передающее форму handler
в SetClipboardViewer
метод, как показано ниже,
IntPtr nextClipboardViewer;
private void OnLoad(object sender, EventArgs e)
{
nextClipboardViewer = SetClipboardViewer(this.Handle);
}
WinApi32
метод
[DllImport("User32.dll")]
internal static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
Поскольку это библиотека классов, я не могу использовать Application.Run
вместо загрузки формы Я запускаю класс формы, как показано ниже:
monitorTask = Task.Run(async delegate
{
log.Info("STA thread start");
var stathread = new Thread(() =>
{
try
{
handler = new ClipboardHandle(); // form class
handler.ClipboardEvent += (e) => { onEventOccured("clipboardCopy", e); };
handler.ShowDialog();
}
catch (Exception ex)
{
log.Error("Exception: ", ex);
}
});
stathread.SetApartmentState(ApartmentState.STA);
stathread.Start();
while (!ct.IsCancellationRequested)
{
await Task.Delay(100);
}
log.Info("unregister and close");
handler.UnRegister();
handler.Close();
stathread.Join();
ct.ThrowIfCancellationRequested();
}, ct);
Я пытался использовать как handler.ShowDialog()
, так и handler.Show()
, ниже я получаю сообщение об ошибке, когда использую handler.ShowDialog()
, а более поздняя версия не ' не выдает никакой ошибки, но не будет никакого триггера события в методе WndProc
при изменениях clipboard
.
Исключение:: System.InvalidOperationException: Отображение модального диалогового окна или формы, когда приложение не работает в режиме UserInteractive не является допустимой операцией. Укажите стиль ServiceNotification или DefaultDesktopOnly для отображения уведомления из приложения-службы. в System. Windows .Forms.Form.ShowDialog (владелец IWin32Window)
Во-первых, я понимаю, что использование ShowDialog () внутри библиотеки классов - это не способ go, но Show () метод также не запускает события изменения буфера обмена, и я не понимаю, что это приложение прекрасно работает, когда метод handler.ShowDialog()
используется внутри библиотеки классов и упоминается в консольном приложении (тестовое приложение ) в visual studio (в режиме отладки), но завершается неудачно, когда размещается как windows служба.
Почему WndProc
не срабатывает при изменении буфера обмена при использовании handler.Show()
, но срабатывает при handler.ShowDialog()
?
Я также попытался запустить службу windows в контексте пользователя Режим. Также упоминаются ниже сообщения,
stackoverflow.com / questions / 8928713 / как решать проблемы, показывающие модальное диалоговое окно или форма, когда приложение - Я
Любые идеи или помощь очень ценится. Заранее спасибо.