2012-01-16 14 views
6

मैं Process.Start() का उपयोग करके अपने प्रोग्राम से नोटपैड खोलता हूं लेकिन नया खोला गया नोटपैड स्क्रीन को कवर करता है। लेकिन मैं चाहता हूं कि मेरा आवेदन अपना ध्यान बनाए रखे।एक प्रक्रिया (नोटपैड) खोलने के बाद फोकस को वापस कैसे सेट करें?

मैं इसी तरह (समान Process.Start का उपयोग) एमएस एक्सेल और वर्ड लेकिन वापस अपने सभी मैं लिखने की ज़रूरत फार्म के लिए ध्यान केंद्रित पाने के लिए खोल रहा है:

this.Focus(); 

लेकिन नोटपैड के साथ मोड़: मैं नोटपैड खोलने (और इस तरह की सभी अन्य प्रक्रियाएं)

Process process = new Process(); 
process.StartInfo.UseShellExecute = true; 
process.EnableRaisingEvents = true; 
process.StartInfo.FileName = @"abc.log"; 
process.Start(); 

अब नोटपैड फोकस लेता है।

मैं इन की कोशिश की:

  1. this.Activate(), this.Focus(), अनावश्यक एक और लंबी समाधान here से मिला

  2. [DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)] 
    public static extern IntPtr SetFocus(HandleRef hWnd); 
    
    { 
        IntPtr hWnd = myProcess.Handle; 
        SetFocus(new HandleRef(null, hWnd)); 
    } 
    
  3. [DllImport("User32")] 
    private static extern int SetForegroundWindow(IntPtr hwnd); 
    
    [DllImportAttribute("User32.DLL")] 
    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 
    private const int SW_SHOW = 5; 
    private const int SW_MINIMIZE = 6; 
    private const int SW_RESTORE = 9; 
    
    { 
        ShowWindow(Process.GetCurrentProcess().MainWindowHandle, SW_RESTORE); 
        SetForegroundWindow(Process.GetCurrentProcess().MainWindowHandle); 
    } 
    
  4. उल्लेख करने के लिए।

जो अभी भी नोटपैड पर ध्यान केंद्रित करता है। खिड़की पर ध्यान केंद्रित करना इतना मुश्किल क्यों है, वह भी एप्लिकेशन की अपनी खिड़की?

संपादित करें: सबसे अच्छा मैं नोटपैड को कम कर सकता हूं, लेकिन यह अभी भी उपरोक्त सभी कोडों को आजमाने के बाद फ़ॉर्म पर ध्यान नहीं देगा। नोटपैड कम से कम खुलता है, लेकिन फोकस अभी भी नोटपैड पर होगा (कुछ ऐसा जो कभी-कभी हम विंडोज एक्सपी में देखते हैं) और फॉर्म फोकस से बाहर हो जाएगा।

+0

यह ठीक शुरू करने के लिए है एक न्यूनतम राज्य में खिड़की? – NoviceProgrammer

+0

हाँ, यह ठीक है, लेकिन यह अभी भी काम नहीं करेगा। मैं इसे अपने प्रश्न में अपडेट करूंगा – nawfal

+0

क्या आपने यह कोशिश की है? http://stackoverflow.com/questions/2121911/starting-a-process-without-stealing-focus-c – NoviceProgrammer

उत्तर

9

मैंने इंटरनेट पर लगभग हर चीज की कोशिश की (इसलिए इसके बारे में सुनिश्चित करें :))। सबसे अच्छा मैं अपने फॉर्म को अन्य सभी रूपों के शीर्ष पर प्राप्त कर सकता हूं, लेकिन फोकस के बिना (@ हंस पासेंट की विधि से जा रहा है)। कोड के भारी ब्लॉक से जाकर, मुझे किसी भी तरह यह महसूस करना आसान हो जाएगा। इसलिए मैंने हमेशा अन्य कोड के भाग के साथ SetForegroundWindow() का उपयोग किया। कभी सोचा नहीं कि केवल SetForegroundWindow() चाल करेगा।

यह काम किया।

[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool SetForegroundWindow(IntPtr hWnd); 

private void button1_Click(object sender, EventArgs e) 
{ 
    Process process = new Process(); 
    process.StartInfo.FileName = @...\abc.log"; 
    process.Start(); 

    process.WaitForInputIdle(); //this is the key!! 

    SetForegroundWindow(this.Handle); 
} 

कई बार माता-पिता के फार्म पर ध्यान देने के में इस विधि पैदावार (ऐसे मामलों में जहां मेरी वांछित प्रपत्र अपनी मूल रूप से एक मॉडल बच्चे रूप है); ऐसे मामलों में, अभी पिछले लाइन के लिए this.Focus() जोड़ने ..

यहां तक ​​कि इस काम किया: here

2

मैं एक ही समस्या थी, मैं अंत में प्रोग्राम के रूप में बुला ऑल्ट-टैब के साथ समापन:

[DllImport("user32.dll")] 
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam); 

private void alttab() 
{ 
    uint WM_SYSCOMMAND = 0x0112; 
    int SC_PREVWINDOW = 0xF050;    

    PostMessage(Process.GetCurrentProcess().MainWindowHandle, WM_SYSCOMMAND, SC_PREVWINDOW, 0); 
} 

// संपादित करें: आप के बजाय बिल्कुल process.MainWindowHandle का उपयोग करना चाहिए

+0

धन्यवाद। कल आपको बताएगा .. निश्चित रूप से अलग सोच है, लेकिन मुझे चिंता है कि यह कामकाज कभी-कभी समस्या पैदा करेगा। क्या आपको कभी इस दृष्टिकोण के साथ कोई समस्या है? – nawfal

+0

यह अच्छी तरह से काम नहीं कर रहा है .. – nawfal

1

विंडोज धकेल से ऐप्स से बचाता है उनके खिड़की के चेहरे में खिड़की, आप इसे काम पर देख रहे हैं। जब कोई ऐप फ़ोकस चुरा सकता है तो सटीक नियम AllowSetForegroundWindow() के लिए एमएसडीएन दस्तावेज़ों में दस्तावेज किए जाते हैं।

इस प्रतिबंध के आस-पास एक बैक-दरवाजा अटैच थ्रेड इनपुट() फ़ंक्शन है। यह कोड अच्छी तरह से काम करता है, मैंने थ्रेड के लिए थ्रेड आईडी ढूंढने पर शॉर्टकट लिया है जो अग्रभूमि विंडो का मालिक है। नोटपैड के लिए काफी अच्छा है, संभवतः अन्य ऐप्स के लिए नहीं। सावधान रहें कि रेमंड चेन इस तरह के हैक को स्वीकार करते हैं।

private void button1_Click(object sender, EventArgs e) { 
     var prc = Process.Start("notepad.exe"); 
     prc.WaitForInputIdle(); 
     int tid = GetCurrentThreadId(); 
     int tidTo = prc.Threads[0].Id; 
     if (!AttachThreadInput(tid, tidTo, true)) throw new Win32Exception(); 
     this.BringToFront(); 
     AttachThreadInput(tid, tidTo, false); 
    } 

    [DllImport("user32.dll", SetLastError = true)] 
    private static extern bool AttachThreadInput(int tid, int tidTo, bool attach); 
    [DllImport("kernel32.dll")] 
    private static extern int GetCurrentThreadId(); 
+0

धन्यवाद। लेकिन मुझे संदेह है कि यदि BringToFront वास्तव में यहां काम करता है। क्या यह नियंत्रण एक और नियंत्रण से ऊपर दिखाई देने के लिए सिर्फ एक उपाय नहीं है? क्या यह नहीं है। एक्टिवेट यहां बेहतर विकल्प है? – nawfal

+0

रेमंड चेन कौन है? इसे स्वीकार करने के लिए? : o – nawfal

+0

Form.BringToFront() SetForegroundWindow() को कॉल करता है, बस कोड को आज़माकर आसानी से देखा जाता है। रेमंड चेन एक लोकप्रिय ब्लॉग के साथ एक माइक्रोसॉफ्ट प्रोग्रामर है। यहां पोस्ट भी जवाब देते हैं, मैं उसे पीसना नहीं चाहता हूं। http://blogs.msdn.com/b/oldnewthing/ –

-1

द्वारा प्रदान की

Microsoft.VisualBasic.Interaction.Shell(@"notepad.exe D:\abc.log", 
             Microsoft.VisualBasic.AppWinStyle.NormalNoFocus); 

समाधान इस प्रयास करें:

public partial class MainForm : Form 
{ 
    private ShowForm showForm; 

    public MainForm() 
    { 
     InitializeComponent(); 
    } 

    private void showButton_Click(object sender, EventArgs e) 
    { 
     this.showForm = new ShowForm(); 
     this.showForm.FormClosed += showForm_FormClosed; 
     this.showForm.Show(this); 
    } 

    private void showForm_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     this.Focus(); 
    } 
} 
+0

इस सवाल का जवाब कैसे दिया जा रहा है? – nawfal