2010-01-07 5 views
0

Je développe une application en utilisant C# ayant des fonctionnalités similaires de copier, coller comme dans Windows. J'ai ajouté des éléments de menu et lié avec des applications respectives.Problème avec SendMessage

Veuillez regarder l'image suivante pour avoir plus d'idée.

Items added to shell menu http://softwaregenius.net/myimages/menu.jpg

Comme nous sélectionner plusieurs éléments dans l'explorateur Windows, vous devez sélectionner plusieurs fichiers et/ou dossiers, puis sélectionnez OS Util-> FastCopy. Un formulaire est ouvert comme indiqué ci-dessous

Form shown on FastCopy http://softwaregenius.net/myimages/fastcopy1.jpg

L'application fonctionne parfaitement. Le problème majeur ici est qu'après avoir sélectionné les fichiers, tous ces fichiers s'ouvrent dans leurs logiciels respectifs. C'est-à-dire que si j'ai sélectionné le document Word, le nom de fichier est ajouté au formulaire FastCopy, mais le fichier s'ouvre également dans Word.

Lorsque j'étudie, j'ai trouvé que ce problème est dû à SendMessage. Je dois utiliser PostMessage au lieu de SendMessage. Mais quand je le fais, l'application ne fonctionne pas.

Ci-dessous mon code de fonction principale en C# 2005

static class Program 
{ 
    static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE92}"); 
    [STAThread] 
    static void Main(string[] args) 
    { 
     string fileName = ""; 
     if (args.Length > 0) 
     { 
      fileName = args[0]; 
     } 
     if (mutex.WaitOne(TimeSpan.Zero, true)) 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      frmFastCopy frm = new frmFastCopy(); 
      frm.AddItemToList(fileName); 
      Application.Run(frm); 

     } 
     else 
     { 
      //The following message is sent just to show up the form 
      NativeMethods.PostMessage(
        (IntPtr)NativeMethods.HWND_BROADCAST, 
        NativeMethods.WM_SHOWME, 
        IntPtr.Zero, 
        IntPtr.Zero); 

      //Send the filename 
      SendFileName(fileName); 
     } 
    } 

    static void SendFileName(string s) 
    { 
     Win32.CopyDataStruct cds = new Win32.CopyDataStruct(); 

     cds.cbData = (s.Length + 1) * 2; 
     cds.lpData = Win32.LocalAlloc(0x40, cds.cbData); 
     Marshal.Copy(s.ToCharArray(), 0, cds.lpData, s.Length); 
     cds.dwData = (IntPtr)1; 
     Win32.SendMessage((IntPtr)NativeMethods.HWND_BROADCAST, Win32.WM_COPYDATA, IntPtr.Zero, ref cds); 
     //NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_BROADCAST, Win32.WM_COPYDATA, cds.lpData, IntPtr.Zero); 
    } 
} 

}


est inférieure à la copie pour WndProc et autre code à partir du formulaire

public partial class frmFastCopy: Formulaire { delegate void AddItemToListDelegate (chaîne itm);

public frmFastCopy() 
    { 
     InitializeComponent(); 
    } 

    public void AddItemToList(string itm) 
    { 
     if (lvFilesAndFolders.InvokeRequired) 
     { 
      AddItemToListDelegate m = new AddItemToListDelegate(AddItemToList); 
      this.Invoke(m, new object[] { itm }); 
     } 
     else 
     { 
      lvFilesAndFolders.Items.Add(itm); 
     } 
    } 
    protected override void WndProc(ref Message m) 
    { 
     if (m.Msg==NativeMethods.WM_SHOWME) 
     { 
       ShowMe(); 
     } 
     if (m.Msg==Win32.WM_COPYDATA) 
     { 
       //string s = Marshal.PtrToStringUni(m.LParam); 
       MessageBox.Show("Got message"); 

       Win32.CopyDataStruct st = (Win32.CopyDataStruct)Marshal.PtrToStructure(m.LParam, typeof(Win32.CopyDataStruct)); 
       string strData = Marshal.PtrToStringUni(st.lpData); 
       AddItemToList(strData); 
     } 
     base.WndProc(ref m); 
    } 
    private void ShowMe() 
    { 
     this.Show(); 
     if (WindowState == FormWindowState.Minimized) 
     { 
      WindowState = FormWindowState.Normal; 
     } 
     // get our current "TopMost" value (ours will always be false though) 
     bool top = TopMost; 
     // make our form jump to the top of everything 
     TopMost = true; 
     // set it back to whatever it was 
     TopMost = top; 
    } 

Voici la classe NativeCode

internal class NativeMethods 
{ 
    public const int HWND_BROADCAST = 0xffff; 
    public static readonly int WM_SHOWME = RegisterWindowMessage("WM_SHOWME"); 
    [DllImport("user32")] 
    public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam); 
    [DllImport("user32")] 
    public static extern int RegisterWindowMessage(string message); 

} 

Je sais que les gars vous êtes génie. Quelqu'un pourrait-il me dire où devrais-je apporter des modifications à ce que les fichiers sélectionnés devraient être ouverts ou plutôt comment je devrais utiliser postmessage.

Merci de partager votre précieux temps.

Cordialement

Irfan

+5

N'écrivez pas d'extensions shell dans du code managé, il s'agit d'une invitation à planter potentiellement un programme utilisant une boîte de dialogue standard Ouvrir ou Enregistrer. Voir aussi http://blogs.msdn.com/oldnewthing/archive/2006/12/18/1317290.aspx – nielsm

+1

Pouvez-vous élaborer sur l'utilisation, pour toujours ma curiosité? Pourquoi n'utilisez-vous pas la classe Presse-papiers? –

+0

Quelle est la valeur de WM_SHOWME? –

Répondre

1

S'il vous plaît regarde mon commentaire (je me demande pourquoi ne pas utiliser la classe Presse-papiers ici). Mais en ignorant cela: Pourquoi diffusez-vous le message?

Pouvez-vous localiser votre application (par nom, classe de fenêtre, peu importe) et seulement envoyer le message à votre propre application?


Pour élaborer sur le traitement des messages: Vous dites au sujet HWND_BROADCAST dans les commentaires ci-dessous:

rien, mais la poignée Cest mondiale pour ma demande.

Non, ce n'est pas le cas. C'est une valeur spéciale qui indique à Windows "ce message est pour toutes les applications". Vous envoyez un WM_SHOWME à toutes les applications. C'est pourquoi j'ai demandé pourquoi vous voudriez faire cela?

S'il vous plaît voir ce poste sur the old new things blog concernant les émissions de messages.

+0

Ouais j'ai utilisé le mutex pour créer seulement l'instance unique. Je pense que vous n'avez pas observé mon code. L'application fonctionne très bien car je n'avais besoin que du problème ici, c'est que les fichiers sélectionnés s'ouvrent également dans leur logiciel respectif. – IrfanRaza

+0

Bonne nouvelle mes amis !!!! La classe Clipboard a résolu mon problème. Merci beaucoup Benjamin. Mais je voudrais quand même vous demander comment utiliser postmessage ici? – IrfanRaza

+1

Heureux d'avoir découvert la classe Presse (prête, utilisable). En ce qui concerne le code: je voulais juste comprendre pourquoi vous utiliseriez HWND_BROADCAST au lieu de chercher votre propre application et de poster ou d'envoyer votre message _directly_, sans diffusion. –

Questions connexes