Checking for Copy vs. Move in Delphi Drag and Drop - delphi

Using the 'standard' VCL drag and drop events OnDragOver and OnDragDrop, how can I distinguish between "Copy" and "Move" operations?
I don't seem to have a TDragType available, and the keyboard Shift state isn't passed to these events.

This is not something you can determine from the events because the events make no assumptions about your application needs or capabilities.
Interpreting a particular drag/drop as having any particular semantics is the responsibility of the application itself - the OS cannot know how the application will react to the dropping of a file so can make no assumptions about what the dragging operation may imply for the user.
For many applications there will be no distinction between copy/move, there will be just drag-and-drop.
The copy/move distinction is something that Windows Explorer applies to file operations. For "vanilla" drag/drops it applies rules based on original and destination drive volumes - dragging/dropping files around on a volume is a move operation, by default. Dragging/dropping across volumes is a copy, by default.
But these are only default rules determined by the application (Windows Explorer). The user can override these default using keyboard shortcuts during dragging and (most importantly) when dropping. But these are defined and interpreted by the particular application - i.e. Windows Explorer - not the OS.
So, if you're application is a drop target for files that may be dragged from Windows Explorer, and if it makes sense for your application to discriminate between copy and move, then you may need to support the same keyboard modifiers that Windows Explorer supports. I don't believe these are modifiable (although I'd advise this be confirmed), so you could simply test the state of the Ctrl or Shift keys in your drag events:
Ctrl = COPY
Shift = MOVE
Ctrl + Shift = MAKE SHORTCUT (if this is applicable to your application)
GetKeyState() can be used to directly interrogate the state of a specific key at any given moment in time.
If a varying "default" behaviour is desired then you would have to apply your own tests to the source information to determine which default makes most sense (i.e. to mimic the Windows Explorer "volume boundary" default rules), or simply choose the most appropriate or intuitive default action for your application.

The short answer is - you don't. The VCL's built-in drag-n-drop system does not distinquish between the two. You can, however, derive your own TDragObject/Ex classes to control what kind of data actually gets dragged around.

If you want to use Drag'n'Drop between your application and other Windows applications, it's worth looking at Anders Melander's Drag and Drop Component Suite for Delphi.
The latest code being here.

Not sure about Delphi specifically, but in C# you check the AllowedEffect property of your event parameter. Since they both link back to Win32 I can't imagine there is much difference.
http://msdn.microsoft.com/en-us/library/system.windows.forms.drageventargs.aspx has a good example. Hope this helps!

Related

When activating OLEControl in my PowerBuilder application, toolbar items disappear

I have created a COM Interop Control in C# to use in my PB application. If I add an ole control to my userobject and select my C# object in the painter, then an olecustomcontrol is created and everything works as expected. However, in order to use a 64-bit version of my object when building the project for a 64-bit platform (in PB Classic 12.6) I added an ole control but hit cancel when asked to select an object, so an olecontrol is created and I can use InsertClass to select my object at runtime. This is working for me but I have one issue: when the user clicks in my control, activating it, the toolbar icons on my MDI window disappear. From the research I have done, it sounds like PB may expect the ole object to provide the menus and toolbars, but my PB menu items are unaffected, it is just the toolbar. My control does contain a toolbar (the control is a rich text editor I created to workaround some shortcomings of the built in control) but I have also tried creating a new Interop Control with only a plain text box on it and got the same results. Actually I also tried using one of the Microsoft controls (Microsoft InkEdit Control) installed on my system, and again got the same results.
Does anyone know how I can fix this toolbar problem? (I'm at a loss, but I'm guessing it may be that I need to somehow tell PB to ignore OLE toolbars and/or tell my C# object not to advertise a toolbar.)
Ah, that legacy code we have to support for decades...
The following would take some research and may not eventually solve the problem, but I'd give it a try. I'd implement a "proxy" COM object that'd serve as an extra layer between your .NET OLE control and its OLE container. Such object would be exposed as OLE control to the PB runtime, and as OLE Container to the .NET control, and forward the COM methods calls between the two. It'd be much easier to code this layer with C++/ATL, but it should be doable with bare C#, too.
Then I'd watch the calls made on IOleInPlaceFrame and IOleInPlaceUIWindow interfaces and block those which lead to the undesired toolbar behavior (if any). I'd also limit the set of OLE control interfaces exposed to the PB runtime to some bare minimum.
The implementation details of AxHost and Control classes might be helpful here, as well as the ATL library source code.
This seems a bug. I created a very simple application that retrieves data into ole control and there was no code in any menu items. As soon data is fetched and ole control gets focus the main MDI toolbar disappear. Somebody should report that bug to SAP.
https://answers.sap.com/questions/300798/toolbar-disappear-when-ole-control-get-focus.html

How to Update Look and Feel of Older Windows User Interface?

I have a really solid computer program that was written for Windows XP. The program still works great and I would like to update the look and feel of the user interface.
At this time, I would like to give the buttons etc. a more sleek, contemporary look. Much better would be to allow functionality of touch and swipe etc. for tablets and such.
Can anyone tell me what tools in Delphi are used to accomplish this? For instance, do I need to change every button and object manually through object inspector or can I update/modify all objects objects within a project using a single set of commands?
You can start by enabling Windows themes, using Project->Options->Appearance from the IDE's main menu. It's on by default since D2007, but won't be on because your app is coming from Delphi 5. (New projects have it turned on by default, but the IDE can't know if you want it enabled or not when importing older projects.)
You can then start looking at adding gesture support by looking into the documentation for TGestureManager and TGesture. There's a TGestureManager for both VCL and FireMonkey (FMX) applications.
Note that for cross-platform support (Android, iOS, and OS X) you'll need to port your application from the VCL to FMX.

How to simulate touch with left mousebutton

I'm developing a Firemonkey Application wich should run on Windows with touchscreen.
Because I have no touchscreen for my development system, I can't test the behavior of some controls. For example the panning in a TListbox doesn't work with the mouse-button. It only works if ssTouch in KeyState is set.
Is there a way to simulate the touch via the mouse?
Regards,
Michael
Well, aside from the obvious answer (save up and get that touchscreen!), there are some solutions, but they might be a bit involved.
If I wanted to do this on PC, I would start by making a copy of the Firemonkey source code and including it in my project.
After checking to see that your 'local' copy of Firemonkey is compiling properly, you will have to edit this file: "FMX.Platform.Win.pas". Open this file and then search for "ssTouch".
Inside of the WM_LBUTTONDOWN handler, there must be some logic which determines whether "ssTouch" is part of the KeyState or not. Add it in yourself, and then the left button should be evaluated as a touch input.

Updates for controls in Win3.1 palette

Some people are saying that I must update the controls in Win3.1 palette (especially TFilterComboBox) with modern ones. But does Delphi provide such new controls?
I need to create a GUI (somehow similar to Windows Explorer, consisting in a DirectoryListBox, FileListBox and a FilterComboBox) where I allow the user to easily explore for files of a specific type. Since the interface is centered around this Explorer, a TOpenDialog will be like hitting the customer with a hammer in the middle of his head. I need an 'easy to use' solution.
Unfortunately Shell Controls are not stable enough to be used as replacement.
The Shell Controls that come as a demo with Delphi only have to be installed, and you'll have some nice shell controls. There is, IMO, no big need to get 3rd party components for that.
Look for ShellCtls (or similar, can't check right now) in your demos folder. That Demos folder can be accessed from the Windows Start menu for your version of Delphi.
Update
They are not in a Demos folder, it is called Samples now. They can be found in Samples\Delphi\VCL\ShellControls. Install vclshlctrls.dproj first and then dclshlctrls.dproj.
In our application we use tpShellShock which works rather well. You may need to tweak it a little for Unicode Delphi, but if I recall correctly that was pretty simple to do.
Here's what it looks like:

How to temporarily turn off "snap-to" (anything) in Delphi IDE /visual designer (D2007)

Every once in a while this drives me crazy: I want to move a control to some precise location, WITHOUT any kind of "snapping" -- snap-to-grid, snap-to-guidelines, snap-to-border, etc... and Delphi won't let me. Is there a key combination that one can use while dragging to temporarily turn off any and all "snapping"? I seem to recall it being available in D6, but can't for the life of me find a similar combination in D2007, short of going into Tools -> Options, etc... (which kind of defeats the purpose).
Drag with the Alt key down to disable snapping to the grid. Snapping to objects will remain in effect. You can use Ctrl with the arrow keys to move one pixel at a time. You can also type the desired coordinates into the Object Inspector.
In Delphi 2009 CodeGear has changed the behavior of ALT+Move to also disable the designer guide lines. But in Delphi 2007 this feature can't be turned off without an external tool.
On of those tools (and I think the only that can do this) is the DDevExtensions 1.6 IDE plugin that adds this ability to ALT+Move for Delphi 2007.

Resources