Saya memiliki aplikasi C # winforms yang menjalankan makro di program lain. Program lain akan terus-menerus memunculkan jendela dan secara umum membuat segala sesuatunya terlihat, karena tidak ada kata yang lebih baik, gila. Saya ingin menerapkan tombol batal yang akan menghentikan proses agar tidak berjalan, tetapi saya tidak bisa membuat jendela tetap di atas. Bagaimana saya melakukan ini di C #?
Sunting: Saya telah mencoba TopMost = true; , tetapi program lain terus memunculkan jendelanya sendiri di atasnya. Apakah ada cara untuk mengirim jendela saya ke atas setiap n milidetik?
Sunting: Cara saya menyelesaikan ini adalah dengan menambahkan ikon baki sistem yang akan membatalkan proses dengan mengklik dua kali di atasnya. Ikon baki sistem tidak tertutupi. Terima kasih untuk semua yang menanggapi. Saya membaca artikel tentang mengapa tidak ada jendela 'super-on-top' ... secara logis tidak berfungsi.
Jawaban:
Form.TopMost
akan berfungsi kecuali jika program lain membuat jendela paling atas.Tidak ada cara untuk membuat jendela yang tidak tercakup oleh jendela paling atas baru dari proses lain. Raymond Chen menjelaskan alasannya.
sumber
Form.ActiveForm.TopMost
Saya sedang mencari untuk membuat aplikasi WinForms saya "Selalu di Atas" tetapi pengaturan "Paling Top" tidak melakukan apa-apa untuk saya. Saya tahu itu mungkin karena WinAmp melakukan ini (bersama dengan sejumlah aplikasi lain).
Apa yang saya lakukan adalah membuat panggilan ke "user32.dll." Saya tidak ragu melakukannya dan hasilnya bagus. Itu adalah pilihan.
Pertama, impor namespace berikut:
using System.Runtime.InteropServices;
Tambahkan beberapa variabel ke deklarasi kelas Anda:
private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); private const UInt32 SWP_NOSIZE = 0x0001; private const UInt32 SWP_NOMOVE = 0x0002; private const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
Tambahkan prototipe untuk fungsi user32.dll:
[DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
Kemudian di kode Anda (saya menambahkan panggilan di Form_Load ()), tambahkan panggilan:
SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
Semoga membantu. Referensi
sumber
Jika yang Anda maksud dengan "menjadi gila" adalah setiap jendela terus mencuri fokus dari yang lain, TopMost tidak akan menyelesaikan masalah.
Sebagai gantinya, coba:
Ini akan menunjukkan bentuk 'anak' tanpa mencuri fokus. Bentuk anak juga akan tetap berada di atas induknya meskipun induknya diaktifkan atau difokuskan. Kode ini hanya berfungsi dengan mudah jika Anda telah membuat instance dari bentuk anak dari dalam formulir pemilik. Jika tidak, Anda mungkin harus menyetel pemilik menggunakan API.
sumber
CalledForm.Owner
ke dirinya sendiri (CalledForm
) akan menyebabkanSystem.ArgumentException
: 'Referensi kontrol melingkar telah dibuat. Kontrol tidak dapat dimiliki oleh atau diasuh untuk dirinya sendiri. 'Atur Form.TopMost
sumber
Saya mengalami selang waktu 5 menit dan saya lupa untuk menentukan formulir secara lengkap seperti ini:
myformName.ActiveForm.TopMost = true;
Tapi yang saya inginkan adalah INI!
this.TopMost = true;
sumber
Set
.TopMost
properti formulir menjadi benar.Anda mungkin tidak ingin membiarkannya seperti ini sepanjang waktu: atur saat proses eksternal Anda dimulai dan kembalikan saat selesai.
sumber
Cara saya menyelesaikannya adalah dengan membuat ikon baki sistem yang memiliki opsi batal.
sumber
Kode berikut membuat jendela selalu berada di atas sekaligus menjadikannya tanpa bingkai.
using System; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; namespace StayOnTop { public partial class Form1 : Form { private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); private const UInt32 SWP_NOSIZE = 0x0001; private const UInt32 SWP_NOMOVE = 0x0002; private const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE; [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); public Form1() { InitializeComponent(); FormBorderStyle = FormBorderStyle.None; TopMost = true; } private void Form1_Load(object sender, EventArgs e) { SetWindowPos(this.Handle, HWND_TOPMOST, 100, 100, 300, 300, TOPMOST_FLAGS); } protected override void WndProc(ref Message m) { const int RESIZE_HANDLE_SIZE = 10; switch (m.Msg) { case 0x0084/*NCHITTEST*/ : base.WndProc(ref m); if ((int)m.Result == 0x01/*HTCLIENT*/) { Point screenPoint = new Point(m.LParam.ToInt32()); Point clientPoint = this.PointToClient(screenPoint); if (clientPoint.Y <= RESIZE_HANDLE_SIZE) { if (clientPoint.X <= RESIZE_HANDLE_SIZE) m.Result = (IntPtr)13/*HTTOPLEFT*/ ; else if (clientPoint.X < (Size.Width - RESIZE_HANDLE_SIZE)) m.Result = (IntPtr)12/*HTTOP*/ ; else m.Result = (IntPtr)14/*HTTOPRIGHT*/ ; } else if (clientPoint.Y <= (Size.Height - RESIZE_HANDLE_SIZE)) { if (clientPoint.X <= RESIZE_HANDLE_SIZE) m.Result = (IntPtr)10/*HTLEFT*/ ; else if (clientPoint.X < (Size.Width - RESIZE_HANDLE_SIZE)) m.Result = (IntPtr)2/*HTCAPTION*/ ; else m.Result = (IntPtr)11/*HTRIGHT*/ ; } else { if (clientPoint.X <= RESIZE_HANDLE_SIZE) m.Result = (IntPtr)16/*HTBOTTOMLEFT*/ ; else if (clientPoint.X < (Size.Width - RESIZE_HANDLE_SIZE)) m.Result = (IntPtr)15/*HTBOTTOM*/ ; else m.Result = (IntPtr)17/*HTBOTTOMRIGHT*/ ; } } return; } base.WndProc(ref m); } protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.Style |= 0x20000; // <--- use 0x20000 return cp; } } } }
sumber
Apa aplikasi lain yang Anda coba untuk tutupi visibilitasnya? Sudahkah Anda menyelidiki cara lain untuk mencapai efek yang Anda inginkan? Harap lakukan sebelum mengarahkan pengguna Anda pada perilaku nakal seperti yang Anda gambarkan: apa yang Anda coba lakukan terdengar seperti apa yang dilakukan situs nakal tertentu dengan jendela browser ...
Setidaknya cobalah untuk mematuhi aturan Kejutan Terkecil . Pengguna berharap dapat menentukan sendiri urutan z dari sebagian besar aplikasi. Anda tidak tahu apa yang paling penting bagi mereka, jadi jika Anda mengubah sesuatu, Anda harus fokus untuk mendorong aplikasi lain di belakang semuanya daripada mempromosikan aplikasi Anda sendiri.
Ini tentu saja lebih rumit, karena Windows tidak memiliki pengelola jendela yang sangat canggih. Dua pendekatan menunjukkan diri mereka sendiri:
sumber
Mengapa tidak menjadikan formulir Anda sebagai kotak dialog:
sumber
TopMost = true
memaksa formulir saya di atas segalanya, termasuk chrome, padahal sebenarnya itu hanya kotak pengaturan dan saya membutuhkannya di atas formulir utama. Kudos to you internet person.Berikut adalah padanan SetForegroundWindow:
Saya telah melihat orang-orang melakukan hal-hal aneh seperti:
this.TopMost = true; this.Focus(); this.BringToFront(); this.TopMost = false;
http://blog.jorgearimany.com/2010/10/win32-setforegroundwindow-equivalent-in.html
sumber
this.Show(); this.Activate(); this.BringToFront();
Tetapi jawaban ini membawa kami ke solusi itu. Terima kasih!Saya tahu ini sudah tua, tetapi saya tidak melihat tanggapan ini.
Di jendela (xaml) tambahkan:
Deactivated="Window_Deactivated"
Di kode di belakang untuk Window_Deactivated:
private void Window_Deactivated(object sender, EventArgs e) { Window window = (Window)sender; window.Activate(); }
Ini akan membuat jendela Anda tetap di atas.
sumber
Berdasarkan jawaban clamum , dan komentar Kevin Vuilleumier tentang bendera lain yang bertanggung jawab atas perilaku tersebut, saya membuat sakelar yang beralih antara on-top dan tidak on-top dengan menekan tombol.
private void button1_Click(object sender, EventArgs e) { if (on) { button1.Text = "yes on top"; IntPtr HwndTopmost = new IntPtr(-1); SetWindowPos(this.Handle, HwndTopmost, 0, 0, 0, 0, TopmostFlags); on = false; } else { button1.Text = "not on top"; IntPtr HwndTopmost = new IntPtr(-2); SetWindowPos(this.Handle, HwndTopmost, 0, 0, 0, 0, TopmostFlags); on = true; } }
sumber