2015-06-24 6 views
8

अंतर्निहित ओएस के समान होने की मैं संवाद बचाने अनुकूलित करने के लिए इस उदाहरण का उपयोग किया गया,फ़ाइल अनुकूलित सहेजें संवाद बचाने संवाद सी #

http://www.codeproject.com/Articles/19566/Extend-OpenFileDialog-and-SaveFileDialog-the-easy

यह अच्छी तरह से काम करता है और मैं भी संवाद को अनुकूलित कर सकते हैं। हालांकि, मैं देखता हूं कि अनुकूलित संवाद अंतर्निहित विंडोज शैली का पालन नहीं करता है। उदाहरण के लिए, अगर मैं विंडोज 7 में हूँ संवाद

enter image description here

इस शब्द से एक संवाद को बचाने के है और यह टैग और सामान की तरह कुछ ही विकल्प हैं करता है इस तरह दिखेगा, होगा। लेकिन देखो और महसूस ओएस सेव संवाद के समान है। हालांकि, जैसा कि ऊपर उल्लेख लिंक के साथ कस्टम संवाद बचाने ऐसा दिखाई देगा,

enter image description here

क्यों यह क्या ओएस प्रस्तावों का पालन नहीं करेंगे? क्या इसे संभालने का कोई तरीका है?


ठीक है, मैं थोड़ा शोध किया और बिंदु जहां मैं Microsoft.WindowsAPICodePack.Dialogs से CommonSaveFileDialog का उपयोग करें और अंतर्निहित संवाद सहेजें बना सकते हैं करने के लिए मिल गया है (जो विंडोज 7 शैली के साथ मैच करता है।)। मैं WindowsAPI खोल पैकेज स्थापित किया है और कुछ इस तरह बनाने के लिए CommonSaveFileDialog नियंत्रण के लिए इस्तेमाल किया,

enter image description here

लाल रंग में चिह्नित नियंत्रण वास्तव में CommonFileDialogLabel/CommonFileDialogTextBox/CommonFileDialogComboBox आदि जो उन एपीआई में प्रदान की जाती हैं कर रहे हैं। लेकिन अब मेरा सवाल यह है कि मैं इस पर उपयोगकर्ता नियंत्रण/कस्टम नियंत्रण कैसे जोड़ूं? मुझे जो जोड़ना है उस पर मुझे पूर्ण नियंत्रण की आवश्यकता है ताकि यह उपयोगकर्ता नियंत्रण हो। कोई विचार .. कृपया धन्यवाद मदद करें।

+0

यह विंडोज एक्सपी आम संवाद बॉक्स शैली है। यदि आप नए विस्मा/7/आदि का उपयोग करना चाहते हैं। शैली तो आपको नए सामान्य आइटम संवाद https://msdn.microsoft.com/en-us/library/windows/desktop/bb776913(v=vs.85).aspx#customizing का उपयोग करना होगा। यह आलेख भी देखें http://www.codeproject.com/Articles/16678/Vista-Goodies-in-C-Using-the-New- Vista -File-Dialog। –

+0

हां ऐसा लगता है। यह पोस्ट विस्टा बदल गया है। लेकिन आपके द्वारा प्रदान किया गया लिंक में सी ++/वीसी ++ कोड है और मैं सी # नेट की तलाश में हूं, क्या कोई अन्य लिंक है? धन्यवाद! – user1821499

+0

क्या कोई मदद कर सकता है? मैंने IFileDialog को अनुकूलित करने का प्रयास किया उदाहरण सी # लेकिन मैं उनमें से किसी का भी उपयोग नहीं कर पा रहा हूं। एक नमूना या उदाहरण वास्तव में सहायक होगा! – user1821499

उत्तर

6

सुझाव दिया समाधान वर्णित के रूप में काम करता है:

फ़ाइल संवाद (इस उदाहरण में प्रयुक्त) के रूप में सहेजें एक उपयोगकर्ता नियंत्रण, CustomSaveFileDialog कहा जाता है के लिए जुड़ा हुआ है। इसका लाभ यह है कि यह टूलबॉक्स में मौजूद है, और यह स्वचालित रूप से IDISposable इंटरफ़ेस लागू करता है। हालांकि, यह एक साधारण सी # वर्ग भी हो सकता था।

इस नियंत्रण में एक मनमाने ढंग से आवेदन विशिष्ट उपयोगकर्ता नियंत्रण को स्वीकार करने वाले निर्माता हैं जो फ़ाइल संवाद में दिखाई देने वाले सभी तत्वों को होस्ट करते हैं। जब मुझे सही सवाल मिला, तो यही आवश्यक है।

CustomSaveFileDialog निम्नलिखित गुण है:

  • मनमाना उपयोगकर्ता नियंत्रण फ़ाइल संवाद की तह तक डॉक को स्वीकार करते हुए यानी वे फ़ाइल का आकार बदलने का पालन करें संवाद
  • अतिरिक्त तत्वों के लिए कोई विशेष व्यवहार (बटन, छवियों, चेकबॉक्स आदि) आवश्यक है। वे अन्य विंडोज़ में सामान्य रूप से कार्य करते हैं।

यह वर्णित वर्ग के कोड है:

using System; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 
using System.Diagnostics; 

namespace customSaveFileDialog 
{ 
    public partial class CustomSaveFileDialog : UserControl 
    { 
     //https://stackoverflow.com/questions/9665579/setting-up-hook-on-windows-messages 
     delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, 
      IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime); 

     const uint WINEVENT_OUTOFCONTEXT = 0; 

     [DllImport("user32.dll")] 
     private static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr 
      hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, 
      uint idThread, uint dwFlags); 

     [DllImport("user32.dll")] 
     private static extern bool UnhookWinEvent(IntPtr hWinEventHook); 

     [DllImport("user32.dll")] 
     private static extern bool MoveWindow(IntPtr hWnd, int x, int y, int w, int h, bool repaint); 
     private struct RECT { public int Left; public int Top; public int Right; public int Bottom; } 

     [DllImport("user32.dll")] 
     private static extern bool GetClientRect(IntPtr hWnd, out RECT rc); 

     [DllImport("kernel32.dll")] 
     private static extern uint GetLastError(); 

     [DllImport("user32.dll", SetLastError = true)] 
     private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 

     [DllImport("user32.dll", SetLastError = true)] 
     private static extern IntPtr SetParent(IntPtr hwndChild, IntPtr hwndNewParent); 

     [DllImport("user32.dll", SetLastError = true)] 
     private static extern IntPtr GetParent(IntPtr hWnd); 

     private IntPtr hDlg;  // Save As dialog handle 
     private IntPtr hHook;  // Event hook 
     private IntPtr hCtrl;  // App. specific user control handle 

     UserControl ctrl;   // App. specific user control 

     //Static variable containing the instance object 
     private static CustomSaveFileDialog customSaveFileDialog; 

     //public property for the user 
     //theSaveFileDialog has been added to the control in the designer from the Toolbox 
     public SaveFileDialog Dlg { get { return theSaveFileDialog; } } 

     //Event hook delegate 
     private static WinEventDelegate procDelegate = new WinEventDelegate(WinEventProc); 

     /// <summary> 
     /// Constructor 
     /// </summary> 
     /// <param name="ctrl">The User Control to be displayed in the file dialog</param> 
     public CustomSaveFileDialog(UserControl ctrl) 
     { 
      InitializeComponent(); 

      customSaveFileDialog = this; 
      this.ctrl = ctrl; 
      hCtrl = ctrl.Handle; 

      //Setup Hook; for simplicity, hook all possible events from the current process 
      hHook = SetWinEventHook(1, 0x7fffffff, IntPtr.Zero, 
        procDelegate, (uint)Process.GetCurrentProcess().Id, 0, WINEVENT_OUTOFCONTEXT); 
     } 


     // Hook function 
     static void WinEventProc(IntPtr hWinEventHook, uint eventType, 
      IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) 
     { 
      CustomSaveFileDialog csfdg = customSaveFileDialog; 
      if (csfdg.hDlg == IntPtr.Zero) 
       csfdg.hDlg = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "#32770", "Save As"); 

      if (hwnd == csfdg.hDlg) 
      { 
       IntPtr hParent = GetParent(csfdg.hCtrl); 

       //this is done only once 
       if (!(hParent == csfdg.hDlg)) 
        SetParent(csfdg.hCtrl, csfdg.hDlg); //Bind the user control to the Common Dialog 

       RECT cliRect; 
       GetClientRect(csfdg.hDlg, out cliRect); 

       //Position the button in the file dialog 
       MoveWindow(csfdg.hCtrl, cliRect.Left + 130, cliRect.Bottom - 55, 500, 60, true); 
      } 
     } 
    } 
} 

अनिवार्य हिस्सा खिड़कियों घटनाओं के hooking है। इसे that post से लिया गया है।

यह ध्यान दिया जा सकता है कि "FindWindowEx" फ़ंक्शन (WinEventProc में) "सामान्य रूप से सहेजें" के शीर्षक के साथ सभी सामान्य संवाद (और शायद अधिक) पाता है। यदि यह एक समस्या होनी चाहिए, तो अधिक फ़िल्टरिंग आवश्यक होगी, उदाहरण के लिए केवल वर्तमान धागे में खोज कर। इस तरह के एक खोज समारोह here पाया जा सकता है।

इसके अतिरिक्त (उपरोक्त कोड में नहीं दिखाया गया) CustormSaveFileDialog.desinger.cs में "निपटान" विधि पैरामीटर के रूप में hhook हैंडल के साथ Unhook फ़ंक्शन शामिल है।

सॉफ्टवेयर को डीबग मोड में विंडोज 7 में परीक्षण किया गया है। एक परीक्षण के रूप में, एक बटन के साथ एक सरल फार्म खिड़की से लागू किया गया है:

 //Test for the customized "Save As" dialog 
     private void button1_Click(object sender, EventArgs e) 
     { 
      //Arbitrary User Control 
      myUserControl ctrl = new myUserControl(); 

      using (CustomSaveFileDialog csfdg = new CustomSaveFileDialog(ctrl)) 
      { 
       csfdg.Dlg.FileName = "test"; 

       //Show the Save As dialog associated to the CustomFileDialog control 
       DialogResult res = csfdg.Dlg.ShowDialog(); 
       if (res == System.Windows.Forms.DialogResult.OK) 
        MessageBox.Show("Save Dialog Finished"); 
      } 
     } 

और - और साथ ही एक परीक्षण - applicatioin विशिष्ट उपयोगकर्ता नियंत्रण निम्न इवेंट संभालता है:

using System; 
using System.Windows.Forms; 

namespace CustomFile 
{ 
    public partial class myUserControl : UserControl 
    { 
     public myUserControl() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      MessageBox.Show("Button Clicked"); 
     } 

     private void pictureBox1_Click(object sender, EventArgs e) 
     { 
      MessageBox.Show("Image Clicked"); 

     } 

     private void checkBox1_CheckedChanged(object sender, EventArgs e) 
     { 
      if (!checkBox1.Checked) 
       pictureBox1.Visible = false; 
      else 
       pictureBox1.Visible = true; 
     } 
    } 
} 

निम्नलिखित उत्पादन उत्पादन किया जाता है:

enter image description here

अगली फिल्म एक और स्क्रीनशॉट पता चलता है, फ़ाइल संवाद आकार दिया, और चेकबॉक्स छवि प्रदर्शित करने अनचेक है

enter image description here

+0

यह काम करता है लेकिन उपयोगकर्ता नियंत्रण जो आपने यहां चित्र में दिखाया है उससे बड़ा नहीं हो सकता है। "प्रकार के रूप में सहेजें" और "ब्राउज़/छुपाएं फ़ोल्डर" लिंक के बीच बहुत कम जगह है। मेरा उपयोगकर्ता नियंत्रण बड़ा हो सकता है और मुझे बीच में अतिरिक्त जगह चाहिए। क्या यह संभव है? – user1821499

+0

हां, आप सही हैं। प्रस्तुत समाधान केवल अंतरिक्ष के भीतर आम संवाद में मामूली जोड़ों के लिए काम करता है। आप http://www.codeproject.com/Articles/16276/Customizing-OpenFileDialog-in-NET से परामर्श ले सकते हैं, जो आपके शुरुआती पोस्ट में आपके द्वारा उद्धृत समाधान का आधार है, और यहां प्रस्तुत किए गए से कहीं अधिक जटिल है । संक्षेप में, आईएमओ एमएस द्वारा हास्यास्पद है कि हम इस तरह के एक संवाद को अनुकूलित करने के लिए सभी प्रकार के पिनवोक के साथ टिंकर करें। – josh

+0

अच्छी तरह से कहा .. धन्यवाद जोश। मैं देखूंगा कि मेरी ज़रूरतों के लिए सबसे अच्छा समाधान क्या है। – user1821499

संबंधित मुद्दे