जवाबों:
हम्म, बस फॉर्म को ओवरराइड नहीं कर रहा है।
protected override bool ShowWithoutActivation
{
get { return true; }
}
और यदि आप नहीं चाहते कि उपयोगकर्ता इस अधिसूचना विंडो पर क्लिक करें, तो आप CreateParams को ओवरराइड कर सकते हैं:
protected override CreateParams CreateParams
{
get
{
CreateParams baseParams = base.CreateParams;
const int WS_EX_NOACTIVATE = 0x08000000;
const int WS_EX_TOOLWINDOW = 0x00000080;
baseParams.ExStyle |= ( int )( WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW );
return baseParams;
}
}
form1.Enabled = false
आंतरिक नियंत्रण पर ध्यान केंद्रित करने से रोकने के लिए सेट करने की भी आवश्यकता थी
WS_EX_NOACTIVATE
और WS_EX_TOOLWINDOW
कर रहे हैं 0x08000000
और 0x00000080
क्रमशः।
PInvoke.net की ShowWindow विधि से चोरी :
private const int SW_SHOWNOACTIVATE = 4;
private const int HWND_TOPMOST = -1;
private const uint SWP_NOACTIVATE = 0x0010;
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
static extern bool SetWindowPos(
int hWnd, // Window handle
int hWndInsertAfter, // Placement-order handle
int X, // Horizontal position
int Y, // Vertical position
int cx, // Width
int cy, // Height
uint uFlags); // Window positioning flags
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
static void ShowInactiveTopmost(Form frm)
{
ShowWindow(frm.Handle, SW_SHOWNOACTIVATE);
SetWindowPos(frm.Handle.ToInt32(), HWND_TOPMOST,
frm.Left, frm.Top, frm.Width, frm.Height,
SWP_NOACTIVATE);
}
(एलेक्स लाइमन ने इसका उत्तर दिया, मैं सीधे कोड को पेस्ट करके इसका विस्तार कर रहा हूं। संपादित अधिकारों वाले कोई व्यक्ति इसे वहां पर कॉपी कर सकता है और मैं इसे सभी देखभाल के लिए हटा सकता हूं;)
यदि आप Win32 P / Invoke का उपयोग करने के लिए तैयार हैं , तो आप ShowWindow विधि का उपयोग कर सकते हैं (पहला कोड नमूना वही करता है जो आप चाहते हैं)।
इसी से मेरा काम बना है। यह टॉपमोस्ट प्रदान करता है लेकिन फ़ोकस-चोरी के बिना।
protected override bool ShowWithoutActivation
{
get { return true; }
}
private const int WS_EX_TOPMOST = 0x00000008;
protected override CreateParams CreateParams
{
get
{
CreateParams createParams = base.CreateParams;
createParams.ExStyle |= WS_EX_TOPMOST;
return createParams;
}
}
दृश्य स्टूडियो डिजाइनर, या कहीं और में TopMost सेटिंग को छोड़ना याद रखें।
यह चोरी, गलती, उधार, यहाँ से (Workarounds पर क्लिक करें):
ऐसा करना एक हैक की तरह लगता है, लेकिन यह काम करने लगता है:
this.TopMost = true; // as a result the form gets thrown to the front
this.TopMost = false; // but we don't actually want our form to always be on top
संपादित करें: ध्यान दें, यह केवल ध्यान केंद्रित किए बिना पहले से ही बनाए गए फॉर्म को बढ़ाता है।
Alex Lyman / TheSoftwareJedi के उत्तरों में pinvoke.net का नमूना कोड खिड़की को "सबसे ऊपरी" विंडो बना देगा, जिसका अर्थ है कि आप इसे पॉप अप करने के बाद सामान्य खिड़कियों के पीछे नहीं रख सकते। माटिया के विवरण को देखते हुए कि वह इसके लिए क्या उपयोग करना चाहता है, वही हो सकता है जो वह चाहता है। लेकिन अगर आप चाहते हैं कि आपके द्वारा इसे पॉप अप करने के बाद उपयोगकर्ता आपकी विंडो को अन्य विंडो के पीछे रख सके, तो नमूने में केवल HWND_TOPMOST (-1) के बजाय HWND_TOP (0) का उपयोग करें।
WPF में आप इसे इस तरह से हल कर सकते हैं:
विंडो में ये विशेषताएँ डालें:
<Window
x:Class="myApplication.winNotification"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Notification Popup" Width="300" SizeToContent="Height"
WindowStyle="None" AllowsTransparency="True" Background="Transparent" ShowInTaskbar="False" Topmost="True" Focusable="False" ShowActivated="False" >
</Window>
अंतिम एक विशेषता वह है जिसे आपको ShowActivated = "गलत" की आवश्यकता है।
नोटिफिकेशन फॉर्म को एक अलग थ्रेड में बनाएँ और शुरू करें और फॉर्म खुलने के बाद फ़ोकस को वापस अपने मुख्य फॉर्म में रीसेट करें। नोटिफिकेशन फॉर्म में एक OnFormOpened ईवेंट प्रदान करें जो इवेंट से निकाल दिया गया है Form.Shown
। कुछ इस तरह:
private void StartNotfication()
{
Thread th = new Thread(new ThreadStart(delegate
{
NotificationForm frm = new NotificationForm();
frm.OnFormOpen += NotificationOpened;
frm.ShowDialog();
}));
th.Name = "NotificationForm";
th.Start();
}
private void NotificationOpened()
{
this.Focus(); // Put focus back on the original calling Form
}
आप अपने NotifcationForm ऑब्जेक्ट के चारों ओर एक हैंडल भी रख सकते हैं ताकि इसे मुख्य रूप ( frm.Close()
) द्वारा प्रोग्रामेटिक रूप से बंद किया जा सके ।
कुछ विवरण गायब हैं, लेकिन उम्मीद है कि यह आपको सही दिशा में जा रहा है।
आप इस पर विचार करना चाहते हैं कि आप किस प्रकार की अधिसूचना प्रदर्शित करना चाहते हैं।
यदि उपयोगकर्ता को किसी घटना के बारे में बताने के लिए यह पूरी तरह से महत्वपूर्ण है, तो Messagebox.Show का उपयोग अनुशंसित तरीका होगा, इसकी प्रकृति के कारण किसी भी अन्य घटनाओं को मुख्य विंडो पर ब्लॉक करने के लिए, जब तक उपयोगकर्ता इसकी पुष्टि नहीं करता। हालांकि पॉप-अप ब्लाइंडनेस से अवगत रहें।
यदि यह महत्वपूर्ण से कम है, तो आप सूचनाओं को प्रदर्शित करने के लिए वैकल्पिक तरीके का उपयोग करना चाह सकते हैं, जैसे कि विंडो के नीचे एक टूलबार। आपने लिखा है, कि आप स्क्रीन के नीचे-दाईं ओर सूचनाएँ प्रदर्शित करते हैं - ऐसा करने का मानक तरीका एक सिस्टम ट्रे आइकन के संयोजन के साथ एक गुब्बारा टिप का उपयोग करना होगा ।
यह अच्छा काम करता है।
देखें: OpenIcon - MSDN और SetForegroundWindow - MSDN
using System.Runtime.InteropServices;
[DllImport("user32.dll")]
static extern bool OpenIcon(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
public static void ActivateInstance()
{
IntPtr hWnd = IntPtr hWnd = Process.GetCurrentProcess().MainWindowHandle;
// Restore the program.
bool result = OpenIcon(hWnd);
// Activate the application.
result = SetForegroundWindow(hWnd);
// End the current instance of the application.
//System.Environment.Exit(0);
}
आप इसे अकेले तर्क द्वारा भी संभाल सकते हैं, हालांकि मुझे यह स्वीकार करना होगा कि ऊपर दिए गए सुझाव जहां आप लाते हैं, वहां पर बिना फोकस के चोरी करने के लिए लाया गया एक तरीका है।
किसी भी तरह, मैं इस में भाग गया और इसे पहले से ही हाल ही में किए गए कॉल को आगे लाने के लिए DateToFront कॉल की अनुमति न देने के लिए डेटटाइम प्रॉपर्टी का उपयोग करके हल किया।
एक कोर क्लास मान लीजिए, 'कोर', जो उदाहरण के लिए तीन रूपों को संभालता है, 'फॉर्म 1, 2 और 3'। प्रत्येक फॉर्म को एक डेटटाइम प्रॉपर्टी और एक सक्रिय घटना की आवश्यकता होती है जो विंडोज़ को सामने लाने के लिए कोर कहते हैं:
internal static DateTime LastBringToFrontTime { get; set; }
private void Form1_Activated(object sender, EventArgs e)
{
var eventTime = DateTime.Now;
if ((eventTime - LastBringToFrontTime).TotalMilliseconds > 500)
Core.BringAllToFront(this);
LastBringToFrontTime = eventTime;
}
और फिर कोर क्लास में काम बनाएँ:
internal static void BringAllToFront(Form inForm)
{
Form1.BringToFront();
Form2.BringToFront();
Form3.BringToFront();
inForm.Focus();
}
साइड नोट पर, यदि आप एक न्यूनतम विंडो को उसकी मूल स्थिति (अधिकतम नहीं) पर पुनर्स्थापित करना चाहते हैं, तो उपयोग करें:
inForm.WindowState = FormWindowState.Normal;
फिर से, मुझे पता है कि यह एक SendToFrontWithoutFocus की कमी में सिर्फ एक पैच समाधान है। यह एक सुझाव के रूप में है यदि आप DLL फ़ाइल से बचना चाहते हैं।
मुझे नहीं पता कि इसे नेक्रो-पोस्टिंग के रूप में माना जाता है, लेकिन यह वही है जो मैंने तब से किया है जब मैंने इसे उपयोगकर्ता के "शोविंडो" और "सेटविंडो पोस" विधियों के साथ काम करने के लिए नहीं दिया। और नहीं, "ShowWithoutActivation" को ओवरराइड करने से इस मामले में काम नहीं होता है क्योंकि नई विंडो हमेशा ऑन-टॉप होनी चाहिए। वैसे भी, मैंने एक सहायक विधि बनाई जो पैरामीटर के रूप में एक रूप लेती है; जब बुलाया जाता है, तो यह प्रपत्र दिखाता है, इसे सामने लाता है और वर्तमान विंडो के फोकस को चुराने के बिना इसे TopMost बनाता है (जाहिर है यह करता है, लेकिन उपयोगकर्ता ध्यान नहीं देगा)।
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern IntPtr SetForegroundWindow(IntPtr hWnd);
public static void ShowTopmostNoFocus(Form f)
{
IntPtr activeWin = GetForegroundWindow();
f.Show();
f.BringToFront();
f.TopMost = true;
if (activeWin.ToInt32() > 0)
{
SetForegroundWindow(activeWin);
}
}
मुझे पता है कि यह बेवकूफ लग सकता है, लेकिन यह काम किया:
this.TopMost = true;
this.TopMost = false;
this.TopMost = true;
this.SendToBack();
मुझे अपनी खिड़की TopMost के साथ ऐसा करने की आवश्यकता थी। मैंने ऊपर PInvoke मेथड लागू किया, लेकिन पाया कि मेरे लोड इवेंट को तलहा की तरह नहीं बुलाया जा रहा था। मैं आखिरकार सफल हुआ। शायद यह किसी की मदद करेगा। यहाँ मेरा समाधान है:
form.Visible = false;
form.TopMost = false;
ShowWindow(form.Handle, ShowNoActivate);
SetWindowPos(form.Handle, HWND_TOPMOST,
form.Left, form.Top, form.Width, form.Height,
NoActivate);
form.Visible = true; //So that Load event happens
जब आप एक नया फॉर्म बनाते हैं
Form f = new Form();
f.ShowDialog();
यह फ़ोकस चुराता है क्योंकि आपका कोड मुख्य फ़ॉर्म पर निष्पादन जारी नहीं रख सकता है जब तक कि यह फ़ॉर्म बंद न हो।
एक नया रूप बनाने के लिए थ्रेडिंग का उपयोग करके अपवाद है। Form.Show ()। सुनिश्चित करें कि धागा विश्व स्तर पर दिखाई दे रहा है, क्योंकि यदि आप इसे किसी फ़ंक्शन के भीतर घोषित करते हैं, जैसे ही आपका फ़ंक्शन बाहर निकलता है, तो आपका धागा समाप्त हो जाएगा और फॉर्म गायब हो जाएगा।
यह पता लगा window.WindowState = WindowState.Minimized;
:।