|
Thanks for your reply.
Meanwhile I've come a lot further. The problem was that methods SetData and GetData where not implemented. Therefore I created a new DataObject class which re-implements these methods. This is the code I have so far which is working but needs some adjustments here and there. Also I'm not sure whether all allocated objects are released correctly.
Regards,
Kees
public partial class CustomControl1 : Control
{
DragDropHelper Helper;
public CustomControl1()
{
InitializeComponent();
this.AllowDrop = true;
}
protected override void OnPaint(PaintEventArgs pe)
{
Brush B = new SolidBrush(Color.White);
pe.Graphics.FillRectangle(B, pe.ClipRectangle);
}
protected override void OnMouseDown(MouseEventArgs e)
{
DataFormats.Format ganttbarFormat = DataFormats.GetFormat("Ganttbar");
object ganttbar = new object();
DataObject dragObject = new DataObjectEx(ganttbarFormat.Name, ganttbar);
DoDragDrop(dragObject, DragDropEffects.All);
}
private void UpdateDragImage(System.Runtime.InteropServices.ComTypes.IDataObject dragObject)
{
if (Helper == null)
{
Helper = new DragDropHelper();
}
IDragSourceHelper Drag = (IDragSourceHelper)Helper;
SHDRAGIMAGE tt = new SHDRAGIMAGE();
Bitmap img = new Bitmap(@"C:\Temp\DragImage.bmp");
tt.ptOffset.x = 0;
tt.ptOffset.y = 0;
tt.sizeDragImage.x = img.Width;
tt.sizeDragImage.y = img.Height;
tt.hbmpDragImage = img.GetHbitmap();
tt.crColorKey = 0;
Drag.InitializeFromBitmap(ref tt, dragObject);
}
protected override void OnDragOver(DragEventArgs drgevent)
{
IDropTargetHelper H = (IDropTargetHelper)Helper;
POINT p = new POINT();
p.x = drgevent.X;
p.y = drgevent.Y;
H.DragOver(ref p, DragDropEffects.Copy);
drgevent.Effect = DragDropEffects.Copy;
}
protected override void OnDragDrop(DragEventArgs drgevent)
{
System.Runtime.InteropServices.ComTypes.IDataObject dragObject =
(System.Runtime.InteropServices.ComTypes.IDataObject)drgevent.Data;
IDropTargetHelper H = (IDropTargetHelper)Helper;
POINT p = new POINT();
p.x = drgevent.X;
p.y = drgevent.Y;
H.Drop(dragObject, ref p, DragDropEffects.Copy);
base.OnDragDrop(drgevent);
}
protected override void OnDragEnter(DragEventArgs drgevent)
{
System.Runtime.InteropServices.ComTypes.IDataObject dragObject =
(System.Runtime.InteropServices.ComTypes.IDataObject)drgevent.Data;
UpdateDragImage(dragObject);
IDropTargetHelper H = (IDropTargetHelper)Helper;
POINT p = new POINT();
p.x = drgevent.X;
p.y = drgevent.Y;
H.DragEnter(Handle, dragObject, ref p, DragDropEffects.Copy);
drgevent.Effect = DragDropEffects.Copy;
}
protected override void OnDragLeave(EventArgs e)
{
IDropTargetHelper H = (IDropTargetHelper)Helper;
H.DragLeave();
base.OnDragLeave(e);
}
protected override void OnGiveFeedback(GiveFeedbackEventArgs gfbevent)
{
// base.OnGiveFeedback(gfbevent);
}
protected override void OnQueryContinueDrag(QueryContinueDragEventArgs qcdevent)
{
if (qcdevent.EscapePressed == true)
{
qcdevent.Action = DragAction.Cancel;
}
// base.OnQueryContinueDrag(qcdevent);
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
public struct SHDRAGIMAGE
{
public POINT sizeDragImage;
public POINT ptOffset;
public IntPtr hbmpDragImage;
public uint crColorKey;
}
[ComImport, Guid("DE5BF786-477A-11d2-839D-00C04FD918D0"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IDragSourceHelper
{
void InitializeFromBitmap(
ref SHDRAGIMAGE pshdi,
[MarshalAs(UnmanagedType.Interface)]
System.Runtime.InteropServices.ComTypes.IDataObject pDataObject);
void InitializeFromWindow(
IntPtr hwnd,
ref POINT point,
[MarshalAs(UnmanagedType.Interface)]
System.Runtime.InteropServices.ComTypes.IDataObject pDataObject);
}
[ComImport, Guid("4657278B-411B-11d2-839A-00C04FD918D0"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IDropTargetHelper
{
void DragEnter(
IntPtr hwnd,
[MarshalAs(UnmanagedType.Interface)]
System.Runtime.InteropServices.ComTypes.IDataObject pDataObject,
ref POINT point,
DragDropEffects dwEffect);
void DragLeave();
void DragOver(ref POINT point, DragDropEffects dwEffect);
void Drop(
[MarshalAs(UnmanagedType.Interface)]
System.Runtime.InteropServices.ComTypes.IDataObject pDataObject,
ref POINT point,
DragDropEffects dwEffect);
void Show([MarshalAs(UnmanagedType.Bool)] bool fShow);
}
[ComImport, Guid("4657278A-411B-11d2-839A-00C04FD918D0")]
class DragDropHelper
{
}
public class FormatetDataObject
{
public FORMATETC format;
public STGMEDIUM medium;
}
public class DataObjectEx : DataObject, System.Runtime.InteropServices.ComTypes.IDataObject
{
public DataObjectEx(string format, object data)
: base(format, data)
{
}
public void SetData(ref FORMATETC formatIn, ref STGMEDIUM medium, bool release)
{
string s = formatIn.tymed.ToString() + formatIn.cfFormat.ToString();
FormatetDataObject dataObject = new FormatetDataObject();
dataObject.format = formatIn;
dataObject.medium = medium;
base.SetData(s, dataObject);
}
public void GetData(ref FORMATETC format, out STGMEDIUM medium)
{
string key = format.tymed.ToString() + format.dwAspect.ToString() + format.cfFormat.ToString();
FormatetDataObject dataObject;
dataObject = (FormatetDataObject)base.GetData(key);
if (dataObject != null)
{
System.Diagnostics.Debug.Assert(format.cfFormat == dataObject.format.cfFormat &&
format.dwAspect == dataObject.format.dwAspect &&
format.tymed == dataObject.format.tymed);
medium = dataObject.medium;
}
else
//
// return empty medium
//
{
STGMEDIUM m;
m.unionmember = IntPtr.Zero;
m.tymed = TYMED.TYMED_NULL;
m.pUnkForRelease = null;
medium = m;
}
}
public int QueryGetData(ref FORMATETC format)
{
string key = format.tymed.ToString() + format.dwAspect.ToString() + format.cfFormat.ToString();
if (base.GetDataPresent(key))
{
return 0; //S_OK
}
else
{
return 1; // S_FALSE
}
}
}
}
|
|
|
|
|
Hi,
Maybe someone can help me with my problem.
I have associated a filetype with my C# program. If I double-click on one of those, my program starts but doesn't do anything with the file because so far I didn't know what windows actually is doing.
Does windows starts the program with the filepath as a parameter or what happens?
How do I get the filepath into my program?
Thanks in advance.
|
|
|
|
|
Windows passes the filepath as a command line argument. Command line arguments are available as a string array to your applications Main method.
eg:
static class Program
{
[STAThread]
static void Main(string[] args)
{
foreach (string arg in args)
{
}
}
}
Phil
The opinions expressed in this post are not necessarily those of the author, especially if you find them impolite, inaccurate or inflammatory.
|
|
|
|
|
|
Hi,
Im using C# and MS Access,
I was wondering if someone could tell me how to store an object of a class into the database, with an sql query.
My class is variable length so i cant separate its members into columns.
i tried to do this with th ebinary formatter, but it gives an error
Type 'Billing_Module.Bill' in Assembly 'Billing Module, Version=1.0.2924.30808, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
MemoryStream fs = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, (object)newBill);
fs.Close();
aConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+path);
string queryCommand= "insert into BillHistory values ("+newBill.billNumber.ToString()+","+fs.ToString()+")";
can someone help me?
|
|
|
|
|
You need to implement ISerializable[^].
You might want to consider that if your class is changed, will it cause any problems for the saved objects.
|
|
|
|
|
Marking the classes with Serializable attribute should be enough.
|
|
|
|
|
i've had problems in the past where there are events on the object they need to be marked as nonserializable or the app tries to serialise anything that is hooked up to the event.
|
|
|
|
|
You can mark those fields as NonSerialized that you don't want to be serialized.
|
|
|
|
|
This kind of thing always seems like a good idea until you try to maintain it. It would be much better from a normalisation view point to create a database structure to store your data as things like version changes could get you in an absolute mess otherwise.
Failing that implement a custom xmlserialiser for your class so that you can import older versions of the code with just the new properties missing.
Russell
|
|
|
|
|
We can add various controls either using the designer of VS or thru programming/coding.
I want to know:
a) which one is good practice to carry out ?
b) what the difference between them ?
c) Even though we have VS, somtime we design/use control thru coding, why ?
|
|
|
|
|
humdumof wrote: a) which one is good practice to carry out ?
It depends on what you want to do. Adding controls through the designer is great for controls that will always be there (it makes it much easier to modify the controls). Adding controls via code is great if they are dynamic. (Also note that when the designer creates controls it is just writing code for them also)
humdumof wrote: b) what the difference between them ?
There is none. The designer will just write code for you. See the designer.cs file that goes along with your form. You will see that your form is a partial class. You get control over one file, visual studio gets the other.
humdumof wrote: c) Even though we have VS, somtime we design/use control thru coding, why ?
VS cannot do everything. The developers that created it do not (cannot) know everything that you might want to do with forms.
|
|
|
|
|
My best suggestion:
Look at Visual Studio as a productivity tool. If you lean on the designer very heavily, your ability to grasp several concepts might be stunted(delegate registration comes to mind)
I would suggest using Visual Studio to get yourself up and moving....learn the syntax of the language, and then step back a little bit and figure out what exactly it is that the IDE generates for you. Learn the concepts of explicitly declaring your own controls(will probably help you along your way to learning how to develop custom user controls, should you ever need to)....learn how to explicitly register and de-register event handlers.(This is usually your first exposure to delegates in the language) ....and once you get the concepts down, you will realize that the code that VS generates for you is generally very trivial and you can go back to letting it do its thing for you...with the knowledge of what it is doing, you will be able to tweak it if it's "canned" generation is ever not what you actually needed it to do.
"I need build Skynet. Plz send code"
|
|
|
|
|
Is there a IN operator in c#
I need to perform an operation like below:
if (item in Array[]/Arraylist[])
delete item
Regards,
Pavas
|
|
|
|
|
try to use if(array.Contains(item))
My small attempt...
|
|
|
|
|
Ohh yeh, thanks a lot.
Regards,
Pavas
|
|
|
|
|
uhhh......why not just suggest that he use the "in" keyword?
"I need build Skynet. Plz send code"
|
|
|
|
|
Alaric_ wrote: uhhh......why not just suggest that he use the "in" keyword?
What "in" keyword can be used in an if statement?
|
|
|
|
|
I think he's talking about the IN keyword (that he didn't bother reading the docs on) used in Linq.
|
|
|
|
|
Hi all,
I'm using a DateTimePicker Control to select a day (01/01/2008 for example)
is there a way to customise the Date Format so that I can use Relative Date ?
for example today is 03/01/2008 and I want to select 01/01/2008 so I just write -2d (relative date from today)
thanks for any ideas
|
|
|
|
|
that you can simply achieve thru code right?
My small attempt...
|
|
|
|
|
I can't enter (-2D) because the Date format is fixed ("MM dd yyyy" for example)
is there a way to enable editing the Date value without checking the format
or is there a way to create a relative format
sure when I get -2D in the Value property I can achieve thru code
thanks
modified on Thursday, January 03, 2008 7:13:19 AM
|
|
|
|
|
I am developing a windows application which needs automatic update. Any idea on how to implement this ?
|
|
|
|
|
ClickOnce does that, doesn't it ?
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
Christian Graus wrote: ClickOnce does that, doesn't it
Thanks, I checked and it does. But I am just trying other way. I will keep a web service which gives update notifications to the windows application. Windows application will download updates and invoke update program(a separate program I will make). This new program will close current running application and update the exe's with new one downloaded, and restarts the application. Do you think it's a fair idea ?
|
|
|
|