When your Clipboard isn't their Clipboard. Or my Clipboard...

by Michael S. Kaplan, published on 2011/03/23 07:01 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2011/03/23/10144161.aspx


And in a bizarre turn of events it was a question that had very little to do with internationalization that caught my eye:

Hi,

I saw there are two Clipboard in System.Windows and System.Windows.Forms respectively. Can someone help me to understand what’s the difference between these two and what’s the guidelines for when to use each?

Also, why we have two class that has nearly the same functionality, which is very confusing, at least for me.

Thanks,

Too true!

They actually come from two different places (System.Windows.Forms.Clipboard is in WinForms housed in System.Windows.Forms.dll, and System.Windows.Clipboard is in Windows Presentation Foundation (WPF) housed in PresentationCore.dll).

Admittedly they are pretty similar (both are wrapping the same native functionality that has been in Windows for the last fifteen versions, so how different could they really be?).

But they are not entirely compatible since they are different types (in particular their DataObject and IDataObject definitions in particular make drag-and-drop in shared components that span the two technologies a lot more complicated than they ought to be.

As my friend Paul pointed out in the thread, the WPF version was added for a simple reason -- so that a WPF application wouldn't have to load WinForms just to copy and paste.

Of course this points to a design problem that could have been avoided in the original .Net release, and one that could have been fixed in the version introduced in 3.5 when WPF was added: the clipboard functionality is not properly factored!

Now as you all know, the clipboard works throughout Windows -- and when I say this I mean that a technology completely unlike either of the above two technologies -- the console -- can also use the clipboard. It even has its own managed wrapper (System.Console), though if you want to use the clipboard you have to pull in either WinForms or WPF.

And that is dumb.

Or go native.

But the WinForms/Console split was understood when .Net 1.0 shipped, and the WPF/WinForms/Console splits were understood when .Net 3.5 shipped.

At any point they could have put the code at a lower level, one all could share. And if one or more were already written they could have gutted the written ones and called the lower level shared one.

It would have been easy.

And after all, they've already done it.

Twice!

Though when the suggestions along the above lines are made, they point out all the excuses why not to do the work, such as:

  1. the clipboard can only be opened by one process at a time;
  2. the Win32 clipboard API is very painful to use;
  3. lower level components were designed to be OS-agnostic;
  4. the clipboard only lets you store one item;
  5. it shouldn't be up to .Net to make the Windows API usable.

and so on.

I'm not impressed.

Even ignoring the whole Microsoft.Win32 namespace that would be perfect for a Clipboard class!

For #4 and #5 and pretty much all of them, .Net could have made their own brand new thing instead of wrapping the old one if they feel it is so limited. They could drive the change, and be the change! They ship with Windows so anything they add would be around for all of Windows too, in no worse of a way that the Windows "only latest version" provides, and probably better since they can go downlevel.

In other words, DEVDIV is much better than Windows to jump in here and do it right, if they are convinced Windows is doing it wrong....

Oh wait, never mind. As I pointed out in Microsoft is better as one big company, architecting new features like that is not what DEVDIV does. So of course they want the thing they wrap to do the heavy lifting.

It's like they shot their wad when they designed the memory allocator to get rid of ref-counting and a few other things. :-)

The above was me teasing them a bit, so don't read too much into it. Though it's fun when other people prove the points I make without even realizing they are doing so!

So never mind on pointing out they are the perhaps the best people to do it and get Windows toeventually pick it up like they do with Office. They don't want to think outside that box. And I can respect that.

To be perfectly honest trying to add new features to the clipboard is hard -- Office tried to do it a few versions ago, and have at this point almost completely removed the feature they added since the number of people with "this is great!" feedback were overwhelmingly outnumbered by the people with "this blows goats!" feedback. Even now pieces of it are still there (it's hard to remove low level functionality once it's surfaced to top level UI), but in Office 14 it is mostly history.

So with Office having struck out here I wouldn't suggest DEVDiV try to hit that one out of the park when they are bat.

But perhaps fixing what is broken in their own implementation:

would fit the mission that .Net has to do quality wrapping of functionality people use all the time. It would ease the maintenance burden and make it easier for developers to use.

As an aside, there are other features that got stuck in WinForms that should have been in Microsoft.Win32 -- like InputLanguage, for example.

It's like WinForms had a bunch of extra devs who did core work that had to be done, and

were all napping when such classes were stuck in the wrong place, and in the case of InputLanguage with incomplete functionality based on the abilities of what it's wrapping.

But I digress.... :-)

I really believe .Net did some stuff wrong here and really should take steps to fix things. I know I'm not the only one to do clipboard stuff in Win32 p/invoke just to avoid some of the weirdnesses the managed implementations add to the mix. And that can't be what they intended.

They are not the group that you generally expect poor factoring or shoddy design from. At all. They really ought to fix this!

In my mind I blame this all on the fact that Katy and Kim aren't at Microsoft anymore, and Joe isn't in that group anymore. Which is silly since none of them were working on these things anyway so its not like having then around would change anything. Well, I mean other the fact that all of them would listen to me rant about it, and be amused.

Though I am having lunch with Kim later today. Maybe I can guilt her into paying for lunch for not speaking up about this bug while she was here? Just kidding!

The moral of the whole story in this blog? I should clearly stick to internationalization, where I have strong opinions.... :-)


Richard on 23 Mar 2011 1:05 PM:

There's a whole lot of refactoring that needs to be done, and probably won't be done for the sake of backwards-compatibility.

For example, the IWin32Window interface is defined twice - once in WinForms and once in WPF. Even though the interfaces are identical, they're two completely different interfaces to .NET; a class which implements one can't be passed to a method which expects the other.

Drawing is another nightmare - WinForms and WebForms use System.Drawing, whereas WPF does its own thing. I understand that WPF is based on newer technology behind the scenes, but do we really need two versions of every shared class?!

At some point, I think they need to ditch backwards compatibility and start again. If they don't, I fear the BCL could collapse under the weight of outdated and obsolete technology.

Cheong on 23 Mar 2011 7:01 PM:

Oh... I thought that they have to seperate the namespace because lots of controls in WPF are not "real" window objects, so the handling would be a bit different (You'll need to do some collision testing behind the scene, etc.).

Actually I have no problem that they have to maintain seperate set of classes/function calls for WinForm/WPF, especially when they may have to support scenerios that they may have to make it works as Windows application and Browser application.

Michael S. Kaplan on 23 Mar 2011 7:19 PM:

That isn't why they did this.

But are you saying you are okay with having to pull the other of those libraries in for a CONSOLE app?

Cheong on 23 Mar 2011 10:22 PM:

No. I'm talking about the nature of WPF.

WPF applications doesn't necessary be Windows application, they can also be applications that runs in web browsers. Therefore I think it's reasonable that they leave the provision that the clipboard related function may behave differently for WPF web cases (At least in that case the documentation will be different, and becomes unnecessarily complicated for normal WinForm users). I'd think that probably for similar reason only one of the common dialog function is implemented under the Microsoft.Win32.CommonDialog class (The OpenFileDialog and SaveFileDialog classes are subclass of FileDialog, so I count only once. And it should be able to work for both Windows application and web containers).

Michael S. Kaplan on 24 Mar 2011 5:40 AM:

So you don't think a more reasonable design is a single shared bit of code that wraps the core clipboard functionality (pretty much written since the WPF as and WinForms clipboard code and OM is largely the same), and then if WinForms or WPF or PowerShell or the managed MMC snapin on anything needs extra help it can be built atop it?

The current design largely duplicates the same code in two places and provides no help in the others. This is a poorly factored solution.

Yet the fix is straightforward enough -- gut the two existing frameworks, put the code in the CLR somewhere, and have everyone (including the two existing implementations, for back compat) call the shared code. This can allow code with different needs to build those needs into its own extensions and not burden others with them....

Random832 on 24 Mar 2011 6:12 AM:

3.lower level components were designed to be OS-agnostic;

Why is a clipboard considered an OS-specific concept when a console is not?

5.it shouldn't be up to .Net to make the Windows API usable.

It is, however, absolutely up to .Net to make the .Net API usable. If that requires making something heavier and demoting win32 from "the thing they wrap" to 'back-end', then they should do that. By supporting a clipboard at all, .Net took responsibility for making the .Net clipboard usable.


referenced by

2011/03/28 Address formats are hard, let's go shopping!, revisited (aka To me, 'good enough' just isn't good enough)

go to newer or older post, or back to index or month or day