Laden...

Drop File vom Programm aus

Erstellt von steffen_dec vor 15 Jahren Letzter Beitrag vor 15 Jahren 3.519 Views
S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren
Drop File vom Programm aus

Hallo Leute,

ich habe ein fremdes Control in meiner Anwendung, welches Drop von Bildern unterstützt. D.h. der Benutzer kann ein beliebiges Bitmap in das Control reinziehen und fallen lassen.

Meine Frage:
Wie kann ich dies mit Hilfe von C# machen? Also die Drop-Interaktion nachcoden!? Damit das Control denkt, es wäre der Benutzer der das Bild gedropped hat 🙂

Währe cool wenn jemand eine Idee hätte 🤔

Danke
Steffen

1.346 Beiträge seit 2008
vor 15 Jahren

Jede Form und jedes Control hat Drag Events zb this.DragOver Damit müsste man das machen.Hab ich selber aber noch nich ausprobiert. Versuch ich jetzt auch mal 😁

edit : Hab grad rausgefunden man muss erst this.AllowDrop = true;

Grüß pdelvo

1.346 Beiträge seit 2008
vor 15 Jahren

So ich habs jetzt hinbekommen.
Man kann auf das Programm ein Bild ziehen und es wird in einer PictureBox angezeigt :


private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.MaximumSize = pictureBox1.Size;
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
this.AllowDrop = true;
this.DragEnter += new DragEventHandler(Form1_DragOver);
this.DragDrop += new DragEventHandler(Form1_DragDrop);
}

void Form1_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] FileList = (string[])e.Data.GetData(DataFormats.FileDrop, false);
if (FileList.Count() == 1)
{

FileInfo fi = new FileInfo(FileList[0]);
if (fi.Extension == ".gif" | fi.Extension == ".bmp" | fi.Extension == ".jpg" | fi.Extension == ".jpeg";)
{
pictureBox1.Image = Image.FromFile(FileList[0]);
}
}
}
else
e.Effect = DragDropEffects.None;
}

void Form1_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] FileList = (string[])e.Data.GetData(DataFormats.FileDrop, false);
if (FileList.Count() == 1)
{

FileInfo fi = new FileInfo(FileList[0]);
if (fi.Extension == ".gif" | fi.Extension == ".bmp" | fi.Extension == ".jpg" | fi.Extension == ".jpeg";)
{
e.Effect = DragDropEffects.Move;
}
}
}
else
e.Effect = DragDropEffects.None;
}

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren

Hallo, danke für deine Mühe aber dass habe ich nicht gemeint.... darüber gibts genügend beispiele...

ich möchte über das Programm ein Drop auslösen mit einer bestimmten datei die ich aussuche... lies mal nochmal meinen ersten beitrag 😉

Gruß
Steffen

Edit: Du kannst doch jetzt mal probieren ein Bild über DragDrop reinzuladen ohne die maus zubenutzen...

1.346 Beiträge seit 2008
vor 15 Jahren

Hab ich mich wol verlesen, das geht so:


void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
string path =Path.Combine(Environment.GetEnvironmentVariable("TEMP";) , "tempimage.jpg";);
try{
File.Delete(path);
}catch{}

pictureBox1.Image.Save(path);
DataObject obj = new DataObject(DataFormats.FileDrop,path);
obj.SetFileDropList(new System.Collections.Specialized.StringCollection() { path });
//pictureBox1.GiveFeedback += new GiveFeedbackEventHandler(pictureBox1_GiveFeedback);
pictureBox1.DoDragDrop(obj, DragDropEffects.Copy);
}

(Hab lange gebrauch bis es funktioniert hat)

Gruß pdelvo

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren

hmm irgendwie ist es immer noch nicht dass was ich brauche...

nochmal:

ich möchte eine Bitmap-Datei von der Platte in ein Control in meinem Programm Dropen, das Control hat AllowDrop aktiviert und ist auch implementiert, da es manuell mit der Maus funktioniert... jetzt will ich dies automatisch über das Programm machen...

1.346 Beiträge seit 2008
vor 15 Jahren

Meinst du jetzt sowas


Bitmap bmp = Bitmap.FromFile(@"A:\dresse\zum\File.bmp");

Dafür brauch man kein Drag 'N' Drop

Entweder du drückst dich falsch aus oder ich bin zu doof

Gruß pdelvo

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren

Ich müsste wahrscheinlich die WM_DROPFILES verschicken oder? nur wie stelle ich das wParam zusammen 🤔http://msdn.microsoft.com/en-us/library/bb774303(VS.85).aspx

Es ist so, ich habe bei mir im Programm ein fremdes Control von einem anderem Hersteller (von welchem ich kein code habe), in einem Sonderfall, kann man in das Control nur per DragDrop ein Bild fallen lassen und ich möchte genau dies nachprogrammieren... verstehst du jetzt was ich meine?

1.346 Beiträge seit 2008
vor 15 Jahren

Jetz versteh ich was du meinst.Bin aber leider überfragt.Wende dich mal an den Hersteller des Controls. Oder suche nochmal im Context also Control. ...

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren
S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren

die beiden seiten habe ich auch schon gelesen,

nur wie kriege ich das ganze in C# portiert?

2.760 Beiträge seit 2006
vor 15 Jahren

So wie es aussieht geht es ja "nur" um GlobalAlloc, GlobalLock, PostMessage und GlobalFree. Das sind API methoden die du dir mit einem DLLImport holen kannst.
Dokumentation dazu dürfte sich in der MSDN und auf PInvoke.net finden lassen.

In der Regel sollte alles was du brauchst in irgendwelchen *.h Files in der Windows SDK rumliegen (Konstanten usw.). Einige Teile kannst du sicher auch aus dem Codeproject Artikel bemühen.

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren

das schwierige dabei ist das zusammenstellen der Struktur DROPFILES

ich werde es mal probieren und dann den Versuch hier posten.

4.939 Beiträge seit 2008
vor 15 Jahren

Ich kann mir aber nicht vorstellen, daß der Hersteller des externen Controls NUR die Möglichkeit per Drag&Drop vorgesehen hat. Es gibt sicherlich ein Property, das die Zuweisung vornimmt.

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren

hier mein gescheiterter Versuch:


        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll")]
        static extern IntPtr GlobalAlloc(uint uFlags, int dwBytes);
        [DllImport("kernel32.dll")]
        static extern IntPtr GlobalLock(IntPtr hMem);
        [DllImport("kernel32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool GlobalUnlock(IntPtr hMem);
        [DllImport("kernel32.dll")]
        static extern IntPtr GlobalFree(IntPtr hMem);

        public const uint GMEM_FIXED = 0x0000;
        public const uint GMEM_SHARE = 0x2000;
        public const uint WM_DROPFILES = 0x0233;
        
        public struct POINT
        {
            public int x, y;
            public POINT(int p1, int p2)
            {
                x = p1;
                y = p2;
            }
        }

        public struct DROPFILES 
        {
            public IntPtr pFiles;
            public POINT pt;
            public bool fNC;
            public bool fWide;
        }

string strPath = @"D:\test.bmp";
                IntPtr hGlobal = IntPtr.Zero;

                hGlobal = GlobalAlloc(GMEM_SHARE, strPath.Length + 2);
                IntPtr ptrLock = GlobalLock(hGlobal);

                POINT point;
                point.x = 100;
                point.y = 100;

                DROPFILES oDropFiles;
                oDropFiles.pFiles = ptrLock;
                oDropFiles.fNC = false;
                oDropFiles.fWide = false;
                oDropFiles.pt = point;

                System.Runtime.InteropServices.ComTypes.STGMEDIUM oMedium = new System.Runtime.InteropServices.ComTypes.STGMEDIUM();
                oMedium.tymed = System.Runtime.InteropServices.ComTypes.TYMED.TYMED_HGLOBAL;
                oMedium.unionmember = ptrLock;
                
                //Send Message with a file reference.
                bool bSent = PostMessage((IntPtr)Cameras[iIndex].DisplayControl.Handle, WM_DROPFILES, oMedium, IntPtr.Zero);

                bool bRet = GlobalUnlock(hGlobal);
                GlobalFree(hGlobal); 

man muss ja als wParam ein IntPtr übergeben, bloss wie komme ich an den Zeiger von STGMEDIUM?

3.511 Beiträge seit 2005
vor 15 Jahren

man muss ja als wParam ein IntPtr übergeben, bloss wie komme ich an den Zeiger von STGMEDIUM?

System.Runtime.InteropServices.Marshal.StructureToPtr

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren

Ich kann mir aber nicht vorstellen, daß der Hersteller des externen Controls NUR die Möglichkeit per Drag&Drop vorgesehen hat. Es gibt sicherlich ein Property, das die Zuweisung vornimmt.

Es gibt auch andere Möglichkeit eine Datei reinzuladen, bloß in einem bestimmten Sonderfall gehts es aus bestimmten Gründen nicht, es funktioniert dann nur per Drag&Drop.

EDIT:

neuer gescheiterter Versuch (danke an Khalid!)


                string strPath = @"D:\test.bmp";
                IntPtr hGlobal = IntPtr.Zero;

                hGlobal = GlobalAlloc(GMEM_SHARE, strPath.Length + 2);
                IntPtr ptrLock = GlobalLock(hGlobal);

                POINT point;
                point.x = 100;
                point.y = 100;

                DROPFILES oDropFiles;
                oDropFiles.pFiles = ptrLock;
                oDropFiles.fNC = false;
                oDropFiles.fWide = false;
                oDropFiles.pt = point;

                System.Runtime.InteropServices.ComTypes.STGMEDIUM oMedium = new System.Runtime.InteropServices.ComTypes.STGMEDIUM();
                oMedium.tymed = System.Runtime.InteropServices.ComTypes.TYMED.TYMED_HGLOBAL;
                oMedium.unionmember = ptrLock;

                IntPtr pM = Marshal.AllocHGlobal(Marshal.SizeOf(oMedium));
                Marshal.StructureToPtr(oMedium, pM, false);

                //Send Message with a file reference.
                bool bSent = PostMessage((IntPtr)Cameras[iIndex].DisplayControl.Handle, WM_DROPFILES, pM, IntPtr.Zero);

                bool bRet = GlobalUnlock(hGlobal);
                GlobalFree(hGlobal); 


S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren

hat keiner eine Idee wo der Fehler sein könnte? X( 🙁

2.760 Beiträge seit 2006
vor 15 Jahren

Wie äußert sich das nicht funktionieren denn?
Evtl. ist POINT (100,100) nicht korrekt.

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren

ich habe gerade noch dies gefunden:
http://forums.fanatic.net.nz/index.php?showtopic=18873

hab es auch probiert, nur kriege ich es nicht hin 🙁 da kommt nichts an...

Ich hab mal ein Testprojekt erstellt wo dass ganze drin ist.

die Message wird auf jedenfall generiert und verschickt (siehe WndProc), bloß löst es kein DragDrop-Event aus 🤔

habe ich da irgendwo einen Fehler?

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren

*hochschieb* 😁

Wo sind den alle WinAPI Experten!? 🙁

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren

Wenn jemand eine Lösung dafür hat, bin ich immer ganz ohr!

hab es zwar anders lösen können, aber über Dropfile wäre es viel eleganter gewesen.

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren

Hat es noch niemand ausprobiert? X(

ich bin immer noch auf der Suche nach einer Lösung 🤔

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 15 Jahren

hat sich noch keiner daran gewagt? X(